@@ -153,6 +153,7 @@ static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
153
153
const char *msg);
154
154
static RawStmt *makeRawStmt (Node *stmt, int stmt_location);
155
155
static void updateRawStmtEnd (RawStmt *rs, int end_location);
156
+ static void updatePreparableStmtEnd (Node *n, int end_location);
156
157
static Node *makeColumnRef (char *colname, List *indirection,
157
158
int location, core_yyscan_t yyscanner);
158
159
static Node *makeTypeCast (Node *arg, TypeName *typename , int location);
@@ -176,7 +177,7 @@ static void insertSelectOptions(SelectStmt *stmt,
176
177
SelectLimit *limitClause,
177
178
WithClause *withClause,
178
179
core_yyscan_t yyscanner);
179
- static Node *makeSetOp (SetOperation op, bool all, Node *larg, Node *rarg);
180
+ static Node *makeSetOp (SetOperation op, bool all, Node *larg, Node *rarg, int location );
180
181
static Node *doNegate (Node *n, int location);
181
182
static void doNegateFloat (Float *v);
182
183
static Node *makeAndExpr (Node *lexpr, Node *rexpr, int location);
@@ -3383,6 +3384,7 @@ CopyStmt: COPY opt_binary qualified_name opt_column_list
3383
3384
{
3384
3385
CopyStmt *n = makeNode(CopyStmt);
3385
3386
3387
+ updatePreparableStmtEnd ($3 , @4 );
3386
3388
n->relation = NULL ;
3387
3389
n->query = $3 ;
3388
3390
n->attlist = NIL;
@@ -12150,6 +12152,7 @@ InsertStmt:
12150
12152
$5 ->onConflictClause = $6 ;
12151
12153
$5 ->returningList = $7 ;
12152
12154
$5 ->withClause = $1 ;
12155
+ $5 ->stmt_location = @$ ;
12153
12156
$$ = (Node *) $5 ;
12154
12157
}
12155
12158
;
@@ -12303,6 +12306,7 @@ DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias
12303
12306
n->whereClause = $6 ;
12304
12307
n->returningList = $7 ;
12305
12308
n->withClause = $1 ;
12309
+ n->stmt_location = @$ ;
12306
12310
$$ = (Node *) n;
12307
12311
}
12308
12312
;
@@ -12377,6 +12381,7 @@ UpdateStmt: opt_with_clause UPDATE relation_expr_opt_alias
12377
12381
n->whereClause = $7 ;
12378
12382
n->returningList = $8 ;
12379
12383
n->withClause = $1 ;
12384
+ n->stmt_location = @$ ;
12380
12385
$$ = (Node *) n;
12381
12386
}
12382
12387
;
@@ -12454,6 +12459,7 @@ MergeStmt:
12454
12459
m->joinCondition = $8 ;
12455
12460
m->mergeWhenClauses = $9 ;
12456
12461
m->returningList = $10 ;
12462
+ m->stmt_location = @$ ;
12457
12463
12458
12464
$$ = (Node *) m;
12459
12465
}
@@ -12694,7 +12700,20 @@ SelectStmt: select_no_parens %prec UMINUS
12694
12700
;
12695
12701
12696
12702
select_with_parens :
12697
- ' (' select_no_parens ' )' { $$ = $2 ; }
12703
+ ' (' select_no_parens ' )'
12704
+ {
12705
+ SelectStmt *n = (SelectStmt *) $2 ;
12706
+
12707
+ /*
12708
+ * As SelectStmt's location starts at the SELECT keyword,
12709
+ * we need to track the length of the SelectStmt within
12710
+ * parentheses to be able to extract the relevant part
12711
+ * of the query. Without this, the RawStmt's length would
12712
+ * be used and would include the closing parenthesis.
12713
+ */
12714
+ n->stmt_len = @3 - @2 ;
12715
+ $$ = $2 ;
12716
+ }
12698
12717
| ' (' select_with_parens ' )' { $$ = $2 ; }
12699
12718
;
12700
12719
@@ -12816,6 +12835,7 @@ simple_select:
12816
12835
n->groupDistinct = ($7 )->distinct;
12817
12836
n->havingClause = $8 ;
12818
12837
n->windowClause = $9 ;
12838
+ n->stmt_location = @1 ;
12819
12839
$$ = (Node *) n;
12820
12840
}
12821
12841
| SELECT distinct_clause target_list
@@ -12833,6 +12853,7 @@ simple_select:
12833
12853
n->groupDistinct = ($7 )->distinct;
12834
12854
n->havingClause = $8 ;
12835
12855
n->windowClause = $9 ;
12856
+ n->stmt_location = @1 ;
12836
12857
$$ = (Node *) n;
12837
12858
}
12838
12859
| values_clause { $$ = $1 ; }
@@ -12853,19 +12874,20 @@ simple_select:
12853
12874
12854
12875
n->targetList = list_make1(rt);
12855
12876
n->fromClause = list_make1($2 );
12877
+ n->stmt_location = @1 ;
12856
12878
$$ = (Node *) n;
12857
12879
}
12858
12880
| select_clause UNION set_quantifier select_clause
12859
12881
{
12860
- $$ = makeSetOp(SETOP_UNION, $3 == SET_QUANTIFIER_ALL, $1 , $4 );
12882
+ $$ = makeSetOp(SETOP_UNION, $3 == SET_QUANTIFIER_ALL, $1 , $4 , @1 );
12861
12883
}
12862
12884
| select_clause INTERSECT set_quantifier select_clause
12863
12885
{
12864
- $$ = makeSetOp(SETOP_INTERSECT, $3 == SET_QUANTIFIER_ALL, $1 , $4 );
12886
+ $$ = makeSetOp(SETOP_INTERSECT, $3 == SET_QUANTIFIER_ALL, $1 , $4 , @1 );
12865
12887
}
12866
12888
| select_clause EXCEPT set_quantifier select_clause
12867
12889
{
12868
- $$ = makeSetOp(SETOP_EXCEPT, $3 == SET_QUANTIFIER_ALL, $1 , $4 );
12890
+ $$ = makeSetOp(SETOP_EXCEPT, $3 == SET_QUANTIFIER_ALL, $1 , $4 , @1 );
12869
12891
}
12870
12892
;
12871
12893
@@ -13423,6 +13445,7 @@ values_clause:
13423
13445
{
13424
13446
SelectStmt *n = makeNode(SelectStmt);
13425
13447
13448
+ n->stmt_location = @1 ;
13426
13449
n->valuesLists = list_make1($3 );
13427
13450
$$ = (Node *) n;
13428
13451
}
@@ -18565,6 +18588,47 @@ updateRawStmtEnd(RawStmt *rs, int end_location)
18565
18588
rs->stmt_len = end_location - rs->stmt_location;
18566
18589
}
18567
18590
18591
+ /*
18592
+ * Adjust a PreparableStmt to reflect that it doesn't run to the end of the
18593
+ * string.
18594
+ */
18595
+ static void
18596
+ updatePreparableStmtEnd(Node *n, int end_location)
18597
+ {
18598
+ if (IsA(n, SelectStmt))
18599
+ {
18600
+ SelectStmt *stmt = (SelectStmt *)n;
18601
+
18602
+ stmt->stmt_len = end_location - stmt->stmt_location;
18603
+ }
18604
+ else if (IsA(n, InsertStmt))
18605
+ {
18606
+ InsertStmt *stmt = (InsertStmt *)n;
18607
+
18608
+ stmt->stmt_len = end_location - stmt->stmt_location;
18609
+ }
18610
+ else if (IsA(n, UpdateStmt))
18611
+ {
18612
+ UpdateStmt *stmt = (UpdateStmt *)n;
18613
+
18614
+ stmt->stmt_len = end_location - stmt->stmt_location;
18615
+ }
18616
+ else if (IsA(n, DeleteStmt))
18617
+ {
18618
+ DeleteStmt *stmt = (DeleteStmt *)n;
18619
+
18620
+ stmt->stmt_len = end_location - stmt->stmt_location;
18621
+ }
18622
+ else if (IsA(n, MergeStmt))
18623
+ {
18624
+ MergeStmt *stmt = (MergeStmt *)n;
18625
+
18626
+ stmt->stmt_len = end_location - stmt->stmt_location;
18627
+ }
18628
+ else
18629
+ elog(ERROR, "unexpected node type %d", (int) n->type);
18630
+ }
18631
+
18568
18632
static Node *
18569
18633
makeColumnRef(char *colname, List *indirection,
18570
18634
int location, core_yyscan_t yyscanner)
@@ -18943,18 +19007,22 @@ insertSelectOptions(SelectStmt *stmt,
18943
19007
errmsg("multiple WITH clauses not allowed"),
18944
19008
parser_errposition(exprLocation((Node *) withClause))));
18945
19009
stmt->withClause = withClause;
19010
+
19011
+ /* Update SelectStmt's location to the start of the WITH clause */
19012
+ stmt->stmt_location = withClause->location;
18946
19013
}
18947
19014
}
18948
19015
18949
19016
static Node *
18950
- makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
19017
+ makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg, int location )
18951
19018
{
18952
19019
SelectStmt *n = makeNode(SelectStmt);
18953
19020
18954
19021
n->op = op;
18955
19022
n->all = all;
18956
19023
n->larg = (SelectStmt *) larg;
18957
19024
n->rarg = (SelectStmt *) rarg;
19025
+ n->stmt_location = location;
18958
19026
return (Node *) n;
18959
19027
}
18960
19028
0 commit comments