1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * analyze.c |
4 | * transform the raw parse tree into a query tree |
5 | * |
6 | * For optimizable statements, we are careful to obtain a suitable lock on |
7 | * each referenced table, and other modules of the backend preserve or |
8 | * re-obtain these locks before depending on the results. It is therefore |
9 | * okay to do significant semantic analysis of these statements. For |
10 | * utility commands, no locks are obtained here (and if they were, we could |
11 | * not be sure we'd still have them at execution). Hence the general rule |
12 | * for utility commands is to just dump them into a Query node untransformed. |
13 | * DECLARE CURSOR, EXPLAIN, and CREATE TABLE AS are exceptions because they |
14 | * contain optimizable statements, which we should transform. |
15 | * |
16 | * |
17 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
18 | * Portions Copyright (c) 1994, Regents of the University of California |
19 | * |
20 | * src/backend/parser/analyze.c |
21 | * |
22 | *------------------------------------------------------------------------- |
23 | */ |
24 | |
25 | #include "postgres.h" |
26 | |
27 | #include "access/sysattr.h" |
28 | #include "catalog/pg_type.h" |
29 | #include "miscadmin.h" |
30 | #include "nodes/makefuncs.h" |
31 | #include "nodes/nodeFuncs.h" |
32 | #include "optimizer/optimizer.h" |
33 | #include "parser/analyze.h" |
34 | #include "parser/parse_agg.h" |
35 | #include "parser/parse_clause.h" |
36 | #include "parser/parse_coerce.h" |
37 | #include "parser/parse_collate.h" |
38 | #include "parser/parse_cte.h" |
39 | #include "parser/parse_expr.h" |
40 | #include "parser/parse_func.h" |
41 | #include "parser/parse_oper.h" |
42 | #include "parser/parse_param.h" |
43 | #include "parser/parse_relation.h" |
44 | #include "parser/parse_target.h" |
45 | #include "parser/parsetree.h" |
46 | #include "rewrite/rewriteManip.h" |
47 | #include "utils/rel.h" |
48 | |
49 | |
50 | /* Hook for plugins to get control at end of parse analysis */ |
51 | post_parse_analyze_hook_type post_parse_analyze_hook = NULL; |
52 | |
53 | static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree); |
54 | static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); |
55 | static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt); |
56 | static List *transformInsertRow(ParseState *pstate, List *exprlist, |
57 | List *stmtcols, List *icolumns, List *attrnos, |
58 | bool strip_indirection); |
59 | static OnConflictExpr *transformOnConflictClause(ParseState *pstate, |
60 | OnConflictClause *onConflictClause); |
61 | static int count_rowexpr_columns(ParseState *pstate, Node *expr); |
62 | static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); |
63 | static Query *transformValuesClause(ParseState *pstate, SelectStmt *stmt); |
64 | static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); |
65 | static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, |
66 | bool isTopLevel, List **targetlist); |
67 | static void determineRecursiveColTypes(ParseState *pstate, |
68 | Node *larg, List *nrtargetlist); |
69 | static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); |
70 | static List *transformReturningList(ParseState *pstate, List *returningList); |
71 | static List *transformUpdateTargetList(ParseState *pstate, |
72 | List *targetList); |
73 | static Query *transformDeclareCursorStmt(ParseState *pstate, |
74 | DeclareCursorStmt *stmt); |
75 | static Query *transformExplainStmt(ParseState *pstate, |
76 | ExplainStmt *stmt); |
77 | static Query *transformCreateTableAsStmt(ParseState *pstate, |
78 | CreateTableAsStmt *stmt); |
79 | static Query *transformCallStmt(ParseState *pstate, |
80 | CallStmt *stmt); |
81 | static void transformLockingClause(ParseState *pstate, Query *qry, |
82 | LockingClause *lc, bool pushedDown); |
83 | #ifdef RAW_EXPRESSION_COVERAGE_TEST |
84 | static bool test_raw_expression_coverage(Node *node, void *context); |
85 | #endif |
86 | |
87 | |
88 | /* |
89 | * parse_analyze |
90 | * Analyze a raw parse tree and transform it to Query form. |
91 | * |
92 | * Optionally, information about $n parameter types can be supplied. |
93 | * References to $n indexes not defined by paramTypes[] are disallowed. |
94 | * |
95 | * The result is a Query node. Optimizable statements require considerable |
96 | * transformation, while utility-type statements are simply hung off |
97 | * a dummy CMD_UTILITY Query node. |
98 | */ |
99 | Query * |
100 | parse_analyze(RawStmt *parseTree, const char *sourceText, |
101 | Oid *paramTypes, int numParams, |
102 | QueryEnvironment *queryEnv) |
103 | { |
104 | ParseState *pstate = make_parsestate(NULL); |
105 | Query *query; |
106 | |
107 | Assert(sourceText != NULL); /* required as of 8.4 */ |
108 | |
109 | pstate->p_sourcetext = sourceText; |
110 | |
111 | if (numParams > 0) |
112 | parse_fixed_parameters(pstate, paramTypes, numParams); |
113 | |
114 | pstate->p_queryEnv = queryEnv; |
115 | |
116 | query = transformTopLevelStmt(pstate, parseTree); |
117 | |
118 | if (post_parse_analyze_hook) |
119 | (*post_parse_analyze_hook) (pstate, query); |
120 | |
121 | free_parsestate(pstate); |
122 | |
123 | return query; |
124 | } |
125 | |
126 | /* |
127 | * parse_analyze_varparams |
128 | * |
129 | * This variant is used when it's okay to deduce information about $n |
130 | * symbol datatypes from context. The passed-in paramTypes[] array can |
131 | * be modified or enlarged (via repalloc). |
132 | */ |
133 | Query * |
134 | parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, |
135 | Oid **paramTypes, int *numParams) |
136 | { |
137 | ParseState *pstate = make_parsestate(NULL); |
138 | Query *query; |
139 | |
140 | Assert(sourceText != NULL); /* required as of 8.4 */ |
141 | |
142 | pstate->p_sourcetext = sourceText; |
143 | |
144 | parse_variable_parameters(pstate, paramTypes, numParams); |
145 | |
146 | query = transformTopLevelStmt(pstate, parseTree); |
147 | |
148 | /* make sure all is well with parameter types */ |
149 | check_variable_parameters(pstate, query); |
150 | |
151 | if (post_parse_analyze_hook) |
152 | (*post_parse_analyze_hook) (pstate, query); |
153 | |
154 | free_parsestate(pstate); |
155 | |
156 | return query; |
157 | } |
158 | |
159 | /* |
160 | * parse_sub_analyze |
161 | * Entry point for recursively analyzing a sub-statement. |
162 | */ |
163 | Query * |
164 | parse_sub_analyze(Node *parseTree, ParseState *parentParseState, |
165 | CommonTableExpr *parentCTE, |
166 | bool locked_from_parent, |
167 | bool resolve_unknowns) |
168 | { |
169 | ParseState *pstate = make_parsestate(parentParseState); |
170 | Query *query; |
171 | |
172 | pstate->p_parent_cte = parentCTE; |
173 | pstate->p_locked_from_parent = locked_from_parent; |
174 | pstate->p_resolve_unknowns = resolve_unknowns; |
175 | |
176 | query = transformStmt(pstate, parseTree); |
177 | |
178 | free_parsestate(pstate); |
179 | |
180 | return query; |
181 | } |
182 | |
183 | /* |
184 | * transformTopLevelStmt - |
185 | * transform a Parse tree into a Query tree. |
186 | * |
187 | * This function is just responsible for transferring statement location data |
188 | * from the RawStmt into the finished Query. |
189 | */ |
190 | Query * |
191 | transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree) |
192 | { |
193 | Query *result; |
194 | |
195 | /* We're at top level, so allow SELECT INTO */ |
196 | result = transformOptionalSelectInto(pstate, parseTree->stmt); |
197 | |
198 | result->stmt_location = parseTree->stmt_location; |
199 | result->stmt_len = parseTree->stmt_len; |
200 | |
201 | return result; |
202 | } |
203 | |
204 | /* |
205 | * transformOptionalSelectInto - |
206 | * If SELECT has INTO, convert it to CREATE TABLE AS. |
207 | * |
208 | * The only thing we do here that we don't do in transformStmt() is to |
209 | * convert SELECT ... INTO into CREATE TABLE AS. Since utility statements |
210 | * aren't allowed within larger statements, this is only allowed at the top |
211 | * of the parse tree, and so we only try it before entering the recursive |
212 | * transformStmt() processing. |
213 | */ |
214 | static Query * |
215 | transformOptionalSelectInto(ParseState *pstate, Node *parseTree) |
216 | { |
217 | if (IsA(parseTree, SelectStmt)) |
218 | { |
219 | SelectStmt *stmt = (SelectStmt *) parseTree; |
220 | |
221 | /* If it's a set-operation tree, drill down to leftmost SelectStmt */ |
222 | while (stmt && stmt->op != SETOP_NONE) |
223 | stmt = stmt->larg; |
224 | Assert(stmt && IsA(stmt, SelectStmt) &&stmt->larg == NULL); |
225 | |
226 | if (stmt->intoClause) |
227 | { |
228 | CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); |
229 | |
230 | ctas->query = parseTree; |
231 | ctas->into = stmt->intoClause; |
232 | ctas->relkind = OBJECT_TABLE; |
233 | ctas->is_select_into = true; |
234 | |
235 | /* |
236 | * Remove the intoClause from the SelectStmt. This makes it safe |
237 | * for transformSelectStmt to complain if it finds intoClause set |
238 | * (implying that the INTO appeared in a disallowed place). |
239 | */ |
240 | stmt->intoClause = NULL; |
241 | |
242 | parseTree = (Node *) ctas; |
243 | } |
244 | } |
245 | |
246 | return transformStmt(pstate, parseTree); |
247 | } |
248 | |
249 | /* |
250 | * transformStmt - |
251 | * recursively transform a Parse tree into a Query tree. |
252 | */ |
253 | Query * |
254 | transformStmt(ParseState *pstate, Node *parseTree) |
255 | { |
256 | Query *result; |
257 | |
258 | /* |
259 | * We apply RAW_EXPRESSION_COVERAGE_TEST testing to basic DML statements; |
260 | * we can't just run it on everything because raw_expression_tree_walker() |
261 | * doesn't claim to handle utility statements. |
262 | */ |
263 | #ifdef RAW_EXPRESSION_COVERAGE_TEST |
264 | switch (nodeTag(parseTree)) |
265 | { |
266 | case T_SelectStmt: |
267 | case T_InsertStmt: |
268 | case T_UpdateStmt: |
269 | case T_DeleteStmt: |
270 | (void) test_raw_expression_coverage(parseTree, NULL); |
271 | break; |
272 | default: |
273 | break; |
274 | } |
275 | #endif /* RAW_EXPRESSION_COVERAGE_TEST */ |
276 | |
277 | switch (nodeTag(parseTree)) |
278 | { |
279 | /* |
280 | * Optimizable statements |
281 | */ |
282 | case T_InsertStmt: |
283 | result = transformInsertStmt(pstate, (InsertStmt *) parseTree); |
284 | break; |
285 | |
286 | case T_DeleteStmt: |
287 | result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree); |
288 | break; |
289 | |
290 | case T_UpdateStmt: |
291 | result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree); |
292 | break; |
293 | |
294 | case T_SelectStmt: |
295 | { |
296 | SelectStmt *n = (SelectStmt *) parseTree; |
297 | |
298 | if (n->valuesLists) |
299 | result = transformValuesClause(pstate, n); |
300 | else if (n->op == SETOP_NONE) |
301 | result = transformSelectStmt(pstate, n); |
302 | else |
303 | result = transformSetOperationStmt(pstate, n); |
304 | } |
305 | break; |
306 | |
307 | /* |
308 | * Special cases |
309 | */ |
310 | case T_DeclareCursorStmt: |
311 | result = transformDeclareCursorStmt(pstate, |
312 | (DeclareCursorStmt *) parseTree); |
313 | break; |
314 | |
315 | case T_ExplainStmt: |
316 | result = transformExplainStmt(pstate, |
317 | (ExplainStmt *) parseTree); |
318 | break; |
319 | |
320 | case T_CreateTableAsStmt: |
321 | result = transformCreateTableAsStmt(pstate, |
322 | (CreateTableAsStmt *) parseTree); |
323 | break; |
324 | |
325 | case T_CallStmt: |
326 | result = transformCallStmt(pstate, |
327 | (CallStmt *) parseTree); |
328 | break; |
329 | |
330 | default: |
331 | |
332 | /* |
333 | * other statements don't require any transformation; just return |
334 | * the original parsetree with a Query node plastered on top. |
335 | */ |
336 | result = makeNode(Query); |
337 | result->commandType = CMD_UTILITY; |
338 | result->utilityStmt = (Node *) parseTree; |
339 | break; |
340 | } |
341 | |
342 | /* Mark as original query until we learn differently */ |
343 | result->querySource = QSRC_ORIGINAL; |
344 | result->canSetTag = true; |
345 | |
346 | return result; |
347 | } |
348 | |
349 | /* |
350 | * analyze_requires_snapshot |
351 | * Returns true if a snapshot must be set before doing parse analysis |
352 | * on the given raw parse tree. |
353 | * |
354 | * Classification here should match transformStmt(). |
355 | */ |
356 | bool |
357 | analyze_requires_snapshot(RawStmt *parseTree) |
358 | { |
359 | bool result; |
360 | |
361 | switch (nodeTag(parseTree->stmt)) |
362 | { |
363 | /* |
364 | * Optimizable statements |
365 | */ |
366 | case T_InsertStmt: |
367 | case T_DeleteStmt: |
368 | case T_UpdateStmt: |
369 | case T_SelectStmt: |
370 | result = true; |
371 | break; |
372 | |
373 | /* |
374 | * Special cases |
375 | */ |
376 | case T_DeclareCursorStmt: |
377 | case T_ExplainStmt: |
378 | case T_CreateTableAsStmt: |
379 | /* yes, because we must analyze the contained statement */ |
380 | result = true; |
381 | break; |
382 | |
383 | default: |
384 | /* other utility statements don't have any real parse analysis */ |
385 | result = false; |
386 | break; |
387 | } |
388 | |
389 | return result; |
390 | } |
391 | |
392 | /* |
393 | * transformDeleteStmt - |
394 | * transforms a Delete Statement |
395 | */ |
396 | static Query * |
397 | transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) |
398 | { |
399 | Query *qry = makeNode(Query); |
400 | ParseNamespaceItem *nsitem; |
401 | Node *qual; |
402 | |
403 | qry->commandType = CMD_DELETE; |
404 | |
405 | /* process the WITH clause independently of all else */ |
406 | if (stmt->withClause) |
407 | { |
408 | qry->hasRecursive = stmt->withClause->recursive; |
409 | qry->cteList = transformWithClause(pstate, stmt->withClause); |
410 | qry->hasModifyingCTE = pstate->p_hasModifyingCTE; |
411 | } |
412 | |
413 | /* set up range table with just the result rel */ |
414 | qry->resultRelation = setTargetTable(pstate, stmt->relation, |
415 | stmt->relation->inh, |
416 | true, |
417 | ACL_DELETE); |
418 | |
419 | /* grab the namespace item made by setTargetTable */ |
420 | nsitem = (ParseNamespaceItem *) llast(pstate->p_namespace); |
421 | |
422 | /* there's no DISTINCT in DELETE */ |
423 | qry->distinctClause = NIL; |
424 | |
425 | /* subqueries in USING cannot access the result relation */ |
426 | nsitem->p_lateral_only = true; |
427 | nsitem->p_lateral_ok = false; |
428 | |
429 | /* |
430 | * The USING clause is non-standard SQL syntax, and is equivalent in |
431 | * functionality to the FROM list that can be specified for UPDATE. The |
432 | * USING keyword is used rather than FROM because FROM is already a |
433 | * keyword in the DELETE syntax. |
434 | */ |
435 | transformFromClause(pstate, stmt->usingClause); |
436 | |
437 | /* remaining clauses can reference the result relation normally */ |
438 | nsitem->p_lateral_only = false; |
439 | nsitem->p_lateral_ok = true; |
440 | |
441 | qual = transformWhereClause(pstate, stmt->whereClause, |
442 | EXPR_KIND_WHERE, "WHERE" ); |
443 | |
444 | qry->returningList = transformReturningList(pstate, stmt->returningList); |
445 | |
446 | /* done building the range table and jointree */ |
447 | qry->rtable = pstate->p_rtable; |
448 | qry->jointree = makeFromExpr(pstate->p_joinlist, qual); |
449 | |
450 | qry->hasSubLinks = pstate->p_hasSubLinks; |
451 | qry->hasWindowFuncs = pstate->p_hasWindowFuncs; |
452 | qry->hasTargetSRFs = pstate->p_hasTargetSRFs; |
453 | qry->hasAggs = pstate->p_hasAggs; |
454 | |
455 | assign_query_collations(pstate, qry); |
456 | |
457 | /* this must be done after collations, for reliable comparison of exprs */ |
458 | if (pstate->p_hasAggs) |
459 | parseCheckAggregates(pstate, qry); |
460 | |
461 | return qry; |
462 | } |
463 | |
464 | /* |
465 | * transformInsertStmt - |
466 | * transform an Insert Statement |
467 | */ |
468 | static Query * |
469 | transformInsertStmt(ParseState *pstate, InsertStmt *stmt) |
470 | { |
471 | Query *qry = makeNode(Query); |
472 | SelectStmt *selectStmt = (SelectStmt *) stmt->selectStmt; |
473 | List *exprList = NIL; |
474 | bool isGeneralSelect; |
475 | List *sub_rtable; |
476 | List *sub_namespace; |
477 | List *icolumns; |
478 | List *attrnos; |
479 | RangeTblEntry *rte; |
480 | RangeTblRef *rtr; |
481 | ListCell *icols; |
482 | ListCell *attnos; |
483 | ListCell *lc; |
484 | bool isOnConflictUpdate; |
485 | AclMode targetPerms; |
486 | |
487 | /* There can't be any outer WITH to worry about */ |
488 | Assert(pstate->p_ctenamespace == NIL); |
489 | |
490 | qry->commandType = CMD_INSERT; |
491 | pstate->p_is_insert = true; |
492 | |
493 | /* process the WITH clause independently of all else */ |
494 | if (stmt->withClause) |
495 | { |
496 | qry->hasRecursive = stmt->withClause->recursive; |
497 | qry->cteList = transformWithClause(pstate, stmt->withClause); |
498 | qry->hasModifyingCTE = pstate->p_hasModifyingCTE; |
499 | } |
500 | |
501 | qry->override = stmt->override; |
502 | |
503 | isOnConflictUpdate = (stmt->onConflictClause && |
504 | stmt->onConflictClause->action == ONCONFLICT_UPDATE); |
505 | |
506 | /* |
507 | * We have three cases to deal with: DEFAULT VALUES (selectStmt == NULL), |
508 | * VALUES list, or general SELECT input. We special-case VALUES, both for |
509 | * efficiency and so we can handle DEFAULT specifications. |
510 | * |
511 | * The grammar allows attaching ORDER BY, LIMIT, FOR UPDATE, or WITH to a |
512 | * VALUES clause. If we have any of those, treat it as a general SELECT; |
513 | * so it will work, but you can't use DEFAULT items together with those. |
514 | */ |
515 | isGeneralSelect = (selectStmt && (selectStmt->valuesLists == NIL || |
516 | selectStmt->sortClause != NIL || |
517 | selectStmt->limitOffset != NULL || |
518 | selectStmt->limitCount != NULL || |
519 | selectStmt->lockingClause != NIL || |
520 | selectStmt->withClause != NULL)); |
521 | |
522 | /* |
523 | * If a non-nil rangetable/namespace was passed in, and we are doing |
524 | * INSERT/SELECT, arrange to pass the rangetable/namespace down to the |
525 | * SELECT. This can only happen if we are inside a CREATE RULE, and in |
526 | * that case we want the rule's OLD and NEW rtable entries to appear as |
527 | * part of the SELECT's rtable, not as outer references for it. (Kluge!) |
528 | * The SELECT's joinlist is not affected however. We must do this before |
529 | * adding the target table to the INSERT's rtable. |
530 | */ |
531 | if (isGeneralSelect) |
532 | { |
533 | sub_rtable = pstate->p_rtable; |
534 | pstate->p_rtable = NIL; |
535 | sub_namespace = pstate->p_namespace; |
536 | pstate->p_namespace = NIL; |
537 | } |
538 | else |
539 | { |
540 | sub_rtable = NIL; /* not used, but keep compiler quiet */ |
541 | sub_namespace = NIL; |
542 | } |
543 | |
544 | /* |
545 | * Must get write lock on INSERT target table before scanning SELECT, else |
546 | * we will grab the wrong kind of initial lock if the target table is also |
547 | * mentioned in the SELECT part. Note that the target table is not added |
548 | * to the joinlist or namespace. |
549 | */ |
550 | targetPerms = ACL_INSERT; |
551 | if (isOnConflictUpdate) |
552 | targetPerms |= ACL_UPDATE; |
553 | qry->resultRelation = setTargetTable(pstate, stmt->relation, |
554 | false, false, targetPerms); |
555 | |
556 | /* Validate stmt->cols list, or build default list if no list given */ |
557 | icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos); |
558 | Assert(list_length(icolumns) == list_length(attrnos)); |
559 | |
560 | /* |
561 | * Determine which variant of INSERT we have. |
562 | */ |
563 | if (selectStmt == NULL) |
564 | { |
565 | /* |
566 | * We have INSERT ... DEFAULT VALUES. We can handle this case by |
567 | * emitting an empty targetlist --- all columns will be defaulted when |
568 | * the planner expands the targetlist. |
569 | */ |
570 | exprList = NIL; |
571 | } |
572 | else if (isGeneralSelect) |
573 | { |
574 | /* |
575 | * We make the sub-pstate a child of the outer pstate so that it can |
576 | * see any Param definitions supplied from above. Since the outer |
577 | * pstate's rtable and namespace are presently empty, there are no |
578 | * side-effects of exposing names the sub-SELECT shouldn't be able to |
579 | * see. |
580 | */ |
581 | ParseState *sub_pstate = make_parsestate(pstate); |
582 | Query *selectQuery; |
583 | |
584 | /* |
585 | * Process the source SELECT. |
586 | * |
587 | * It is important that this be handled just like a standalone SELECT; |
588 | * otherwise the behavior of SELECT within INSERT might be different |
589 | * from a stand-alone SELECT. (Indeed, Postgres up through 6.5 had |
590 | * bugs of just that nature...) |
591 | * |
592 | * The sole exception is that we prevent resolving unknown-type |
593 | * outputs as TEXT. This does not change the semantics since if the |
594 | * column type matters semantically, it would have been resolved to |
595 | * something else anyway. Doing this lets us resolve such outputs as |
596 | * the target column's type, which we handle below. |
597 | */ |
598 | sub_pstate->p_rtable = sub_rtable; |
599 | sub_pstate->p_joinexprs = NIL; /* sub_rtable has no joins */ |
600 | sub_pstate->p_namespace = sub_namespace; |
601 | sub_pstate->p_resolve_unknowns = false; |
602 | |
603 | selectQuery = transformStmt(sub_pstate, stmt->selectStmt); |
604 | |
605 | free_parsestate(sub_pstate); |
606 | |
607 | /* The grammar should have produced a SELECT */ |
608 | if (!IsA(selectQuery, Query) || |
609 | selectQuery->commandType != CMD_SELECT) |
610 | elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT" ); |
611 | |
612 | /* |
613 | * Make the source be a subquery in the INSERT's rangetable, and add |
614 | * it to the INSERT's joinlist. |
615 | */ |
616 | rte = addRangeTableEntryForSubquery(pstate, |
617 | selectQuery, |
618 | makeAlias("*SELECT*" , NIL), |
619 | false, |
620 | false); |
621 | rtr = makeNode(RangeTblRef); |
622 | /* assume new rte is at end */ |
623 | rtr->rtindex = list_length(pstate->p_rtable); |
624 | Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable)); |
625 | pstate->p_joinlist = lappend(pstate->p_joinlist, rtr); |
626 | |
627 | /*---------- |
628 | * Generate an expression list for the INSERT that selects all the |
629 | * non-resjunk columns from the subquery. (INSERT's tlist must be |
630 | * separate from the subquery's tlist because we may add columns, |
631 | * insert datatype coercions, etc.) |
632 | * |
633 | * HACK: unknown-type constants and params in the SELECT's targetlist |
634 | * are copied up as-is rather than being referenced as subquery |
635 | * outputs. This is to ensure that when we try to coerce them to |
636 | * the target column's datatype, the right things happen (see |
637 | * special cases in coerce_type). Otherwise, this fails: |
638 | * INSERT INTO foo SELECT 'bar', ... FROM baz |
639 | *---------- |
640 | */ |
641 | exprList = NIL; |
642 | foreach(lc, selectQuery->targetList) |
643 | { |
644 | TargetEntry *tle = (TargetEntry *) lfirst(lc); |
645 | Expr *expr; |
646 | |
647 | if (tle->resjunk) |
648 | continue; |
649 | if (tle->expr && |
650 | (IsA(tle->expr, Const) ||IsA(tle->expr, Param)) && |
651 | exprType((Node *) tle->expr) == UNKNOWNOID) |
652 | expr = tle->expr; |
653 | else |
654 | { |
655 | Var *var = makeVarFromTargetEntry(rtr->rtindex, tle); |
656 | |
657 | var->location = exprLocation((Node *) tle->expr); |
658 | expr = (Expr *) var; |
659 | } |
660 | exprList = lappend(exprList, expr); |
661 | } |
662 | |
663 | /* Prepare row for assignment to target table */ |
664 | exprList = transformInsertRow(pstate, exprList, |
665 | stmt->cols, |
666 | icolumns, attrnos, |
667 | false); |
668 | } |
669 | else if (list_length(selectStmt->valuesLists) > 1) |
670 | { |
671 | /* |
672 | * Process INSERT ... VALUES with multiple VALUES sublists. We |
673 | * generate a VALUES RTE holding the transformed expression lists, and |
674 | * build up a targetlist containing Vars that reference the VALUES |
675 | * RTE. |
676 | */ |
677 | List *exprsLists = NIL; |
678 | List *coltypes = NIL; |
679 | List *coltypmods = NIL; |
680 | List *colcollations = NIL; |
681 | int sublist_length = -1; |
682 | bool lateral = false; |
683 | |
684 | Assert(selectStmt->intoClause == NULL); |
685 | |
686 | foreach(lc, selectStmt->valuesLists) |
687 | { |
688 | List *sublist = (List *) lfirst(lc); |
689 | |
690 | /* |
691 | * Do basic expression transformation (same as a ROW() expr, but |
692 | * allow SetToDefault at top level) |
693 | */ |
694 | sublist = transformExpressionList(pstate, sublist, |
695 | EXPR_KIND_VALUES, true); |
696 | |
697 | /* |
698 | * All the sublists must be the same length, *after* |
699 | * transformation (which might expand '*' into multiple items). |
700 | * The VALUES RTE can't handle anything different. |
701 | */ |
702 | if (sublist_length < 0) |
703 | { |
704 | /* Remember post-transformation length of first sublist */ |
705 | sublist_length = list_length(sublist); |
706 | } |
707 | else if (sublist_length != list_length(sublist)) |
708 | { |
709 | ereport(ERROR, |
710 | (errcode(ERRCODE_SYNTAX_ERROR), |
711 | errmsg("VALUES lists must all be the same length" ), |
712 | parser_errposition(pstate, |
713 | exprLocation((Node *) sublist)))); |
714 | } |
715 | |
716 | /* |
717 | * Prepare row for assignment to target table. We process any |
718 | * indirection on the target column specs normally but then strip |
719 | * off the resulting field/array assignment nodes, since we don't |
720 | * want the parsed statement to contain copies of those in each |
721 | * VALUES row. (It's annoying to have to transform the |
722 | * indirection specs over and over like this, but avoiding it |
723 | * would take some really messy refactoring of |
724 | * transformAssignmentIndirection.) |
725 | */ |
726 | sublist = transformInsertRow(pstate, sublist, |
727 | stmt->cols, |
728 | icolumns, attrnos, |
729 | true); |
730 | |
731 | /* |
732 | * We must assign collations now because assign_query_collations |
733 | * doesn't process rangetable entries. We just assign all the |
734 | * collations independently in each row, and don't worry about |
735 | * whether they are consistent vertically. The outer INSERT query |
736 | * isn't going to care about the collations of the VALUES columns, |
737 | * so it's not worth the effort to identify a common collation for |
738 | * each one here. (But note this does have one user-visible |
739 | * consequence: INSERT ... VALUES won't complain about conflicting |
740 | * explicit COLLATEs in a column, whereas the same VALUES |
741 | * construct in another context would complain.) |
742 | */ |
743 | assign_list_collations(pstate, sublist); |
744 | |
745 | exprsLists = lappend(exprsLists, sublist); |
746 | } |
747 | |
748 | /* |
749 | * Construct column type/typmod/collation lists for the VALUES RTE. |
750 | * Every expression in each column has been coerced to the type/typmod |
751 | * of the corresponding target column or subfield, so it's sufficient |
752 | * to look at the exprType/exprTypmod of the first row. We don't care |
753 | * about the collation labeling, so just fill in InvalidOid for that. |
754 | */ |
755 | foreach(lc, (List *) linitial(exprsLists)) |
756 | { |
757 | Node *val = (Node *) lfirst(lc); |
758 | |
759 | coltypes = lappend_oid(coltypes, exprType(val)); |
760 | coltypmods = lappend_int(coltypmods, exprTypmod(val)); |
761 | colcollations = lappend_oid(colcollations, InvalidOid); |
762 | } |
763 | |
764 | /* |
765 | * Ordinarily there can't be any current-level Vars in the expression |
766 | * lists, because the namespace was empty ... but if we're inside |
767 | * CREATE RULE, then NEW/OLD references might appear. In that case we |
768 | * have to mark the VALUES RTE as LATERAL. |
769 | */ |
770 | if (list_length(pstate->p_rtable) != 1 && |
771 | contain_vars_of_level((Node *) exprsLists, 0)) |
772 | lateral = true; |
773 | |
774 | /* |
775 | * Generate the VALUES RTE |
776 | */ |
777 | rte = addRangeTableEntryForValues(pstate, exprsLists, |
778 | coltypes, coltypmods, colcollations, |
779 | NULL, lateral, true); |
780 | rtr = makeNode(RangeTblRef); |
781 | /* assume new rte is at end */ |
782 | rtr->rtindex = list_length(pstate->p_rtable); |
783 | Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable)); |
784 | pstate->p_joinlist = lappend(pstate->p_joinlist, rtr); |
785 | |
786 | /* |
787 | * Generate list of Vars referencing the RTE |
788 | */ |
789 | expandRTE(rte, rtr->rtindex, 0, -1, false, NULL, &exprList); |
790 | |
791 | /* |
792 | * Re-apply any indirection on the target column specs to the Vars |
793 | */ |
794 | exprList = transformInsertRow(pstate, exprList, |
795 | stmt->cols, |
796 | icolumns, attrnos, |
797 | false); |
798 | } |
799 | else |
800 | { |
801 | /* |
802 | * Process INSERT ... VALUES with a single VALUES sublist. We treat |
803 | * this case separately for efficiency. The sublist is just computed |
804 | * directly as the Query's targetlist, with no VALUES RTE. So it |
805 | * works just like a SELECT without any FROM. |
806 | */ |
807 | List *valuesLists = selectStmt->valuesLists; |
808 | |
809 | Assert(list_length(valuesLists) == 1); |
810 | Assert(selectStmt->intoClause == NULL); |
811 | |
812 | /* |
813 | * Do basic expression transformation (same as a ROW() expr, but allow |
814 | * SetToDefault at top level) |
815 | */ |
816 | exprList = transformExpressionList(pstate, |
817 | (List *) linitial(valuesLists), |
818 | EXPR_KIND_VALUES_SINGLE, |
819 | true); |
820 | |
821 | /* Prepare row for assignment to target table */ |
822 | exprList = transformInsertRow(pstate, exprList, |
823 | stmt->cols, |
824 | icolumns, attrnos, |
825 | false); |
826 | } |
827 | |
828 | /* |
829 | * Generate query's target list using the computed list of expressions. |
830 | * Also, mark all the target columns as needing insert permissions. |
831 | */ |
832 | rte = pstate->p_target_rangetblentry; |
833 | qry->targetList = NIL; |
834 | Assert(list_length(exprList) <= list_length(icolumns)); |
835 | forthree(lc, exprList, icols, icolumns, attnos, attrnos) |
836 | { |
837 | Expr *expr = (Expr *) lfirst(lc); |
838 | ResTarget *col = lfirst_node(ResTarget, icols); |
839 | AttrNumber attr_num = (AttrNumber) lfirst_int(attnos); |
840 | TargetEntry *tle; |
841 | |
842 | tle = makeTargetEntry(expr, |
843 | attr_num, |
844 | col->name, |
845 | false); |
846 | qry->targetList = lappend(qry->targetList, tle); |
847 | |
848 | rte->insertedCols = bms_add_member(rte->insertedCols, |
849 | attr_num - FirstLowInvalidHeapAttributeNumber); |
850 | } |
851 | |
852 | /* Process ON CONFLICT, if any. */ |
853 | if (stmt->onConflictClause) |
854 | qry->onConflict = transformOnConflictClause(pstate, |
855 | stmt->onConflictClause); |
856 | |
857 | /* |
858 | * If we have a RETURNING clause, we need to add the target relation to |
859 | * the query namespace before processing it, so that Var references in |
860 | * RETURNING will work. Also, remove any namespace entries added in a |
861 | * sub-SELECT or VALUES list. |
862 | */ |
863 | if (stmt->returningList) |
864 | { |
865 | pstate->p_namespace = NIL; |
866 | addRTEtoQuery(pstate, pstate->p_target_rangetblentry, |
867 | false, true, true); |
868 | qry->returningList = transformReturningList(pstate, |
869 | stmt->returningList); |
870 | } |
871 | |
872 | /* done building the range table and jointree */ |
873 | qry->rtable = pstate->p_rtable; |
874 | qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); |
875 | |
876 | qry->hasTargetSRFs = pstate->p_hasTargetSRFs; |
877 | qry->hasSubLinks = pstate->p_hasSubLinks; |
878 | |
879 | assign_query_collations(pstate, qry); |
880 | |
881 | return qry; |
882 | } |
883 | |
884 | /* |
885 | * Prepare an INSERT row for assignment to the target table. |
886 | * |
887 | * exprlist: transformed expressions for source values; these might come from |
888 | * a VALUES row, or be Vars referencing a sub-SELECT or VALUES RTE output. |
889 | * stmtcols: original target-columns spec for INSERT (we just test for NIL) |
890 | * icolumns: effective target-columns spec (list of ResTarget) |
891 | * attrnos: integer column numbers (must be same length as icolumns) |
892 | * strip_indirection: if true, remove any field/array assignment nodes |
893 | */ |
894 | static List * |
895 | transformInsertRow(ParseState *pstate, List *exprlist, |
896 | List *stmtcols, List *icolumns, List *attrnos, |
897 | bool strip_indirection) |
898 | { |
899 | List *result; |
900 | ListCell *lc; |
901 | ListCell *icols; |
902 | ListCell *attnos; |
903 | |
904 | /* |
905 | * Check length of expr list. It must not have more expressions than |
906 | * there are target columns. We allow fewer, but only if no explicit |
907 | * columns list was given (the remaining columns are implicitly |
908 | * defaulted). Note we must check this *after* transformation because |
909 | * that could expand '*' into multiple items. |
910 | */ |
911 | if (list_length(exprlist) > list_length(icolumns)) |
912 | ereport(ERROR, |
913 | (errcode(ERRCODE_SYNTAX_ERROR), |
914 | errmsg("INSERT has more expressions than target columns" ), |
915 | parser_errposition(pstate, |
916 | exprLocation(list_nth(exprlist, |
917 | list_length(icolumns)))))); |
918 | if (stmtcols != NIL && |
919 | list_length(exprlist) < list_length(icolumns)) |
920 | { |
921 | /* |
922 | * We can get here for cases like INSERT ... SELECT (a,b,c) FROM ... |
923 | * where the user accidentally created a RowExpr instead of separate |
924 | * columns. Add a suitable hint if that seems to be the problem, |
925 | * because the main error message is quite misleading for this case. |
926 | * (If there's no stmtcols, you'll get something about data type |
927 | * mismatch, which is less misleading so we don't worry about giving a |
928 | * hint in that case.) |
929 | */ |
930 | ereport(ERROR, |
931 | (errcode(ERRCODE_SYNTAX_ERROR), |
932 | errmsg("INSERT has more target columns than expressions" ), |
933 | ((list_length(exprlist) == 1 && |
934 | count_rowexpr_columns(pstate, linitial(exprlist)) == |
935 | list_length(icolumns)) ? |
936 | errhint("The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" ) : 0), |
937 | parser_errposition(pstate, |
938 | exprLocation(list_nth(icolumns, |
939 | list_length(exprlist)))))); |
940 | } |
941 | |
942 | /* |
943 | * Prepare columns for assignment to target table. |
944 | */ |
945 | result = NIL; |
946 | forthree(lc, exprlist, icols, icolumns, attnos, attrnos) |
947 | { |
948 | Expr *expr = (Expr *) lfirst(lc); |
949 | ResTarget *col = lfirst_node(ResTarget, icols); |
950 | int attno = lfirst_int(attnos); |
951 | |
952 | expr = transformAssignedExpr(pstate, expr, |
953 | EXPR_KIND_INSERT_TARGET, |
954 | col->name, |
955 | attno, |
956 | col->indirection, |
957 | col->location); |
958 | |
959 | if (strip_indirection) |
960 | { |
961 | while (expr) |
962 | { |
963 | if (IsA(expr, FieldStore)) |
964 | { |
965 | FieldStore *fstore = (FieldStore *) expr; |
966 | |
967 | expr = (Expr *) linitial(fstore->newvals); |
968 | } |
969 | else if (IsA(expr, SubscriptingRef)) |
970 | { |
971 | SubscriptingRef *sbsref = (SubscriptingRef *) expr; |
972 | |
973 | if (sbsref->refassgnexpr == NULL) |
974 | break; |
975 | |
976 | expr = sbsref->refassgnexpr; |
977 | } |
978 | else |
979 | break; |
980 | } |
981 | } |
982 | |
983 | result = lappend(result, expr); |
984 | } |
985 | |
986 | return result; |
987 | } |
988 | |
989 | /* |
990 | * transformOnConflictClause - |
991 | * transforms an OnConflictClause in an INSERT |
992 | */ |
993 | static OnConflictExpr * |
994 | transformOnConflictClause(ParseState *pstate, |
995 | OnConflictClause *onConflictClause) |
996 | { |
997 | List *arbiterElems; |
998 | Node *arbiterWhere; |
999 | Oid arbiterConstraint; |
1000 | List *onConflictSet = NIL; |
1001 | Node *onConflictWhere = NULL; |
1002 | RangeTblEntry *exclRte = NULL; |
1003 | int exclRelIndex = 0; |
1004 | List *exclRelTlist = NIL; |
1005 | OnConflictExpr *result; |
1006 | |
1007 | /* Process the arbiter clause, ON CONFLICT ON (...) */ |
1008 | transformOnConflictArbiter(pstate, onConflictClause, &arbiterElems, |
1009 | &arbiterWhere, &arbiterConstraint); |
1010 | |
1011 | /* Process DO UPDATE */ |
1012 | if (onConflictClause->action == ONCONFLICT_UPDATE) |
1013 | { |
1014 | Relation targetrel = pstate->p_target_relation; |
1015 | |
1016 | /* |
1017 | * All INSERT expressions have been parsed, get ready for potentially |
1018 | * existing SET statements that need to be processed like an UPDATE. |
1019 | */ |
1020 | pstate->p_is_insert = false; |
1021 | |
1022 | /* |
1023 | * Add range table entry for the EXCLUDED pseudo relation. relkind is |
1024 | * set to composite to signal that we're not dealing with an actual |
1025 | * relation, and no permission checks are required on it. (We'll |
1026 | * check the actual target relation, instead.) |
1027 | */ |
1028 | exclRte = addRangeTableEntryForRelation(pstate, |
1029 | targetrel, |
1030 | RowExclusiveLock, |
1031 | makeAlias("excluded" , NIL), |
1032 | false, false); |
1033 | exclRte->relkind = RELKIND_COMPOSITE_TYPE; |
1034 | exclRte->requiredPerms = 0; |
1035 | /* other permissions fields in exclRte are already empty */ |
1036 | |
1037 | exclRelIndex = list_length(pstate->p_rtable); |
1038 | |
1039 | /* Create EXCLUDED rel's targetlist for use by EXPLAIN */ |
1040 | exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel, |
1041 | exclRelIndex); |
1042 | |
1043 | /* |
1044 | * Add EXCLUDED and the target RTE to the namespace, so that they can |
1045 | * be used in the UPDATE subexpressions. |
1046 | */ |
1047 | addRTEtoQuery(pstate, exclRte, false, true, true); |
1048 | addRTEtoQuery(pstate, pstate->p_target_rangetblentry, |
1049 | false, true, true); |
1050 | |
1051 | /* |
1052 | * Now transform the UPDATE subexpressions. |
1053 | */ |
1054 | onConflictSet = |
1055 | transformUpdateTargetList(pstate, onConflictClause->targetList); |
1056 | |
1057 | onConflictWhere = transformWhereClause(pstate, |
1058 | onConflictClause->whereClause, |
1059 | EXPR_KIND_WHERE, "WHERE" ); |
1060 | } |
1061 | |
1062 | /* Finally, build ON CONFLICT DO [NOTHING | UPDATE] expression */ |
1063 | result = makeNode(OnConflictExpr); |
1064 | |
1065 | result->action = onConflictClause->action; |
1066 | result->arbiterElems = arbiterElems; |
1067 | result->arbiterWhere = arbiterWhere; |
1068 | result->constraint = arbiterConstraint; |
1069 | result->onConflictSet = onConflictSet; |
1070 | result->onConflictWhere = onConflictWhere; |
1071 | result->exclRelIndex = exclRelIndex; |
1072 | result->exclRelTlist = exclRelTlist; |
1073 | |
1074 | return result; |
1075 | } |
1076 | |
1077 | |
1078 | /* |
1079 | * BuildOnConflictExcludedTargetlist |
1080 | * Create target list for the EXCLUDED pseudo-relation of ON CONFLICT, |
1081 | * representing the columns of targetrel with varno exclRelIndex. |
1082 | * |
1083 | * Note: Exported for use in the rewriter. |
1084 | */ |
1085 | List * |
1086 | BuildOnConflictExcludedTargetlist(Relation targetrel, |
1087 | Index exclRelIndex) |
1088 | { |
1089 | List *result = NIL; |
1090 | int attno; |
1091 | Var *var; |
1092 | TargetEntry *te; |
1093 | |
1094 | /* |
1095 | * Note that resnos of the tlist must correspond to attnos of the |
1096 | * underlying relation, hence we need entries for dropped columns too. |
1097 | */ |
1098 | for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++) |
1099 | { |
1100 | Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno); |
1101 | char *name; |
1102 | |
1103 | if (attr->attisdropped) |
1104 | { |
1105 | /* |
1106 | * can't use atttypid here, but it doesn't really matter what type |
1107 | * the Const claims to be. |
1108 | */ |
1109 | var = (Var *) makeNullConst(INT4OID, -1, InvalidOid); |
1110 | name = NULL; |
1111 | } |
1112 | else |
1113 | { |
1114 | var = makeVar(exclRelIndex, attno + 1, |
1115 | attr->atttypid, attr->atttypmod, |
1116 | attr->attcollation, |
1117 | 0); |
1118 | name = pstrdup(NameStr(attr->attname)); |
1119 | } |
1120 | |
1121 | te = makeTargetEntry((Expr *) var, |
1122 | attno + 1, |
1123 | name, |
1124 | false); |
1125 | |
1126 | result = lappend(result, te); |
1127 | } |
1128 | |
1129 | /* |
1130 | * Add a whole-row-Var entry to support references to "EXCLUDED.*". Like |
1131 | * the other entries in the EXCLUDED tlist, its resno must match the Var's |
1132 | * varattno, else the wrong things happen while resolving references in |
1133 | * setrefs.c. This is against normal conventions for targetlists, but |
1134 | * it's okay since we don't use this as a real tlist. |
1135 | */ |
1136 | var = makeVar(exclRelIndex, InvalidAttrNumber, |
1137 | targetrel->rd_rel->reltype, |
1138 | -1, InvalidOid, 0); |
1139 | te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true); |
1140 | result = lappend(result, te); |
1141 | |
1142 | return result; |
1143 | } |
1144 | |
1145 | |
1146 | /* |
1147 | * count_rowexpr_columns - |
1148 | * get number of columns contained in a ROW() expression; |
1149 | * return -1 if expression isn't a RowExpr or a Var referencing one. |
1150 | * |
1151 | * This is currently used only for hint purposes, so we aren't terribly |
1152 | * tense about recognizing all possible cases. The Var case is interesting |
1153 | * because that's what we'll get in the INSERT ... SELECT (...) case. |
1154 | */ |
1155 | static int |
1156 | count_rowexpr_columns(ParseState *pstate, Node *expr) |
1157 | { |
1158 | if (expr == NULL) |
1159 | return -1; |
1160 | if (IsA(expr, RowExpr)) |
1161 | return list_length(((RowExpr *) expr)->args); |
1162 | if (IsA(expr, Var)) |
1163 | { |
1164 | Var *var = (Var *) expr; |
1165 | AttrNumber attnum = var->varattno; |
1166 | |
1167 | if (attnum > 0 && var->vartype == RECORDOID) |
1168 | { |
1169 | RangeTblEntry *rte; |
1170 | |
1171 | rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup); |
1172 | if (rte->rtekind == RTE_SUBQUERY) |
1173 | { |
1174 | /* Subselect-in-FROM: examine sub-select's output expr */ |
1175 | TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList, |
1176 | attnum); |
1177 | |
1178 | if (ste == NULL || ste->resjunk) |
1179 | return -1; |
1180 | expr = (Node *) ste->expr; |
1181 | if (IsA(expr, RowExpr)) |
1182 | return list_length(((RowExpr *) expr)->args); |
1183 | } |
1184 | } |
1185 | } |
1186 | return -1; |
1187 | } |
1188 | |
1189 | |
1190 | /* |
1191 | * transformSelectStmt - |
1192 | * transforms a Select Statement |
1193 | * |
1194 | * Note: this covers only cases with no set operations and no VALUES lists; |
1195 | * see below for the other cases. |
1196 | */ |
1197 | static Query * |
1198 | transformSelectStmt(ParseState *pstate, SelectStmt *stmt) |
1199 | { |
1200 | Query *qry = makeNode(Query); |
1201 | Node *qual; |
1202 | ListCell *l; |
1203 | |
1204 | qry->commandType = CMD_SELECT; |
1205 | |
1206 | /* process the WITH clause independently of all else */ |
1207 | if (stmt->withClause) |
1208 | { |
1209 | qry->hasRecursive = stmt->withClause->recursive; |
1210 | qry->cteList = transformWithClause(pstate, stmt->withClause); |
1211 | qry->hasModifyingCTE = pstate->p_hasModifyingCTE; |
1212 | } |
1213 | |
1214 | /* Complain if we get called from someplace where INTO is not allowed */ |
1215 | if (stmt->intoClause) |
1216 | ereport(ERROR, |
1217 | (errcode(ERRCODE_SYNTAX_ERROR), |
1218 | errmsg("SELECT ... INTO is not allowed here" ), |
1219 | parser_errposition(pstate, |
1220 | exprLocation((Node *) stmt->intoClause)))); |
1221 | |
1222 | /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */ |
1223 | pstate->p_locking_clause = stmt->lockingClause; |
1224 | |
1225 | /* make WINDOW info available for window functions, too */ |
1226 | pstate->p_windowdefs = stmt->windowClause; |
1227 | |
1228 | /* process the FROM clause */ |
1229 | transformFromClause(pstate, stmt->fromClause); |
1230 | |
1231 | /* transform targetlist */ |
1232 | qry->targetList = transformTargetList(pstate, stmt->targetList, |
1233 | EXPR_KIND_SELECT_TARGET); |
1234 | |
1235 | /* mark column origins */ |
1236 | markTargetListOrigins(pstate, qry->targetList); |
1237 | |
1238 | /* transform WHERE */ |
1239 | qual = transformWhereClause(pstate, stmt->whereClause, |
1240 | EXPR_KIND_WHERE, "WHERE" ); |
1241 | |
1242 | /* initial processing of HAVING clause is much like WHERE clause */ |
1243 | qry->havingQual = transformWhereClause(pstate, stmt->havingClause, |
1244 | EXPR_KIND_HAVING, "HAVING" ); |
1245 | |
1246 | /* |
1247 | * Transform sorting/grouping stuff. Do ORDER BY first because both |
1248 | * transformGroupClause and transformDistinctClause need the results. Note |
1249 | * that these functions can also change the targetList, so it's passed to |
1250 | * them by reference. |
1251 | */ |
1252 | qry->sortClause = transformSortClause(pstate, |
1253 | stmt->sortClause, |
1254 | &qry->targetList, |
1255 | EXPR_KIND_ORDER_BY, |
1256 | false /* allow SQL92 rules */ ); |
1257 | |
1258 | qry->groupClause = transformGroupClause(pstate, |
1259 | stmt->groupClause, |
1260 | &qry->groupingSets, |
1261 | &qry->targetList, |
1262 | qry->sortClause, |
1263 | EXPR_KIND_GROUP_BY, |
1264 | false /* allow SQL92 rules */ ); |
1265 | |
1266 | if (stmt->distinctClause == NIL) |
1267 | { |
1268 | qry->distinctClause = NIL; |
1269 | qry->hasDistinctOn = false; |
1270 | } |
1271 | else if (linitial(stmt->distinctClause) == NULL) |
1272 | { |
1273 | /* We had SELECT DISTINCT */ |
1274 | qry->distinctClause = transformDistinctClause(pstate, |
1275 | &qry->targetList, |
1276 | qry->sortClause, |
1277 | false); |
1278 | qry->hasDistinctOn = false; |
1279 | } |
1280 | else |
1281 | { |
1282 | /* We had SELECT DISTINCT ON */ |
1283 | qry->distinctClause = transformDistinctOnClause(pstate, |
1284 | stmt->distinctClause, |
1285 | &qry->targetList, |
1286 | qry->sortClause); |
1287 | qry->hasDistinctOn = true; |
1288 | } |
1289 | |
1290 | /* transform LIMIT */ |
1291 | qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset, |
1292 | EXPR_KIND_OFFSET, "OFFSET" ); |
1293 | qry->limitCount = transformLimitClause(pstate, stmt->limitCount, |
1294 | EXPR_KIND_LIMIT, "LIMIT" ); |
1295 | |
1296 | /* transform window clauses after we have seen all window functions */ |
1297 | qry->windowClause = transformWindowDefinitions(pstate, |
1298 | pstate->p_windowdefs, |
1299 | &qry->targetList); |
1300 | |
1301 | /* resolve any still-unresolved output columns as being type text */ |
1302 | if (pstate->p_resolve_unknowns) |
1303 | resolveTargetListUnknowns(pstate, qry->targetList); |
1304 | |
1305 | qry->rtable = pstate->p_rtable; |
1306 | qry->jointree = makeFromExpr(pstate->p_joinlist, qual); |
1307 | |
1308 | qry->hasSubLinks = pstate->p_hasSubLinks; |
1309 | qry->hasWindowFuncs = pstate->p_hasWindowFuncs; |
1310 | qry->hasTargetSRFs = pstate->p_hasTargetSRFs; |
1311 | qry->hasAggs = pstate->p_hasAggs; |
1312 | |
1313 | foreach(l, stmt->lockingClause) |
1314 | { |
1315 | transformLockingClause(pstate, qry, |
1316 | (LockingClause *) lfirst(l), false); |
1317 | } |
1318 | |
1319 | assign_query_collations(pstate, qry); |
1320 | |
1321 | /* this must be done after collations, for reliable comparison of exprs */ |
1322 | if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) |
1323 | parseCheckAggregates(pstate, qry); |
1324 | |
1325 | return qry; |
1326 | } |
1327 | |
1328 | /* |
1329 | * transformValuesClause - |
1330 | * transforms a VALUES clause that's being used as a standalone SELECT |
1331 | * |
1332 | * We build a Query containing a VALUES RTE, rather as if one had written |
1333 | * SELECT * FROM (VALUES ...) AS "*VALUES*" |
1334 | */ |
1335 | static Query * |
1336 | transformValuesClause(ParseState *pstate, SelectStmt *stmt) |
1337 | { |
1338 | Query *qry = makeNode(Query); |
1339 | List *exprsLists; |
1340 | List *coltypes = NIL; |
1341 | List *coltypmods = NIL; |
1342 | List *colcollations = NIL; |
1343 | List **colexprs = NULL; |
1344 | int sublist_length = -1; |
1345 | bool lateral = false; |
1346 | RangeTblEntry *rte; |
1347 | int rtindex; |
1348 | ListCell *lc; |
1349 | ListCell *lc2; |
1350 | int i; |
1351 | |
1352 | qry->commandType = CMD_SELECT; |
1353 | |
1354 | /* Most SELECT stuff doesn't apply in a VALUES clause */ |
1355 | Assert(stmt->distinctClause == NIL); |
1356 | Assert(stmt->intoClause == NULL); |
1357 | Assert(stmt->targetList == NIL); |
1358 | Assert(stmt->fromClause == NIL); |
1359 | Assert(stmt->whereClause == NULL); |
1360 | Assert(stmt->groupClause == NIL); |
1361 | Assert(stmt->havingClause == NULL); |
1362 | Assert(stmt->windowClause == NIL); |
1363 | Assert(stmt->op == SETOP_NONE); |
1364 | |
1365 | /* process the WITH clause independently of all else */ |
1366 | if (stmt->withClause) |
1367 | { |
1368 | qry->hasRecursive = stmt->withClause->recursive; |
1369 | qry->cteList = transformWithClause(pstate, stmt->withClause); |
1370 | qry->hasModifyingCTE = pstate->p_hasModifyingCTE; |
1371 | } |
1372 | |
1373 | /* |
1374 | * For each row of VALUES, transform the raw expressions. |
1375 | * |
1376 | * Note that the intermediate representation we build is column-organized |
1377 | * not row-organized. That simplifies the type and collation processing |
1378 | * below. |
1379 | */ |
1380 | foreach(lc, stmt->valuesLists) |
1381 | { |
1382 | List *sublist = (List *) lfirst(lc); |
1383 | |
1384 | /* |
1385 | * Do basic expression transformation (same as a ROW() expr, but here |
1386 | * we disallow SetToDefault) |
1387 | */ |
1388 | sublist = transformExpressionList(pstate, sublist, |
1389 | EXPR_KIND_VALUES, false); |
1390 | |
1391 | /* |
1392 | * All the sublists must be the same length, *after* transformation |
1393 | * (which might expand '*' into multiple items). The VALUES RTE can't |
1394 | * handle anything different. |
1395 | */ |
1396 | if (sublist_length < 0) |
1397 | { |
1398 | /* Remember post-transformation length of first sublist */ |
1399 | sublist_length = list_length(sublist); |
1400 | /* and allocate array for per-column lists */ |
1401 | colexprs = (List **) palloc0(sublist_length * sizeof(List *)); |
1402 | } |
1403 | else if (sublist_length != list_length(sublist)) |
1404 | { |
1405 | ereport(ERROR, |
1406 | (errcode(ERRCODE_SYNTAX_ERROR), |
1407 | errmsg("VALUES lists must all be the same length" ), |
1408 | parser_errposition(pstate, |
1409 | exprLocation((Node *) sublist)))); |
1410 | } |
1411 | |
1412 | /* Build per-column expression lists */ |
1413 | i = 0; |
1414 | foreach(lc2, sublist) |
1415 | { |
1416 | Node *col = (Node *) lfirst(lc2); |
1417 | |
1418 | colexprs[i] = lappend(colexprs[i], col); |
1419 | i++; |
1420 | } |
1421 | |
1422 | /* Release sub-list's cells to save memory */ |
1423 | list_free(sublist); |
1424 | } |
1425 | |
1426 | /* |
1427 | * Now resolve the common types of the columns, and coerce everything to |
1428 | * those types. Then identify the common typmod and common collation, if |
1429 | * any, of each column. |
1430 | * |
1431 | * We must do collation processing now because (1) assign_query_collations |
1432 | * doesn't process rangetable entries, and (2) we need to label the VALUES |
1433 | * RTE with column collations for use in the outer query. We don't |
1434 | * consider conflict of implicit collations to be an error here; instead |
1435 | * the column will just show InvalidOid as its collation, and you'll get a |
1436 | * failure later if that results in failure to resolve a collation. |
1437 | * |
1438 | * Note we modify the per-column expression lists in-place. |
1439 | */ |
1440 | for (i = 0; i < sublist_length; i++) |
1441 | { |
1442 | Oid coltype; |
1443 | int32 coltypmod = -1; |
1444 | Oid colcoll; |
1445 | bool first = true; |
1446 | |
1447 | coltype = select_common_type(pstate, colexprs[i], "VALUES" , NULL); |
1448 | |
1449 | foreach(lc, colexprs[i]) |
1450 | { |
1451 | Node *col = (Node *) lfirst(lc); |
1452 | |
1453 | col = coerce_to_common_type(pstate, col, coltype, "VALUES" ); |
1454 | lfirst(lc) = (void *) col; |
1455 | if (first) |
1456 | { |
1457 | coltypmod = exprTypmod(col); |
1458 | first = false; |
1459 | } |
1460 | else |
1461 | { |
1462 | /* As soon as we see a non-matching typmod, fall back to -1 */ |
1463 | if (coltypmod >= 0 && coltypmod != exprTypmod(col)) |
1464 | coltypmod = -1; |
1465 | } |
1466 | } |
1467 | |
1468 | colcoll = select_common_collation(pstate, colexprs[i], true); |
1469 | |
1470 | coltypes = lappend_oid(coltypes, coltype); |
1471 | coltypmods = lappend_int(coltypmods, coltypmod); |
1472 | colcollations = lappend_oid(colcollations, colcoll); |
1473 | } |
1474 | |
1475 | /* |
1476 | * Finally, rearrange the coerced expressions into row-organized lists. |
1477 | */ |
1478 | exprsLists = NIL; |
1479 | foreach(lc, colexprs[0]) |
1480 | { |
1481 | Node *col = (Node *) lfirst(lc); |
1482 | List *sublist; |
1483 | |
1484 | sublist = list_make1(col); |
1485 | exprsLists = lappend(exprsLists, sublist); |
1486 | } |
1487 | list_free(colexprs[0]); |
1488 | for (i = 1; i < sublist_length; i++) |
1489 | { |
1490 | forboth(lc, colexprs[i], lc2, exprsLists) |
1491 | { |
1492 | Node *col = (Node *) lfirst(lc); |
1493 | List *sublist = lfirst(lc2); |
1494 | |
1495 | /* sublist pointer in exprsLists won't need adjustment */ |
1496 | (void) lappend(sublist, col); |
1497 | } |
1498 | list_free(colexprs[i]); |
1499 | } |
1500 | |
1501 | /* |
1502 | * Ordinarily there can't be any current-level Vars in the expression |
1503 | * lists, because the namespace was empty ... but if we're inside CREATE |
1504 | * RULE, then NEW/OLD references might appear. In that case we have to |
1505 | * mark the VALUES RTE as LATERAL. |
1506 | */ |
1507 | if (pstate->p_rtable != NIL && |
1508 | contain_vars_of_level((Node *) exprsLists, 0)) |
1509 | lateral = true; |
1510 | |
1511 | /* |
1512 | * Generate the VALUES RTE |
1513 | */ |
1514 | rte = addRangeTableEntryForValues(pstate, exprsLists, |
1515 | coltypes, coltypmods, colcollations, |
1516 | NULL, lateral, true); |
1517 | addRTEtoQuery(pstate, rte, true, true, true); |
1518 | |
1519 | /* assume new rte is at end */ |
1520 | rtindex = list_length(pstate->p_rtable); |
1521 | Assert(rte == rt_fetch(rtindex, pstate->p_rtable)); |
1522 | |
1523 | /* |
1524 | * Generate a targetlist as though expanding "*" |
1525 | */ |
1526 | Assert(pstate->p_next_resno == 1); |
1527 | qry->targetList = expandRelAttrs(pstate, rte, rtindex, 0, -1); |
1528 | |
1529 | /* |
1530 | * The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE to a |
1531 | * VALUES, so cope. |
1532 | */ |
1533 | qry->sortClause = transformSortClause(pstate, |
1534 | stmt->sortClause, |
1535 | &qry->targetList, |
1536 | EXPR_KIND_ORDER_BY, |
1537 | false /* allow SQL92 rules */ ); |
1538 | |
1539 | qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset, |
1540 | EXPR_KIND_OFFSET, "OFFSET" ); |
1541 | qry->limitCount = transformLimitClause(pstate, stmt->limitCount, |
1542 | EXPR_KIND_LIMIT, "LIMIT" ); |
1543 | |
1544 | if (stmt->lockingClause) |
1545 | ereport(ERROR, |
1546 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
1547 | /*------ |
1548 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
1549 | errmsg("%s cannot be applied to VALUES" , |
1550 | LCS_asString(((LockingClause *) |
1551 | linitial(stmt->lockingClause))->strength)))); |
1552 | |
1553 | qry->rtable = pstate->p_rtable; |
1554 | qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); |
1555 | |
1556 | qry->hasSubLinks = pstate->p_hasSubLinks; |
1557 | |
1558 | assign_query_collations(pstate, qry); |
1559 | |
1560 | return qry; |
1561 | } |
1562 | |
1563 | /* |
1564 | * transformSetOperationStmt - |
1565 | * transforms a set-operations tree |
1566 | * |
1567 | * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT |
1568 | * structure to it. We must transform each leaf SELECT and build up a top- |
1569 | * level Query that contains the leaf SELECTs as subqueries in its rangetable. |
1570 | * The tree of set operations is converted into the setOperations field of |
1571 | * the top-level Query. |
1572 | */ |
1573 | static Query * |
1574 | transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) |
1575 | { |
1576 | Query *qry = makeNode(Query); |
1577 | SelectStmt *leftmostSelect; |
1578 | int leftmostRTI; |
1579 | Query *leftmostQuery; |
1580 | SetOperationStmt *sostmt; |
1581 | List *sortClause; |
1582 | Node *limitOffset; |
1583 | Node *limitCount; |
1584 | List *lockingClause; |
1585 | WithClause *withClause; |
1586 | Node *node; |
1587 | ListCell *left_tlist, |
1588 | *lct, |
1589 | *lcm, |
1590 | *lcc, |
1591 | *l; |
1592 | List *targetvars, |
1593 | *targetnames, |
1594 | *sv_namespace; |
1595 | int sv_rtable_length; |
1596 | RangeTblEntry *jrte; |
1597 | int tllen; |
1598 | |
1599 | qry->commandType = CMD_SELECT; |
1600 | |
1601 | /* |
1602 | * Find leftmost leaf SelectStmt. We currently only need to do this in |
1603 | * order to deliver a suitable error message if there's an INTO clause |
1604 | * there, implying the set-op tree is in a context that doesn't allow |
1605 | * INTO. (transformSetOperationTree would throw error anyway, but it |
1606 | * seems worth the trouble to throw a different error for non-leftmost |
1607 | * INTO, so we produce that error in transformSetOperationTree.) |
1608 | */ |
1609 | leftmostSelect = stmt->larg; |
1610 | while (leftmostSelect && leftmostSelect->op != SETOP_NONE) |
1611 | leftmostSelect = leftmostSelect->larg; |
1612 | Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) && |
1613 | leftmostSelect->larg == NULL); |
1614 | if (leftmostSelect->intoClause) |
1615 | ereport(ERROR, |
1616 | (errcode(ERRCODE_SYNTAX_ERROR), |
1617 | errmsg("SELECT ... INTO is not allowed here" ), |
1618 | parser_errposition(pstate, |
1619 | exprLocation((Node *) leftmostSelect->intoClause)))); |
1620 | |
1621 | /* |
1622 | * We need to extract ORDER BY and other top-level clauses here and not |
1623 | * let transformSetOperationTree() see them --- else it'll just recurse |
1624 | * right back here! |
1625 | */ |
1626 | sortClause = stmt->sortClause; |
1627 | limitOffset = stmt->limitOffset; |
1628 | limitCount = stmt->limitCount; |
1629 | lockingClause = stmt->lockingClause; |
1630 | withClause = stmt->withClause; |
1631 | |
1632 | stmt->sortClause = NIL; |
1633 | stmt->limitOffset = NULL; |
1634 | stmt->limitCount = NULL; |
1635 | stmt->lockingClause = NIL; |
1636 | stmt->withClause = NULL; |
1637 | |
1638 | /* We don't support FOR UPDATE/SHARE with set ops at the moment. */ |
1639 | if (lockingClause) |
1640 | ereport(ERROR, |
1641 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
1642 | /*------ |
1643 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
1644 | errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT" , |
1645 | LCS_asString(((LockingClause *) |
1646 | linitial(lockingClause))->strength)))); |
1647 | |
1648 | /* Process the WITH clause independently of all else */ |
1649 | if (withClause) |
1650 | { |
1651 | qry->hasRecursive = withClause->recursive; |
1652 | qry->cteList = transformWithClause(pstate, withClause); |
1653 | qry->hasModifyingCTE = pstate->p_hasModifyingCTE; |
1654 | } |
1655 | |
1656 | /* |
1657 | * Recursively transform the components of the tree. |
1658 | */ |
1659 | sostmt = castNode(SetOperationStmt, |
1660 | transformSetOperationTree(pstate, stmt, true, NULL)); |
1661 | Assert(sostmt); |
1662 | qry->setOperations = (Node *) sostmt; |
1663 | |
1664 | /* |
1665 | * Re-find leftmost SELECT (now it's a sub-query in rangetable) |
1666 | */ |
1667 | node = sostmt->larg; |
1668 | while (node && IsA(node, SetOperationStmt)) |
1669 | node = ((SetOperationStmt *) node)->larg; |
1670 | Assert(node && IsA(node, RangeTblRef)); |
1671 | leftmostRTI = ((RangeTblRef *) node)->rtindex; |
1672 | leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery; |
1673 | Assert(leftmostQuery != NULL); |
1674 | |
1675 | /* |
1676 | * Generate dummy targetlist for outer query using column names of |
1677 | * leftmost select and common datatypes/collations of topmost set |
1678 | * operation. Also make lists of the dummy vars and their names for use |
1679 | * in parsing ORDER BY. |
1680 | * |
1681 | * Note: we use leftmostRTI as the varno of the dummy variables. It |
1682 | * shouldn't matter too much which RT index they have, as long as they |
1683 | * have one that corresponds to a real RT entry; else funny things may |
1684 | * happen when the tree is mashed by rule rewriting. |
1685 | */ |
1686 | qry->targetList = NIL; |
1687 | targetvars = NIL; |
1688 | targetnames = NIL; |
1689 | |
1690 | forfour(lct, sostmt->colTypes, |
1691 | lcm, sostmt->colTypmods, |
1692 | lcc, sostmt->colCollations, |
1693 | left_tlist, leftmostQuery->targetList) |
1694 | { |
1695 | Oid colType = lfirst_oid(lct); |
1696 | int32 colTypmod = lfirst_int(lcm); |
1697 | Oid colCollation = lfirst_oid(lcc); |
1698 | TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist); |
1699 | char *colName; |
1700 | TargetEntry *tle; |
1701 | Var *var; |
1702 | |
1703 | Assert(!lefttle->resjunk); |
1704 | colName = pstrdup(lefttle->resname); |
1705 | var = makeVar(leftmostRTI, |
1706 | lefttle->resno, |
1707 | colType, |
1708 | colTypmod, |
1709 | colCollation, |
1710 | 0); |
1711 | var->location = exprLocation((Node *) lefttle->expr); |
1712 | tle = makeTargetEntry((Expr *) var, |
1713 | (AttrNumber) pstate->p_next_resno++, |
1714 | colName, |
1715 | false); |
1716 | qry->targetList = lappend(qry->targetList, tle); |
1717 | targetvars = lappend(targetvars, var); |
1718 | targetnames = lappend(targetnames, makeString(colName)); |
1719 | } |
1720 | |
1721 | /* |
1722 | * As a first step towards supporting sort clauses that are expressions |
1723 | * using the output columns, generate a namespace entry that makes the |
1724 | * output columns visible. A Join RTE node is handy for this, since we |
1725 | * can easily control the Vars generated upon matches. |
1726 | * |
1727 | * Note: we don't yet do anything useful with such cases, but at least |
1728 | * "ORDER BY upper(foo)" will draw the right error message rather than |
1729 | * "foo not found". |
1730 | */ |
1731 | sv_rtable_length = list_length(pstate->p_rtable); |
1732 | |
1733 | jrte = addRangeTableEntryForJoin(pstate, |
1734 | targetnames, |
1735 | JOIN_INNER, |
1736 | targetvars, |
1737 | NULL, |
1738 | false); |
1739 | |
1740 | sv_namespace = pstate->p_namespace; |
1741 | pstate->p_namespace = NIL; |
1742 | |
1743 | /* add jrte to column namespace only */ |
1744 | addRTEtoQuery(pstate, jrte, false, false, true); |
1745 | |
1746 | /* |
1747 | * For now, we don't support resjunk sort clauses on the output of a |
1748 | * setOperation tree --- you can only use the SQL92-spec options of |
1749 | * selecting an output column by name or number. Enforce by checking that |
1750 | * transformSortClause doesn't add any items to tlist. |
1751 | */ |
1752 | tllen = list_length(qry->targetList); |
1753 | |
1754 | qry->sortClause = transformSortClause(pstate, |
1755 | sortClause, |
1756 | &qry->targetList, |
1757 | EXPR_KIND_ORDER_BY, |
1758 | false /* allow SQL92 rules */ ); |
1759 | |
1760 | /* restore namespace, remove jrte from rtable */ |
1761 | pstate->p_namespace = sv_namespace; |
1762 | pstate->p_rtable = list_truncate(pstate->p_rtable, sv_rtable_length); |
1763 | |
1764 | if (tllen != list_length(qry->targetList)) |
1765 | ereport(ERROR, |
1766 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
1767 | errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause" ), |
1768 | errdetail("Only result column names can be used, not expressions or functions." ), |
1769 | errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause." ), |
1770 | parser_errposition(pstate, |
1771 | exprLocation(list_nth(qry->targetList, tllen))))); |
1772 | |
1773 | qry->limitOffset = transformLimitClause(pstate, limitOffset, |
1774 | EXPR_KIND_OFFSET, "OFFSET" ); |
1775 | qry->limitCount = transformLimitClause(pstate, limitCount, |
1776 | EXPR_KIND_LIMIT, "LIMIT" ); |
1777 | |
1778 | qry->rtable = pstate->p_rtable; |
1779 | qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); |
1780 | |
1781 | qry->hasSubLinks = pstate->p_hasSubLinks; |
1782 | qry->hasWindowFuncs = pstate->p_hasWindowFuncs; |
1783 | qry->hasTargetSRFs = pstate->p_hasTargetSRFs; |
1784 | qry->hasAggs = pstate->p_hasAggs; |
1785 | |
1786 | foreach(l, lockingClause) |
1787 | { |
1788 | transformLockingClause(pstate, qry, |
1789 | (LockingClause *) lfirst(l), false); |
1790 | } |
1791 | |
1792 | assign_query_collations(pstate, qry); |
1793 | |
1794 | /* this must be done after collations, for reliable comparison of exprs */ |
1795 | if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) |
1796 | parseCheckAggregates(pstate, qry); |
1797 | |
1798 | return qry; |
1799 | } |
1800 | |
1801 | /* |
1802 | * transformSetOperationTree |
1803 | * Recursively transform leaves and internal nodes of a set-op tree |
1804 | * |
1805 | * In addition to returning the transformed node, if targetlist isn't NULL |
1806 | * then we return a list of its non-resjunk TargetEntry nodes. For a leaf |
1807 | * set-op node these are the actual targetlist entries; otherwise they are |
1808 | * dummy entries created to carry the type, typmod, collation, and location |
1809 | * (for error messages) of each output column of the set-op node. This info |
1810 | * is needed only during the internal recursion of this function, so outside |
1811 | * callers pass NULL for targetlist. Note: the reason for passing the |
1812 | * actual targetlist entries of a leaf node is so that upper levels can |
1813 | * replace UNKNOWN Consts with properly-coerced constants. |
1814 | */ |
1815 | static Node * |
1816 | transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, |
1817 | bool isTopLevel, List **targetlist) |
1818 | { |
1819 | bool isLeaf; |
1820 | |
1821 | Assert(stmt && IsA(stmt, SelectStmt)); |
1822 | |
1823 | /* Guard against stack overflow due to overly complex set-expressions */ |
1824 | check_stack_depth(); |
1825 | |
1826 | /* |
1827 | * Validity-check both leaf and internal SELECTs for disallowed ops. |
1828 | */ |
1829 | if (stmt->intoClause) |
1830 | ereport(ERROR, |
1831 | (errcode(ERRCODE_SYNTAX_ERROR), |
1832 | errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" ), |
1833 | parser_errposition(pstate, |
1834 | exprLocation((Node *) stmt->intoClause)))); |
1835 | |
1836 | /* We don't support FOR UPDATE/SHARE with set ops at the moment. */ |
1837 | if (stmt->lockingClause) |
1838 | ereport(ERROR, |
1839 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
1840 | /*------ |
1841 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
1842 | errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT" , |
1843 | LCS_asString(((LockingClause *) |
1844 | linitial(stmt->lockingClause))->strength)))); |
1845 | |
1846 | /* |
1847 | * If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE, |
1848 | * or WITH clauses attached, we need to treat it like a leaf node to |
1849 | * generate an independent sub-Query tree. Otherwise, it can be |
1850 | * represented by a SetOperationStmt node underneath the parent Query. |
1851 | */ |
1852 | if (stmt->op == SETOP_NONE) |
1853 | { |
1854 | Assert(stmt->larg == NULL && stmt->rarg == NULL); |
1855 | isLeaf = true; |
1856 | } |
1857 | else |
1858 | { |
1859 | Assert(stmt->larg != NULL && stmt->rarg != NULL); |
1860 | if (stmt->sortClause || stmt->limitOffset || stmt->limitCount || |
1861 | stmt->lockingClause || stmt->withClause) |
1862 | isLeaf = true; |
1863 | else |
1864 | isLeaf = false; |
1865 | } |
1866 | |
1867 | if (isLeaf) |
1868 | { |
1869 | /* Process leaf SELECT */ |
1870 | Query *selectQuery; |
1871 | char selectName[32]; |
1872 | RangeTblEntry *rte PG_USED_FOR_ASSERTS_ONLY; |
1873 | RangeTblRef *rtr; |
1874 | ListCell *tl; |
1875 | |
1876 | /* |
1877 | * Transform SelectStmt into a Query. |
1878 | * |
1879 | * This works the same as SELECT transformation normally would, except |
1880 | * that we prevent resolving unknown-type outputs as TEXT. This does |
1881 | * not change the subquery's semantics since if the column type |
1882 | * matters semantically, it would have been resolved to something else |
1883 | * anyway. Doing this lets us resolve such outputs using |
1884 | * select_common_type(), below. |
1885 | * |
1886 | * Note: previously transformed sub-queries don't affect the parsing |
1887 | * of this sub-query, because they are not in the toplevel pstate's |
1888 | * namespace list. |
1889 | */ |
1890 | selectQuery = parse_sub_analyze((Node *) stmt, pstate, |
1891 | NULL, false, false); |
1892 | |
1893 | /* |
1894 | * Check for bogus references to Vars on the current query level (but |
1895 | * upper-level references are okay). Normally this can't happen |
1896 | * because the namespace will be empty, but it could happen if we are |
1897 | * inside a rule. |
1898 | */ |
1899 | if (pstate->p_namespace) |
1900 | { |
1901 | if (contain_vars_of_level((Node *) selectQuery, 1)) |
1902 | ereport(ERROR, |
1903 | (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), |
1904 | errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" ), |
1905 | parser_errposition(pstate, |
1906 | locate_var_of_level((Node *) selectQuery, 1)))); |
1907 | } |
1908 | |
1909 | /* |
1910 | * Extract a list of the non-junk TLEs for upper-level processing. |
1911 | */ |
1912 | if (targetlist) |
1913 | { |
1914 | *targetlist = NIL; |
1915 | foreach(tl, selectQuery->targetList) |
1916 | { |
1917 | TargetEntry *tle = (TargetEntry *) lfirst(tl); |
1918 | |
1919 | if (!tle->resjunk) |
1920 | *targetlist = lappend(*targetlist, tle); |
1921 | } |
1922 | } |
1923 | |
1924 | /* |
1925 | * Make the leaf query be a subquery in the top-level rangetable. |
1926 | */ |
1927 | snprintf(selectName, sizeof(selectName), "*SELECT* %d" , |
1928 | list_length(pstate->p_rtable) + 1); |
1929 | rte = addRangeTableEntryForSubquery(pstate, |
1930 | selectQuery, |
1931 | makeAlias(selectName, NIL), |
1932 | false, |
1933 | false); |
1934 | |
1935 | /* |
1936 | * Return a RangeTblRef to replace the SelectStmt in the set-op tree. |
1937 | */ |
1938 | rtr = makeNode(RangeTblRef); |
1939 | /* assume new rte is at end */ |
1940 | rtr->rtindex = list_length(pstate->p_rtable); |
1941 | Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable)); |
1942 | return (Node *) rtr; |
1943 | } |
1944 | else |
1945 | { |
1946 | /* Process an internal node (set operation node) */ |
1947 | SetOperationStmt *op = makeNode(SetOperationStmt); |
1948 | List *ltargetlist; |
1949 | List *rtargetlist; |
1950 | ListCell *ltl; |
1951 | ListCell *rtl; |
1952 | const char *context; |
1953 | |
1954 | context = (stmt->op == SETOP_UNION ? "UNION" : |
1955 | (stmt->op == SETOP_INTERSECT ? "INTERSECT" : |
1956 | "EXCEPT" )); |
1957 | |
1958 | op->op = stmt->op; |
1959 | op->all = stmt->all; |
1960 | |
1961 | /* |
1962 | * Recursively transform the left child node. |
1963 | */ |
1964 | op->larg = transformSetOperationTree(pstate, stmt->larg, |
1965 | false, |
1966 | <argetlist); |
1967 | |
1968 | /* |
1969 | * If we are processing a recursive union query, now is the time to |
1970 | * examine the non-recursive term's output columns and mark the |
1971 | * containing CTE as having those result columns. We should do this |
1972 | * only at the topmost setop of the CTE, of course. |
1973 | */ |
1974 | if (isTopLevel && |
1975 | pstate->p_parent_cte && |
1976 | pstate->p_parent_cte->cterecursive) |
1977 | determineRecursiveColTypes(pstate, op->larg, ltargetlist); |
1978 | |
1979 | /* |
1980 | * Recursively transform the right child node. |
1981 | */ |
1982 | op->rarg = transformSetOperationTree(pstate, stmt->rarg, |
1983 | false, |
1984 | &rtargetlist); |
1985 | |
1986 | /* |
1987 | * Verify that the two children have the same number of non-junk |
1988 | * columns, and determine the types of the merged output columns. |
1989 | */ |
1990 | if (list_length(ltargetlist) != list_length(rtargetlist)) |
1991 | ereport(ERROR, |
1992 | (errcode(ERRCODE_SYNTAX_ERROR), |
1993 | errmsg("each %s query must have the same number of columns" , |
1994 | context), |
1995 | parser_errposition(pstate, |
1996 | exprLocation((Node *) rtargetlist)))); |
1997 | |
1998 | if (targetlist) |
1999 | *targetlist = NIL; |
2000 | op->colTypes = NIL; |
2001 | op->colTypmods = NIL; |
2002 | op->colCollations = NIL; |
2003 | op->groupClauses = NIL; |
2004 | forboth(ltl, ltargetlist, rtl, rtargetlist) |
2005 | { |
2006 | TargetEntry *ltle = (TargetEntry *) lfirst(ltl); |
2007 | TargetEntry *rtle = (TargetEntry *) lfirst(rtl); |
2008 | Node *lcolnode = (Node *) ltle->expr; |
2009 | Node *rcolnode = (Node *) rtle->expr; |
2010 | Oid lcoltype = exprType(lcolnode); |
2011 | Oid rcoltype = exprType(rcolnode); |
2012 | int32 lcoltypmod = exprTypmod(lcolnode); |
2013 | int32 rcoltypmod = exprTypmod(rcolnode); |
2014 | Node *bestexpr; |
2015 | int bestlocation; |
2016 | Oid rescoltype; |
2017 | int32 rescoltypmod; |
2018 | Oid rescolcoll; |
2019 | |
2020 | /* select common type, same as CASE et al */ |
2021 | rescoltype = select_common_type(pstate, |
2022 | list_make2(lcolnode, rcolnode), |
2023 | context, |
2024 | &bestexpr); |
2025 | bestlocation = exprLocation(bestexpr); |
2026 | /* if same type and same typmod, use typmod; else default */ |
2027 | if (lcoltype == rcoltype && lcoltypmod == rcoltypmod) |
2028 | rescoltypmod = lcoltypmod; |
2029 | else |
2030 | rescoltypmod = -1; |
2031 | |
2032 | /* |
2033 | * Verify the coercions are actually possible. If not, we'd fail |
2034 | * later anyway, but we want to fail now while we have sufficient |
2035 | * context to produce an error cursor position. |
2036 | * |
2037 | * For all non-UNKNOWN-type cases, we verify coercibility but we |
2038 | * don't modify the child's expression, for fear of changing the |
2039 | * child query's semantics. |
2040 | * |
2041 | * If a child expression is an UNKNOWN-type Const or Param, we |
2042 | * want to replace it with the coerced expression. This can only |
2043 | * happen when the child is a leaf set-op node. It's safe to |
2044 | * replace the expression because if the child query's semantics |
2045 | * depended on the type of this output column, it'd have already |
2046 | * coerced the UNKNOWN to something else. We want to do this |
2047 | * because (a) we want to verify that a Const is valid for the |
2048 | * target type, or resolve the actual type of an UNKNOWN Param, |
2049 | * and (b) we want to avoid unnecessary discrepancies between the |
2050 | * output type of the child query and the resolved target type. |
2051 | * Such a discrepancy would disable optimization in the planner. |
2052 | * |
2053 | * If it's some other UNKNOWN-type node, eg a Var, we do nothing |
2054 | * (knowing that coerce_to_common_type would fail). The planner |
2055 | * is sometimes able to fold an UNKNOWN Var to a constant before |
2056 | * it has to coerce the type, so failing now would just break |
2057 | * cases that might work. |
2058 | */ |
2059 | if (lcoltype != UNKNOWNOID) |
2060 | lcolnode = coerce_to_common_type(pstate, lcolnode, |
2061 | rescoltype, context); |
2062 | else if (IsA(lcolnode, Const) || |
2063 | IsA(lcolnode, Param)) |
2064 | { |
2065 | lcolnode = coerce_to_common_type(pstate, lcolnode, |
2066 | rescoltype, context); |
2067 | ltle->expr = (Expr *) lcolnode; |
2068 | } |
2069 | |
2070 | if (rcoltype != UNKNOWNOID) |
2071 | rcolnode = coerce_to_common_type(pstate, rcolnode, |
2072 | rescoltype, context); |
2073 | else if (IsA(rcolnode, Const) || |
2074 | IsA(rcolnode, Param)) |
2075 | { |
2076 | rcolnode = coerce_to_common_type(pstate, rcolnode, |
2077 | rescoltype, context); |
2078 | rtle->expr = (Expr *) rcolnode; |
2079 | } |
2080 | |
2081 | /* |
2082 | * Select common collation. A common collation is required for |
2083 | * all set operators except UNION ALL; see SQL:2008 7.13 <query |
2084 | * expression> Syntax Rule 15c. (If we fail to identify a common |
2085 | * collation for a UNION ALL column, the colCollations element |
2086 | * will be set to InvalidOid, which may result in a runtime error |
2087 | * if something at a higher query level wants to use the column's |
2088 | * collation.) |
2089 | */ |
2090 | rescolcoll = select_common_collation(pstate, |
2091 | list_make2(lcolnode, rcolnode), |
2092 | (op->op == SETOP_UNION && op->all)); |
2093 | |
2094 | /* emit results */ |
2095 | op->colTypes = lappend_oid(op->colTypes, rescoltype); |
2096 | op->colTypmods = lappend_int(op->colTypmods, rescoltypmod); |
2097 | op->colCollations = lappend_oid(op->colCollations, rescolcoll); |
2098 | |
2099 | /* |
2100 | * For all cases except UNION ALL, identify the grouping operators |
2101 | * (and, if available, sorting operators) that will be used to |
2102 | * eliminate duplicates. |
2103 | */ |
2104 | if (op->op != SETOP_UNION || !op->all) |
2105 | { |
2106 | SortGroupClause *grpcl = makeNode(SortGroupClause); |
2107 | Oid sortop; |
2108 | Oid eqop; |
2109 | bool hashable; |
2110 | ParseCallbackState pcbstate; |
2111 | |
2112 | setup_parser_errposition_callback(&pcbstate, pstate, |
2113 | bestlocation); |
2114 | |
2115 | /* determine the eqop and optional sortop */ |
2116 | get_sort_group_operators(rescoltype, |
2117 | false, true, false, |
2118 | &sortop, &eqop, NULL, |
2119 | &hashable); |
2120 | |
2121 | cancel_parser_errposition_callback(&pcbstate); |
2122 | |
2123 | /* we don't have a tlist yet, so can't assign sortgrouprefs */ |
2124 | grpcl->tleSortGroupRef = 0; |
2125 | grpcl->eqop = eqop; |
2126 | grpcl->sortop = sortop; |
2127 | grpcl->nulls_first = false; /* OK with or without sortop */ |
2128 | grpcl->hashable = hashable; |
2129 | |
2130 | op->groupClauses = lappend(op->groupClauses, grpcl); |
2131 | } |
2132 | |
2133 | /* |
2134 | * Construct a dummy tlist entry to return. We use a SetToDefault |
2135 | * node for the expression, since it carries exactly the fields |
2136 | * needed, but any other expression node type would do as well. |
2137 | */ |
2138 | if (targetlist) |
2139 | { |
2140 | SetToDefault *rescolnode = makeNode(SetToDefault); |
2141 | TargetEntry *restle; |
2142 | |
2143 | rescolnode->typeId = rescoltype; |
2144 | rescolnode->typeMod = rescoltypmod; |
2145 | rescolnode->collation = rescolcoll; |
2146 | rescolnode->location = bestlocation; |
2147 | restle = makeTargetEntry((Expr *) rescolnode, |
2148 | 0, /* no need to set resno */ |
2149 | NULL, |
2150 | false); |
2151 | *targetlist = lappend(*targetlist, restle); |
2152 | } |
2153 | } |
2154 | |
2155 | return (Node *) op; |
2156 | } |
2157 | } |
2158 | |
2159 | /* |
2160 | * Process the outputs of the non-recursive term of a recursive union |
2161 | * to set up the parent CTE's columns |
2162 | */ |
2163 | static void |
2164 | determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist) |
2165 | { |
2166 | Node *node; |
2167 | int leftmostRTI; |
2168 | Query *leftmostQuery; |
2169 | List *targetList; |
2170 | ListCell *left_tlist; |
2171 | ListCell *nrtl; |
2172 | int next_resno; |
2173 | |
2174 | /* |
2175 | * Find leftmost leaf SELECT |
2176 | */ |
2177 | node = larg; |
2178 | while (node && IsA(node, SetOperationStmt)) |
2179 | node = ((SetOperationStmt *) node)->larg; |
2180 | Assert(node && IsA(node, RangeTblRef)); |
2181 | leftmostRTI = ((RangeTblRef *) node)->rtindex; |
2182 | leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery; |
2183 | Assert(leftmostQuery != NULL); |
2184 | |
2185 | /* |
2186 | * Generate dummy targetlist using column names of leftmost select and |
2187 | * dummy result expressions of the non-recursive term. |
2188 | */ |
2189 | targetList = NIL; |
2190 | next_resno = 1; |
2191 | |
2192 | forboth(nrtl, nrtargetlist, left_tlist, leftmostQuery->targetList) |
2193 | { |
2194 | TargetEntry *nrtle = (TargetEntry *) lfirst(nrtl); |
2195 | TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist); |
2196 | char *colName; |
2197 | TargetEntry *tle; |
2198 | |
2199 | Assert(!lefttle->resjunk); |
2200 | colName = pstrdup(lefttle->resname); |
2201 | tle = makeTargetEntry(nrtle->expr, |
2202 | next_resno++, |
2203 | colName, |
2204 | false); |
2205 | targetList = lappend(targetList, tle); |
2206 | } |
2207 | |
2208 | /* Now build CTE's output column info using dummy targetlist */ |
2209 | analyzeCTETargetList(pstate, pstate->p_parent_cte, targetList); |
2210 | } |
2211 | |
2212 | |
2213 | /* |
2214 | * transformUpdateStmt - |
2215 | * transforms an update statement |
2216 | */ |
2217 | static Query * |
2218 | transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) |
2219 | { |
2220 | Query *qry = makeNode(Query); |
2221 | ParseNamespaceItem *nsitem; |
2222 | Node *qual; |
2223 | |
2224 | qry->commandType = CMD_UPDATE; |
2225 | pstate->p_is_insert = false; |
2226 | |
2227 | /* process the WITH clause independently of all else */ |
2228 | if (stmt->withClause) |
2229 | { |
2230 | qry->hasRecursive = stmt->withClause->recursive; |
2231 | qry->cteList = transformWithClause(pstate, stmt->withClause); |
2232 | qry->hasModifyingCTE = pstate->p_hasModifyingCTE; |
2233 | } |
2234 | |
2235 | qry->resultRelation = setTargetTable(pstate, stmt->relation, |
2236 | stmt->relation->inh, |
2237 | true, |
2238 | ACL_UPDATE); |
2239 | |
2240 | /* grab the namespace item made by setTargetTable */ |
2241 | nsitem = (ParseNamespaceItem *) llast(pstate->p_namespace); |
2242 | |
2243 | /* subqueries in FROM cannot access the result relation */ |
2244 | nsitem->p_lateral_only = true; |
2245 | nsitem->p_lateral_ok = false; |
2246 | |
2247 | /* |
2248 | * the FROM clause is non-standard SQL syntax. We used to be able to do |
2249 | * this with REPLACE in POSTQUEL so we keep the feature. |
2250 | */ |
2251 | transformFromClause(pstate, stmt->fromClause); |
2252 | |
2253 | /* remaining clauses can reference the result relation normally */ |
2254 | nsitem->p_lateral_only = false; |
2255 | nsitem->p_lateral_ok = true; |
2256 | |
2257 | qual = transformWhereClause(pstate, stmt->whereClause, |
2258 | EXPR_KIND_WHERE, "WHERE" ); |
2259 | |
2260 | qry->returningList = transformReturningList(pstate, stmt->returningList); |
2261 | |
2262 | /* |
2263 | * Now we are done with SELECT-like processing, and can get on with |
2264 | * transforming the target list to match the UPDATE target columns. |
2265 | */ |
2266 | qry->targetList = transformUpdateTargetList(pstate, stmt->targetList); |
2267 | |
2268 | qry->rtable = pstate->p_rtable; |
2269 | qry->jointree = makeFromExpr(pstate->p_joinlist, qual); |
2270 | |
2271 | qry->hasTargetSRFs = pstate->p_hasTargetSRFs; |
2272 | qry->hasSubLinks = pstate->p_hasSubLinks; |
2273 | |
2274 | assign_query_collations(pstate, qry); |
2275 | |
2276 | return qry; |
2277 | } |
2278 | |
2279 | /* |
2280 | * transformUpdateTargetList - |
2281 | * handle SET clause in UPDATE/INSERT ... ON CONFLICT UPDATE |
2282 | */ |
2283 | static List * |
2284 | transformUpdateTargetList(ParseState *pstate, List *origTlist) |
2285 | { |
2286 | List *tlist = NIL; |
2287 | RangeTblEntry *target_rte; |
2288 | ListCell *orig_tl; |
2289 | ListCell *tl; |
2290 | TupleDesc tupdesc = pstate->p_target_relation->rd_att; |
2291 | |
2292 | tlist = transformTargetList(pstate, origTlist, |
2293 | EXPR_KIND_UPDATE_SOURCE); |
2294 | |
2295 | /* Prepare to assign non-conflicting resnos to resjunk attributes */ |
2296 | if (pstate->p_next_resno <= RelationGetNumberOfAttributes(pstate->p_target_relation)) |
2297 | pstate->p_next_resno = RelationGetNumberOfAttributes(pstate->p_target_relation) + 1; |
2298 | |
2299 | /* Prepare non-junk columns for assignment to target table */ |
2300 | target_rte = pstate->p_target_rangetblentry; |
2301 | orig_tl = list_head(origTlist); |
2302 | |
2303 | foreach(tl, tlist) |
2304 | { |
2305 | TargetEntry *tle = (TargetEntry *) lfirst(tl); |
2306 | ResTarget *origTarget; |
2307 | int attrno; |
2308 | |
2309 | if (tle->resjunk) |
2310 | { |
2311 | /* |
2312 | * Resjunk nodes need no additional processing, but be sure they |
2313 | * have resnos that do not match any target columns; else rewriter |
2314 | * or planner might get confused. They don't need a resname |
2315 | * either. |
2316 | */ |
2317 | tle->resno = (AttrNumber) pstate->p_next_resno++; |
2318 | tle->resname = NULL; |
2319 | continue; |
2320 | } |
2321 | if (orig_tl == NULL) |
2322 | elog(ERROR, "UPDATE target count mismatch --- internal error" ); |
2323 | origTarget = lfirst_node(ResTarget, orig_tl); |
2324 | |
2325 | attrno = attnameAttNum(pstate->p_target_relation, |
2326 | origTarget->name, true); |
2327 | if (attrno == InvalidAttrNumber) |
2328 | ereport(ERROR, |
2329 | (errcode(ERRCODE_UNDEFINED_COLUMN), |
2330 | errmsg("column \"%s\" of relation \"%s\" does not exist" , |
2331 | origTarget->name, |
2332 | RelationGetRelationName(pstate->p_target_relation)), |
2333 | parser_errposition(pstate, origTarget->location))); |
2334 | |
2335 | updateTargetListEntry(pstate, tle, origTarget->name, |
2336 | attrno, |
2337 | origTarget->indirection, |
2338 | origTarget->location); |
2339 | |
2340 | /* Mark the target column as requiring update permissions */ |
2341 | target_rte->updatedCols = bms_add_member(target_rte->updatedCols, |
2342 | attrno - FirstLowInvalidHeapAttributeNumber); |
2343 | |
2344 | orig_tl = lnext(orig_tl); |
2345 | } |
2346 | if (orig_tl != NULL) |
2347 | elog(ERROR, "UPDATE target count mismatch --- internal error" ); |
2348 | |
2349 | /* |
2350 | * Record in extraUpdatedCols generated columns referencing updated base |
2351 | * columns. |
2352 | */ |
2353 | if (tupdesc->constr && |
2354 | tupdesc->constr->has_generated_stored) |
2355 | { |
2356 | for (int i = 0; i < tupdesc->constr->num_defval; i++) |
2357 | { |
2358 | AttrDefault defval = tupdesc->constr->defval[i]; |
2359 | Node *expr; |
2360 | Bitmapset *attrs_used = NULL; |
2361 | |
2362 | /* skip if not generated column */ |
2363 | if (!TupleDescAttr(tupdesc, defval.adnum - 1)->attgenerated) |
2364 | continue; |
2365 | |
2366 | expr = stringToNode(defval.adbin); |
2367 | pull_varattnos(expr, 1, &attrs_used); |
2368 | |
2369 | if (bms_overlap(target_rte->updatedCols, attrs_used)) |
2370 | target_rte->extraUpdatedCols = bms_add_member(target_rte->extraUpdatedCols, |
2371 | defval.adnum - FirstLowInvalidHeapAttributeNumber); |
2372 | } |
2373 | } |
2374 | |
2375 | return tlist; |
2376 | } |
2377 | |
2378 | /* |
2379 | * transformReturningList - |
2380 | * handle a RETURNING clause in INSERT/UPDATE/DELETE |
2381 | */ |
2382 | static List * |
2383 | transformReturningList(ParseState *pstate, List *returningList) |
2384 | { |
2385 | List *rlist; |
2386 | int save_next_resno; |
2387 | |
2388 | if (returningList == NIL) |
2389 | return NIL; /* nothing to do */ |
2390 | |
2391 | /* |
2392 | * We need to assign resnos starting at one in the RETURNING list. Save |
2393 | * and restore the main tlist's value of p_next_resno, just in case |
2394 | * someone looks at it later (probably won't happen). |
2395 | */ |
2396 | save_next_resno = pstate->p_next_resno; |
2397 | pstate->p_next_resno = 1; |
2398 | |
2399 | /* transform RETURNING identically to a SELECT targetlist */ |
2400 | rlist = transformTargetList(pstate, returningList, EXPR_KIND_RETURNING); |
2401 | |
2402 | /* |
2403 | * Complain if the nonempty tlist expanded to nothing (which is possible |
2404 | * if it contains only a star-expansion of a zero-column table). If we |
2405 | * allow this, the parsed Query will look like it didn't have RETURNING, |
2406 | * with results that would probably surprise the user. |
2407 | */ |
2408 | if (rlist == NIL) |
2409 | ereport(ERROR, |
2410 | (errcode(ERRCODE_SYNTAX_ERROR), |
2411 | errmsg("RETURNING must have at least one column" ), |
2412 | parser_errposition(pstate, |
2413 | exprLocation(linitial(returningList))))); |
2414 | |
2415 | /* mark column origins */ |
2416 | markTargetListOrigins(pstate, rlist); |
2417 | |
2418 | /* resolve any still-unresolved output columns as being type text */ |
2419 | if (pstate->p_resolve_unknowns) |
2420 | resolveTargetListUnknowns(pstate, rlist); |
2421 | |
2422 | /* restore state */ |
2423 | pstate->p_next_resno = save_next_resno; |
2424 | |
2425 | return rlist; |
2426 | } |
2427 | |
2428 | |
2429 | /* |
2430 | * transformDeclareCursorStmt - |
2431 | * transform a DECLARE CURSOR Statement |
2432 | * |
2433 | * DECLARE CURSOR is like other utility statements in that we emit it as a |
2434 | * CMD_UTILITY Query node; however, we must first transform the contained |
2435 | * query. We used to postpone that until execution, but it's really necessary |
2436 | * to do it during the normal parse analysis phase to ensure that side effects |
2437 | * of parser hooks happen at the expected time. |
2438 | */ |
2439 | static Query * |
2440 | transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt) |
2441 | { |
2442 | Query *result; |
2443 | Query *query; |
2444 | |
2445 | /* |
2446 | * Don't allow both SCROLL and NO SCROLL to be specified |
2447 | */ |
2448 | if ((stmt->options & CURSOR_OPT_SCROLL) && |
2449 | (stmt->options & CURSOR_OPT_NO_SCROLL)) |
2450 | ereport(ERROR, |
2451 | (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), |
2452 | errmsg("cannot specify both SCROLL and NO SCROLL" ))); |
2453 | |
2454 | /* Transform contained query, not allowing SELECT INTO */ |
2455 | query = transformStmt(pstate, stmt->query); |
2456 | stmt->query = (Node *) query; |
2457 | |
2458 | /* Grammar should not have allowed anything but SELECT */ |
2459 | if (!IsA(query, Query) || |
2460 | query->commandType != CMD_SELECT) |
2461 | elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR" ); |
2462 | |
2463 | /* |
2464 | * We also disallow data-modifying WITH in a cursor. (This could be |
2465 | * allowed, but the semantics of when the updates occur might be |
2466 | * surprising.) |
2467 | */ |
2468 | if (query->hasModifyingCTE) |
2469 | ereport(ERROR, |
2470 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2471 | errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH" ))); |
2472 | |
2473 | /* FOR UPDATE and WITH HOLD are not compatible */ |
2474 | if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD)) |
2475 | ereport(ERROR, |
2476 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2477 | /*------ |
2478 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2479 | errmsg("DECLARE CURSOR WITH HOLD ... %s is not supported" , |
2480 | LCS_asString(((RowMarkClause *) |
2481 | linitial(query->rowMarks))->strength)), |
2482 | errdetail("Holdable cursors must be READ ONLY." ))); |
2483 | |
2484 | /* FOR UPDATE and SCROLL are not compatible */ |
2485 | if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_SCROLL)) |
2486 | ereport(ERROR, |
2487 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2488 | /*------ |
2489 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2490 | errmsg("DECLARE SCROLL CURSOR ... %s is not supported" , |
2491 | LCS_asString(((RowMarkClause *) |
2492 | linitial(query->rowMarks))->strength)), |
2493 | errdetail("Scrollable cursors must be READ ONLY." ))); |
2494 | |
2495 | /* FOR UPDATE and INSENSITIVE are not compatible */ |
2496 | if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_INSENSITIVE)) |
2497 | ereport(ERROR, |
2498 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2499 | /*------ |
2500 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2501 | errmsg("DECLARE INSENSITIVE CURSOR ... %s is not supported" , |
2502 | LCS_asString(((RowMarkClause *) |
2503 | linitial(query->rowMarks))->strength)), |
2504 | errdetail("Insensitive cursors must be READ ONLY." ))); |
2505 | |
2506 | /* represent the command as a utility Query */ |
2507 | result = makeNode(Query); |
2508 | result->commandType = CMD_UTILITY; |
2509 | result->utilityStmt = (Node *) stmt; |
2510 | |
2511 | return result; |
2512 | } |
2513 | |
2514 | |
2515 | /* |
2516 | * transformExplainStmt - |
2517 | * transform an EXPLAIN Statement |
2518 | * |
2519 | * EXPLAIN is like other utility statements in that we emit it as a |
2520 | * CMD_UTILITY Query node; however, we must first transform the contained |
2521 | * query. We used to postpone that until execution, but it's really necessary |
2522 | * to do it during the normal parse analysis phase to ensure that side effects |
2523 | * of parser hooks happen at the expected time. |
2524 | */ |
2525 | static Query * |
2526 | transformExplainStmt(ParseState *pstate, ExplainStmt *stmt) |
2527 | { |
2528 | Query *result; |
2529 | |
2530 | /* transform contained query, allowing SELECT INTO */ |
2531 | stmt->query = (Node *) transformOptionalSelectInto(pstate, stmt->query); |
2532 | |
2533 | /* represent the command as a utility Query */ |
2534 | result = makeNode(Query); |
2535 | result->commandType = CMD_UTILITY; |
2536 | result->utilityStmt = (Node *) stmt; |
2537 | |
2538 | return result; |
2539 | } |
2540 | |
2541 | |
2542 | /* |
2543 | * transformCreateTableAsStmt - |
2544 | * transform a CREATE TABLE AS, SELECT ... INTO, or CREATE MATERIALIZED VIEW |
2545 | * Statement |
2546 | * |
2547 | * As with DECLARE CURSOR and EXPLAIN, transform the contained statement now. |
2548 | */ |
2549 | static Query * |
2550 | transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt) |
2551 | { |
2552 | Query *result; |
2553 | Query *query; |
2554 | |
2555 | /* transform contained query, not allowing SELECT INTO */ |
2556 | query = transformStmt(pstate, stmt->query); |
2557 | stmt->query = (Node *) query; |
2558 | |
2559 | /* additional work needed for CREATE MATERIALIZED VIEW */ |
2560 | if (stmt->relkind == OBJECT_MATVIEW) |
2561 | { |
2562 | /* |
2563 | * Prohibit a data-modifying CTE in the query used to create a |
2564 | * materialized view. It's not sufficiently clear what the user would |
2565 | * want to happen if the MV is refreshed or incrementally maintained. |
2566 | */ |
2567 | if (query->hasModifyingCTE) |
2568 | ereport(ERROR, |
2569 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2570 | errmsg("materialized views must not use data-modifying statements in WITH" ))); |
2571 | |
2572 | /* |
2573 | * Check whether any temporary database objects are used in the |
2574 | * creation query. It would be hard to refresh data or incrementally |
2575 | * maintain it if a source disappeared. |
2576 | */ |
2577 | if (isQueryUsingTempRelation(query)) |
2578 | ereport(ERROR, |
2579 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2580 | errmsg("materialized views must not use temporary tables or views" ))); |
2581 | |
2582 | /* |
2583 | * A materialized view would either need to save parameters for use in |
2584 | * maintaining/loading the data or prohibit them entirely. The latter |
2585 | * seems safer and more sane. |
2586 | */ |
2587 | if (query_contains_extern_params(query)) |
2588 | ereport(ERROR, |
2589 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2590 | errmsg("materialized views may not be defined using bound parameters" ))); |
2591 | |
2592 | /* |
2593 | * For now, we disallow unlogged materialized views, because it seems |
2594 | * like a bad idea for them to just go to empty after a crash. (If we |
2595 | * could mark them as unpopulated, that would be better, but that |
2596 | * requires catalog changes which crash recovery can't presently |
2597 | * handle.) |
2598 | */ |
2599 | if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED) |
2600 | ereport(ERROR, |
2601 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2602 | errmsg("materialized views cannot be unlogged" ))); |
2603 | |
2604 | /* |
2605 | * At runtime, we'll need a copy of the parsed-but-not-rewritten Query |
2606 | * for purposes of creating the view's ON SELECT rule. We stash that |
2607 | * in the IntoClause because that's where intorel_startup() can |
2608 | * conveniently get it from. |
2609 | */ |
2610 | stmt->into->viewQuery = (Node *) copyObject(query); |
2611 | } |
2612 | |
2613 | /* represent the command as a utility Query */ |
2614 | result = makeNode(Query); |
2615 | result->commandType = CMD_UTILITY; |
2616 | result->utilityStmt = (Node *) stmt; |
2617 | |
2618 | return result; |
2619 | } |
2620 | |
2621 | /* |
2622 | * transform a CallStmt |
2623 | * |
2624 | * We need to do parse analysis on the procedure call and its arguments. |
2625 | */ |
2626 | static Query * |
2627 | transformCallStmt(ParseState *pstate, CallStmt *stmt) |
2628 | { |
2629 | List *targs; |
2630 | ListCell *lc; |
2631 | Node *node; |
2632 | Query *result; |
2633 | |
2634 | targs = NIL; |
2635 | foreach(lc, stmt->funccall->args) |
2636 | { |
2637 | targs = lappend(targs, transformExpr(pstate, |
2638 | (Node *) lfirst(lc), |
2639 | EXPR_KIND_CALL_ARGUMENT)); |
2640 | } |
2641 | |
2642 | node = ParseFuncOrColumn(pstate, |
2643 | stmt->funccall->funcname, |
2644 | targs, |
2645 | pstate->p_last_srf, |
2646 | stmt->funccall, |
2647 | true, |
2648 | stmt->funccall->location); |
2649 | |
2650 | assign_expr_collations(pstate, node); |
2651 | |
2652 | stmt->funcexpr = castNode(FuncExpr, node); |
2653 | |
2654 | result = makeNode(Query); |
2655 | result->commandType = CMD_UTILITY; |
2656 | result->utilityStmt = (Node *) stmt; |
2657 | |
2658 | return result; |
2659 | } |
2660 | |
2661 | /* |
2662 | * Produce a string representation of a LockClauseStrength value. |
2663 | * This should only be applied to valid values (not LCS_NONE). |
2664 | */ |
2665 | const char * |
2666 | LCS_asString(LockClauseStrength strength) |
2667 | { |
2668 | switch (strength) |
2669 | { |
2670 | case LCS_NONE: |
2671 | Assert(false); |
2672 | break; |
2673 | case LCS_FORKEYSHARE: |
2674 | return "FOR KEY SHARE" ; |
2675 | case LCS_FORSHARE: |
2676 | return "FOR SHARE" ; |
2677 | case LCS_FORNOKEYUPDATE: |
2678 | return "FOR NO KEY UPDATE" ; |
2679 | case LCS_FORUPDATE: |
2680 | return "FOR UPDATE" ; |
2681 | } |
2682 | return "FOR some" ; /* shouldn't happen */ |
2683 | } |
2684 | |
2685 | /* |
2686 | * Check for features that are not supported with FOR [KEY] UPDATE/SHARE. |
2687 | * |
2688 | * exported so planner can check again after rewriting, query pullup, etc |
2689 | */ |
2690 | void |
2691 | CheckSelectLocking(Query *qry, LockClauseStrength strength) |
2692 | { |
2693 | Assert(strength != LCS_NONE); /* else caller error */ |
2694 | |
2695 | if (qry->setOperations) |
2696 | ereport(ERROR, |
2697 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2698 | /*------ |
2699 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2700 | errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT" , |
2701 | LCS_asString(strength)))); |
2702 | if (qry->distinctClause != NIL) |
2703 | ereport(ERROR, |
2704 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2705 | /*------ |
2706 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2707 | errmsg("%s is not allowed with DISTINCT clause" , |
2708 | LCS_asString(strength)))); |
2709 | if (qry->groupClause != NIL) |
2710 | ereport(ERROR, |
2711 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2712 | /*------ |
2713 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2714 | errmsg("%s is not allowed with GROUP BY clause" , |
2715 | LCS_asString(strength)))); |
2716 | if (qry->havingQual != NULL) |
2717 | ereport(ERROR, |
2718 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2719 | /*------ |
2720 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2721 | errmsg("%s is not allowed with HAVING clause" , |
2722 | LCS_asString(strength)))); |
2723 | if (qry->hasAggs) |
2724 | ereport(ERROR, |
2725 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2726 | /*------ |
2727 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2728 | errmsg("%s is not allowed with aggregate functions" , |
2729 | LCS_asString(strength)))); |
2730 | if (qry->hasWindowFuncs) |
2731 | ereport(ERROR, |
2732 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2733 | /*------ |
2734 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2735 | errmsg("%s is not allowed with window functions" , |
2736 | LCS_asString(strength)))); |
2737 | if (qry->hasTargetSRFs) |
2738 | ereport(ERROR, |
2739 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2740 | /*------ |
2741 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2742 | errmsg("%s is not allowed with set-returning functions in the target list" , |
2743 | LCS_asString(strength)))); |
2744 | } |
2745 | |
2746 | /* |
2747 | * Transform a FOR [KEY] UPDATE/SHARE clause |
2748 | * |
2749 | * This basically involves replacing names by integer relids. |
2750 | * |
2751 | * NB: if you need to change this, see also markQueryForLocking() |
2752 | * in rewriteHandler.c, and isLockedRefname() in parse_relation.c. |
2753 | */ |
2754 | static void |
2755 | transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, |
2756 | bool pushedDown) |
2757 | { |
2758 | List *lockedRels = lc->lockedRels; |
2759 | ListCell *l; |
2760 | ListCell *rt; |
2761 | Index i; |
2762 | LockingClause *allrels; |
2763 | |
2764 | CheckSelectLocking(qry, lc->strength); |
2765 | |
2766 | /* make a clause we can pass down to subqueries to select all rels */ |
2767 | allrels = makeNode(LockingClause); |
2768 | allrels->lockedRels = NIL; /* indicates all rels */ |
2769 | allrels->strength = lc->strength; |
2770 | allrels->waitPolicy = lc->waitPolicy; |
2771 | |
2772 | if (lockedRels == NIL) |
2773 | { |
2774 | /* all regular tables used in query */ |
2775 | i = 0; |
2776 | foreach(rt, qry->rtable) |
2777 | { |
2778 | RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt); |
2779 | |
2780 | ++i; |
2781 | switch (rte->rtekind) |
2782 | { |
2783 | case RTE_RELATION: |
2784 | applyLockingClause(qry, i, lc->strength, lc->waitPolicy, |
2785 | pushedDown); |
2786 | rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; |
2787 | break; |
2788 | case RTE_SUBQUERY: |
2789 | applyLockingClause(qry, i, lc->strength, lc->waitPolicy, |
2790 | pushedDown); |
2791 | |
2792 | /* |
2793 | * FOR UPDATE/SHARE of subquery is propagated to all of |
2794 | * subquery's rels, too. We could do this later (based on |
2795 | * the marking of the subquery RTE) but it is convenient |
2796 | * to have local knowledge in each query level about which |
2797 | * rels need to be opened with RowShareLock. |
2798 | */ |
2799 | transformLockingClause(pstate, rte->subquery, |
2800 | allrels, true); |
2801 | break; |
2802 | default: |
2803 | /* ignore JOIN, SPECIAL, FUNCTION, VALUES, CTE RTEs */ |
2804 | break; |
2805 | } |
2806 | } |
2807 | } |
2808 | else |
2809 | { |
2810 | /* just the named tables */ |
2811 | foreach(l, lockedRels) |
2812 | { |
2813 | RangeVar *thisrel = (RangeVar *) lfirst(l); |
2814 | |
2815 | /* For simplicity we insist on unqualified alias names here */ |
2816 | if (thisrel->catalogname || thisrel->schemaname) |
2817 | ereport(ERROR, |
2818 | (errcode(ERRCODE_SYNTAX_ERROR), |
2819 | /*------ |
2820 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2821 | errmsg("%s must specify unqualified relation names" , |
2822 | LCS_asString(lc->strength)), |
2823 | parser_errposition(pstate, thisrel->location))); |
2824 | |
2825 | i = 0; |
2826 | foreach(rt, qry->rtable) |
2827 | { |
2828 | RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt); |
2829 | |
2830 | ++i; |
2831 | if (strcmp(rte->eref->aliasname, thisrel->relname) == 0) |
2832 | { |
2833 | switch (rte->rtekind) |
2834 | { |
2835 | case RTE_RELATION: |
2836 | applyLockingClause(qry, i, lc->strength, |
2837 | lc->waitPolicy, pushedDown); |
2838 | rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; |
2839 | break; |
2840 | case RTE_SUBQUERY: |
2841 | applyLockingClause(qry, i, lc->strength, |
2842 | lc->waitPolicy, pushedDown); |
2843 | /* see comment above */ |
2844 | transformLockingClause(pstate, rte->subquery, |
2845 | allrels, true); |
2846 | break; |
2847 | case RTE_JOIN: |
2848 | ereport(ERROR, |
2849 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2850 | /*------ |
2851 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2852 | errmsg("%s cannot be applied to a join" , |
2853 | LCS_asString(lc->strength)), |
2854 | parser_errposition(pstate, thisrel->location))); |
2855 | break; |
2856 | case RTE_FUNCTION: |
2857 | ereport(ERROR, |
2858 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2859 | /*------ |
2860 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2861 | errmsg("%s cannot be applied to a function" , |
2862 | LCS_asString(lc->strength)), |
2863 | parser_errposition(pstate, thisrel->location))); |
2864 | break; |
2865 | case RTE_TABLEFUNC: |
2866 | ereport(ERROR, |
2867 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2868 | /*------ |
2869 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2870 | errmsg("%s cannot be applied to a table function" , |
2871 | LCS_asString(lc->strength)), |
2872 | parser_errposition(pstate, thisrel->location))); |
2873 | break; |
2874 | case RTE_VALUES: |
2875 | ereport(ERROR, |
2876 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2877 | /*------ |
2878 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2879 | errmsg("%s cannot be applied to VALUES" , |
2880 | LCS_asString(lc->strength)), |
2881 | parser_errposition(pstate, thisrel->location))); |
2882 | break; |
2883 | case RTE_CTE: |
2884 | ereport(ERROR, |
2885 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2886 | /*------ |
2887 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2888 | errmsg("%s cannot be applied to a WITH query" , |
2889 | LCS_asString(lc->strength)), |
2890 | parser_errposition(pstate, thisrel->location))); |
2891 | break; |
2892 | case RTE_NAMEDTUPLESTORE: |
2893 | ereport(ERROR, |
2894 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
2895 | /*------ |
2896 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2897 | errmsg("%s cannot be applied to a named tuplestore" , |
2898 | LCS_asString(lc->strength)), |
2899 | parser_errposition(pstate, thisrel->location))); |
2900 | break; |
2901 | |
2902 | /* Shouldn't be possible to see RTE_RESULT here */ |
2903 | |
2904 | default: |
2905 | elog(ERROR, "unrecognized RTE type: %d" , |
2906 | (int) rte->rtekind); |
2907 | break; |
2908 | } |
2909 | break; /* out of foreach loop */ |
2910 | } |
2911 | } |
2912 | if (rt == NULL) |
2913 | ereport(ERROR, |
2914 | (errcode(ERRCODE_UNDEFINED_TABLE), |
2915 | /*------ |
2916 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
2917 | errmsg("relation \"%s\" in %s clause not found in FROM clause" , |
2918 | thisrel->relname, |
2919 | LCS_asString(lc->strength)), |
2920 | parser_errposition(pstate, thisrel->location))); |
2921 | } |
2922 | } |
2923 | } |
2924 | |
2925 | /* |
2926 | * Record locking info for a single rangetable item |
2927 | */ |
2928 | void |
2929 | applyLockingClause(Query *qry, Index rtindex, |
2930 | LockClauseStrength strength, LockWaitPolicy waitPolicy, |
2931 | bool pushedDown) |
2932 | { |
2933 | RowMarkClause *rc; |
2934 | |
2935 | Assert(strength != LCS_NONE); /* else caller error */ |
2936 | |
2937 | /* If it's an explicit clause, make sure hasForUpdate gets set */ |
2938 | if (!pushedDown) |
2939 | qry->hasForUpdate = true; |
2940 | |
2941 | /* Check for pre-existing entry for same rtindex */ |
2942 | if ((rc = get_parse_rowmark(qry, rtindex)) != NULL) |
2943 | { |
2944 | /* |
2945 | * If the same RTE is specified with more than one locking strength, |
2946 | * use the strongest. (Reasonable, since you can't take both a shared |
2947 | * and exclusive lock at the same time; it'll end up being exclusive |
2948 | * anyway.) |
2949 | * |
2950 | * Similarly, if the same RTE is specified with more than one lock |
2951 | * wait policy, consider that NOWAIT wins over SKIP LOCKED, which in |
2952 | * turn wins over waiting for the lock (the default). This is a bit |
2953 | * more debatable but raising an error doesn't seem helpful. (Consider |
2954 | * for instance SELECT FOR UPDATE NOWAIT from a view that internally |
2955 | * contains a plain FOR UPDATE spec.) Having NOWAIT win over SKIP |
2956 | * LOCKED is reasonable since the former throws an error in case of |
2957 | * coming across a locked tuple, which may be undesirable in some |
2958 | * cases but it seems better than silently returning inconsistent |
2959 | * results. |
2960 | * |
2961 | * And of course pushedDown becomes false if any clause is explicit. |
2962 | */ |
2963 | rc->strength = Max(rc->strength, strength); |
2964 | rc->waitPolicy = Max(rc->waitPolicy, waitPolicy); |
2965 | rc->pushedDown &= pushedDown; |
2966 | return; |
2967 | } |
2968 | |
2969 | /* Make a new RowMarkClause */ |
2970 | rc = makeNode(RowMarkClause); |
2971 | rc->rti = rtindex; |
2972 | rc->strength = strength; |
2973 | rc->waitPolicy = waitPolicy; |
2974 | rc->pushedDown = pushedDown; |
2975 | qry->rowMarks = lappend(qry->rowMarks, rc); |
2976 | } |
2977 | |
2978 | /* |
2979 | * Coverage testing for raw_expression_tree_walker(). |
2980 | * |
2981 | * When enabled, we run raw_expression_tree_walker() over every DML statement |
2982 | * submitted to parse analysis. Without this provision, that function is only |
2983 | * applied in limited cases involving CTEs, and we don't really want to have |
2984 | * to test everything inside as well as outside a CTE. |
2985 | */ |
2986 | #ifdef RAW_EXPRESSION_COVERAGE_TEST |
2987 | |
2988 | static bool |
2989 | test_raw_expression_coverage(Node *node, void *context) |
2990 | { |
2991 | if (node == NULL) |
2992 | return false; |
2993 | return raw_expression_tree_walker(node, |
2994 | test_raw_expression_coverage, |
2995 | context); |
2996 | } |
2997 | |
2998 | #endif /* RAW_EXPRESSION_COVERAGE_TEST */ |
2999 | |