aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/preproc/parser.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-03-11 13:22:52 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2015-03-11 13:22:52 -0400
commitc6b3c939b7e0f1d35f4ed4996e71420a993810d2 (patch)
tree0a1e0d6c70f09ff85e49c33352360bdd4a15ca32 /src/interfaces/ecpg/preproc/parser.c
parent21dcda2713656a7483e3280ac9d2ada20a87a9a9 (diff)
downloadpostgresql-c6b3c939b7e0f1d35f4ed4996e71420a993810d2.tar.gz
postgresql-c6b3c939b7e0f1d35f4ed4996e71420a993810d2.zip
Make operator precedence follow the SQL standard more closely.
While the SQL standard is pretty vague on the overall topic of operator precedence (because it never presents a unified BNF for all expressions), it does seem reasonable to conclude from the spec for <boolean value expression> that OR has the lowest precedence, then AND, then NOT, then IS tests, then the six standard comparison operators, then everything else (since any non-boolean operator in a WHERE clause would need to be an argument of one of these). We were only sort of on board with that: most notably, while "<" ">" and "=" had properly low precedence, "<=" ">=" and "<>" were treated as generic operators and so had significantly higher precedence. And "IS" tests were even higher precedence than those, which is very clearly wrong per spec. Another problem was that "foo NOT SOMETHING bar" constructs, such as "x NOT LIKE y", were treated inconsistently because of a bison implementation artifact: they had the documented precedence with respect to operators to their right, but behaved like NOT (i.e., very low priority) with respect to operators to their left. Fixing the precedence issues is just a small matter of rearranging the precedence declarations in gram.y, except for the NOT problem, which requires adding an additional lookahead case in base_yylex() so that we can attach a different token precedence to NOT LIKE and allied two-word operators. The bulk of this patch is not the bug fix per se, but adding logic to parse_expr.c to allow giving warnings if an expression has changed meaning because of these precedence changes. These warnings are off by default and are enabled by the new GUC operator_precedence_warning. It's believed that very few applications will be affected by these changes, but it was agreed that a warning mechanism is essential to help debug any that are.
Diffstat (limited to 'src/interfaces/ecpg/preproc/parser.c')
-rw-r--r--src/interfaces/ecpg/preproc/parser.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/preproc/parser.c b/src/interfaces/ecpg/preproc/parser.c
index 099a213d118..662a90a3f6b 100644
--- a/src/interfaces/ecpg/preproc/parser.c
+++ b/src/interfaces/ecpg/preproc/parser.c
@@ -75,6 +75,9 @@ filtered_base_yylex(void)
*/
switch (cur_token)
{
+ case NOT:
+ cur_token_length = 3;
+ break;
case NULLS_P:
cur_token_length = 5;
break;
@@ -119,6 +122,20 @@ filtered_base_yylex(void)
/* Replace cur_token if needed, based on lookahead */
switch (cur_token)
{
+ case NOT:
+ /* Replace NOT by NOT_LA if it's followed by BETWEEN, IN, etc */
+ switch (next_token)
+ {
+ case BETWEEN:
+ case IN_P:
+ case LIKE:
+ case ILIKE:
+ case SIMILAR:
+ cur_token = NOT_LA;
+ break;
+ }
+ break;
+
case NULLS_P:
/* Replace NULLS_P by NULLS_LA if it's followed by FIRST or LAST */
switch (next_token)