Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
a1ee0662
Commit
a1ee0662
authored
Sep 20, 2001
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Provide tunable knob for x = NULL -> x IS NULL transformation, default to off.
parent
fd5e9597
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
101 additions
and
51 deletions
+101
-51
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+16
-8
doc/src/sgml/runtime.sgml
doc/src/sgml/runtime.sgml
+44
-1
src/backend/parser/gram.y
src/backend/parser/gram.y
+3
-26
src/backend/parser/parse_expr.c
src/backend/parser/parse_expr.c
+32
-10
src/backend/utils/misc/guc.c
src/backend/utils/misc/guc.c
+2
-4
src/include/parser/gramparse.h
src/include/parser/gramparse.h
+2
-1
src/include/parser/parse_expr.h
src/include/parser/parse_expr.h
+2
-1
No files found.
doc/src/sgml/func.sgml
View file @
a1ee0662
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.7
1 2001/09/10 02:46:18 ishii
Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.7
2 2001/09/20 14:20:26 petere
Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
...
...
@@ -266,16 +266,24 @@
Do <emphasis>not</emphasis> use
<literal><replaceable>expression</replaceable> = NULL</literal>
because NULL is not <quote>equal to</quote> NULL. (NULL represents
an unknown value, so it is not known whether two unknown values are
equal.) <productname>Postgres</productname> presently converts
<literal>x = NULL</literal> clauses to <literal>x IS NULL</literal> to
allow some broken client applications (such as
<productname>Microsoft Access</productname>) to work, but this may
be discontinued in a future release.
an unknown value, and it is not known whether two unknown values are
equal.)
</para>
<para>
Boolean values can be tested using the constructs
Some applications may (incorrectly) require that
<literal><replaceable>expression</replaceable> = NULL</literal>
returns true if <replaceable>expression</replaceable> evaluates to
the NULL value. To support these applications, the run-time option
<varname>transform_null_equals</varname> can be turned on (e.g.,
<literal>SET transform_null_equals TO ON;</literal>).
<productname>PostgreSQL</productname> would then convert <literal>x
= NULL</literal> clauses to <literal>x IS NULL</literal>. This was
the default behavior in releases 6.5 through 7.1.
</para>
<para>
Boolean values can also be tested using the constructs
<synopsis>
<replaceable>expression</replaceable> IS TRUE
<replaceable>expression</replaceable> IS NOT TRUE
...
...
doc/src/sgml/runtime.sgml
View file @
a1ee0662
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.8
0 2001/09/16 16:11:09
petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.8
1 2001/09/20 14:20:27
petere Exp $
-->
<Chapter Id="runtime">
...
...
@@ -1201,6 +1201,49 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TRANSFORM_NULL_EQUALS</varname> (<type>boolean</type>)</term>
<listitem>
<para>
When turned on, expressions of the form
<literal><replaceable>expr</> = NULL</literal> (or
<literal>NULL = <replaceable>expr</></literal>) are treated as
<literal><replaceable>expr</> IS NULL</literal>, that is, they
return true if <replaceable>expr</> evaluates to the NULL
value, and false otherwise. The correct behavior of
<literal><replaceable>expr</> = NULL</literal> is to always
return NULL (unknown). Therefore this option defaults to off.
</para>
<para>
However, filtered forms in <productname>Microsoft
Access</productname> generate queries that appear to use
<literal><replaceable>expr</> = NULL</literal> to test for
NULLs, so if you use that interface to access the database you
might want to turn this option on. Since expressions of the
form <literal><replaceable>expr</> = NULL</literal> always
return NULL (using the correct interpretation) they are not
very useful and do not appear often in normal applications, so
this option does little harm in practice. But new users are
frequently confused about the semantics of expressions
involving NULL, so we do not turn this option on by default.
</para>
<para>
Note that this option only affects the literal <literal>=</>
operator, not other comparison operators or other expressions
that are computationally equivalent to some expression
involving the equals operator (such as <literal>IN</literal>).
Thus, this option is not a general fix for bad programming.
</para>
<para>
Refer to the <citetitle>User's Guide</citetitle> for related
information.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PORT</varname> (<type>integer</type>)</term>
<listitem>
...
...
src/backend/parser/gram.y
View file @
a1ee0662
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.25
1 2001/09/18 01:59:06 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.25
2 2001/09/20 14:20:27 petere
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -89,7 +89,6 @@ static void insertSelectOptions(SelectStmt *stmt,
List *sortClause, List *forUpdate,
Node *limitOffset, Node *limitCount);
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
static bool exprIsNullConstant(Node *arg);
static Node *doNegate(Node *n);
static void doNegateFloat(Value *v);
...
...
@@ -4465,29 +4464,7 @@ a_expr: c_expr
| a_expr '>' a_expr
{ $$ = makeA_Expr(OP, ">", $1, $3); }
| a_expr '=' a_expr
{
/*
* Special-case "foo = NULL" and "NULL = foo" for
* compatibility with standards-broken products
* (like Microsoft's). Turn these into IS NULL exprs.
*/
if (exprIsNullConstant($3))
{
NullTest *n = makeNode(NullTest);
n->arg = $1;
n->nulltesttype = IS_NULL;
$$ = (Node *)n;
}
else if (exprIsNullConstant($1))
{
NullTest *n = makeNode(NullTest);
n->arg = $3;
n->nulltesttype = IS_NULL;
$$ = (Node *)n;
}
else
$$ = makeA_Expr(OP, "=", $1, $3);
}
{ $$ = makeA_Expr(OP, "=", $1, $3); }
| a_expr Op a_expr
{ $$ = makeA_Expr(OP, $2, $1, $3); }
...
...
@@ -6137,7 +6114,7 @@ Oid param_type(int t)
/*
* Test whether an a_expr is a plain NULL constant or not.
*/
static
bool
bool
exprIsNullConstant(Node *arg)
{
if (arg && IsA(arg, A_Const))
...
...
src/backend/parser/parse_expr.c
View file @
a1ee0662
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.
99 2001/08/09 18:28:1
7 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.
100 2001/09/20 14:20:2
7 petere Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -34,9 +34,10 @@
int
max_expr_depth
=
DEFAULT_MAX_EXPR_DEPTH
;
static
int
expr_depth_counter
=
0
;
bool
Transform_null_equals
=
false
;
static
Node
*
parser_typecast_constant
(
Value
*
expr
,
TypeName
*
typename
);
static
Node
*
parser_typecast_expression
(
ParseState
*
pstate
,
Node
*
expr
,
TypeName
*
typename
);
...
...
@@ -157,14 +158,35 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
{
case
OP
:
{
Node
*
lexpr
=
transformExpr
(
pstate
,
a
->
lexpr
,
precedence
);
Node
*
rexpr
=
transformExpr
(
pstate
,
a
->
rexpr
,
precedence
);
result
=
(
Node
*
)
make_op
(
a
->
opname
,
lexpr
,
rexpr
);
/*
* Special-case "foo = NULL" and "NULL = foo" for
* compatibility with standards-broken products
* (like Microsoft's). Turn these into IS NULL exprs.
*/
if
(
Transform_null_equals
&&
strcmp
(
a
->
opname
,
"="
)
==
0
&&
(
exprIsNullConstant
(
a
->
lexpr
)
||
exprIsNullConstant
(
a
->
rexpr
)))
{
NullTest
*
n
=
makeNode
(
NullTest
);
n
->
nulltesttype
=
IS_NULL
;
if
(
exprIsNullConstant
(
a
->
lexpr
))
n
->
arg
=
a
->
rexpr
;
else
n
->
arg
=
a
->
lexpr
;
result
=
transformExpr
(
pstate
,
n
,
precedence
);
}
else
{
Node
*
lexpr
=
transformExpr
(
pstate
,
a
->
lexpr
,
precedence
);
Node
*
rexpr
=
transformExpr
(
pstate
,
a
->
rexpr
,
precedence
);
result
=
(
Node
*
)
make_op
(
a
->
opname
,
lexpr
,
rexpr
);
}
}
break
;
case
AND
:
...
...
src/backend/utils/misc/guc.c
View file @
a1ee0662
...
...
@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.4
8 2001/09/12 14:06:3
7 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.4
9 2001/09/20 14:20:2
7 petere Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
...
...
@@ -247,12 +247,10 @@ static struct config_bool
{
"show_source_port"
,
PGC_SIGHUP
,
&
ShowPortNumber
,
false
,
NULL
},
{
"sql_inheritance"
,
PGC_USERSET
,
&
SQL_inheritance
,
true
,
NULL
},
{
"australian_timezones"
,
PGC_USERSET
,
&
Australian_timezones
,
false
,
ClearDateCache
},
{
"fixbtree"
,
PGC_POSTMASTER
,
&
FixBTree
,
true
,
NULL
},
{
"password_encryption"
,
PGC_USERSET
,
&
Password_encryption
,
false
,
NULL
},
{
"transform_null_equals"
,
PGC_USERSET
,
&
Transform_null_equals
,
false
,
NULL
},
{
NULL
,
0
,
NULL
,
false
,
NULL
}
};
...
...
src/include/parser/gramparse.h
View file @
a1ee0662
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: gramparse.h,v 1.1
5 2001/02/09 03:26:27 tgl
Exp $
* $Id: gramparse.h,v 1.1
6 2001/09/20 14:20:28 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -29,5 +29,6 @@ extern Oid param_type(int t);
extern
int
yyparse
(
void
);
extern
char
*
xlateSqlFunc
(
char
*
name
);
extern
char
*
xlateSqlType
(
char
*
name
);
bool
exprIsNullConstant
(
Node
*
arg
);
#endif
/* GRAMPARSE_H */
src/include/parser/parse_expr.h
View file @
a1ee0662
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_expr.h,v 1.2
1 2001/01/24 19:43:27 momjian
Exp $
* $Id: parse_expr.h,v 1.2
2 2001/09/20 14:20:28 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -20,6 +20,7 @@
#define EXPR_RELATION_FIRST 2
extern
int
max_expr_depth
;
extern
bool
Transform_null_equals
;
extern
Node
*
transformExpr
(
ParseState
*
pstate
,
Node
*
expr
,
int
precedence
);
extern
Oid
exprType
(
Node
*
expr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment