Add parse location fields to NullTest and BooleanTest structs.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 22 Feb 2015 19:40:27 +0000 (14:40 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 22 Feb 2015 19:40:27 +0000 (14:40 -0500)
We did not need a location tag on NullTest or BooleanTest before, because
no error messages referred directly to their locations.  That's planned
to change though, so add these fields in a separate housekeeping commit.

Catversion bump because stored rules may change.

14 files changed:
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/nodeFuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/planagg.c
src/backend/optimizer/prep/prepqual.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/plancat.c
src/backend/parser/gram.y
src/backend/parser/parse_expr.c
src/backend/rewrite/rewriteManip.c
src/include/catalog/catversion.h
src/include/nodes/primnodes.h

index 8798cbe43db5abeb50313cce0de79a1111e3281f..5282a4fec22c26622c0d65f35471d0f95adb6f0b 100644 (file)
@@ -1693,6 +1693,7 @@ _copyNullTest(const NullTest *from)
    COPY_NODE_FIELD(arg);
    COPY_SCALAR_FIELD(nulltesttype);
    COPY_SCALAR_FIELD(argisrow);
+   COPY_LOCATION_FIELD(location);
 
    return newnode;
 }
@@ -1707,6 +1708,7 @@ _copyBooleanTest(const BooleanTest *from)
 
    COPY_NODE_FIELD(arg);
    COPY_SCALAR_FIELD(booltesttype);
+   COPY_LOCATION_FIELD(location);
 
    return newnode;
 }
index a90386b8004c91462546898f1bfc4225b44321c8..fe509b0ad1cb3d43a57e73f5c2803d1077d0919c 100644 (file)
@@ -622,6 +622,7 @@ _equalNullTest(const NullTest *a, const NullTest *b)
    COMPARE_NODE_FIELD(arg);
    COMPARE_SCALAR_FIELD(nulltesttype);
    COMPARE_SCALAR_FIELD(argisrow);
+   COMPARE_LOCATION_FIELD(location);
 
    return true;
 }
@@ -631,6 +632,7 @@ _equalBooleanTest(const BooleanTest *a, const BooleanTest *b)
 {
    COMPARE_NODE_FIELD(arg);
    COMPARE_SCALAR_FIELD(booltesttype);
+   COMPARE_LOCATION_FIELD(location);
 
    return true;
 }
index 21dfda7f795b7ca897116adc3e620d302381b23e..d6f1f5bb6d7d3c62af415ad52b8988dcc7e98e68 100644 (file)
@@ -1346,12 +1346,22 @@ exprLocation(const Node *expr)
            }
            break;
        case T_NullTest:
-           /* just use argument's location */
-           loc = exprLocation((Node *) ((const NullTest *) expr)->arg);
+           {
+               const NullTest *nexpr = (const NullTest *) expr;
+
+               /* Much as above */
+               loc = leftmostLoc(nexpr->location,
+                                 exprLocation((Node *) nexpr->arg));
+           }
            break;
        case T_BooleanTest:
-           /* just use argument's location */
-           loc = exprLocation((Node *) ((const BooleanTest *) expr)->arg);
+           {
+               const BooleanTest *bexpr = (const BooleanTest *) expr;
+
+               /* Much as above */
+               loc = leftmostLoc(bexpr->location,
+                                 exprLocation((Node *) bexpr->arg));
+           }
            break;
        case T_CoerceToDomain:
            {
index 67b7d40406a90ae34babe2cda38ebe7eefd0fdc7..98aa5f0310293ef3015162933c4af133295735d9 100644 (file)
@@ -1370,6 +1370,7 @@ _outNullTest(StringInfo str, const NullTest *node)
    WRITE_NODE_FIELD(arg);
    WRITE_ENUM_FIELD(nulltesttype, NullTestType);
    WRITE_BOOL_FIELD(argisrow);
+   WRITE_LOCATION_FIELD(location);
 }
 
 static void
@@ -1379,6 +1380,7 @@ _outBooleanTest(StringInfo str, const BooleanTest *node)
 
    WRITE_NODE_FIELD(arg);
    WRITE_ENUM_FIELD(booltesttype, BoolTestType);
+   WRITE_LOCATION_FIELD(location);
 }
 
 static void
index ae24d0514fecc8862937d1d8fcf25aca108f140a..563209c56150d4de00bf93ad03a1de0b74741acf 100644 (file)
@@ -1044,6 +1044,7 @@ _readNullTest(void)
    READ_NODE_FIELD(arg);
    READ_ENUM_FIELD(nulltesttype, NullTestType);
    READ_BOOL_FIELD(argisrow);
+   READ_LOCATION_FIELD(location);
 
    READ_DONE();
 }
@@ -1058,6 +1059,7 @@ _readBooleanTest(void)
 
    READ_NODE_FIELD(arg);
    READ_ENUM_FIELD(booltesttype, BoolTestType);
+   READ_LOCATION_FIELD(location);
 
    READ_DONE();
 }
index b90c2ef48cb851c6b26a881e63e7106821b27298..af772a2c99333a8a9bf4ecf079122c500f0ef36c 100644 (file)
@@ -449,6 +449,7 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
    ntest->arg = copyObject(mminfo->target);
    /* we checked it wasn't a rowtype in find_minmax_aggs_walker */
    ntest->argisrow = false;
+   ntest->location = -1;
 
    /* User might have had that in WHERE already */
    if (!list_member((List *) parse->jointree->quals, ntest))
index bd50926b13d119721e5e610dcbf04a30e6c3fdad..1176e819dd0744a7373c2d2201a1b41388f610dc 100644 (file)
@@ -212,6 +212,7 @@ negate_clause(Node *node)
                    newexpr->nulltesttype = (expr->nulltesttype == IS_NULL ?
                                             IS_NOT_NULL : IS_NULL);
                    newexpr->argisrow = expr->argisrow;
+                   newexpr->location = expr->location;
                    return (Node *) newexpr;
                }
            }
@@ -247,6 +248,7 @@ negate_clause(Node *node)
                             (int) expr->booltesttype);
                        break;
                }
+               newexpr->location = expr->location;
                return (Node *) newexpr;
            }
            break;
index b340b017154950018ed23c2275a9646c5fcfcd68..84d58ae595eb32e4568c2440a4eb5e88e4136cde 100644 (file)
@@ -3305,6 +3305,7 @@ eval_const_expressions_mutator(Node *node,
                        newntest->arg = (Expr *) relem;
                        newntest->nulltesttype = ntest->nulltesttype;
                        newntest->argisrow = type_is_rowtype(exprType(relem));
+                       newntest->location = ntest->location;
                        newargs = lappend(newargs, newntest);
                    }
                    /* If all the inputs were constants, result is TRUE */
@@ -3343,6 +3344,7 @@ eval_const_expressions_mutator(Node *node,
                newntest->arg = (Expr *) arg;
                newntest->nulltesttype = ntest->nulltesttype;
                newntest->argisrow = ntest->argisrow;
+               newntest->location = ntest->location;
                return (Node *) newntest;
            }
        case T_BooleanTest:
@@ -3395,6 +3397,7 @@ eval_const_expressions_mutator(Node *node,
                newbtest = makeNode(BooleanTest);
                newbtest->arg = (Expr *) arg;
                newbtest->booltesttype = btest->booltesttype;
+               newbtest->location = btest->location;
                return (Node *) newbtest;
            }
        case T_PlaceHolderVar:
index 5cbd6a98f202b1dcdbd3df775d948e969b9d56b5..313a5c1ab2bc7f3270126620a94a225c54a1ff65 100644 (file)
@@ -720,6 +720,7 @@ get_relation_constraints(PlannerInfo *root,
                                                  0);
                    ntest->nulltesttype = IS_NOT_NULL;
                    ntest->argisrow = type_is_rowtype(att->atttypid);
+                   ntest->location = -1;
                    result = lappend(result, ntest);
                }
            }
index b8af29639790bbb4e1398023af3de2af63c158ab..76b0affff069d54476e4e63dec536f7d643a3500 100644 (file)
@@ -11299,6 +11299,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    NullTest *n = makeNode(NullTest);
                    n->arg = (Expr *) $1;
                    n->nulltesttype = IS_NULL;
+                   n->location = @2;
                    $$ = (Node *)n;
                }
            | a_expr ISNULL
@@ -11306,6 +11307,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    NullTest *n = makeNode(NullTest);
                    n->arg = (Expr *) $1;
                    n->nulltesttype = IS_NULL;
+                   n->location = @2;
                    $$ = (Node *)n;
                }
            | a_expr IS NOT NULL_P                      %prec IS
@@ -11313,6 +11315,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    NullTest *n = makeNode(NullTest);
                    n->arg = (Expr *) $1;
                    n->nulltesttype = IS_NOT_NULL;
+                   n->location = @2;
                    $$ = (Node *)n;
                }
            | a_expr NOTNULL
@@ -11320,6 +11323,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    NullTest *n = makeNode(NullTest);
                    n->arg = (Expr *) $1;
                    n->nulltesttype = IS_NOT_NULL;
+                   n->location = @2;
                    $$ = (Node *)n;
                }
            | row OVERLAPS row
@@ -11343,6 +11347,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    BooleanTest *b = makeNode(BooleanTest);
                    b->arg = (Expr *) $1;
                    b->booltesttype = IS_TRUE;
+                   b->location = @2;
                    $$ = (Node *)b;
                }
            | a_expr IS NOT TRUE_P                      %prec IS
@@ -11350,6 +11355,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    BooleanTest *b = makeNode(BooleanTest);
                    b->arg = (Expr *) $1;
                    b->booltesttype = IS_NOT_TRUE;
+                   b->location = @2;
                    $$ = (Node *)b;
                }
            | a_expr IS FALSE_P                         %prec IS
@@ -11357,6 +11363,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    BooleanTest *b = makeNode(BooleanTest);
                    b->arg = (Expr *) $1;
                    b->booltesttype = IS_FALSE;
+                   b->location = @2;
                    $$ = (Node *)b;
                }
            | a_expr IS NOT FALSE_P                     %prec IS
@@ -11364,6 +11371,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    BooleanTest *b = makeNode(BooleanTest);
                    b->arg = (Expr *) $1;
                    b->booltesttype = IS_NOT_FALSE;
+                   b->location = @2;
                    $$ = (Node *)b;
                }
            | a_expr IS UNKNOWN                         %prec IS
@@ -11371,6 +11379,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    BooleanTest *b = makeNode(BooleanTest);
                    b->arg = (Expr *) $1;
                    b->booltesttype = IS_UNKNOWN;
+                   b->location = @2;
                    $$ = (Node *)b;
                }
            | a_expr IS NOT UNKNOWN                     %prec IS
@@ -11378,6 +11387,7 @@ a_expr:     c_expr                                  { $$ = $1; }
                    BooleanTest *b = makeNode(BooleanTest);
                    b->arg = (Expr *) $1;
                    b->booltesttype = IS_NOT_UNKNOWN;
+                   b->location = @2;
                    $$ = (Node *)b;
                }
            | a_expr IS DISTINCT FROM a_expr            %prec IS
index 791639a7db351f7fa170c55606b388d8328da47f..f314745818b233e159540e3aa3658814a3354027 100644 (file)
@@ -789,6 +789,7 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
        NullTest   *n = makeNode(NullTest);
 
        n->nulltesttype = IS_NULL;
+       n->location = a->location;
 
        if (exprIsNullConstant(lexpr))
            n->arg = (Expr *) rexpr;
index 75dd41eab62ad1955741bace10832468b2e8b849..df457080fea689621335fa4adb8a6486481bc03a 100644 (file)
@@ -1023,6 +1023,7 @@ AddInvertedQual(Query *parsetree, Node *qual)
    invqual = makeNode(BooleanTest);
    invqual->arg = (Expr *) qual;
    invqual->booltesttype = IS_NOT_TRUE;
+   invqual->location = -1;
 
    AddQual(parsetree, (Node *) invqual);
 }
index 7133b96151443a0e70dd328b82e2a9224dd77dfe..7ed743df97068c7dc4e86711bb12916d022ec0ca 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201502191
+#define CATALOG_VERSION_NO 201502221
 
 #endif
index 1d06f426be4e543bbce4d5755f4cb06a77936813..b004da6dc4c7d138afd61bcb7b40e7b5bbc17b98 100644 (file)
@@ -1050,6 +1050,7 @@ typedef struct NullTest
    Expr       *arg;            /* input expression */
    NullTestType nulltesttype;  /* IS NULL, IS NOT NULL */
    bool        argisrow;       /* T if input is of a composite type */
+   int         location;       /* token location, or -1 if unknown */
 } NullTest;
 
 /*
@@ -1071,6 +1072,7 @@ typedef struct BooleanTest
    Expr        xpr;
    Expr       *arg;            /* input expression */
    BoolTestType booltesttype;  /* test type */
+   int         location;       /* token location, or -1 if unknown */
 } BooleanTest;
 
 /*