diff options
| author | Tom Lane | 2016-07-26 19:25:02 +0000 |
|---|---|---|
| committer | Tom Lane | 2016-07-26 19:25:02 +0000 |
| commit | 4452000f310b8c1c947ee724618c1bc31ed20242 (patch) | |
| tree | 456eb11e244335261237e07559ead10849313447 /src/backend/executor/execQual.c | |
| parent | c1a95425780ef8e72c2f65504a7e90bcb223ca4a (diff) | |
Fix constant-folding of ROW(...) IS [NOT] NULL with composite fields.
The SQL standard appears to specify that IS [NOT] NULL's tests of field
nullness are non-recursive, ie, we shouldn't consider that a composite
field with value ROW(NULL,NULL) is null for this purpose.
ExecEvalNullTest got this right, but eval_const_expressions did not,
leading to weird inconsistencies depending on whether the expression
was such that the planner could apply constant folding.
Also, adjust the docs to mention that IS [NOT] DISTINCT FROM NULL can be
used as a substitute test if a simple null check is wanted for a rowtype
argument. That motivated reordering things so that IS [NOT] DISTINCT FROM
is described before IS [NOT] NULL. In HEAD, I went a bit further and added
a table showing all the comparison-related predicates.
Per bug #14235. Back-patch to all supported branches, since it's certainly
undesirable that constant-folding should change the semantics.
Report and patch by Andrew Gierth; assorted wordsmithing and revised
regression test cases by me.
Report: <[email protected]>
Diffstat (limited to 'src/backend/executor/execQual.c')
| -rw-r--r-- | src/backend/executor/execQual.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index d04d1a89a7f..2b9102125ef 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -3815,6 +3815,21 @@ ExecEvalNullTest(NullTestState *nstate, if (ntest->argisrow && !(*isNull)) { + /* + * The SQL standard defines IS [NOT] NULL for a non-null rowtype + * argument as: + * + * "R IS NULL" is true if every field is the null value. + * + * "R IS NOT NULL" is true if no field is the null value. + * + * This definition is (apparently intentionally) not recursive; so our + * tests on the fields are primitive attisnull tests, not recursive + * checks to see if they are all-nulls or no-nulls rowtypes. + * + * The standard does not consider the possibility of zero-field rows, + * but here we consider them to vacuously satisfy both predicates. + */ HeapTupleHeader tuple; Oid tupType; int32 tupTypmod; |
