conditional rules (rules with WHERE clauses). We cannot support these
since there's noplace to hang a condition on a utility statement.
We caught the other case (attempt to attach a condition at rewrite time)
awhile ago, but this one escaped notice until now.
to do that, but inconsistently.) Make bit type reject too short input,
too, per SQL. Since it no longer zero pads, 'zpbit*' has been renamed to
'bit*' in the source, hence initdb.
in referencing and referenced columns of an fk constraint
aren't comparable using '=' at constraint definition time
rather than insert/update time.
Stephan Szabo
a separate statement (though it can still be invoked as part of VACUUM, too).
pg_statistic redesigned to be more flexible about what statistics are
stored. ANALYZE now collects a list of several of the most common values,
not just one, plus a histogram (not just the min and max values). Random
sampling is used to make the process reasonably fast even on very large
tables. The number of values and histogram bins collected is now
user-settable via an ALTER TABLE command.
There is more still to do; the new stats are not being used everywhere
they could be in the planner. But the remaining changes for this project
should be localized, and the behavior is already better than before.
A not-very-related change is that sorting now makes use of btree comparison
routines if it can find one, rather than invoking '<' twice.
such as
SELECT f1 FROM foo UNION SELECT ... ORDER BY upper(f1)
to draw
'ORDER BY on a UNION/INTERSECT/EXCEPT result must be on one of the result columns'
rather than the uninformative 'f1 not found' we were producing before.
Eventually this should actually work, but that looks much too hard to try
to implement in late beta...
clause with an alias is a <subquery> and therefore hides table references
appearing within it, according to the spec. This is the same as the
preliminary patch I posted to pgsql-patches yesterday, plus some really
grotty code in ruleutils.c to reverse-list a query tree with the correct
alias name depending on context. I'd rather not have done that, but unless
we want to force another initdb for 7.1, there's no other way for now.
and revert documentation to describe the existing INHERITS clause
instead, per recent discussion in pghackers. Also fix implementation
of SQL_inheritance SET variable: it is not cool to look at this var
during the initial parsing phase, only during parse_analyze(). See
recent bug report concerning misinterpretation of date constants just
after a SET TIMEZONE command. gram.y really has to be an invariant
transformation of the query string to a raw parsetree; anything that
can vary with time must be done during parse analysis.
work where we can (given that the executor only handles it at top level)
and generate an error where we can't. Note that while the parser has
been allowing views to say SELECT FOR UPDATE for a few weeks now, that
hasn't actually worked until just now.
I believe this should fix the issue that Philip Warner
noticed about the check for unique constraints meeting the
referenced keys of a foreign key constraint allowing the
specification of a subset of a foreign key instead of
rejecting it. I also added tests for a base case of
this to the foreign key and alter table tests and patches
for expected output.
report from Joel Burton. Turns out that my simple idea of turning the
SELECT into a subquery does not interact well *at all* with the way the
rule rewriter works. Really what we need to make INSERT ... SELECT work
cleanly is to decouple targetlists from rangetables: an INSERT ... SELECT
wants to have two levels of targetlist but only one rangetable. No time
for that for 7.1, however, so I've inserted some ugly hacks to make the
rewriter know explicitly about the structure of INSERT ... SELECT queries.
Ugh :-(
maintained for each cache entry. A cache entry will not be freed until
the matching ReleaseSysCache call has been executed. This eliminates
worries about cache entries getting dropped while still in use. See
my posting to pg-hackers of even date for more info.
(WAL logging for this is not done yet, however.) Clean up a number of really
crufty things that are no longer needed now that DROP behaves nicely. Make
temp table mapper do the right things when drop or rename affecting a temp
table is rolled back. Also, remove "relation modified while in use" error
check, in favor of locking tables at first reference and holding that lock
throughout the statement.
took some rejiggering of typename and ACL parsing, as well as moving
parse_analyze call out of parser(). Restructure postgres.c processing
so that parse analysis and rewrite are skipped when in abort-transaction
state. Only COMMIT and ABORT statements will be processed beyond the raw
parser() phase. This addresses problem of parser failing with database access
errors while in aborted state (see pghackers discussions around 7/28/00).
Also fix some bugs with COMMIT/ABORT statements appearing in the middle of
a single query input string.
Function, operator, and aggregate arguments/results can now use full
TypeName production, in particular foo[] for array types.
DROP OPERATOR and COMMENT ON OPERATOR were broken for unary operators.
Allow CREATE AGGREGATE to accept unquoted numeric constants for initcond.
SQL92 semantics, including support for ALL option. All three can be used
in subqueries and views. DISTINCT and ORDER BY work now in views, too.
This rewrite fixes many problems with cross-datatype UNIONs and INSERT/SELECT
where the SELECT yields different datatypes than the INSERT needs. I did
that by making UNION subqueries and SELECT in INSERT be treated like
subselects-in-FROM, thereby allowing an extra level of targetlist where the
datatype conversions can be inserted safely.
INITDB NEEDED!
(Don't forget that an alias is required.) Views reimplemented as expanding
to subselect-in-FROM. Grouping, aggregates, DISTINCT in views actually
work now (he says optimistically). No UNION support in subselects/views
yet, but I have some ideas about that. Rule-related permissions checking
moved out of rewriter and into executor.
INITDB REQUIRED!
- rename ichar() to chr() (discussed with Tom)
- add docs for oracle compatible routines:
btrim()
ascii()
chr()
repeat()
- fix bug with timezone in to_char()
- all to_char() variants return NULL instead textin("")
if it's needful.
The contrib/odbc is without changes and contains same routines as main
tree ... because I not sure how plans are Thomas with this :-)
Karel
---------------------------------------------------------------------------
This effectively one line patch should fix the fact that
foreign key definitions in create table were erroring if
a primary key was defined. I was using the columns
list to get the columns of the table for comparison, but
it got reused as a temporary list inside the primary key
stuff.
Stephan Szabo
didn't hear anything about, but which would
have broken with the function manager changes
anyway.
Well, this patch checks that a unique constraint
of some form (unique or pk) is on the referenced
columns of an FK constraint and that the columns
in the referencing table exist at creation time.
The former is to move closer to SQL compatibility
and the latter is in answer to a bug report.
I also added a basic check of this functionality
to the alter table and foreign key regression
tests.
Stephan Szabo
sszabo@bigpanda.com
including utility statements. Still can't copy or compare executor
state, but at present that doesn't seem to be necessary. This makes
it possible to execute most (all?) utility statements in plpgsql.
Had to change parsetree representation of CreateTrigStmt so that it
contained only legal Nodes, and not bare string constants.
from Param nodes, per discussion a few days ago on pghackers. Add new
expression node type FieldSelect that implements the functionality where
it's actually needed. Clean up some other unused fields in Func nodes
as well.
NOTE: initdb forced due to change in stored expression trees for rules.
Include updates for the comment.sql regression test.
Implement SET SESSION CHARACTERISTICS and SET DefaultXactIsoLevel.
Implement SET SESSION CHARACTERISTICS TRANSACTION COMMIT
and SET AutoCommit in the parser only.
Need to add code to actually do something.
Implement WITHOUT TIME ZONE type qualifier.
Define SCHEMA keyword, along with stubbed-out grammar.
Implement "[IN|INOUT|OUT] [varname] type" function arguments
in parser only; INOUT and OUT throws an elog(ERROR).
Add PATH as a type-specific token, since PATH is in SQL99
to support schema resource search and resolution.
discussion of 5/19/00). pg_index is now searched for indexes of a
relation using an indexscan. Moreover, this is done once and cached
in the relcache entry for the relation, in the form of a list of OIDs
for the indexes. This list is used by the parser and executor to drive
lookups in the pg_index syscache when they want to know the properties
of the indexes. Net result: index information will be fully cached
for repetitive operations such as inserts.
key call sites are changed, but most called functions are still oldstyle.
An exception is that the PL managers are updated (so, for example, NULL
handling now behaves as expected in plperl and plpgsql functions).
NOTE initdb is forced due to added column in pg_proc.
keys lists of Constraint nodes. This eliminates a type pun that would
probably have caused trouble someday, and eliminates circular references
in the parsetree that were causing trouble now.
Also, change parser's uses of strcasecmp() to strcmp(). Since scan.l
has downcased any unquoted identifier, it is never correct to check an
identifier with strcasecmp() in the parser. For example,
CREATE TABLE FOO (f1 int, UNIQUE("F1"));
was accepted, which is wrong, and xlateSqlFunc did more than it should:
select datetime();
ERROR: Function 'timestamp()' does not exist
(good)
select "DateTime"();
ERROR: Function 'timestamp()' does not exist
(bad)
Implement TIME WITH TIME ZONE type (timetz internal type).
Remap length() for character strings to CHAR_LENGTH() for SQL92
and to remove the ambiguity with geometric length() functions.
Keep length() for character strings for backward compatibility.
Shrink stored views by removing internal column name list from visible rte.
Implement min(), max() for time and timetz data types.
Implement conversion of TIME to INTERVAL.
Implement abs(), mod(), fac() for the int8 data type.
Rename some math functions to generic names:
round(), sqrt(), cbrt(), pow(), etc.
Rename NUMERIC power() function to pow().
Fix int2 factorial to calculate result in int4.
Enhance the Oracle compatibility function translate() to work with string
arguments (from Edwin Ramirez).
Modify pg_proc system table to remove OID holes.
as independent clauses in the grammar. analyze.c takes care of putting
the data where it belongs and complaining about invalid combinations.
Also, make TEMP (and TEMPORARY) non-reserved words.
SELECT a FROM t1 tx (a);
Allow join syntax, including queries like
SELECT * FROM t1 NATURAL JOIN t2;
Update RTE structure to hold column aliases in an Attr structure.
Added constraint dumping capability to pg_dump (also from Stephan)
Fixed DROP TABLE -> RelationBuildTriggers: 2 record(s) not found for rel
error.
Fixed little error in gram.y I made the last days.
Jan
SELECT DISTINCT ON (expr [, expr ...]) targetlist ...
and there is a check to make sure that the user didn't specify an ORDER BY
that's incompatible with the DISTINCT operation.
Reimplement nodeUnique and nodeGroup to use the proper datatype-specific
equality function for each column being compared --- they used to do
bitwise comparisons or convert the data to text strings and strcmp().
(To add insult to injury, they'd look up the conversion functions once
for each tuple...) Parse/plan representation of DISTINCT is now a list
of SortClause nodes.
initdb forced by querytree change...
allows casts without specific length requirements to continue to work
as they did before; that is, x::char will not truncate the value of x,
whereas x::char(1) will. Likewise for NUMERIC precision/scale.
The column length defaults of char(1) and numeric(30,6) are now inserted
in analyze.c's processing of CREATE TABLE.
yet, but at least we can give a better error message:
regression=> select count(distinct f1) from int4_tbl;
ERROR: aggregate(DISTINCT ...) is not implemented yet
instead of 'parser: parse error at or near distinct'.
subselects can only appear on the righthand side of a binary operator.
That's still true for quantified predicates like x = ANY (SELECT ...),
but a subselect that delivers a single result can now appear anywhere
in an expression. This is implemented by changing EXPR_SUBLINK sublinks
to represent just the (SELECT ...) expression, without any 'left hand
side' or combining operator --- so they're now more like EXISTS_SUBLINK.
To handle the case of '(x, y, z) = (SELECT ...)', I added a new sublink
type MULTIEXPR_SUBLINK, which acts just like EXPR_SUBLINK used to.
But the grammar will only generate one for a multiple-left-hand-side
row expression.
mentioned in FROM but not elsewhere in the query: such tables should be
joined over anyway. Aside from being more standards-compliant, this allows
removal of some very ugly hacks for COUNT(*) processing. Also, allow
HAVING clause without aggregate functions, since SQL does. Clean up
CREATE RULE statement-list syntax the same way Bruce just fixed the
main stmtmulti production.
CAUTION: addition of a field to RangeTblEntry nodes breaks stored rules;
you will have to initdb if you have any rules.
expressions in CREATE TABLE. There is no longer an emasculated expression
syntax for these things; it's full a_expr for constraints, and b_expr
for defaults (unfortunately the fact that NOT NULL is a part of the
column constraint syntax causes a shift/reduce conflict if you try a_expr.
Oh well --- at least parenthesized boolean expressions work now). Also,
stored expression for a column default is not pre-coerced to the column
type; we rely on transformInsertStatement to do that when the default is
actually used. This means "f1 datetime default 'now'" behaves the way
people usually expect it to.
BTW, all the support code is now there to implement ALTER TABLE ADD
CONSTRAINT and ALTER TABLE ADD COLUMN with a default value. I didn't
actually teach ALTER TABLE to call it, but it wouldn't be much work.
additional argument specifying the kind of lock to acquire/release (or
'NoLock' to do no lock processing). Ensure that all relations are locked
with some appropriate lock level before being examined --- this ensures
that relevant shared-inval messages have been processed and should prevent
problems caused by concurrent VACUUM. Fix several bugs having to do with
mismatched increment/decrement of relation ref count and mismatched
heap_open/close (which amounts to the same thing). A bogus ref count on
a relation doesn't matter much *unless* a SI Inval message happens to
arrive at the wrong time, which is probably why we got away with this
sloppiness for so long. Repair missing grab of AccessExclusiveLock in
DROP TABLE, ALTER/RENAME TABLE, etc, as noted by Hiroshi.
Recommend 'make clean all' after pulling this update; I modified the
Relation struct layout slightly.
Will post further discussion to pghackers list shortly.
sort order down into planner, instead of handling it only at the very top
level of the planner. This fixes many things. An explicit sort is now
avoided if there is a cheaper alternative (typically an indexscan) not
only for ORDER BY, but also for the internal sort of GROUP BY. It works
even when there is no other reason (such as a WHERE condition) to consider
the indexscan. It works for indexes on functions. It works for indexes
on functions, backwards. It's just so cool...
CAUTION: I have changed the representation of SortClause nodes, therefore
THIS UPDATE BREAKS STORED RULES. You will need to initdb.
of the SELECT part of the statement is just like a plain SELECT. All
INSERT-specific processing happens after the SELECT parsing is done.
This eliminates many problems, e.g. INSERT ... SELECT ... GROUP BY using
the wrong column labels. Ensure that DEFAULT clauses are coerced to
the target column type, whether or not stored clause produces the right
type. Substantial cleanup of parser's array support.
aggregate functions, as in
select a, b from foo group by a;
The ungrouped reference to b is not kosher, but formerly we neglected to
check this unless there was an aggregate function somewhere in the query.
lists are now plain old garden-variety Lists, allocated with palloc,
rather than specialized expansible-array data allocated with malloc.
This substantially simplifies their handling and eliminates several
sources of memory leakage.
Several basic types of erroneous queries (syntax error, attempt to
insert a duplicate key into a unique index) now demonstrably leak
zero bytes per query.
constraints. Reported by Tom Lane.
Now, check for duplicate indices and retain the one which is a primary-key.
Adjust elog NOTICE messages to surround table and column names with single
quotes.
Ok. I made patches replacing all of "#if FALSE" or "#if 0" to "#ifdef
NOT_USED" for current. I have tested these patches in that the
postgres binaries are identical.
Included patches fix a portability problem of unsetenv() used in
6.4.2 multi-byte support. unsetenv() is only avaliable on FreeBSD and
Linux so I decided to replace with putenv().
a field was labelled as a primary key, the system automatically
created a unique index on the field. This patch extends it so
that the index has the indisprimary field set. You can pull a list
of primary keys with the followiing select.
SELECT pg_class.relname, pg_attribute.attname
FROM pg_class, pg_attribute, pg_index
WHERE pg_class.oid = pg_attribute.attrelid AND
pg_class.oid = pg_index.indrelid AND
pg_index.indkey[0] = pg_attribute.attnum AND
pg_index.indisunique = 't';
There is nothing in this patch that modifies the template database to
set the indisprimary attribute for system tables. Should they be
changed or should we only be concerned with user tables?
D'Arcy
INTERSECT and EXCEPT is available for postgresql-v6.4!
The patch against v6.4 is included at the end of the current text
(in uuencoded form!)
I also included the text of my Master's Thesis. (a postscript
version). I hope that you find something of it useful and would be
happy if parts of it find their way into the PostgreSQL documentation
project (If so, tell me, then I send the sources of the document!)
The contents of the document are:
-) The first chapter might be of less interest as it gives only an
overview on SQL.
-) The second chapter gives a description on much of PostgreSQL's
features (like user defined types etc. and how to use these features)
-) The third chapter starts with an overview of PostgreSQL's internal
structure with focus on the stages a query has to pass (i.e. parser,
planner/optimizer, executor). Then a detailed description of the
implementation of the Having clause and the Intersect/Except logic is
given.
Originally I worked on v6.3.2 but never found time enough to prepare
and post a patch. Now I applied the changes to v6.4 to get Intersect
and Except working with the new version. Chapter 3 of my documentation
deals with the changes against v6.3.2, so keep that in mind when
comparing the parts of the code printed there with the patched sources
of v6.4.
Here are some remarks on the patch. There are some things that have
still to be done but at the moment I don't have time to do them
myself. (I'm doing my military service at the moment) Sorry for that
:-(
-) I used a rewrite technique for the implementation of the Except/Intersect
logic which rewrites the query to a semantically equivalent query before
it is handed to the rewrite system (for views, rules etc.), planner,
executor etc.
-) In v6.3.2 the types of the attributes of two select statements
connected by the UNION keyword had to match 100%. In v6.4 the types
only need to be familiar (i.e. int and float can be mixed). Since this
feature did not exist when I worked on Intersect/Except it
does not work correctly for Except/Intersect queries WHEN USED IN
COMBINATION WITH UNIONS! (i.e. sometimes the wrong type is used for the
resulting table. This is because until now the types of the attributes of
the first select statement have been used for the resulting table.
When Intersects and/or Excepts are used in combination with Unions it
might happen, that the first select statement of the original query
appears at another position in the query which will be executed. The reason
for this is the technique used for the implementation of
Except/Intersect which does a query rewrite!)
NOTE: It is NOT broken for pure UNION queries and pure INTERSECT/EXCEPT
queries!!!
-) I had to add the field intersect_clause to some data structures
but did not find time to implement printfuncs for the new field.
This does NOT break the debug modes but when an Except/Intersect
is used the query debug output will be the already rewritten query.
-) Massive changes to the grammar rules for SELECT and INSERT statements
have been necessary (see comments in gram.y and documentation for
deatails) in order to be able to use mixed queries like
(SELECT ... UNION (SELECT ... EXCEPT SELECT)) INTERSECT SELECT...;
-) When using UNION/EXCEPT/INTERSECT you will get:
NOTICE: equal: "Don't know if nodes of type xxx are equal".
I did not have time to add comparsion support for all the needed nodes,
but the default behaviour of the function equal met my requirements.
I did not dare to supress this message!
That's the reason why the regression test for union will fail: These
messages are also included in the union.out file!
-) Somebody of you changed the union_planner() function for v6.4
(I copied the targetlist to new_tlist and that was removed and
replaced by a cleanup of the original targetlist). These chnages
violated some having queries executed against views so I changed
it back again. I did not have time to examine the differences between the
two versions but now it works :-)
If you want to find out, try the file queries/view_having.sql on
both versions and compare the results . Two queries won't produce a
correct result with your version.
regards
Stefan
statements:
- the table definition with a default clause referencing the sequence;
- a CREATE SEQUENCE statement;
- a UNIQUE constraint, which expands into a CREATE INDEX statement.
This is not a perfect solution, since the sequence will remain even if
the table is dropped. Also, there is no absolute protection on updating
the sequence column.
now. Here some tested features, (examples included in the patch):
1.1) Subselects in the having clause 1.2) Double nested subselects
1.3) Subselects used in the where clause and in the having clause
simultaneously 1.4) Union Selects using having 1.5) Indexes
on the base relations are used correctly 1.6) Unallowed Queries
are prevented (e.g. qualifications in the
having clause that belong to the where clause) 1.7) Insert
into as select
2) Queries using the having clause on view relations also work
but there are some restrictions:
2.1) Create View as Select ... Having ...; using base tables in
the select 2.1.1) The Query rewrite system:
2.1.2) Why are only simple queries allowed against a view from 2.1)
? 2.2) Select ... from testview1, testview2, ... having...; 3) Bug
in ExecMergeJoin ??
Regards Stefan
yyerror ones from bison. It also includes a few 'enhancements' to
the C programming style (which are, of course, personal).
The other patch removes the compilation of backend/lib/qsort.c, as
qsort() is a standard function in stdlib.h and can be used any
where else (and it is). It was only used in
backend/optimizer/geqo/geqo_pool.c, backend/optimizer/path/predmig.c,
and backend/storage/page/bufpage.c
> > Some or all of these changes might not be appropriate for v6.3,
since we > > are in beta testing and since they do not affect the
current functionality. > > For those cases, how about submitting
patches based on the final v6.3 > > release?
There's more to come. Please review these patches. I ran the
regression tests and they only failed where this was expected
(random, geo, etc).
Cheers,
Jeroen
sequential scans! (I think it will also work with hash, index, etc
but I did not check it out! I made some High level changes which
should work for all access methods, but maybe I'm wrong. Please
let me know.)
Now it is possible to make queries like:
select s.sname, max(p.pid), min(p.pid) from part p, supplier s
where s.sid=p.sid group by s.sname having max(pid)=6 and min(pid)=1
or avg(pid)=4;
Having does not work yet for queries that contain a subselect
statement in the Having clause, I'll try to fix this in the next
days.
If there are some bugs, please let me know, I'll start to read the
mailinglists now!
Now here is the patch against the original 6.3 version (no snapshot!!):
Stefan
Pass List* of Aggregs into executor, and create needed array there.
No longer need to double-processs Aggregs with second copy in Query.
Fix crash when doing:
select sum(x+1) from test where 1 > 0;
Subject: [HACKERS] equal column and table name patch
This fixes a bug where selects fail when there is a column with the same
name as the table it's a part of.
as ints and longs. Touches on quite a few function args as
well. Most other files look ok as far as Oids go...still checking
though...
Since Oids are type'd as unsigned ints, they should prolly be used
with the %ud format string in elog and sprintf messages. Not sure
what kind of strangeness that could produce.
Darren King
Changes:
* Unique index capability works using the syntax 'create unique
index'.
* Duplicate OID's in the system tables are removed. I put
little scripts called 'duplicate_oids' and 'find_oid' in
include/catalog that help to find and remove duplicate OID's.
I also moved 'unused_oids' from backend/catalog to
include/catalog, since it has to be in the same directory
as the include files in order to work.
* The backend tries converting the name of a function or aggregate
to all lowercase if the original name given doesn't work (mostly
for compatibility with ODBC).
* You can 'SELECT NULL' to your heart's content.
* I put my _bt_updateitem fix in instead, which uses
_bt_insertonpg so that even if the new key is so big that
the page has to be split, everything still works.
* All literal references to system catalog OID's have been
replaced with references to define'd constants from the catalog
header files.
* I added a couple of node copy functions. I think this was a
preliminary attempt to get rules to work.
cache. I found if I manually added a line to flush the whole relation
cache, the assert error disappeared. Looking through the code, I found
that the relation cache is flushed at the end of each query if the
reference count is zero for the relation. However, printf's showed that
the rd_relcnt(reference count) for the accessed query was not returning
to zero after each query.
It turns out the parser was doing a heap_ropen in parser/analyze.c to
get information about the table's columns, but was not doing a
heap_close.
This was causing the query after the ALTER TABLE ADD to see the old
table structure, and the executor's assert was reporting the problem.
Previously Postgres95 wouldn't accept 'order by' clauses with fields
referred to as '<table>.<field>', e.g.:
select t1.field1, t2.field2 from table1 t1, table2 t2
order by t2.field2;
This syntax is required by the ODBC SQL spec.
Submitted by: Dan McGuirk <mcguirk@indirect.com>
While a normal SELECT statement can contain a GROUP BY clause, a cursor
declaration cannot. This was not the case in PG-1.0. Was there a good
reason why this was changed? Are cursors being phased out? Is there any way
to get data with just a SELECT (and without a DECLARE CURSOR ...)?
The patch below seems to fix things. If anyone can see a problem with it,
please let me know. Thanks.
Submitted by: David Smith <dasmith@perseus.tufts.edu>
The updating of array fields is broken in Postgres95-1.01, An array can
be only replaced with a new array but not have some elements modified.
This is caused by two bugs in the parser and in the array utilities.
Furthermore it is not possible to update array with a base type of
variable length.
- submitted by: Massimo Dal Zotto <dz@cs.unitn.it>
I have written some patches which add support for NULLs to Postgres95.
In fact support for NULLs was already present in postgres, but it had been
disabled because not completely debugged, I believe. My patches simply add
some checks here and there. To enable the new code you must add -DNULL_PATCH
to CFLAGS in Makefile.global. After recompiling you can do things like:
insert into a (x, y) values (1, NULL);
update a set x = NULL where x = 0;
You can't still use a "where x=NULL" clause, you must use ISNULL instead.
This could probably be an easy fix to do.
Submitted by: Massimo Dal Zotto <dz@cs.unitn.it>