Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
analyze.c
Go to the documentation of this file.
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-2025, 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_proc.h"
29#include "catalog/pg_type.h"
30#include "commands/defrem.h"
31#include "miscadmin.h"
32#include "nodes/makefuncs.h"
33#include "nodes/nodeFuncs.h"
34#include "nodes/queryjumble.h"
35#include "optimizer/optimizer.h"
36#include "parser/analyze.h"
37#include "parser/parse_agg.h"
38#include "parser/parse_clause.h"
39#include "parser/parse_coerce.h"
41#include "parser/parse_cte.h"
42#include "parser/parse_expr.h"
43#include "parser/parse_func.h"
44#include "parser/parse_merge.h"
45#include "parser/parse_oper.h"
46#include "parser/parse_param.h"
48#include "parser/parse_target.h"
49#include "parser/parse_type.h"
50#include "parser/parsetree.h"
52#include "utils/builtins.h"
53#include "utils/guc.h"
54#include "utils/rel.h"
55#include "utils/syscache.h"
56
57
58/* Passthrough data for transformPLAssignStmtTarget */
60{
61 PLAssignStmt *stmt; /* the assignment statement */
62 Node *target; /* node representing the target variable */
63 List *indirection; /* indirection yet to be applied to target */
65
66/* Hook for plugins to get control at end of parse analysis */
68
69static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree);
73 OnConflictClause *onConflictClause);
74static int count_rowexpr_columns(ParseState *pstate, Node *expr);
76 SelectStmtPassthrough *passthru);
80 bool isTopLevel, List **targetlist);
81static void determineRecursiveColTypes(ParseState *pstate,
82 Node *larg, List *nrtargetlist);
87static List *transformPLAssignStmtTarget(ParseState *pstate, List *tlist,
88 SelectStmtPassthrough *passthru);
95static Query *transformCallStmt(ParseState *pstate,
96 CallStmt *stmt);
97static void transformLockingClause(ParseState *pstate, Query *qry,
98 LockingClause *lc, bool pushedDown);
99#ifdef DEBUG_NODE_TESTS_ENABLED
100static bool test_raw_expression_coverage(Node *node, void *context);
101#endif
102
103
104/*
105 * parse_analyze_fixedparams
106 * Analyze a raw parse tree and transform it to Query form.
107 *
108 * Optionally, information about $n parameter types can be supplied.
109 * References to $n indexes not defined by paramTypes[] are disallowed.
110 *
111 * The result is a Query node. Optimizable statements require considerable
112 * transformation, while utility-type statements are simply hung off
113 * a dummy CMD_UTILITY Query node.
114 */
115Query *
116parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText,
117 const Oid *paramTypes, int numParams,
118 QueryEnvironment *queryEnv)
119{
120 ParseState *pstate = make_parsestate(NULL);
121 Query *query;
122 JumbleState *jstate = NULL;
123
124 Assert(sourceText != NULL); /* required as of 8.4 */
125
126 pstate->p_sourcetext = sourceText;
127
128 if (numParams > 0)
129 setup_parse_fixed_parameters(pstate, paramTypes, numParams);
130
131 pstate->p_queryEnv = queryEnv;
132
133 query = transformTopLevelStmt(pstate, parseTree);
134
135 if (IsQueryIdEnabled())
136 jstate = JumbleQuery(query);
137
139 (*post_parse_analyze_hook) (pstate, query, jstate);
140
141 free_parsestate(pstate);
142
143 pgstat_report_query_id(query->queryId, false);
144
145 return query;
146}
147
148/*
149 * parse_analyze_varparams
150 *
151 * This variant is used when it's okay to deduce information about $n
152 * symbol datatypes from context. The passed-in paramTypes[] array can
153 * be modified or enlarged (via repalloc).
154 */
155Query *
156parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
157 Oid **paramTypes, int *numParams,
158 QueryEnvironment *queryEnv)
159{
160 ParseState *pstate = make_parsestate(NULL);
161 Query *query;
162 JumbleState *jstate = NULL;
163
164 Assert(sourceText != NULL); /* required as of 8.4 */
165
166 pstate->p_sourcetext = sourceText;
167
168 setup_parse_variable_parameters(pstate, paramTypes, numParams);
169
170 pstate->p_queryEnv = queryEnv;
171
172 query = transformTopLevelStmt(pstate, parseTree);
173
174 /* make sure all is well with parameter types */
175 check_variable_parameters(pstate, query);
176
177 if (IsQueryIdEnabled())
178 jstate = JumbleQuery(query);
179
181 (*post_parse_analyze_hook) (pstate, query, jstate);
182
183 free_parsestate(pstate);
184
185 pgstat_report_query_id(query->queryId, false);
186
187 return query;
188}
189
190/*
191 * parse_analyze_withcb
192 *
193 * This variant is used when the caller supplies their own parser callback to
194 * resolve parameters and possibly other things.
195 */
196Query *
197parse_analyze_withcb(RawStmt *parseTree, const char *sourceText,
198 ParserSetupHook parserSetup,
199 void *parserSetupArg,
200 QueryEnvironment *queryEnv)
201{
202 ParseState *pstate = make_parsestate(NULL);
203 Query *query;
204 JumbleState *jstate = NULL;
205
206 Assert(sourceText != NULL); /* required as of 8.4 */
207
208 pstate->p_sourcetext = sourceText;
209 pstate->p_queryEnv = queryEnv;
210 (*parserSetup) (pstate, parserSetupArg);
211
212 query = transformTopLevelStmt(pstate, parseTree);
213
214 if (IsQueryIdEnabled())
215 jstate = JumbleQuery(query);
216
218 (*post_parse_analyze_hook) (pstate, query, jstate);
219
220 free_parsestate(pstate);
221
222 pgstat_report_query_id(query->queryId, false);
223
224 return query;
225}
226
227
228/*
229 * parse_sub_analyze
230 * Entry point for recursively analyzing a sub-statement.
231 */
232Query *
233parse_sub_analyze(Node *parseTree, ParseState *parentParseState,
234 CommonTableExpr *parentCTE,
235 bool locked_from_parent,
236 bool resolve_unknowns)
237{
238 ParseState *pstate = make_parsestate(parentParseState);
239 Query *query;
240
241 pstate->p_parent_cte = parentCTE;
242 pstate->p_locked_from_parent = locked_from_parent;
243 pstate->p_resolve_unknowns = resolve_unknowns;
244
245 query = transformStmt(pstate, parseTree);
246
247 free_parsestate(pstate);
248
249 return query;
250}
251
252/*
253 * transformTopLevelStmt -
254 * transform a Parse tree into a Query tree.
255 *
256 * This function is just responsible for transferring statement location data
257 * from the RawStmt into the finished Query.
258 */
259Query *
261{
262 Query *result;
263
264 /* We're at top level, so allow SELECT INTO */
265 result = transformOptionalSelectInto(pstate, parseTree->stmt);
266
267 result->stmt_location = parseTree->stmt_location;
268 result->stmt_len = parseTree->stmt_len;
269
270 return result;
271}
272
273/*
274 * transformOptionalSelectInto -
275 * If SELECT has INTO, convert it to CREATE TABLE AS.
276 *
277 * The only thing we do here that we don't do in transformStmt() is to
278 * convert SELECT ... INTO into CREATE TABLE AS. Since utility statements
279 * aren't allowed within larger statements, this is only allowed at the top
280 * of the parse tree, and so we only try it before entering the recursive
281 * transformStmt() processing.
282 */
283static Query *
285{
286 if (IsA(parseTree, SelectStmt))
287 {
288 SelectStmt *stmt = (SelectStmt *) parseTree;
289
290 /* If it's a set-operation tree, drill down to leftmost SelectStmt */
291 while (stmt && stmt->op != SETOP_NONE)
292 stmt = stmt->larg;
293 Assert(stmt && IsA(stmt, SelectStmt) && stmt->larg == NULL);
294
295 if (stmt->intoClause)
296 {
298
299 ctas->query = parseTree;
300 ctas->into = stmt->intoClause;
301 ctas->objtype = OBJECT_TABLE;
302 ctas->is_select_into = true;
303
304 /*
305 * Remove the intoClause from the SelectStmt. This makes it safe
306 * for transformSelectStmt to complain if it finds intoClause set
307 * (implying that the INTO appeared in a disallowed place).
308 */
309 stmt->intoClause = NULL;
310
311 parseTree = (Node *) ctas;
312 }
313 }
314
315 return transformStmt(pstate, parseTree);
316}
317
318/*
319 * transformStmt -
320 * recursively transform a Parse tree into a Query tree.
321 */
322Query *
323transformStmt(ParseState *pstate, Node *parseTree)
324{
325 Query *result;
326
327#ifdef DEBUG_NODE_TESTS_ENABLED
328
329 /*
330 * We apply debug_raw_expression_coverage_test testing to basic DML
331 * statements; we can't just run it on everything because
332 * raw_expression_tree_walker() doesn't claim to handle utility
333 * statements.
334 */
335 if (Debug_raw_expression_coverage_test)
336 {
337 switch (nodeTag(parseTree))
338 {
339 case T_SelectStmt:
340 case T_InsertStmt:
341 case T_UpdateStmt:
342 case T_DeleteStmt:
343 case T_MergeStmt:
344 (void) test_raw_expression_coverage(parseTree, NULL);
345 break;
346 default:
347 break;
348 }
349 }
350#endif /* DEBUG_NODE_TESTS_ENABLED */
351
352 /*
353 * Caution: when changing the set of statement types that have non-default
354 * processing here, see also stmt_requires_parse_analysis() and
355 * analyze_requires_snapshot().
356 */
357 switch (nodeTag(parseTree))
358 {
359 /*
360 * Optimizable statements
361 */
362 case T_InsertStmt:
363 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
364 break;
365
366 case T_DeleteStmt:
367 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
368 break;
369
370 case T_UpdateStmt:
371 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
372 break;
373
374 case T_MergeStmt:
375 result = transformMergeStmt(pstate, (MergeStmt *) parseTree);
376 break;
377
378 case T_SelectStmt:
379 {
380 SelectStmt *n = (SelectStmt *) parseTree;
381
382 if (n->valuesLists)
383 result = transformValuesClause(pstate, n);
384 else if (n->op == SETOP_NONE)
385 result = transformSelectStmt(pstate, n, NULL);
386 else
387 result = transformSetOperationStmt(pstate, n);
388 }
389 break;
390
391 case T_ReturnStmt:
392 result = transformReturnStmt(pstate, (ReturnStmt *) parseTree);
393 break;
394
395 case T_PLAssignStmt:
396 result = transformPLAssignStmt(pstate,
397 (PLAssignStmt *) parseTree);
398 break;
399
400 /*
401 * Special cases
402 */
403 case T_DeclareCursorStmt:
404 result = transformDeclareCursorStmt(pstate,
405 (DeclareCursorStmt *) parseTree);
406 break;
407
408 case T_ExplainStmt:
409 result = transformExplainStmt(pstate,
410 (ExplainStmt *) parseTree);
411 break;
412
413 case T_CreateTableAsStmt:
414 result = transformCreateTableAsStmt(pstate,
415 (CreateTableAsStmt *) parseTree);
416 break;
417
418 case T_CallStmt:
419 result = transformCallStmt(pstate,
420 (CallStmt *) parseTree);
421 break;
422
423 default:
424
425 /*
426 * other statements don't require any transformation; just return
427 * the original parsetree with a Query node plastered on top.
428 */
429 result = makeNode(Query);
430 result->commandType = CMD_UTILITY;
431 result->utilityStmt = (Node *) parseTree;
432 break;
433 }
434
435 /* Mark as original query until we learn differently */
436 result->querySource = QSRC_ORIGINAL;
437 result->canSetTag = true;
438
439 return result;
440}
441
442/*
443 * stmt_requires_parse_analysis
444 * Returns true if parse analysis will do anything non-trivial
445 * with the given raw parse tree.
446 *
447 * Generally, this should return true for any statement type for which
448 * transformStmt() does more than wrap a CMD_UTILITY Query around it.
449 * When it returns false, the caller can assume that there is no situation
450 * in which parse analysis of the raw statement could need to be re-done.
451 *
452 * Currently, since the rewriter and planner do nothing for CMD_UTILITY
453 * Queries, a false result means that the entire parse analysis/rewrite/plan
454 * pipeline will never need to be re-done. If that ever changes, callers
455 * will likely need adjustment.
456 */
457bool
459{
460 bool result;
461
462 switch (nodeTag(parseTree->stmt))
463 {
464 /*
465 * Optimizable statements
466 */
467 case T_InsertStmt:
468 case T_DeleteStmt:
469 case T_UpdateStmt:
470 case T_MergeStmt:
471 case T_SelectStmt:
472 case T_ReturnStmt:
473 case T_PLAssignStmt:
474 result = true;
475 break;
476
477 /*
478 * Special cases
479 */
480 case T_DeclareCursorStmt:
481 case T_ExplainStmt:
482 case T_CreateTableAsStmt:
483 case T_CallStmt:
484 result = true;
485 break;
486
487 default:
488 /* all other statements just get wrapped in a CMD_UTILITY Query */
489 result = false;
490 break;
491 }
492
493 return result;
494}
495
496/*
497 * analyze_requires_snapshot
498 * Returns true if a snapshot must be set before doing parse analysis
499 * on the given raw parse tree.
500 */
501bool
503{
504 /*
505 * Currently, this should return true in exactly the same cases that
506 * stmt_requires_parse_analysis() does, so we just invoke that function
507 * rather than duplicating it. We keep the two entry points separate for
508 * clarity of callers, since from the callers' standpoint these are
509 * different conditions.
510 *
511 * While there may someday be a statement type for which transformStmt()
512 * does something nontrivial and yet no snapshot is needed for that
513 * processing, it seems likely that making such a choice would be fragile.
514 * If you want to install an exception, document the reasoning for it in a
515 * comment.
516 */
517 return stmt_requires_parse_analysis(parseTree);
518}
519
520/*
521 * query_requires_rewrite_plan()
522 * Returns true if rewriting or planning is non-trivial for this Query.
523 *
524 * This is much like stmt_requires_parse_analysis(), but applies one step
525 * further down the pipeline.
526 *
527 * We do not provide an equivalent of analyze_requires_snapshot(): callers
528 * can assume that any rewriting or planning activity needs a snapshot.
529 */
530bool
532{
533 bool result;
534
535 if (query->commandType != CMD_UTILITY)
536 {
537 /* All optimizable statements require rewriting/planning */
538 result = true;
539 }
540 else
541 {
542 /* This list should match stmt_requires_parse_analysis() */
543 switch (nodeTag(query->utilityStmt))
544 {
545 case T_DeclareCursorStmt:
546 case T_ExplainStmt:
547 case T_CreateTableAsStmt:
548 case T_CallStmt:
549 result = true;
550 break;
551 default:
552 result = false;
553 break;
554 }
555 }
556 return result;
557}
558
559/*
560 * transformDeleteStmt -
561 * transforms a Delete Statement
562 */
563static Query *
565{
566 Query *qry = makeNode(Query);
567 ParseNamespaceItem *nsitem;
568 Node *qual;
569
570 qry->commandType = CMD_DELETE;
571
572 /* process the WITH clause independently of all else */
573 if (stmt->withClause)
574 {
575 qry->hasRecursive = stmt->withClause->recursive;
576 qry->cteList = transformWithClause(pstate, stmt->withClause);
577 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
578 }
579
580 /* set up range table with just the result rel */
581 qry->resultRelation = setTargetTable(pstate, stmt->relation,
582 stmt->relation->inh,
583 true,
584 ACL_DELETE);
585 nsitem = pstate->p_target_nsitem;
586
587 /* there's no DISTINCT in DELETE */
588 qry->distinctClause = NIL;
589
590 /* subqueries in USING cannot access the result relation */
591 nsitem->p_lateral_only = true;
592 nsitem->p_lateral_ok = false;
593
594 /*
595 * The USING clause is non-standard SQL syntax, and is equivalent in
596 * functionality to the FROM list that can be specified for UPDATE. The
597 * USING keyword is used rather than FROM because FROM is already a
598 * keyword in the DELETE syntax.
599 */
600 transformFromClause(pstate, stmt->usingClause);
601
602 /* remaining clauses can reference the result relation normally */
603 nsitem->p_lateral_only = false;
604 nsitem->p_lateral_ok = true;
605
606 qual = transformWhereClause(pstate, stmt->whereClause,
607 EXPR_KIND_WHERE, "WHERE");
608
609 transformReturningClause(pstate, qry, stmt->returningClause,
611
612 /* done building the range table and jointree */
613 qry->rtable = pstate->p_rtable;
614 qry->rteperminfos = pstate->p_rteperminfos;
615 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
616
617 qry->hasSubLinks = pstate->p_hasSubLinks;
618 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
619 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
620 qry->hasAggs = pstate->p_hasAggs;
621
622 assign_query_collations(pstate, qry);
623
624 /* this must be done after collations, for reliable comparison of exprs */
625 if (pstate->p_hasAggs)
626 parseCheckAggregates(pstate, qry);
627
628 return qry;
629}
630
631/*
632 * transformInsertStmt -
633 * transform an Insert Statement
634 */
635static Query *
637{
638 Query *qry = makeNode(Query);
639 SelectStmt *selectStmt = (SelectStmt *) stmt->selectStmt;
640 List *exprList = NIL;
641 bool isGeneralSelect;
642 List *sub_rtable;
643 List *sub_rteperminfos;
644 List *sub_namespace;
645 List *icolumns;
646 List *attrnos;
647 ParseNamespaceItem *nsitem;
648 RTEPermissionInfo *perminfo;
649 ListCell *icols;
650 ListCell *attnos;
651 ListCell *lc;
652 bool isOnConflictUpdate;
653 AclMode targetPerms;
654
655 /* There can't be any outer WITH to worry about */
656 Assert(pstate->p_ctenamespace == NIL);
657
658 qry->commandType = CMD_INSERT;
659 pstate->p_is_insert = true;
660
661 /* process the WITH clause independently of all else */
662 if (stmt->withClause)
663 {
664 qry->hasRecursive = stmt->withClause->recursive;
665 qry->cteList = transformWithClause(pstate, stmt->withClause);
666 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
667 }
668
669 qry->override = stmt->override;
670
671 isOnConflictUpdate = (stmt->onConflictClause &&
672 stmt->onConflictClause->action == ONCONFLICT_UPDATE);
673
674 /*
675 * We have three cases to deal with: DEFAULT VALUES (selectStmt == NULL),
676 * VALUES list, or general SELECT input. We special-case VALUES, both for
677 * efficiency and so we can handle DEFAULT specifications.
678 *
679 * The grammar allows attaching ORDER BY, LIMIT, FOR UPDATE, or WITH to a
680 * VALUES clause. If we have any of those, treat it as a general SELECT;
681 * so it will work, but you can't use DEFAULT items together with those.
682 */
683 isGeneralSelect = (selectStmt && (selectStmt->valuesLists == NIL ||
684 selectStmt->sortClause != NIL ||
685 selectStmt->limitOffset != NULL ||
686 selectStmt->limitCount != NULL ||
687 selectStmt->lockingClause != NIL ||
688 selectStmt->withClause != NULL));
689
690 /*
691 * If a non-nil rangetable/namespace was passed in, and we are doing
692 * INSERT/SELECT, arrange to pass the rangetable/rteperminfos/namespace
693 * down to the SELECT. This can only happen if we are inside a CREATE
694 * RULE, and in that case we want the rule's OLD and NEW rtable entries to
695 * appear as part of the SELECT's rtable, not as outer references for it.
696 * (Kluge!) The SELECT's joinlist is not affected however. We must do
697 * this before adding the target table to the INSERT's rtable.
698 */
699 if (isGeneralSelect)
700 {
701 sub_rtable = pstate->p_rtable;
702 pstate->p_rtable = NIL;
703 sub_rteperminfos = pstate->p_rteperminfos;
704 pstate->p_rteperminfos = NIL;
705 sub_namespace = pstate->p_namespace;
706 pstate->p_namespace = NIL;
707 }
708 else
709 {
710 sub_rtable = NIL; /* not used, but keep compiler quiet */
711 sub_rteperminfos = NIL;
712 sub_namespace = NIL;
713 }
714
715 /*
716 * Must get write lock on INSERT target table before scanning SELECT, else
717 * we will grab the wrong kind of initial lock if the target table is also
718 * mentioned in the SELECT part. Note that the target table is not added
719 * to the joinlist or namespace.
720 */
721 targetPerms = ACL_INSERT;
722 if (isOnConflictUpdate)
723 targetPerms |= ACL_UPDATE;
724 qry->resultRelation = setTargetTable(pstate, stmt->relation,
725 false, false, targetPerms);
726
727 /* Validate stmt->cols list, or build default list if no list given */
728 icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
729 Assert(list_length(icolumns) == list_length(attrnos));
730
731 /*
732 * Determine which variant of INSERT we have.
733 */
734 if (selectStmt == NULL)
735 {
736 /*
737 * We have INSERT ... DEFAULT VALUES. We can handle this case by
738 * emitting an empty targetlist --- all columns will be defaulted when
739 * the planner expands the targetlist.
740 */
741 exprList = NIL;
742 }
743 else if (isGeneralSelect)
744 {
745 /*
746 * We make the sub-pstate a child of the outer pstate so that it can
747 * see any Param definitions supplied from above. Since the outer
748 * pstate's rtable and namespace are presently empty, there are no
749 * side-effects of exposing names the sub-SELECT shouldn't be able to
750 * see.
751 */
752 ParseState *sub_pstate = make_parsestate(pstate);
753 Query *selectQuery;
754
755 /*
756 * Process the source SELECT.
757 *
758 * It is important that this be handled just like a standalone SELECT;
759 * otherwise the behavior of SELECT within INSERT might be different
760 * from a stand-alone SELECT. (Indeed, Postgres up through 6.5 had
761 * bugs of just that nature...)
762 *
763 * The sole exception is that we prevent resolving unknown-type
764 * outputs as TEXT. This does not change the semantics since if the
765 * column type matters semantically, it would have been resolved to
766 * something else anyway. Doing this lets us resolve such outputs as
767 * the target column's type, which we handle below.
768 */
769 sub_pstate->p_rtable = sub_rtable;
770 sub_pstate->p_rteperminfos = sub_rteperminfos;
771 sub_pstate->p_joinexprs = NIL; /* sub_rtable has no joins */
772 sub_pstate->p_nullingrels = NIL;
773 sub_pstate->p_namespace = sub_namespace;
774 sub_pstate->p_resolve_unknowns = false;
775
776 selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
777
778 free_parsestate(sub_pstate);
779
780 /* The grammar should have produced a SELECT */
781 if (!IsA(selectQuery, Query) ||
782 selectQuery->commandType != CMD_SELECT)
783 elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT");
784
785 /*
786 * Make the source be a subquery in the INSERT's rangetable, and add
787 * it to the INSERT's joinlist (but not the namespace).
788 */
789 nsitem = addRangeTableEntryForSubquery(pstate,
790 selectQuery,
791 NULL,
792 false,
793 false);
794 addNSItemToQuery(pstate, nsitem, true, false, false);
795
796 /*----------
797 * Generate an expression list for the INSERT that selects all the
798 * non-resjunk columns from the subquery. (INSERT's tlist must be
799 * separate from the subquery's tlist because we may add columns,
800 * insert datatype coercions, etc.)
801 *
802 * HACK: unknown-type constants and params in the SELECT's targetlist
803 * are copied up as-is rather than being referenced as subquery
804 * outputs. This is to ensure that when we try to coerce them to
805 * the target column's datatype, the right things happen (see
806 * special cases in coerce_type). Otherwise, this fails:
807 * INSERT INTO foo SELECT 'bar', ... FROM baz
808 *----------
809 */
810 exprList = NIL;
811 foreach(lc, selectQuery->targetList)
812 {
813 TargetEntry *tle = (TargetEntry *) lfirst(lc);
814 Expr *expr;
815
816 if (tle->resjunk)
817 continue;
818 if (tle->expr &&
819 (IsA(tle->expr, Const) || IsA(tle->expr, Param)) &&
820 exprType((Node *) tle->expr) == UNKNOWNOID)
821 expr = tle->expr;
822 else
823 {
824 Var *var = makeVarFromTargetEntry(nsitem->p_rtindex, tle);
825
826 var->location = exprLocation((Node *) tle->expr);
827 expr = (Expr *) var;
828 }
829 exprList = lappend(exprList, expr);
830 }
831
832 /* Prepare row for assignment to target table */
833 exprList = transformInsertRow(pstate, exprList,
834 stmt->cols,
835 icolumns, attrnos,
836 false);
837 }
838 else if (list_length(selectStmt->valuesLists) > 1)
839 {
840 /*
841 * Process INSERT ... VALUES with multiple VALUES sublists. We
842 * generate a VALUES RTE holding the transformed expression lists, and
843 * build up a targetlist containing Vars that reference the VALUES
844 * RTE.
845 */
846 List *exprsLists = NIL;
847 List *coltypes = NIL;
848 List *coltypmods = NIL;
849 List *colcollations = NIL;
850 int sublist_length = -1;
851 bool lateral = false;
852
853 Assert(selectStmt->intoClause == NULL);
854
855 foreach(lc, selectStmt->valuesLists)
856 {
857 List *sublist = (List *) lfirst(lc);
858
859 /*
860 * Do basic expression transformation (same as a ROW() expr, but
861 * allow SetToDefault at top level)
862 */
863 sublist = transformExpressionList(pstate, sublist,
864 EXPR_KIND_VALUES, true);
865
866 /*
867 * All the sublists must be the same length, *after*
868 * transformation (which might expand '*' into multiple items).
869 * The VALUES RTE can't handle anything different.
870 */
871 if (sublist_length < 0)
872 {
873 /* Remember post-transformation length of first sublist */
874 sublist_length = list_length(sublist);
875 }
876 else if (sublist_length != list_length(sublist))
877 {
879 (errcode(ERRCODE_SYNTAX_ERROR),
880 errmsg("VALUES lists must all be the same length"),
881 parser_errposition(pstate,
882 exprLocation((Node *) sublist))));
883 }
884
885 /*
886 * Prepare row for assignment to target table. We process any
887 * indirection on the target column specs normally but then strip
888 * off the resulting field/array assignment nodes, since we don't
889 * want the parsed statement to contain copies of those in each
890 * VALUES row. (It's annoying to have to transform the
891 * indirection specs over and over like this, but avoiding it
892 * would take some really messy refactoring of
893 * transformAssignmentIndirection.)
894 */
895 sublist = transformInsertRow(pstate, sublist,
896 stmt->cols,
897 icolumns, attrnos,
898 true);
899
900 /*
901 * We must assign collations now because assign_query_collations
902 * doesn't process rangetable entries. We just assign all the
903 * collations independently in each row, and don't worry about
904 * whether they are consistent vertically. The outer INSERT query
905 * isn't going to care about the collations of the VALUES columns,
906 * so it's not worth the effort to identify a common collation for
907 * each one here. (But note this does have one user-visible
908 * consequence: INSERT ... VALUES won't complain about conflicting
909 * explicit COLLATEs in a column, whereas the same VALUES
910 * construct in another context would complain.)
911 */
912 assign_list_collations(pstate, sublist);
913
914 exprsLists = lappend(exprsLists, sublist);
915 }
916
917 /*
918 * Construct column type/typmod/collation lists for the VALUES RTE.
919 * Every expression in each column has been coerced to the type/typmod
920 * of the corresponding target column or subfield, so it's sufficient
921 * to look at the exprType/exprTypmod of the first row. We don't care
922 * about the collation labeling, so just fill in InvalidOid for that.
923 */
924 foreach(lc, (List *) linitial(exprsLists))
925 {
926 Node *val = (Node *) lfirst(lc);
927
928 coltypes = lappend_oid(coltypes, exprType(val));
929 coltypmods = lappend_int(coltypmods, exprTypmod(val));
930 colcollations = lappend_oid(colcollations, InvalidOid);
931 }
932
933 /*
934 * Ordinarily there can't be any current-level Vars in the expression
935 * lists, because the namespace was empty ... but if we're inside
936 * CREATE RULE, then NEW/OLD references might appear. In that case we
937 * have to mark the VALUES RTE as LATERAL.
938 */
939 if (list_length(pstate->p_rtable) != 1 &&
940 contain_vars_of_level((Node *) exprsLists, 0))
941 lateral = true;
942
943 /*
944 * Generate the VALUES RTE
945 */
946 nsitem = addRangeTableEntryForValues(pstate, exprsLists,
947 coltypes, coltypmods, colcollations,
948 NULL, lateral, true);
949 addNSItemToQuery(pstate, nsitem, true, false, false);
950
951 /*
952 * Generate list of Vars referencing the RTE
953 */
954 exprList = expandNSItemVars(pstate, nsitem, 0, -1, NULL);
955
956 /*
957 * Re-apply any indirection on the target column specs to the Vars
958 */
959 exprList = transformInsertRow(pstate, exprList,
960 stmt->cols,
961 icolumns, attrnos,
962 false);
963 }
964 else
965 {
966 /*
967 * Process INSERT ... VALUES with a single VALUES sublist. We treat
968 * this case separately for efficiency. The sublist is just computed
969 * directly as the Query's targetlist, with no VALUES RTE. So it
970 * works just like a SELECT without any FROM.
971 */
972 List *valuesLists = selectStmt->valuesLists;
973
974 Assert(list_length(valuesLists) == 1);
975 Assert(selectStmt->intoClause == NULL);
976
977 /*
978 * Do basic expression transformation (same as a ROW() expr, but allow
979 * SetToDefault at top level)
980 */
981 exprList = transformExpressionList(pstate,
982 (List *) linitial(valuesLists),
984 true);
985
986 /* Prepare row for assignment to target table */
987 exprList = transformInsertRow(pstate, exprList,
988 stmt->cols,
989 icolumns, attrnos,
990 false);
991 }
992
993 /*
994 * Generate query's target list using the computed list of expressions.
995 * Also, mark all the target columns as needing insert permissions.
996 */
997 perminfo = pstate->p_target_nsitem->p_perminfo;
998 qry->targetList = NIL;
999 Assert(list_length(exprList) <= list_length(icolumns));
1000 forthree(lc, exprList, icols, icolumns, attnos, attrnos)
1001 {
1002 Expr *expr = (Expr *) lfirst(lc);
1003 ResTarget *col = lfirst_node(ResTarget, icols);
1004 AttrNumber attr_num = (AttrNumber) lfirst_int(attnos);
1005 TargetEntry *tle;
1006
1007 tle = makeTargetEntry(expr,
1008 attr_num,
1009 col->name,
1010 false);
1011 qry->targetList = lappend(qry->targetList, tle);
1012
1013 perminfo->insertedCols = bms_add_member(perminfo->insertedCols,
1015 }
1016
1017 /*
1018 * If we have any clauses yet to process, set the query namespace to
1019 * contain only the target relation, removing any entries added in a
1020 * sub-SELECT or VALUES list.
1021 */
1022 if (stmt->onConflictClause || stmt->returningClause)
1023 {
1024 pstate->p_namespace = NIL;
1025 addNSItemToQuery(pstate, pstate->p_target_nsitem,
1026 false, true, true);
1027 }
1028
1029 /* Process ON CONFLICT, if any. */
1030 if (stmt->onConflictClause)
1031 qry->onConflict = transformOnConflictClause(pstate,
1032 stmt->onConflictClause);
1033
1034 /* Process RETURNING, if any. */
1035 if (stmt->returningClause)
1036 transformReturningClause(pstate, qry, stmt->returningClause,
1038
1039 /* done building the range table and jointree */
1040 qry->rtable = pstate->p_rtable;
1041 qry->rteperminfos = pstate->p_rteperminfos;
1042 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1043
1044 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
1045 qry->hasSubLinks = pstate->p_hasSubLinks;
1046
1047 assign_query_collations(pstate, qry);
1048
1049 return qry;
1050}
1051
1052/*
1053 * Prepare an INSERT row for assignment to the target table.
1054 *
1055 * exprlist: transformed expressions for source values; these might come from
1056 * a VALUES row, or be Vars referencing a sub-SELECT or VALUES RTE output.
1057 * stmtcols: original target-columns spec for INSERT (we just test for NIL)
1058 * icolumns: effective target-columns spec (list of ResTarget)
1059 * attrnos: integer column numbers (must be same length as icolumns)
1060 * strip_indirection: if true, remove any field/array assignment nodes
1061 */
1062List *
1064 List *stmtcols, List *icolumns, List *attrnos,
1065 bool strip_indirection)
1066{
1067 List *result;
1068 ListCell *lc;
1069 ListCell *icols;
1070 ListCell *attnos;
1071
1072 /*
1073 * Check length of expr list. It must not have more expressions than
1074 * there are target columns. We allow fewer, but only if no explicit
1075 * columns list was given (the remaining columns are implicitly
1076 * defaulted). Note we must check this *after* transformation because
1077 * that could expand '*' into multiple items.
1078 */
1079 if (list_length(exprlist) > list_length(icolumns))
1080 ereport(ERROR,
1081 (errcode(ERRCODE_SYNTAX_ERROR),
1082 errmsg("INSERT has more expressions than target columns"),
1083 parser_errposition(pstate,
1084 exprLocation(list_nth(exprlist,
1085 list_length(icolumns))))));
1086 if (stmtcols != NIL &&
1087 list_length(exprlist) < list_length(icolumns))
1088 {
1089 /*
1090 * We can get here for cases like INSERT ... SELECT (a,b,c) FROM ...
1091 * where the user accidentally created a RowExpr instead of separate
1092 * columns. Add a suitable hint if that seems to be the problem,
1093 * because the main error message is quite misleading for this case.
1094 * (If there's no stmtcols, you'll get something about data type
1095 * mismatch, which is less misleading so we don't worry about giving a
1096 * hint in that case.)
1097 */
1098 ereport(ERROR,
1099 (errcode(ERRCODE_SYNTAX_ERROR),
1100 errmsg("INSERT has more target columns than expressions"),
1101 ((list_length(exprlist) == 1 &&
1102 count_rowexpr_columns(pstate, linitial(exprlist)) ==
1103 list_length(icolumns)) ?
1104 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),
1105 parser_errposition(pstate,
1106 exprLocation(list_nth(icolumns,
1107 list_length(exprlist))))));
1108 }
1109
1110 /*
1111 * Prepare columns for assignment to target table.
1112 */
1113 result = NIL;
1114 forthree(lc, exprlist, icols, icolumns, attnos, attrnos)
1115 {
1116 Expr *expr = (Expr *) lfirst(lc);
1117 ResTarget *col = lfirst_node(ResTarget, icols);
1118 int attno = lfirst_int(attnos);
1119
1120 expr = transformAssignedExpr(pstate, expr,
1122 col->name,
1123 attno,
1124 col->indirection,
1125 col->location);
1126
1127 if (strip_indirection)
1128 {
1129 /*
1130 * We need to remove top-level FieldStores and SubscriptingRefs,
1131 * as well as any CoerceToDomain appearing above one of those ---
1132 * but not a CoerceToDomain that isn't above one of those.
1133 */
1134 while (expr)
1135 {
1136 Expr *subexpr = expr;
1137
1138 while (IsA(subexpr, CoerceToDomain))
1139 {
1140 subexpr = ((CoerceToDomain *) subexpr)->arg;
1141 }
1142 if (IsA(subexpr, FieldStore))
1143 {
1144 FieldStore *fstore = (FieldStore *) subexpr;
1145
1146 expr = (Expr *) linitial(fstore->newvals);
1147 }
1148 else if (IsA(subexpr, SubscriptingRef))
1149 {
1150 SubscriptingRef *sbsref = (SubscriptingRef *) subexpr;
1151
1152 if (sbsref->refassgnexpr == NULL)
1153 break;
1154
1155 expr = sbsref->refassgnexpr;
1156 }
1157 else
1158 break;
1159 }
1160 }
1161
1162 result = lappend(result, expr);
1163 }
1164
1165 return result;
1166}
1167
1168/*
1169 * transformOnConflictClause -
1170 * transforms an OnConflictClause in an INSERT
1171 */
1172static OnConflictExpr *
1174 OnConflictClause *onConflictClause)
1175{
1176 ParseNamespaceItem *exclNSItem = NULL;
1177 List *arbiterElems;
1178 Node *arbiterWhere;
1179 Oid arbiterConstraint;
1180 List *onConflictSet = NIL;
1181 Node *onConflictWhere = NULL;
1182 int exclRelIndex = 0;
1183 List *exclRelTlist = NIL;
1184 OnConflictExpr *result;
1185
1186 /*
1187 * If this is ON CONFLICT ... UPDATE, first create the range table entry
1188 * for the EXCLUDED pseudo relation, so that that will be present while
1189 * processing arbiter expressions. (You can't actually reference it from
1190 * there, but this provides a useful error message if you try.)
1191 */
1192 if (onConflictClause->action == ONCONFLICT_UPDATE)
1193 {
1194 Relation targetrel = pstate->p_target_relation;
1195 RangeTblEntry *exclRte;
1196
1197 exclNSItem = addRangeTableEntryForRelation(pstate,
1198 targetrel,
1200 makeAlias("excluded", NIL),
1201 false, false);
1202 exclRte = exclNSItem->p_rte;
1203 exclRelIndex = exclNSItem->p_rtindex;
1204
1205 /*
1206 * relkind is set to composite to signal that we're not dealing with
1207 * an actual relation, and no permission checks are required on it.
1208 * (We'll check the actual target relation, instead.)
1209 */
1210 exclRte->relkind = RELKIND_COMPOSITE_TYPE;
1211
1212 /* Create EXCLUDED rel's targetlist for use by EXPLAIN */
1213 exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel,
1214 exclRelIndex);
1215 }
1216
1217 /* Process the arbiter clause, ON CONFLICT ON (...) */
1218 transformOnConflictArbiter(pstate, onConflictClause, &arbiterElems,
1219 &arbiterWhere, &arbiterConstraint);
1220
1221 /* Process DO UPDATE */
1222 if (onConflictClause->action == ONCONFLICT_UPDATE)
1223 {
1224 /*
1225 * Expressions in the UPDATE targetlist need to be handled like UPDATE
1226 * not INSERT. We don't need to save/restore this because all INSERT
1227 * expressions have been parsed already.
1228 */
1229 pstate->p_is_insert = false;
1230
1231 /*
1232 * Add the EXCLUDED pseudo relation to the query namespace, making it
1233 * available in the UPDATE subexpressions.
1234 */
1235 addNSItemToQuery(pstate, exclNSItem, false, true, true);
1236
1237 /*
1238 * Now transform the UPDATE subexpressions.
1239 */
1240 onConflictSet =
1241 transformUpdateTargetList(pstate, onConflictClause->targetList);
1242
1243 onConflictWhere = transformWhereClause(pstate,
1244 onConflictClause->whereClause,
1245 EXPR_KIND_WHERE, "WHERE");
1246
1247 /*
1248 * Remove the EXCLUDED pseudo relation from the query namespace, since
1249 * it's not supposed to be available in RETURNING. (Maybe someday we
1250 * could allow that, and drop this step.)
1251 */
1252 Assert((ParseNamespaceItem *) llast(pstate->p_namespace) == exclNSItem);
1253 pstate->p_namespace = list_delete_last(pstate->p_namespace);
1254 }
1255
1256 /* Finally, build ON CONFLICT DO [NOTHING | UPDATE] expression */
1257 result = makeNode(OnConflictExpr);
1258
1259 result->action = onConflictClause->action;
1260 result->arbiterElems = arbiterElems;
1261 result->arbiterWhere = arbiterWhere;
1262 result->constraint = arbiterConstraint;
1263 result->onConflictSet = onConflictSet;
1264 result->onConflictWhere = onConflictWhere;
1265 result->exclRelIndex = exclRelIndex;
1266 result->exclRelTlist = exclRelTlist;
1267
1268 return result;
1269}
1270
1271
1272/*
1273 * BuildOnConflictExcludedTargetlist
1274 * Create target list for the EXCLUDED pseudo-relation of ON CONFLICT,
1275 * representing the columns of targetrel with varno exclRelIndex.
1276 *
1277 * Note: Exported for use in the rewriter.
1278 */
1279List *
1281 Index exclRelIndex)
1282{
1283 List *result = NIL;
1284 int attno;
1285 Var *var;
1286 TargetEntry *te;
1287
1288 /*
1289 * Note that resnos of the tlist must correspond to attnos of the
1290 * underlying relation, hence we need entries for dropped columns too.
1291 */
1292 for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++)
1293 {
1294 Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno);
1295 char *name;
1296
1297 if (attr->attisdropped)
1298 {
1299 /*
1300 * can't use atttypid here, but it doesn't really matter what type
1301 * the Const claims to be.
1302 */
1303 var = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
1304 name = NULL;
1305 }
1306 else
1307 {
1308 var = makeVar(exclRelIndex, attno + 1,
1309 attr->atttypid, attr->atttypmod,
1310 attr->attcollation,
1311 0);
1312 name = pstrdup(NameStr(attr->attname));
1313 }
1314
1315 te = makeTargetEntry((Expr *) var,
1316 attno + 1,
1317 name,
1318 false);
1319
1320 result = lappend(result, te);
1321 }
1322
1323 /*
1324 * Add a whole-row-Var entry to support references to "EXCLUDED.*". Like
1325 * the other entries in the EXCLUDED tlist, its resno must match the Var's
1326 * varattno, else the wrong things happen while resolving references in
1327 * setrefs.c. This is against normal conventions for targetlists, but
1328 * it's okay since we don't use this as a real tlist.
1329 */
1330 var = makeVar(exclRelIndex, InvalidAttrNumber,
1331 targetrel->rd_rel->reltype,
1332 -1, InvalidOid, 0);
1333 te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true);
1334 result = lappend(result, te);
1335
1336 return result;
1337}
1338
1339
1340/*
1341 * count_rowexpr_columns -
1342 * get number of columns contained in a ROW() expression;
1343 * return -1 if expression isn't a RowExpr or a Var referencing one.
1344 *
1345 * This is currently used only for hint purposes, so we aren't terribly
1346 * tense about recognizing all possible cases. The Var case is interesting
1347 * because that's what we'll get in the INSERT ... SELECT (...) case.
1348 */
1349static int
1351{
1352 if (expr == NULL)
1353 return -1;
1354 if (IsA(expr, RowExpr))
1355 return list_length(((RowExpr *) expr)->args);
1356 if (IsA(expr, Var))
1357 {
1358 Var *var = (Var *) expr;
1359 AttrNumber attnum = var->varattno;
1360
1361 if (attnum > 0 && var->vartype == RECORDOID)
1362 {
1363 RangeTblEntry *rte;
1364
1365 rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
1366 if (rte->rtekind == RTE_SUBQUERY)
1367 {
1368 /* Subselect-in-FROM: examine sub-select's output expr */
1370 attnum);
1371
1372 if (ste == NULL || ste->resjunk)
1373 return -1;
1374 expr = (Node *) ste->expr;
1375 if (IsA(expr, RowExpr))
1376 return list_length(((RowExpr *) expr)->args);
1377 }
1378 }
1379 }
1380 return -1;
1381}
1382
1383
1384/*
1385 * transformSelectStmt -
1386 * transforms a Select Statement
1387 *
1388 * This function is also used to transform the source expression of a
1389 * PLAssignStmt. In that usage, passthru is non-NULL and we need to
1390 * call transformPLAssignStmtTarget after the initial transformation of the
1391 * SELECT's targetlist. (We could generalize this into an arbitrary callback
1392 * function, but for now that would just be more notation with no benefit.)
1393 * All the rest is the same as a regular SelectStmt.
1394 *
1395 * Note: this covers only cases with no set operations and no VALUES lists;
1396 * see below for the other cases.
1397 */
1398static Query *
1400 SelectStmtPassthrough *passthru)
1401{
1402 Query *qry = makeNode(Query);
1403 Node *qual;
1404 ListCell *l;
1405
1406 qry->commandType = CMD_SELECT;
1407
1408 /* process the WITH clause independently of all else */
1409 if (stmt->withClause)
1410 {
1411 qry->hasRecursive = stmt->withClause->recursive;
1412 qry->cteList = transformWithClause(pstate, stmt->withClause);
1413 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
1414 }
1415
1416 /* Complain if we get called from someplace where INTO is not allowed */
1417 if (stmt->intoClause)
1418 ereport(ERROR,
1419 (errcode(ERRCODE_SYNTAX_ERROR),
1420 errmsg("SELECT ... INTO is not allowed here"),
1421 parser_errposition(pstate,
1422 exprLocation((Node *) stmt->intoClause))));
1423
1424 /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */
1425 pstate->p_locking_clause = stmt->lockingClause;
1426
1427 /* make WINDOW info available for window functions, too */
1428 pstate->p_windowdefs = stmt->windowClause;
1429
1430 /* process the FROM clause */
1431 transformFromClause(pstate, stmt->fromClause);
1432
1433 /* transform targetlist */
1434 qry->targetList = transformTargetList(pstate, stmt->targetList,
1436
1437 /*
1438 * If we're within a PLAssignStmt, do further transformation of the
1439 * targetlist; that has to happen before we consider sorting or grouping.
1440 * Otherwise, mark column origins (which are useless in a PLAssignStmt).
1441 */
1442 if (passthru)
1444 passthru);
1445 else
1446 markTargetListOrigins(pstate, qry->targetList);
1447
1448 /* transform WHERE */
1449 qual = transformWhereClause(pstate, stmt->whereClause,
1450 EXPR_KIND_WHERE, "WHERE");
1451
1452 /* initial processing of HAVING clause is much like WHERE clause */
1453 qry->havingQual = transformWhereClause(pstate, stmt->havingClause,
1454 EXPR_KIND_HAVING, "HAVING");
1455
1456 /*
1457 * Transform sorting/grouping stuff. Do ORDER BY first because both
1458 * transformGroupClause and transformDistinctClause need the results. Note
1459 * that these functions can also change the targetList, so it's passed to
1460 * them by reference.
1461 */
1462 qry->sortClause = transformSortClause(pstate,
1463 stmt->sortClause,
1464 &qry->targetList,
1466 false /* allow SQL92 rules */ );
1467
1468 qry->groupClause = transformGroupClause(pstate,
1469 stmt->groupClause,
1470 &qry->groupingSets,
1471 &qry->targetList,
1472 qry->sortClause,
1474 false /* allow SQL92 rules */ );
1475 qry->groupDistinct = stmt->groupDistinct;
1476
1477 if (stmt->distinctClause == NIL)
1478 {
1479 qry->distinctClause = NIL;
1480 qry->hasDistinctOn = false;
1481 }
1482 else if (linitial(stmt->distinctClause) == NULL)
1483 {
1484 /* We had SELECT DISTINCT */
1486 &qry->targetList,
1487 qry->sortClause,
1488 false);
1489 qry->hasDistinctOn = false;
1490 }
1491 else
1492 {
1493 /* We had SELECT DISTINCT ON */
1495 stmt->distinctClause,
1496 &qry->targetList,
1497 qry->sortClause);
1498 qry->hasDistinctOn = true;
1499 }
1500
1501 /* transform LIMIT */
1502 qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
1503 EXPR_KIND_OFFSET, "OFFSET",
1504 stmt->limitOption);
1505 qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
1506 EXPR_KIND_LIMIT, "LIMIT",
1507 stmt->limitOption);
1508 qry->limitOption = stmt->limitOption;
1509
1510 /* transform window clauses after we have seen all window functions */
1512 pstate->p_windowdefs,
1513 &qry->targetList);
1514
1515 /* resolve any still-unresolved output columns as being type text */
1516 if (pstate->p_resolve_unknowns)
1518
1519 qry->rtable = pstate->p_rtable;
1520 qry->rteperminfos = pstate->p_rteperminfos;
1521 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
1522
1523 qry->hasSubLinks = pstate->p_hasSubLinks;
1524 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
1525 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
1526 qry->hasAggs = pstate->p_hasAggs;
1527
1528 foreach(l, stmt->lockingClause)
1529 {
1530 transformLockingClause(pstate, qry,
1531 (LockingClause *) lfirst(l), false);
1532 }
1533
1534 assign_query_collations(pstate, qry);
1535
1536 /* this must be done after collations, for reliable comparison of exprs */
1537 if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
1538 parseCheckAggregates(pstate, qry);
1539
1540 return qry;
1541}
1542
1543/*
1544 * transformValuesClause -
1545 * transforms a VALUES clause that's being used as a standalone SELECT
1546 *
1547 * We build a Query containing a VALUES RTE, rather as if one had written
1548 * SELECT * FROM (VALUES ...) AS "*VALUES*"
1549 */
1550static Query *
1552{
1553 Query *qry = makeNode(Query);
1554 List *exprsLists = NIL;
1555 List *coltypes = NIL;
1556 List *coltypmods = NIL;
1557 List *colcollations = NIL;
1558 List **colexprs = NULL;
1559 int sublist_length = -1;
1560 bool lateral = false;
1561 ParseNamespaceItem *nsitem;
1562 ListCell *lc;
1563 ListCell *lc2;
1564 int i;
1565
1566 qry->commandType = CMD_SELECT;
1567
1568 /* Most SELECT stuff doesn't apply in a VALUES clause */
1569 Assert(stmt->distinctClause == NIL);
1570 Assert(stmt->intoClause == NULL);
1571 Assert(stmt->targetList == NIL);
1572 Assert(stmt->fromClause == NIL);
1573 Assert(stmt->whereClause == NULL);
1574 Assert(stmt->groupClause == NIL);
1575 Assert(stmt->havingClause == NULL);
1576 Assert(stmt->windowClause == NIL);
1577 Assert(stmt->op == SETOP_NONE);
1578
1579 /* process the WITH clause independently of all else */
1580 if (stmt->withClause)
1581 {
1582 qry->hasRecursive = stmt->withClause->recursive;
1583 qry->cteList = transformWithClause(pstate, stmt->withClause);
1584 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
1585 }
1586
1587 /*
1588 * For each row of VALUES, transform the raw expressions.
1589 *
1590 * Note that the intermediate representation we build is column-organized
1591 * not row-organized. That simplifies the type and collation processing
1592 * below.
1593 */
1594 foreach(lc, stmt->valuesLists)
1595 {
1596 List *sublist = (List *) lfirst(lc);
1597
1598 /*
1599 * Do basic expression transformation (same as a ROW() expr, but here
1600 * we disallow SetToDefault)
1601 */
1602 sublist = transformExpressionList(pstate, sublist,
1603 EXPR_KIND_VALUES, false);
1604
1605 /*
1606 * All the sublists must be the same length, *after* transformation
1607 * (which might expand '*' into multiple items). The VALUES RTE can't
1608 * handle anything different.
1609 */
1610 if (sublist_length < 0)
1611 {
1612 /* Remember post-transformation length of first sublist */
1613 sublist_length = list_length(sublist);
1614 /* and allocate array for per-column lists */
1615 colexprs = (List **) palloc0(sublist_length * sizeof(List *));
1616 }
1617 else if (sublist_length != list_length(sublist))
1618 {
1619 ereport(ERROR,
1620 (errcode(ERRCODE_SYNTAX_ERROR),
1621 errmsg("VALUES lists must all be the same length"),
1622 parser_errposition(pstate,
1623 exprLocation((Node *) sublist))));
1624 }
1625
1626 /* Build per-column expression lists */
1627 i = 0;
1628 foreach(lc2, sublist)
1629 {
1630 Node *col = (Node *) lfirst(lc2);
1631
1632 colexprs[i] = lappend(colexprs[i], col);
1633 i++;
1634 }
1635
1636 /* Release sub-list's cells to save memory */
1637 list_free(sublist);
1638
1639 /* Prepare an exprsLists element for this row */
1640 exprsLists = lappend(exprsLists, NIL);
1641 }
1642
1643 /*
1644 * Now resolve the common types of the columns, and coerce everything to
1645 * those types. Then identify the common typmod and common collation, if
1646 * any, of each column.
1647 *
1648 * We must do collation processing now because (1) assign_query_collations
1649 * doesn't process rangetable entries, and (2) we need to label the VALUES
1650 * RTE with column collations for use in the outer query. We don't
1651 * consider conflict of implicit collations to be an error here; instead
1652 * the column will just show InvalidOid as its collation, and you'll get a
1653 * failure later if that results in failure to resolve a collation.
1654 *
1655 * Note we modify the per-column expression lists in-place.
1656 */
1657 for (i = 0; i < sublist_length; i++)
1658 {
1659 Oid coltype;
1660 int32 coltypmod;
1661 Oid colcoll;
1662
1663 coltype = select_common_type(pstate, colexprs[i], "VALUES", NULL);
1664
1665 foreach(lc, colexprs[i])
1666 {
1667 Node *col = (Node *) lfirst(lc);
1668
1669 col = coerce_to_common_type(pstate, col, coltype, "VALUES");
1670 lfirst(lc) = col;
1671 }
1672
1673 coltypmod = select_common_typmod(pstate, colexprs[i], coltype);
1674 colcoll = select_common_collation(pstate, colexprs[i], true);
1675
1676 coltypes = lappend_oid(coltypes, coltype);
1677 coltypmods = lappend_int(coltypmods, coltypmod);
1678 colcollations = lappend_oid(colcollations, colcoll);
1679 }
1680
1681 /*
1682 * Finally, rearrange the coerced expressions into row-organized lists.
1683 */
1684 for (i = 0; i < sublist_length; i++)
1685 {
1686 forboth(lc, colexprs[i], lc2, exprsLists)
1687 {
1688 Node *col = (Node *) lfirst(lc);
1689 List *sublist = lfirst(lc2);
1690
1691 sublist = lappend(sublist, col);
1692 lfirst(lc2) = sublist;
1693 }
1694 list_free(colexprs[i]);
1695 }
1696
1697 /*
1698 * Ordinarily there can't be any current-level Vars in the expression
1699 * lists, because the namespace was empty ... but if we're inside CREATE
1700 * RULE, then NEW/OLD references might appear. In that case we have to
1701 * mark the VALUES RTE as LATERAL.
1702 */
1703 if (pstate->p_rtable != NIL &&
1704 contain_vars_of_level((Node *) exprsLists, 0))
1705 lateral = true;
1706
1707 /*
1708 * Generate the VALUES RTE
1709 */
1710 nsitem = addRangeTableEntryForValues(pstate, exprsLists,
1711 coltypes, coltypmods, colcollations,
1712 NULL, lateral, true);
1713 addNSItemToQuery(pstate, nsitem, true, true, true);
1714
1715 /*
1716 * Generate a targetlist as though expanding "*"
1717 */
1718 Assert(pstate->p_next_resno == 1);
1719 qry->targetList = expandNSItemAttrs(pstate, nsitem, 0, true, -1);
1720
1721 /*
1722 * The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE to a
1723 * VALUES, so cope.
1724 */
1725 qry->sortClause = transformSortClause(pstate,
1726 stmt->sortClause,
1727 &qry->targetList,
1729 false /* allow SQL92 rules */ );
1730
1731 qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
1732 EXPR_KIND_OFFSET, "OFFSET",
1733 stmt->limitOption);
1734 qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
1735 EXPR_KIND_LIMIT, "LIMIT",
1736 stmt->limitOption);
1737 qry->limitOption = stmt->limitOption;
1738
1739 if (stmt->lockingClause)
1740 ereport(ERROR,
1741 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1742 /*------
1743 translator: %s is a SQL row locking clause such as FOR UPDATE */
1744 errmsg("%s cannot be applied to VALUES",
1746 linitial(stmt->lockingClause))->strength))));
1747
1748 qry->rtable = pstate->p_rtable;
1749 qry->rteperminfos = pstate->p_rteperminfos;
1750 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1751
1752 qry->hasSubLinks = pstate->p_hasSubLinks;
1753
1754 assign_query_collations(pstate, qry);
1755
1756 return qry;
1757}
1758
1759/*
1760 * transformSetOperationStmt -
1761 * transforms a set-operations tree
1762 *
1763 * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT
1764 * structure to it. We must transform each leaf SELECT and build up a top-
1765 * level Query that contains the leaf SELECTs as subqueries in its rangetable.
1766 * The tree of set operations is converted into the setOperations field of
1767 * the top-level Query.
1768 */
1769static Query *
1771{
1772 Query *qry = makeNode(Query);
1773 SelectStmt *leftmostSelect;
1774 int leftmostRTI;
1775 Query *leftmostQuery;
1776 SetOperationStmt *sostmt;
1777 List *sortClause;
1778 Node *limitOffset;
1779 Node *limitCount;
1780 List *lockingClause;
1781 WithClause *withClause;
1782 Node *node;
1783 ListCell *left_tlist,
1784 *lct,
1785 *lcm,
1786 *lcc,
1787 *l;
1788 List *targetvars,
1789 *targetnames,
1790 *sv_namespace;
1791 int sv_rtable_length;
1792 ParseNamespaceItem *jnsitem;
1793 ParseNamespaceColumn *sortnscolumns;
1794 int sortcolindex;
1795 int tllen;
1796
1797 qry->commandType = CMD_SELECT;
1798
1799 /*
1800 * Find leftmost leaf SelectStmt. We currently only need to do this in
1801 * order to deliver a suitable error message if there's an INTO clause
1802 * there, implying the set-op tree is in a context that doesn't allow
1803 * INTO. (transformSetOperationTree would throw error anyway, but it
1804 * seems worth the trouble to throw a different error for non-leftmost
1805 * INTO, so we produce that error in transformSetOperationTree.)
1806 */
1807 leftmostSelect = stmt->larg;
1808 while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
1809 leftmostSelect = leftmostSelect->larg;
1810 Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
1811 leftmostSelect->larg == NULL);
1812 if (leftmostSelect->intoClause)
1813 ereport(ERROR,
1814 (errcode(ERRCODE_SYNTAX_ERROR),
1815 errmsg("SELECT ... INTO is not allowed here"),
1816 parser_errposition(pstate,
1817 exprLocation((Node *) leftmostSelect->intoClause))));
1818
1819 /*
1820 * We need to extract ORDER BY and other top-level clauses here and not
1821 * let transformSetOperationTree() see them --- else it'll just recurse
1822 * right back here!
1823 */
1824 sortClause = stmt->sortClause;
1825 limitOffset = stmt->limitOffset;
1826 limitCount = stmt->limitCount;
1827 lockingClause = stmt->lockingClause;
1828 withClause = stmt->withClause;
1829
1830 stmt->sortClause = NIL;
1831 stmt->limitOffset = NULL;
1832 stmt->limitCount = NULL;
1833 stmt->lockingClause = NIL;
1834 stmt->withClause = NULL;
1835
1836 /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
1837 if (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",
1844 linitial(lockingClause))->strength))));
1845
1846 /* Process the WITH clause independently of all else */
1847 if (withClause)
1848 {
1849 qry->hasRecursive = withClause->recursive;
1850 qry->cteList = transformWithClause(pstate, withClause);
1851 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
1852 }
1853
1854 /*
1855 * Recursively transform the components of the tree.
1856 */
1857 sostmt = castNode(SetOperationStmt,
1858 transformSetOperationTree(pstate, stmt, true, NULL));
1859 Assert(sostmt);
1860 qry->setOperations = (Node *) sostmt;
1861
1862 /*
1863 * Re-find leftmost SELECT (now it's a sub-query in rangetable)
1864 */
1865 node = sostmt->larg;
1866 while (node && IsA(node, SetOperationStmt))
1867 node = ((SetOperationStmt *) node)->larg;
1868 Assert(node && IsA(node, RangeTblRef));
1869 leftmostRTI = ((RangeTblRef *) node)->rtindex;
1870 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
1871 Assert(leftmostQuery != NULL);
1872
1873 /*
1874 * Generate dummy targetlist for outer query using column names of
1875 * leftmost select and common datatypes/collations of topmost set
1876 * operation. Also make lists of the dummy vars and their names for use
1877 * in parsing ORDER BY.
1878 *
1879 * Note: we use leftmostRTI as the varno of the dummy variables. It
1880 * shouldn't matter too much which RT index they have, as long as they
1881 * have one that corresponds to a real RT entry; else funny things may
1882 * happen when the tree is mashed by rule rewriting.
1883 */
1884 qry->targetList = NIL;
1885 targetvars = NIL;
1886 targetnames = NIL;
1887 sortnscolumns = (ParseNamespaceColumn *)
1888 palloc0(list_length(sostmt->colTypes) * sizeof(ParseNamespaceColumn));
1889 sortcolindex = 0;
1890
1891 forfour(lct, sostmt->colTypes,
1892 lcm, sostmt->colTypmods,
1893 lcc, sostmt->colCollations,
1894 left_tlist, leftmostQuery->targetList)
1895 {
1896 Oid colType = lfirst_oid(lct);
1897 int32 colTypmod = lfirst_int(lcm);
1898 Oid colCollation = lfirst_oid(lcc);
1899 TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
1900 char *colName;
1901 TargetEntry *tle;
1902 Var *var;
1903
1904 Assert(!lefttle->resjunk);
1905 colName = pstrdup(lefttle->resname);
1906 var = makeVar(leftmostRTI,
1907 lefttle->resno,
1908 colType,
1909 colTypmod,
1910 colCollation,
1911 0);
1912 var->location = exprLocation((Node *) lefttle->expr);
1913 tle = makeTargetEntry((Expr *) var,
1914 (AttrNumber) pstate->p_next_resno++,
1915 colName,
1916 false);
1917 qry->targetList = lappend(qry->targetList, tle);
1918 targetvars = lappend(targetvars, var);
1919 targetnames = lappend(targetnames, makeString(colName));
1920 sortnscolumns[sortcolindex].p_varno = leftmostRTI;
1921 sortnscolumns[sortcolindex].p_varattno = lefttle->resno;
1922 sortnscolumns[sortcolindex].p_vartype = colType;
1923 sortnscolumns[sortcolindex].p_vartypmod = colTypmod;
1924 sortnscolumns[sortcolindex].p_varcollid = colCollation;
1925 sortnscolumns[sortcolindex].p_varnosyn = leftmostRTI;
1926 sortnscolumns[sortcolindex].p_varattnosyn = lefttle->resno;
1927 sortcolindex++;
1928 }
1929
1930 /*
1931 * As a first step towards supporting sort clauses that are expressions
1932 * using the output columns, generate a namespace entry that makes the
1933 * output columns visible. A Join RTE node is handy for this, since we
1934 * can easily control the Vars generated upon matches.
1935 *
1936 * Note: we don't yet do anything useful with such cases, but at least
1937 * "ORDER BY upper(foo)" will draw the right error message rather than
1938 * "foo not found".
1939 */
1940 sv_rtable_length = list_length(pstate->p_rtable);
1941
1942 jnsitem = addRangeTableEntryForJoin(pstate,
1943 targetnames,
1944 sortnscolumns,
1945 JOIN_INNER,
1946 0,
1947 targetvars,
1948 NIL,
1949 NIL,
1950 NULL,
1951 NULL,
1952 false);
1953
1954 sv_namespace = pstate->p_namespace;
1955 pstate->p_namespace = NIL;
1956
1957 /* add jnsitem to column namespace only */
1958 addNSItemToQuery(pstate, jnsitem, false, false, true);
1959
1960 /*
1961 * For now, we don't support resjunk sort clauses on the output of a
1962 * setOperation tree --- you can only use the SQL92-spec options of
1963 * selecting an output column by name or number. Enforce by checking that
1964 * transformSortClause doesn't add any items to tlist. Note, if changing
1965 * this, add_setop_child_rel_equivalences() will need to be updated.
1966 */
1967 tllen = list_length(qry->targetList);
1968
1969 qry->sortClause = transformSortClause(pstate,
1970 sortClause,
1971 &qry->targetList,
1973 false /* allow SQL92 rules */ );
1974
1975 /* restore namespace, remove join RTE from rtable */
1976 pstate->p_namespace = sv_namespace;
1977 pstate->p_rtable = list_truncate(pstate->p_rtable, sv_rtable_length);
1978
1979 if (tllen != list_length(qry->targetList))
1980 ereport(ERROR,
1981 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1982 errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause"),
1983 errdetail("Only result column names can be used, not expressions or functions."),
1984 errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
1985 parser_errposition(pstate,
1986 exprLocation(list_nth(qry->targetList, tllen)))));
1987
1988 qry->limitOffset = transformLimitClause(pstate, limitOffset,
1989 EXPR_KIND_OFFSET, "OFFSET",
1990 stmt->limitOption);
1991 qry->limitCount = transformLimitClause(pstate, limitCount,
1992 EXPR_KIND_LIMIT, "LIMIT",
1993 stmt->limitOption);
1994 qry->limitOption = stmt->limitOption;
1995
1996 qry->rtable = pstate->p_rtable;
1997 qry->rteperminfos = pstate->p_rteperminfos;
1998 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1999
2000 qry->hasSubLinks = pstate->p_hasSubLinks;
2001 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
2002 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
2003 qry->hasAggs = pstate->p_hasAggs;
2004
2005 foreach(l, lockingClause)
2006 {
2007 transformLockingClause(pstate, qry,
2008 (LockingClause *) lfirst(l), false);
2009 }
2010
2011 assign_query_collations(pstate, qry);
2012
2013 /* this must be done after collations, for reliable comparison of exprs */
2014 if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
2015 parseCheckAggregates(pstate, qry);
2016
2017 return qry;
2018}
2019
2020/*
2021 * Make a SortGroupClause node for a SetOperationStmt's groupClauses
2022 *
2023 * If require_hash is true, the caller is indicating that they need hash
2024 * support or they will fail. So look extra hard for hash support.
2025 */
2027makeSortGroupClauseForSetOp(Oid rescoltype, bool require_hash)
2028{
2030 Oid sortop;
2031 Oid eqop;
2032 bool hashable;
2033
2034 /* determine the eqop and optional sortop */
2035 get_sort_group_operators(rescoltype,
2036 false, true, false,
2037 &sortop, &eqop, NULL,
2038 &hashable);
2039
2040 /*
2041 * The type cache doesn't believe that record is hashable (see
2042 * cache_record_field_properties()), but if the caller really needs hash
2043 * support, we can assume it does. Worst case, if any components of the
2044 * record don't support hashing, we will fail at execution.
2045 */
2046 if (require_hash && (rescoltype == RECORDOID || rescoltype == RECORDARRAYOID))
2047 hashable = true;
2048
2049 /* we don't have a tlist yet, so can't assign sortgrouprefs */
2050 grpcl->tleSortGroupRef = 0;
2051 grpcl->eqop = eqop;
2052 grpcl->sortop = sortop;
2053 grpcl->reverse_sort = false; /* Sort-op is "less than", or InvalidOid */
2054 grpcl->nulls_first = false; /* OK with or without sortop */
2055 grpcl->hashable = hashable;
2056
2057 return grpcl;
2058}
2059
2060/*
2061 * transformSetOperationTree
2062 * Recursively transform leaves and internal nodes of a set-op tree
2063 *
2064 * In addition to returning the transformed node, if targetlist isn't NULL
2065 * then we return a list of its non-resjunk TargetEntry nodes. For a leaf
2066 * set-op node these are the actual targetlist entries; otherwise they are
2067 * dummy entries created to carry the type, typmod, collation, and location
2068 * (for error messages) of each output column of the set-op node. This info
2069 * is needed only during the internal recursion of this function, so outside
2070 * callers pass NULL for targetlist. Note: the reason for passing the
2071 * actual targetlist entries of a leaf node is so that upper levels can
2072 * replace UNKNOWN Consts with properly-coerced constants.
2073 */
2074static Node *
2076 bool isTopLevel, List **targetlist)
2077{
2078 bool isLeaf;
2079
2081
2082 /* Guard against stack overflow due to overly complex set-expressions */
2084
2085 /*
2086 * Validity-check both leaf and internal SELECTs for disallowed ops.
2087 */
2088 if (stmt->intoClause)
2089 ereport(ERROR,
2090 (errcode(ERRCODE_SYNTAX_ERROR),
2091 errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
2092 parser_errposition(pstate,
2093 exprLocation((Node *) stmt->intoClause))));
2094
2095 /* We don't support FOR UPDATE/SHARE with set ops at the moment. */
2096 if (stmt->lockingClause)
2097 ereport(ERROR,
2098 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2099 /*------
2100 translator: %s is a SQL row locking clause such as FOR UPDATE */
2101 errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
2103 linitial(stmt->lockingClause))->strength))));
2104
2105 /*
2106 * If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE,
2107 * or WITH clauses attached, we need to treat it like a leaf node to
2108 * generate an independent sub-Query tree. Otherwise, it can be
2109 * represented by a SetOperationStmt node underneath the parent Query.
2110 */
2111 if (stmt->op == SETOP_NONE)
2112 {
2113 Assert(stmt->larg == NULL && stmt->rarg == NULL);
2114 isLeaf = true;
2115 }
2116 else
2117 {
2118 Assert(stmt->larg != NULL && stmt->rarg != NULL);
2119 if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
2120 stmt->lockingClause || stmt->withClause)
2121 isLeaf = true;
2122 else
2123 isLeaf = false;
2124 }
2125
2126 if (isLeaf)
2127 {
2128 /* Process leaf SELECT */
2129 Query *selectQuery;
2130 ParseNamespaceItem *nsitem;
2131 RangeTblRef *rtr;
2132 ListCell *tl;
2133
2134 /*
2135 * Transform SelectStmt into a Query.
2136 *
2137 * This works the same as SELECT transformation normally would, except
2138 * that we prevent resolving unknown-type outputs as TEXT. This does
2139 * not change the subquery's semantics since if the column type
2140 * matters semantically, it would have been resolved to something else
2141 * anyway. Doing this lets us resolve such outputs using
2142 * select_common_type(), below.
2143 *
2144 * Note: previously transformed sub-queries don't affect the parsing
2145 * of this sub-query, because they are not in the toplevel pstate's
2146 * namespace list.
2147 */
2148 selectQuery = parse_sub_analyze((Node *) stmt, pstate,
2149 NULL, false, false);
2150
2151 /*
2152 * Check for bogus references to Vars on the current query level (but
2153 * upper-level references are okay). Normally this can't happen
2154 * because the namespace will be empty, but it could happen if we are
2155 * inside a rule.
2156 */
2157 if (pstate->p_namespace)
2158 {
2159 if (contain_vars_of_level((Node *) selectQuery, 1))
2160 ereport(ERROR,
2161 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2162 errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
2163 parser_errposition(pstate,
2164 locate_var_of_level((Node *) selectQuery, 1))));
2165 }
2166
2167 /*
2168 * Extract a list of the non-junk TLEs for upper-level processing.
2169 */
2170 if (targetlist)
2171 {
2172 *targetlist = NIL;
2173 foreach(tl, selectQuery->targetList)
2174 {
2175 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2176
2177 if (!tle->resjunk)
2178 *targetlist = lappend(*targetlist, tle);
2179 }
2180 }
2181
2182 /*
2183 * Make the leaf query be a subquery in the top-level rangetable.
2184 */
2185 nsitem = addRangeTableEntryForSubquery(pstate,
2186 selectQuery,
2187 NULL,
2188 false,
2189 false);
2190
2191 /*
2192 * Return a RangeTblRef to replace the SelectStmt in the set-op tree.
2193 */
2194 rtr = makeNode(RangeTblRef);
2195 rtr->rtindex = nsitem->p_rtindex;
2196 return (Node *) rtr;
2197 }
2198 else
2199 {
2200 /* Process an internal node (set operation node) */
2202 List *ltargetlist;
2203 List *rtargetlist;
2204 ListCell *ltl;
2205 ListCell *rtl;
2206 const char *context;
2207 bool recursive = (pstate->p_parent_cte &&
2208 pstate->p_parent_cte->cterecursive);
2209
2210 context = (stmt->op == SETOP_UNION ? "UNION" :
2211 (stmt->op == SETOP_INTERSECT ? "INTERSECT" :
2212 "EXCEPT"));
2213
2214 op->op = stmt->op;
2215 op->all = stmt->all;
2216
2217 /*
2218 * Recursively transform the left child node.
2219 */
2220 op->larg = transformSetOperationTree(pstate, stmt->larg,
2221 false,
2222 &ltargetlist);
2223
2224 /*
2225 * If we are processing a recursive union query, now is the time to
2226 * examine the non-recursive term's output columns and mark the
2227 * containing CTE as having those result columns. We should do this
2228 * only at the topmost setop of the CTE, of course.
2229 */
2230 if (isTopLevel && recursive)
2231 determineRecursiveColTypes(pstate, op->larg, ltargetlist);
2232
2233 /*
2234 * Recursively transform the right child node.
2235 */
2236 op->rarg = transformSetOperationTree(pstate, stmt->rarg,
2237 false,
2238 &rtargetlist);
2239
2240 /*
2241 * Verify that the two children have the same number of non-junk
2242 * columns, and determine the types of the merged output columns.
2243 */
2244 if (list_length(ltargetlist) != list_length(rtargetlist))
2245 ereport(ERROR,
2246 (errcode(ERRCODE_SYNTAX_ERROR),
2247 errmsg("each %s query must have the same number of columns",
2248 context),
2249 parser_errposition(pstate,
2250 exprLocation((Node *) rtargetlist))));
2251
2252 if (targetlist)
2253 *targetlist = NIL;
2254 op->colTypes = NIL;
2255 op->colTypmods = NIL;
2256 op->colCollations = NIL;
2257 op->groupClauses = NIL;
2258 forboth(ltl, ltargetlist, rtl, rtargetlist)
2259 {
2260 TargetEntry *ltle = (TargetEntry *) lfirst(ltl);
2261 TargetEntry *rtle = (TargetEntry *) lfirst(rtl);
2262 Node *lcolnode = (Node *) ltle->expr;
2263 Node *rcolnode = (Node *) rtle->expr;
2264 Oid lcoltype = exprType(lcolnode);
2265 Oid rcoltype = exprType(rcolnode);
2266 Node *bestexpr;
2267 int bestlocation;
2268 Oid rescoltype;
2269 int32 rescoltypmod;
2270 Oid rescolcoll;
2271
2272 /* select common type, same as CASE et al */
2273 rescoltype = select_common_type(pstate,
2274 list_make2(lcolnode, rcolnode),
2275 context,
2276 &bestexpr);
2277 bestlocation = exprLocation(bestexpr);
2278
2279 /*
2280 * Verify the coercions are actually possible. If not, we'd fail
2281 * later anyway, but we want to fail now while we have sufficient
2282 * context to produce an error cursor position.
2283 *
2284 * For all non-UNKNOWN-type cases, we verify coercibility but we
2285 * don't modify the child's expression, for fear of changing the
2286 * child query's semantics.
2287 *
2288 * If a child expression is an UNKNOWN-type Const or Param, we
2289 * want to replace it with the coerced expression. This can only
2290 * happen when the child is a leaf set-op node. It's safe to
2291 * replace the expression because if the child query's semantics
2292 * depended on the type of this output column, it'd have already
2293 * coerced the UNKNOWN to something else. We want to do this
2294 * because (a) we want to verify that a Const is valid for the
2295 * target type, or resolve the actual type of an UNKNOWN Param,
2296 * and (b) we want to avoid unnecessary discrepancies between the
2297 * output type of the child query and the resolved target type.
2298 * Such a discrepancy would disable optimization in the planner.
2299 *
2300 * If it's some other UNKNOWN-type node, eg a Var, we do nothing
2301 * (knowing that coerce_to_common_type would fail). The planner
2302 * is sometimes able to fold an UNKNOWN Var to a constant before
2303 * it has to coerce the type, so failing now would just break
2304 * cases that might work.
2305 */
2306 if (lcoltype != UNKNOWNOID)
2307 lcolnode = coerce_to_common_type(pstate, lcolnode,
2308 rescoltype, context);
2309 else if (IsA(lcolnode, Const) ||
2310 IsA(lcolnode, Param))
2311 {
2312 lcolnode = coerce_to_common_type(pstate, lcolnode,
2313 rescoltype, context);
2314 ltle->expr = (Expr *) lcolnode;
2315 }
2316
2317 if (rcoltype != UNKNOWNOID)
2318 rcolnode = coerce_to_common_type(pstate, rcolnode,
2319 rescoltype, context);
2320 else if (IsA(rcolnode, Const) ||
2321 IsA(rcolnode, Param))
2322 {
2323 rcolnode = coerce_to_common_type(pstate, rcolnode,
2324 rescoltype, context);
2325 rtle->expr = (Expr *) rcolnode;
2326 }
2327
2328 rescoltypmod = select_common_typmod(pstate,
2329 list_make2(lcolnode, rcolnode),
2330 rescoltype);
2331
2332 /*
2333 * Select common collation. A common collation is required for
2334 * all set operators except UNION ALL; see SQL:2008 7.13 <query
2335 * expression> Syntax Rule 15c. (If we fail to identify a common
2336 * collation for a UNION ALL column, the colCollations element
2337 * will be set to InvalidOid, which may result in a runtime error
2338 * if something at a higher query level wants to use the column's
2339 * collation.)
2340 */
2341 rescolcoll = select_common_collation(pstate,
2342 list_make2(lcolnode, rcolnode),
2343 (op->op == SETOP_UNION && op->all));
2344
2345 /* emit results */
2346 op->colTypes = lappend_oid(op->colTypes, rescoltype);
2347 op->colTypmods = lappend_int(op->colTypmods, rescoltypmod);
2348 op->colCollations = lappend_oid(op->colCollations, rescolcoll);
2349
2350 /*
2351 * For all cases except UNION ALL, identify the grouping operators
2352 * (and, if available, sorting operators) that will be used to
2353 * eliminate duplicates.
2354 */
2355 if (op->op != SETOP_UNION || !op->all)
2356 {
2357 ParseCallbackState pcbstate;
2358
2359 setup_parser_errposition_callback(&pcbstate, pstate,
2360 bestlocation);
2361
2362 /*
2363 * If it's a recursive union, we need to require hashing
2364 * support.
2365 */
2366 op->groupClauses = lappend(op->groupClauses,
2367 makeSortGroupClauseForSetOp(rescoltype, recursive));
2368
2370 }
2371
2372 /*
2373 * Construct a dummy tlist entry to return. We use a SetToDefault
2374 * node for the expression, since it carries exactly the fields
2375 * needed, but any other expression node type would do as well.
2376 */
2377 if (targetlist)
2378 {
2379 SetToDefault *rescolnode = makeNode(SetToDefault);
2380 TargetEntry *restle;
2381
2382 rescolnode->typeId = rescoltype;
2383 rescolnode->typeMod = rescoltypmod;
2384 rescolnode->collation = rescolcoll;
2385 rescolnode->location = bestlocation;
2386 restle = makeTargetEntry((Expr *) rescolnode,
2387 0, /* no need to set resno */
2388 NULL,
2389 false);
2390 *targetlist = lappend(*targetlist, restle);
2391 }
2392 }
2393
2394 return (Node *) op;
2395 }
2396}
2397
2398/*
2399 * Process the outputs of the non-recursive term of a recursive union
2400 * to set up the parent CTE's columns
2401 */
2402static void
2403determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
2404{
2405 Node *node;
2406 int leftmostRTI;
2407 Query *leftmostQuery;
2408 List *targetList;
2409 ListCell *left_tlist;
2410 ListCell *nrtl;
2411 int next_resno;
2412
2413 /*
2414 * Find leftmost leaf SELECT
2415 */
2416 node = larg;
2417 while (node && IsA(node, SetOperationStmt))
2418 node = ((SetOperationStmt *) node)->larg;
2419 Assert(node && IsA(node, RangeTblRef));
2420 leftmostRTI = ((RangeTblRef *) node)->rtindex;
2421 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
2422 Assert(leftmostQuery != NULL);
2423
2424 /*
2425 * Generate dummy targetlist using column names of leftmost select and
2426 * dummy result expressions of the non-recursive term.
2427 */
2428 targetList = NIL;
2429 next_resno = 1;
2430
2431 forboth(nrtl, nrtargetlist, left_tlist, leftmostQuery->targetList)
2432 {
2433 TargetEntry *nrtle = (TargetEntry *) lfirst(nrtl);
2434 TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
2435 char *colName;
2436 TargetEntry *tle;
2437
2438 Assert(!lefttle->resjunk);
2439 colName = pstrdup(lefttle->resname);
2440 tle = makeTargetEntry(nrtle->expr,
2441 next_resno++,
2442 colName,
2443 false);
2444 targetList = lappend(targetList, tle);
2445 }
2446
2447 /* Now build CTE's output column info using dummy targetlist */
2448 analyzeCTETargetList(pstate, pstate->p_parent_cte, targetList);
2449}
2450
2451
2452/*
2453 * transformReturnStmt -
2454 * transforms a return statement
2455 */
2456static Query *
2458{
2459 Query *qry = makeNode(Query);
2460
2461 qry->commandType = CMD_SELECT;
2462 qry->isReturn = true;
2463
2465 1, NULL, false));
2466
2467 if (pstate->p_resolve_unknowns)
2469 qry->rtable = pstate->p_rtable;
2470 qry->rteperminfos = pstate->p_rteperminfos;
2471 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
2472 qry->hasSubLinks = pstate->p_hasSubLinks;
2473 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
2474 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
2475 qry->hasAggs = pstate->p_hasAggs;
2476
2477 assign_query_collations(pstate, qry);
2478
2479 return qry;
2480}
2481
2482
2483/*
2484 * transformUpdateStmt -
2485 * transforms an update statement
2486 */
2487static Query *
2489{
2490 Query *qry = makeNode(Query);
2491 ParseNamespaceItem *nsitem;
2492 Node *qual;
2493
2494 qry->commandType = CMD_UPDATE;
2495 pstate->p_is_insert = false;
2496
2497 /* process the WITH clause independently of all else */
2498 if (stmt->withClause)
2499 {
2500 qry->hasRecursive = stmt->withClause->recursive;
2501 qry->cteList = transformWithClause(pstate, stmt->withClause);
2502 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
2503 }
2504
2505 qry->resultRelation = setTargetTable(pstate, stmt->relation,
2506 stmt->relation->inh,
2507 true,
2508 ACL_UPDATE);
2509 nsitem = pstate->p_target_nsitem;
2510
2511 /* subqueries in FROM cannot access the result relation */
2512 nsitem->p_lateral_only = true;
2513 nsitem->p_lateral_ok = false;
2514
2515 /*
2516 * the FROM clause is non-standard SQL syntax. We used to be able to do
2517 * this with REPLACE in POSTQUEL so we keep the feature.
2518 */
2519 transformFromClause(pstate, stmt->fromClause);
2520
2521 /* remaining clauses can reference the result relation normally */
2522 nsitem->p_lateral_only = false;
2523 nsitem->p_lateral_ok = true;
2524
2525 qual = transformWhereClause(pstate, stmt->whereClause,
2526 EXPR_KIND_WHERE, "WHERE");
2527
2528 transformReturningClause(pstate, qry, stmt->returningClause,
2530
2531 /*
2532 * Now we are done with SELECT-like processing, and can get on with
2533 * transforming the target list to match the UPDATE target columns.
2534 */
2535 qry->targetList = transformUpdateTargetList(pstate, stmt->targetList);
2536
2537 qry->rtable = pstate->p_rtable;
2538 qry->rteperminfos = pstate->p_rteperminfos;
2539 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
2540
2541 qry->hasTargetSRFs = pstate->p_hasTargetSRFs;
2542 qry->hasSubLinks = pstate->p_hasSubLinks;
2543
2544 assign_query_collations(pstate, qry);
2545
2546 return qry;
2547}
2548
2549/*
2550 * transformUpdateTargetList -
2551 * handle SET clause in UPDATE/MERGE/INSERT ... ON CONFLICT UPDATE
2552 */
2553List *
2555{
2556 List *tlist = NIL;
2557 RTEPermissionInfo *target_perminfo;
2558 ListCell *orig_tl;
2559 ListCell *tl;
2560
2561 tlist = transformTargetList(pstate, origTlist,
2563
2564 /* Prepare to assign non-conflicting resnos to resjunk attributes */
2567
2568 /* Prepare non-junk columns for assignment to target table */
2569 target_perminfo = pstate->p_target_nsitem->p_perminfo;
2570 orig_tl = list_head(origTlist);
2571
2572 foreach(tl, tlist)
2573 {
2574 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2575 ResTarget *origTarget;
2576 int attrno;
2577
2578 if (tle->resjunk)
2579 {
2580 /*
2581 * Resjunk nodes need no additional processing, but be sure they
2582 * have resnos that do not match any target columns; else rewriter
2583 * or planner might get confused. They don't need a resname
2584 * either.
2585 */
2586 tle->resno = (AttrNumber) pstate->p_next_resno++;
2587 tle->resname = NULL;
2588 continue;
2589 }
2590 if (orig_tl == NULL)
2591 elog(ERROR, "UPDATE target count mismatch --- internal error");
2592 origTarget = lfirst_node(ResTarget, orig_tl);
2593
2594 attrno = attnameAttNum(pstate->p_target_relation,
2595 origTarget->name, true);
2596 if (attrno == InvalidAttrNumber)
2597 ereport(ERROR,
2598 (errcode(ERRCODE_UNDEFINED_COLUMN),
2599 errmsg("column \"%s\" of relation \"%s\" does not exist",
2600 origTarget->name,
2602 (origTarget->indirection != NIL &&
2603 strcmp(origTarget->name, pstate->p_target_nsitem->p_names->aliasname) == 0) ?
2604 errhint("SET target columns cannot be qualified with the relation name.") : 0,
2605 parser_errposition(pstate, origTarget->location)));
2606
2607 updateTargetListEntry(pstate, tle, origTarget->name,
2608 attrno,
2609 origTarget->indirection,
2610 origTarget->location);
2611
2612 /* Mark the target column as requiring update permissions */
2613 target_perminfo->updatedCols = bms_add_member(target_perminfo->updatedCols,
2615
2616 orig_tl = lnext(origTlist, orig_tl);
2617 }
2618 if (orig_tl != NULL)
2619 elog(ERROR, "UPDATE target count mismatch --- internal error");
2620
2621 return tlist;
2622}
2623
2624/*
2625 * addNSItemForReturning -
2626 * add a ParseNamespaceItem for the OLD or NEW alias in RETURNING.
2627 */
2628static void
2629addNSItemForReturning(ParseState *pstate, const char *aliasname,
2630 VarReturningType returning_type)
2631{
2632 List *colnames;
2633 int numattrs;
2634 ParseNamespaceColumn *nscolumns;
2635 ParseNamespaceItem *nsitem;
2636
2637 /* copy per-column data from the target relation */
2638 colnames = pstate->p_target_nsitem->p_rte->eref->colnames;
2639 numattrs = list_length(colnames);
2640
2641 nscolumns = (ParseNamespaceColumn *)
2642 palloc(numattrs * sizeof(ParseNamespaceColumn));
2643
2644 memcpy(nscolumns, pstate->p_target_nsitem->p_nscolumns,
2645 numattrs * sizeof(ParseNamespaceColumn));
2646
2647 /* mark all columns as returning OLD/NEW */
2648 for (int i = 0; i < numattrs; i++)
2649 nscolumns[i].p_varreturningtype = returning_type;
2650
2651 /* build the nsitem, copying most fields from the target relation */
2652 nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
2653 nsitem->p_names = makeAlias(aliasname, colnames);
2654 nsitem->p_rte = pstate->p_target_nsitem->p_rte;
2655 nsitem->p_rtindex = pstate->p_target_nsitem->p_rtindex;
2656 nsitem->p_perminfo = pstate->p_target_nsitem->p_perminfo;
2657 nsitem->p_nscolumns = nscolumns;
2658 nsitem->p_returning_type = returning_type;
2659
2660 /* add it to the query namespace as a table-only item */
2661 addNSItemToQuery(pstate, nsitem, false, true, false);
2662}
2663
2664/*
2665 * transformReturningClause -
2666 * handle a RETURNING clause in INSERT/UPDATE/DELETE/MERGE
2667 */
2668void
2670 ReturningClause *returningClause,
2671 ParseExprKind exprKind)
2672{
2673 int save_nslen = list_length(pstate->p_namespace);
2674 int save_next_resno;
2675
2676 if (returningClause == NULL)
2677 return; /* nothing to do */
2678
2679 /*
2680 * Scan RETURNING WITH(...) options for OLD/NEW alias names. Complain if
2681 * there is any conflict with existing relations.
2682 */
2683 foreach_node(ReturningOption, option, returningClause->options)
2684 {
2685 switch (option->option)
2686 {
2688 if (qry->returningOldAlias != NULL)
2689 ereport(ERROR,
2690 errcode(ERRCODE_SYNTAX_ERROR),
2691 /* translator: %s is OLD or NEW */
2692 errmsg("%s cannot be specified multiple times", "OLD"),
2693 parser_errposition(pstate, option->location));
2694 qry->returningOldAlias = option->value;
2695 break;
2696
2698 if (qry->returningNewAlias != NULL)
2699 ereport(ERROR,
2700 errcode(ERRCODE_SYNTAX_ERROR),
2701 /* translator: %s is OLD or NEW */
2702 errmsg("%s cannot be specified multiple times", "NEW"),
2703 parser_errposition(pstate, option->location));
2704 qry->returningNewAlias = option->value;
2705 break;
2706
2707 default:
2708 elog(ERROR, "unrecognized returning option: %d", option->option);
2709 }
2710
2711 if (refnameNamespaceItem(pstate, NULL, option->value, -1, NULL) != NULL)
2712 ereport(ERROR,
2713 errcode(ERRCODE_DUPLICATE_ALIAS),
2714 errmsg("table name \"%s\" specified more than once",
2715 option->value),
2716 parser_errposition(pstate, option->location));
2717
2718 addNSItemForReturning(pstate, option->value,
2719 option->option == RETURNING_OPTION_OLD ?
2721 }
2722
2723 /*
2724 * If OLD/NEW alias names weren't explicitly specified, use "old"/"new"
2725 * unless masked by existing relations.
2726 */
2727 if (qry->returningOldAlias == NULL &&
2728 refnameNamespaceItem(pstate, NULL, "old", -1, NULL) == NULL)
2729 {
2730 qry->returningOldAlias = "old";
2732 }
2733 if (qry->returningNewAlias == NULL &&
2734 refnameNamespaceItem(pstate, NULL, "new", -1, NULL) == NULL)
2735 {
2736 qry->returningNewAlias = "new";
2738 }
2739
2740 /*
2741 * We need to assign resnos starting at one in the RETURNING list. Save
2742 * and restore the main tlist's value of p_next_resno, just in case
2743 * someone looks at it later (probably won't happen).
2744 */
2745 save_next_resno = pstate->p_next_resno;
2746 pstate->p_next_resno = 1;
2747
2748 /* transform RETURNING expressions identically to a SELECT targetlist */
2749 qry->returningList = transformTargetList(pstate,
2750 returningClause->exprs,
2751 exprKind);
2752
2753 /*
2754 * Complain if the nonempty tlist expanded to nothing (which is possible
2755 * if it contains only a star-expansion of a zero-column table). If we
2756 * allow this, the parsed Query will look like it didn't have RETURNING,
2757 * with results that would probably surprise the user.
2758 */
2759 if (qry->returningList == NIL)
2760 ereport(ERROR,
2761 (errcode(ERRCODE_SYNTAX_ERROR),
2762 errmsg("RETURNING must have at least one column"),
2763 parser_errposition(pstate,
2764 exprLocation(linitial(returningClause->exprs)))));
2765
2766 /* mark column origins */
2768
2769 /* resolve any still-unresolved output columns as being type text */
2770 if (pstate->p_resolve_unknowns)
2772
2773 /* restore state */
2774 pstate->p_namespace = list_truncate(pstate->p_namespace, save_nslen);
2775 pstate->p_next_resno = save_next_resno;
2776}
2777
2778
2779/*
2780 * transformPLAssignStmt -
2781 * transform a PL/pgSQL assignment statement
2782 *
2783 * If there is no opt_indirection, the transformed statement looks like
2784 * "SELECT a_expr ...", except the expression has been cast to the type of
2785 * the target. With indirection, it's still a SELECT, but the expression will
2786 * incorporate FieldStore and/or assignment SubscriptingRef nodes to compute a
2787 * new value for a container-type variable represented by the target. The
2788 * expression references the target as the container source.
2789 */
2790static Query *
2792{
2793 Query *qry;
2794 ColumnRef *cref = makeNode(ColumnRef);
2795 List *indirection = stmt->indirection;
2796 int nnames = stmt->nnames;
2797 Node *target;
2798 SelectStmtPassthrough passthru;
2799 bool save_resolve_unknowns;
2800
2801 /*
2802 * First, construct a ColumnRef for the target variable. If the target
2803 * has more than one dotted name, we have to pull the extra names out of
2804 * the indirection list.
2805 */
2806 cref->fields = list_make1(makeString(stmt->name));
2807 cref->location = stmt->location;
2808 if (nnames > 1)
2809 {
2810 /* avoid munging the raw parsetree */
2811 indirection = list_copy(indirection);
2812 while (--nnames > 0 && indirection != NIL)
2813 {
2814 Node *ind = (Node *) linitial(indirection);
2815
2816 if (!IsA(ind, String))
2817 elog(ERROR, "invalid name count in PLAssignStmt");
2818 cref->fields = lappend(cref->fields, ind);
2819 indirection = list_delete_first(indirection);
2820 }
2821 }
2822
2823 /*
2824 * Transform the target reference. Typically we will get back a Param
2825 * node, but there's no reason to be too picky about its type. (Note that
2826 * we must do this before calling transformSelectStmt. It's tempting to
2827 * do it inside transformPLAssignStmtTarget, but we need to do it before
2828 * adding any FROM tables to the pstate's namespace, else we might wrongly
2829 * resolve the target as a table column.)
2830 */
2831 target = transformExpr(pstate, (Node *) cref,
2833
2834 /* Set up passthrough data for transformPLAssignStmtTarget */
2835 passthru.stmt = stmt;
2836 passthru.target = target;
2837 passthru.indirection = indirection;
2838
2839 /*
2840 * To avoid duplicating a lot of code, we use transformSelectStmt to do
2841 * almost all of the work. However, we need to do additional processing
2842 * on the SELECT's targetlist after it's been transformed, but before
2843 * possible addition of targetlist items for ORDER BY or GROUP BY.
2844 * transformSelectStmt knows it should call transformPLAssignStmtTarget if
2845 * it's passed a passthru argument.
2846 *
2847 * Also, disable resolution of unknown-type tlist items; PL/pgSQL wants to
2848 * deal with that itself.
2849 */
2850 save_resolve_unknowns = pstate->p_resolve_unknowns;
2851 pstate->p_resolve_unknowns = false;
2852 qry = transformSelectStmt(pstate, stmt->val, &passthru);
2853 pstate->p_resolve_unknowns = save_resolve_unknowns;
2854
2855 return qry;
2856}
2857
2858/*
2859 * Callback function to adjust a SELECT's tlist to make the output suitable
2860 * for assignment to a PLAssignStmt's target variable.
2861 *
2862 * Note: we actually modify the tle->expr in-place, but the function's API
2863 * is set up to not presume that.
2864 */
2865static List *
2867 SelectStmtPassthrough *passthru)
2868{
2869 PLAssignStmt *stmt = passthru->stmt;
2870 Node *target = passthru->target;
2871 List *indirection = passthru->indirection;
2872 Oid targettype;
2873 int32 targettypmod;
2874 Oid targetcollation;
2875 TargetEntry *tle;
2876 Oid type_id;
2877
2878 targettype = exprType(target);
2879 targettypmod = exprTypmod(target);
2880 targetcollation = exprCollation(target);
2881
2882 /* we should have exactly one targetlist item */
2883 if (list_length(tlist) != 1)
2884 ereport(ERROR,
2885 (errcode(ERRCODE_SYNTAX_ERROR),
2886 errmsg_plural("assignment source returned %d column",
2887 "assignment source returned %d columns",
2888 list_length(tlist),
2889 list_length(tlist))));
2890
2891 tle = linitial_node(TargetEntry, tlist);
2892
2893 /*
2894 * This next bit is similar to transformAssignedExpr; the key difference
2895 * is we use COERCION_PLPGSQL not COERCION_ASSIGNMENT.
2896 */
2897 type_id = exprType((Node *) tle->expr);
2898
2900
2901 if (indirection)
2902 {
2903 tle->expr = (Expr *)
2905 target,
2906 stmt->name,
2907 false,
2908 targettype,
2909 targettypmod,
2910 targetcollation,
2911 indirection,
2912 list_head(indirection),
2913 (Node *) tle->expr,
2915 exprLocation(target));
2916 }
2917 else if (targettype != type_id &&
2918 (targettype == RECORDOID || ISCOMPLEX(targettype)) &&
2919 (type_id == RECORDOID || ISCOMPLEX(type_id)))
2920 {
2921 /*
2922 * Hack: do not let coerce_to_target_type() deal with inconsistent
2923 * composite types. Just pass the expression result through as-is,
2924 * and let the PL/pgSQL executor do the conversion its way. This is
2925 * rather bogus, but it's needed for backwards compatibility.
2926 */
2927 }
2928 else
2929 {
2930 /*
2931 * For normal non-qualified target column, do type checking and
2932 * coercion.
2933 */
2934 Node *orig_expr = (Node *) tle->expr;
2935
2936 tle->expr = (Expr *)
2937 coerce_to_target_type(pstate,
2938 orig_expr, type_id,
2939 targettype, targettypmod,
2942 -1);
2943 /* With COERCION_PLPGSQL, this error is probably unreachable */
2944 if (tle->expr == NULL)
2945 ereport(ERROR,
2946 (errcode(ERRCODE_DATATYPE_MISMATCH),
2947 errmsg("variable \"%s\" is of type %s"
2948 " but expression is of type %s",
2949 stmt->name,
2950 format_type_be(targettype),
2951 format_type_be(type_id)),
2952 errhint("You will need to rewrite or cast the expression."),
2953 parser_errposition(pstate, exprLocation(orig_expr))));
2954 }
2955
2956 pstate->p_expr_kind = EXPR_KIND_NONE;
2957
2958 return list_make1(tle);
2959}
2960
2961
2962/*
2963 * transformDeclareCursorStmt -
2964 * transform a DECLARE CURSOR Statement
2965 *
2966 * DECLARE CURSOR is like other utility statements in that we emit it as a
2967 * CMD_UTILITY Query node; however, we must first transform the contained
2968 * query. We used to postpone that until execution, but it's really necessary
2969 * to do it during the normal parse analysis phase to ensure that side effects
2970 * of parser hooks happen at the expected time.
2971 */
2972static Query *
2974{
2975 Query *result;
2976 Query *query;
2977
2978 if ((stmt->options & CURSOR_OPT_SCROLL) &&
2979 (stmt->options & CURSOR_OPT_NO_SCROLL))
2980 ereport(ERROR,
2981 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
2982 /* translator: %s is a SQL keyword */
2983 errmsg("cannot specify both %s and %s",
2984 "SCROLL", "NO SCROLL")));
2985
2986 if ((stmt->options & CURSOR_OPT_ASENSITIVE) &&
2987 (stmt->options & CURSOR_OPT_INSENSITIVE))
2988 ereport(ERROR,
2989 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
2990 /* translator: %s is a SQL keyword */
2991 errmsg("cannot specify both %s and %s",
2992 "ASENSITIVE", "INSENSITIVE")));
2993
2994 /* Transform contained query, not allowing SELECT INTO */
2995 query = transformStmt(pstate, stmt->query);
2996 stmt->query = (Node *) query;
2997
2998 /* Grammar should not have allowed anything but SELECT */
2999 if (!IsA(query, Query) ||
3000 query->commandType != CMD_SELECT)
3001 elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR");
3002
3003 /*
3004 * We also disallow data-modifying WITH in a cursor. (This could be
3005 * allowed, but the semantics of when the updates occur might be
3006 * surprising.)
3007 */
3008 if (query->hasModifyingCTE)
3009 ereport(ERROR,
3010 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3011 errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH")));
3012
3013 /* FOR UPDATE and WITH HOLD are not compatible */
3014 if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD))
3015 ereport(ERROR,
3016 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3017 /*------
3018 translator: %s is a SQL row locking clause such as FOR UPDATE */
3019 errmsg("DECLARE CURSOR WITH HOLD ... %s is not supported",
3021 linitial(query->rowMarks))->strength)),
3022 errdetail("Holdable cursors must be READ ONLY.")));
3023
3024 /* FOR UPDATE and SCROLL are not compatible */
3025 if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_SCROLL))
3026 ereport(ERROR,
3027 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3028 /*------
3029 translator: %s is a SQL row locking clause such as FOR UPDATE */
3030 errmsg("DECLARE SCROLL CURSOR ... %s is not supported",
3032 linitial(query->rowMarks))->strength)),
3033 errdetail("Scrollable cursors must be READ ONLY.")));
3034
3035 /* FOR UPDATE and INSENSITIVE are not compatible */
3036 if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_INSENSITIVE))
3037 ereport(ERROR,
3038 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
3039 /*------
3040 translator: %s is a SQL row locking clause such as FOR UPDATE */
3041 errmsg("DECLARE INSENSITIVE CURSOR ... %s is not valid",
3043 linitial(query->rowMarks))->strength)),
3044 errdetail("Insensitive cursors must be READ ONLY.")));
3045
3046 /* represent the command as a utility Query */
3047 result = makeNode(Query);
3048 result->commandType = CMD_UTILITY;
3049 result->utilityStmt = (Node *) stmt;
3050
3051 return result;
3052}
3053
3054
3055/*
3056 * transformExplainStmt -
3057 * transform an EXPLAIN Statement
3058 *
3059 * EXPLAIN is like other utility statements in that we emit it as a
3060 * CMD_UTILITY Query node; however, we must first transform the contained
3061 * query. We used to postpone that until execution, but it's really necessary
3062 * to do it during the normal parse analysis phase to ensure that side effects
3063 * of parser hooks happen at the expected time.
3064 */
3065static Query *
3067{
3068 Query *result;
3069 bool generic_plan = false;
3070 Oid *paramTypes = NULL;
3071 int numParams = 0;
3072
3073 /*
3074 * If we have no external source of parameter definitions, and the
3075 * GENERIC_PLAN option is specified, then accept variable parameter
3076 * definitions (similarly to PREPARE, for example).
3077 */
3078 if (pstate->p_paramref_hook == NULL)
3079 {
3080 ListCell *lc;
3081
3082 foreach(lc, stmt->options)
3083 {
3084 DefElem *opt = (DefElem *) lfirst(lc);
3085
3086 if (strcmp(opt->defname, "generic_plan") == 0)
3087 generic_plan = defGetBoolean(opt);
3088 /* don't "break", as we want the last value */
3089 }
3090 if (generic_plan)
3091 setup_parse_variable_parameters(pstate, &paramTypes, &numParams);
3092 }
3093
3094 /* transform contained query, allowing SELECT INTO */
3095 stmt->query = (Node *) transformOptionalSelectInto(pstate, stmt->query);
3096
3097 /* make sure all is well with parameter types */
3098 if (generic_plan)
3099 check_variable_parameters(pstate, (Query *) stmt->query);
3100
3101 /* represent the command as a utility Query */
3102 result = makeNode(Query);
3103 result->commandType = CMD_UTILITY;
3104 result->utilityStmt = (Node *) stmt;
3105
3106 return result;
3107}
3108
3109
3110/*
3111 * transformCreateTableAsStmt -
3112 * transform a CREATE TABLE AS, SELECT ... INTO, or CREATE MATERIALIZED VIEW
3113 * Statement
3114 *
3115 * As with DECLARE CURSOR and EXPLAIN, transform the contained statement now.
3116 */
3117static Query *
3119{
3120 Query *result;
3121 Query *query;
3122
3123 /* transform contained query, not allowing SELECT INTO */
3124 query = transformStmt(pstate, stmt->query);
3125 stmt->query = (Node *) query;
3126
3127 /* additional work needed for CREATE MATERIALIZED VIEW */
3128 if (stmt->objtype == OBJECT_MATVIEW)
3129 {
3130 /*
3131 * Prohibit a data-modifying CTE in the query used to create a
3132 * materialized view. It's not sufficiently clear what the user would
3133 * want to happen if the MV is refreshed or incrementally maintained.
3134 */
3135 if (query->hasModifyingCTE)
3136 ereport(ERROR,
3137 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3138 errmsg("materialized views must not use data-modifying statements in WITH")));
3139
3140 /*
3141 * Check whether any temporary database objects are used in the
3142 * creation query. It would be hard to refresh data or incrementally
3143 * maintain it if a source disappeared.
3144 */
3145 if (isQueryUsingTempRelation(query))
3146 ereport(ERROR,
3147 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3148 errmsg("materialized views must not use temporary tables or views")));
3149
3150 /*
3151 * A materialized view would either need to save parameters for use in
3152 * maintaining/loading the data or prohibit them entirely. The latter
3153 * seems safer and more sane.
3154 */
3156 ereport(ERROR,
3157 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3158 errmsg("materialized views may not be defined using bound parameters")));
3159
3160 /*
3161 * For now, we disallow unlogged materialized views, because it seems
3162 * like a bad idea for them to just go to empty after a crash. (If we
3163 * could mark them as unpopulated, that would be better, but that
3164 * requires catalog changes which crash recovery can't presently
3165 * handle.)
3166 */
3167 if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED)
3168 ereport(ERROR,
3169 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3170 errmsg("materialized views cannot be unlogged")));
3171
3172 /*
3173 * At runtime, we'll need a copy of the parsed-but-not-rewritten Query
3174 * for purposes of creating the view's ON SELECT rule. We stash that
3175 * in the IntoClause because that's where intorel_startup() can
3176 * conveniently get it from.
3177 */
3178 stmt->into->viewQuery = copyObject(query);
3179 }
3180
3181 /* represent the command as a utility Query */
3182 result = makeNode(Query);
3183 result->commandType = CMD_UTILITY;
3184 result->utilityStmt = (Node *) stmt;
3185
3186 return result;
3187}
3188
3189/*
3190 * transform a CallStmt
3191 */
3192static Query *
3194{
3195 List *targs;
3196 ListCell *lc;
3197 Node *node;
3198 FuncExpr *fexpr;
3199 HeapTuple proctup;
3200 Datum proargmodes;
3201 bool isNull;
3202 List *outargs = NIL;
3203 Query *result;
3204
3205 /*
3206 * First, do standard parse analysis on the procedure call and its
3207 * arguments, allowing us to identify the called procedure.
3208 */
3209 targs = NIL;
3210 foreach(lc, stmt->funccall->args)
3211 {
3212 targs = lappend(targs, transformExpr(pstate,
3213 (Node *) lfirst(lc),
3215 }
3216
3217 node = ParseFuncOrColumn(pstate,
3218 stmt->funccall->funcname,
3219 targs,
3220 pstate->p_last_srf,
3221 stmt->funccall,
3222 true,
3223 stmt->funccall->location);
3224
3225 assign_expr_collations(pstate, node);
3226
3227 fexpr = castNode(FuncExpr, node);
3228
3229 proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid));
3230 if (!HeapTupleIsValid(proctup))
3231 elog(ERROR, "cache lookup failed for function %u", fexpr->funcid);
3232
3233 /*
3234 * Expand the argument list to deal with named-argument notation and
3235 * default arguments. For ordinary FuncExprs this'd be done during
3236 * planning, but a CallStmt doesn't go through planning, and there seems
3237 * no good reason not to do it here.
3238 */
3239 fexpr->args = expand_function_arguments(fexpr->args,
3240 true,
3241 fexpr->funcresulttype,
3242 proctup);
3243
3244 /* Fetch proargmodes; if it's null, there are no output args */
3245 proargmodes = SysCacheGetAttr(PROCOID, proctup,
3246 Anum_pg_proc_proargmodes,
3247 &isNull);
3248 if (!isNull)
3249 {
3250 /*
3251 * Split the list into input arguments in fexpr->args and output
3252 * arguments in stmt->outargs. INOUT arguments appear in both lists.
3253 */
3254 ArrayType *arr;
3255 int numargs;
3256 char *argmodes;
3257 List *inargs;
3258 int i;
3259
3260 arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
3261 numargs = list_length(fexpr->args);
3262 if (ARR_NDIM(arr) != 1 ||
3263 ARR_DIMS(arr)[0] != numargs ||
3264 ARR_HASNULL(arr) ||
3265 ARR_ELEMTYPE(arr) != CHAROID)
3266 elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
3267 numargs);
3268 argmodes = (char *) ARR_DATA_PTR(arr);
3269
3270 inargs = NIL;
3271 i = 0;
3272 foreach(lc, fexpr->args)
3273 {
3274 Node *n = lfirst(lc);
3275
3276 switch (argmodes[i])
3277 {
3278 case PROARGMODE_IN:
3279 case PROARGMODE_VARIADIC:
3280 inargs = lappend(inargs, n);
3281 break;
3282 case PROARGMODE_OUT:
3283 outargs = lappend(outargs, n);
3284 break;
3285 case PROARGMODE_INOUT:
3286 inargs = lappend(inargs, n);
3287 outargs = lappend(outargs, copyObject(n));
3288 break;
3289 default:
3290 /* note we don't support PROARGMODE_TABLE */
3291 elog(ERROR, "invalid argmode %c for procedure",
3292 argmodes[i]);
3293 break;
3294 }
3295 i++;
3296 }
3297 fexpr->args = inargs;
3298 }
3299
3300 stmt->funcexpr = fexpr;
3301 stmt->outargs = outargs;
3302
3303 ReleaseSysCache(proctup);
3304
3305 /* represent the command as a utility Query */
3306 result = makeNode(Query);
3307 result->commandType = CMD_UTILITY;
3308 result->utilityStmt = (Node *) stmt;
3309
3310 return result;
3311}
3312
3313/*
3314 * Produce a string representation of a LockClauseStrength value.
3315 * This should only be applied to valid values (not LCS_NONE).
3316 */
3317const char *
3319{
3320 switch (strength)
3321 {
3322 case LCS_NONE:
3323 Assert(false);
3324 break;
3325 case LCS_FORKEYSHARE:
3326 return "FOR KEY SHARE";
3327 case LCS_FORSHARE:
3328 return "FOR SHARE";
3329 case LCS_FORNOKEYUPDATE:
3330 return "FOR NO KEY UPDATE";
3331 case LCS_FORUPDATE:
3332 return "FOR UPDATE";
3333 }
3334 return "FOR some"; /* shouldn't happen */
3335}
3336
3337/*
3338 * Check for features that are not supported with FOR [KEY] UPDATE/SHARE.
3339 *
3340 * exported so planner can check again after rewriting, query pullup, etc
3341 */
3342void
3344{
3345 Assert(strength != LCS_NONE); /* else caller error */
3346
3347 if (qry->setOperations)
3348 ereport(ERROR,
3349 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3350 /*------
3351 translator: %s is a SQL row locking clause such as FOR UPDATE */
3352 errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
3353 LCS_asString(strength))));
3354 if (qry->distinctClause != NIL)
3355 ereport(ERROR,
3356 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3357 /*------
3358 translator: %s is a SQL row locking clause such as FOR UPDATE */
3359 errmsg("%s is not allowed with DISTINCT clause",
3360 LCS_asString(strength))));
3361 if (qry->groupClause != NIL || qry->groupingSets != NIL)
3362 ereport(ERROR,
3363 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3364 /*------
3365 translator: %s is a SQL row locking clause such as FOR UPDATE */
3366 errmsg("%s is not allowed with GROUP BY clause",
3367 LCS_asString(strength))));
3368 if (qry->havingQual != NULL)
3369 ereport(ERROR,
3370 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3371 /*------
3372 translator: %s is a SQL row locking clause such as FOR UPDATE */
3373 errmsg("%s is not allowed with HAVING clause",
3374 LCS_asString(strength))));
3375 if (qry->hasAggs)
3376 ereport(ERROR,
3377 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3378 /*------
3379 translator: %s is a SQL row locking clause such as FOR UPDATE */
3380 errmsg("%s is not allowed with aggregate functions",
3381 LCS_asString(strength))));
3382 if (qry->hasWindowFuncs)
3383 ereport(ERROR,
3384 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3385 /*------
3386 translator: %s is a SQL row locking clause such as FOR UPDATE */
3387 errmsg("%s is not allowed with window functions",
3388 LCS_asString(strength))));
3389 if (qry->hasTargetSRFs)
3390 ereport(ERROR,
3391 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3392 /*------
3393 translator: %s is a SQL row locking clause such as FOR UPDATE */
3394 errmsg("%s is not allowed with set-returning functions in the target list",
3395 LCS_asString(strength))));
3396}
3397
3398/*
3399 * Transform a FOR [KEY] UPDATE/SHARE clause
3400 *
3401 * This basically involves replacing names by integer relids.
3402 *
3403 * NB: if you need to change this, see also markQueryForLocking()
3404 * in rewriteHandler.c, and isLockedRefname() in parse_relation.c.
3405 */
3406static void
3408 bool pushedDown)
3409{
3410 List *lockedRels = lc->lockedRels;
3411 ListCell *l;
3412 ListCell *rt;
3413 Index i;
3414 LockingClause *allrels;
3415
3416 CheckSelectLocking(qry, lc->strength);
3417
3418 /* make a clause we can pass down to subqueries to select all rels */
3419 allrels = makeNode(LockingClause);
3420 allrels->lockedRels = NIL; /* indicates all rels */
3421 allrels->strength = lc->strength;
3422 allrels->waitPolicy = lc->waitPolicy;
3423
3424 if (lockedRels == NIL)
3425 {
3426 /*
3427 * Lock all regular tables used in query and its subqueries. We
3428 * examine inFromCl to exclude auto-added RTEs, particularly NEW/OLD
3429 * in rules. This is a bit of an abuse of a mostly-obsolete flag, but
3430 * it's convenient. We can't rely on the namespace mechanism that has
3431 * largely replaced inFromCl, since for example we need to lock
3432 * base-relation RTEs even if they are masked by upper joins.
3433 */
3434 i = 0;
3435 foreach(rt, qry->rtable)
3436 {
3437 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3438
3439 ++i;
3440 if (!rte->inFromCl)
3441 continue;
3442 switch (rte->rtekind)
3443 {
3444 case RTE_RELATION:
3445 {
3446 RTEPermissionInfo *perminfo;
3447
3448 applyLockingClause(qry, i,
3449 lc->strength,
3450 lc->waitPolicy,
3451 pushedDown);
3452 perminfo = getRTEPermissionInfo(qry->rteperminfos, rte);
3454 }
3455 break;
3456 case RTE_SUBQUERY:
3457 applyLockingClause(qry, i, lc->strength, lc->waitPolicy,
3458 pushedDown);
3459
3460 /*
3461 * FOR UPDATE/SHARE of subquery is propagated to all of
3462 * subquery's rels, too. We could do this later (based on
3463 * the marking of the subquery RTE) but it is convenient
3464 * to have local knowledge in each query level about which
3465 * rels need to be opened with RowShareLock.
3466 */
3467 transformLockingClause(pstate, rte->subquery,
3468 allrels, true);
3469 break;
3470 default:
3471 /* ignore JOIN, SPECIAL, FUNCTION, VALUES, CTE RTEs */
3472 break;
3473 }
3474 }
3475 }
3476 else
3477 {
3478 /*
3479 * Lock just the named tables. As above, we allow locking any base
3480 * relation regardless of alias-visibility rules, so we need to
3481 * examine inFromCl to exclude OLD/NEW.
3482 */
3483 foreach(l, lockedRels)
3484 {
3485 RangeVar *thisrel = (RangeVar *) lfirst(l);
3486
3487 /* For simplicity we insist on unqualified alias names here */
3488 if (thisrel->catalogname || thisrel->schemaname)
3489 ereport(ERROR,
3490 (errcode(ERRCODE_SYNTAX_ERROR),
3491 /*------
3492 translator: %s is a SQL row locking clause such as FOR UPDATE */
3493 errmsg("%s must specify unqualified relation names",
3494 LCS_asString(lc->strength)),
3495 parser_errposition(pstate, thisrel->location)));
3496
3497 i = 0;
3498 foreach(rt, qry->rtable)
3499 {
3500 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3501 char *rtename = rte->eref->aliasname;
3502
3503 ++i;
3504 if (!rte->inFromCl)
3505 continue;
3506
3507 /*
3508 * A join RTE without an alias is not visible as a relation
3509 * name and needs to be skipped (otherwise it might hide a
3510 * base relation with the same name), except if it has a USING
3511 * alias, which *is* visible.
3512 *
3513 * Subquery and values RTEs without aliases are never visible
3514 * as relation names and must always be skipped.
3515 */
3516 if (rte->alias == NULL)
3517 {
3518 if (rte->rtekind == RTE_JOIN)
3519 {
3520 if (rte->join_using_alias == NULL)
3521 continue;
3522 rtename = rte->join_using_alias->aliasname;
3523 }
3524 else if (rte->rtekind == RTE_SUBQUERY ||
3525 rte->rtekind == RTE_VALUES)
3526 continue;
3527 }
3528
3529 if (strcmp(rtename, thisrel->relname) == 0)
3530 {
3531 switch (rte->rtekind)
3532 {
3533 case RTE_RELATION:
3534 {
3535 RTEPermissionInfo *perminfo;
3536
3537 applyLockingClause(qry, i,
3538 lc->strength,
3539 lc->waitPolicy,
3540 pushedDown);
3541 perminfo = getRTEPermissionInfo(qry->rteperminfos, rte);
3543 }
3544 break;
3545 case RTE_SUBQUERY:
3546 applyLockingClause(qry, i, lc->strength,
3547 lc->waitPolicy, pushedDown);
3548 /* see comment above */
3549 transformLockingClause(pstate, rte->subquery,
3550 allrels, true);
3551 break;
3552 case RTE_JOIN:
3553 ereport(ERROR,
3554 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3555 /*------
3556 translator: %s is a SQL row locking clause such as FOR UPDATE */
3557 errmsg("%s cannot be applied to a join",
3558 LCS_asString(lc->strength)),
3559 parser_errposition(pstate, thisrel->location)));
3560 break;
3561 case RTE_FUNCTION:
3562 ereport(ERROR,
3563 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3564 /*------
3565 translator: %s is a SQL row locking clause such as FOR UPDATE */
3566 errmsg("%s cannot be applied to a function",
3567 LCS_asString(lc->strength)),
3568 parser_errposition(pstate, thisrel->location)));
3569 break;
3570 case RTE_TABLEFUNC:
3571 ereport(ERROR,
3572 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3573 /*------
3574 translator: %s is a SQL row locking clause such as FOR UPDATE */
3575 errmsg("%s cannot be applied to a table function",
3576 LCS_asString(lc->strength)),
3577 parser_errposition(pstate, thisrel->location)));
3578 break;
3579 case RTE_VALUES:
3580 ereport(ERROR,
3581 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3582 /*------
3583 translator: %s is a SQL row locking clause such as FOR UPDATE */
3584 errmsg("%s cannot be applied to VALUES",
3585 LCS_asString(lc->strength)),
3586 parser_errposition(pstate, thisrel->location)));
3587 break;
3588 case RTE_CTE:
3589 ereport(ERROR,
3590 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3591 /*------
3592 translator: %s is a SQL row locking clause such as FOR UPDATE */
3593 errmsg("%s cannot be applied to a WITH query",
3594 LCS_asString(lc->strength)),
3595 parser_errposition(pstate, thisrel->location)));
3596 break;
3598 ereport(ERROR,
3599 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3600 /*------
3601 translator: %s is a SQL row locking clause such as FOR UPDATE */
3602 errmsg("%s cannot be applied to a named tuplestore",
3603 LCS_asString(lc->strength)),
3604 parser_errposition(pstate, thisrel->location)));
3605 break;
3606
3607 /* Shouldn't be possible to see RTE_RESULT here */
3608
3609 default:
3610 elog(ERROR, "unrecognized RTE type: %d",
3611 (int) rte->rtekind);
3612 break;
3613 }
3614 break; /* out of foreach loop */
3615 }
3616 }
3617 if (rt == NULL)
3618 ereport(ERROR,
3620 /*------
3621 translator: %s is a SQL row locking clause such as FOR UPDATE */
3622 errmsg("relation \"%s\" in %s clause not found in FROM clause",
3623 thisrel->relname,
3624 LCS_asString(lc->strength)),
3625 parser_errposition(pstate, thisrel->location)));
3626 }
3627 }
3628}
3629
3630/*
3631 * Record locking info for a single rangetable item
3632 */
3633void
3635 LockClauseStrength strength, LockWaitPolicy waitPolicy,
3636 bool pushedDown)
3637{
3638 RowMarkClause *rc;
3639
3640 Assert(strength != LCS_NONE); /* else caller error */
3641
3642 /* If it's an explicit clause, make sure hasForUpdate gets set */
3643 if (!pushedDown)
3644 qry->hasForUpdate = true;
3645
3646 /* Check for pre-existing entry for same rtindex */
3647 if ((rc = get_parse_rowmark(qry, rtindex)) != NULL)
3648 {
3649 /*
3650 * If the same RTE is specified with more than one locking strength,
3651 * use the strongest. (Reasonable, since you can't take both a shared
3652 * and exclusive lock at the same time; it'll end up being exclusive
3653 * anyway.)
3654 *
3655 * Similarly, if the same RTE is specified with more than one lock
3656 * wait policy, consider that NOWAIT wins over SKIP LOCKED, which in
3657 * turn wins over waiting for the lock (the default). This is a bit
3658 * more debatable but raising an error doesn't seem helpful. (Consider
3659 * for instance SELECT FOR UPDATE NOWAIT from a view that internally
3660 * contains a plain FOR UPDATE spec.) Having NOWAIT win over SKIP
3661 * LOCKED is reasonable since the former throws an error in case of
3662 * coming across a locked tuple, which may be undesirable in some
3663 * cases but it seems better than silently returning inconsistent
3664 * results.
3665 *
3666 * And of course pushedDown becomes false if any clause is explicit.
3667 */
3668 rc->strength = Max(rc->strength, strength);
3669 rc->waitPolicy = Max(rc->waitPolicy, waitPolicy);
3670 rc->pushedDown &= pushedDown;
3671 return;
3672 }
3673
3674 /* Make a new RowMarkClause */
3675 rc = makeNode(RowMarkClause);
3676 rc->rti = rtindex;
3677 rc->strength = strength;
3678 rc->waitPolicy = waitPolicy;
3679 rc->pushedDown = pushedDown;
3680 qry->rowMarks = lappend(qry->rowMarks, rc);
3681}
3682
3683#ifdef DEBUG_NODE_TESTS_ENABLED
3684/*
3685 * Coverage testing for raw_expression_tree_walker().
3686 *
3687 * When enabled, we run raw_expression_tree_walker() over every DML statement
3688 * submitted to parse analysis. Without this provision, that function is only
3689 * applied in limited cases involving CTEs, and we don't really want to have
3690 * to test everything inside as well as outside a CTE.
3691 */
3692static bool
3693test_raw_expression_coverage(Node *node, void *context)
3694{
3695 if (node == NULL)
3696 return false;
3697 return raw_expression_tree_walker(node,
3698 test_raw_expression_coverage,
3699 context);
3700}
3701#endif /* DEBUG_NODE_TESTS_ENABLED */
void(* post_parse_analyze_hook_type)(ParseState *pstate, Query *query, JumbleState *jstate)
Definition: analyze.h:22
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
#define ARR_HASNULL(a)
Definition: array.h:291
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
void pgstat_report_query_id(int64 query_id, bool force)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
#define NameStr(name)
Definition: c.h:752
#define Max(x, y)
Definition: c.h:998
int32_t int32
Definition: c.h:535
unsigned int Index
Definition: c.h:620
List * expand_function_arguments(List *args, bool include_out_arguments, Oid result_type, HeapTuple func_tuple)
Definition: clauses.c:4278
bool defGetBoolean(DefElem *def)
Definition: define.c:94
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1184
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errhint(const char *fmt,...)
Definition: elog.c:1321
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define stmt
Definition: indent_codes.h:59
long val
Definition: informix.c:689
int i
Definition: isn.c:77
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
List * lappend(List *list, void *datum)
Definition: list.c:339
List * list_delete_first(List *list)
Definition: list.c:943
List * list_copy(const List *oldlist)
Definition: list.c:1573
List * lappend_int(List *list, int datum)
Definition: list.c:357
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
List * list_delete_last(List *list)
Definition: list.c:957
void list_free(List *list)
Definition: list.c:1546
List * list_truncate(List *list, int new_size)
Definition: list.c:631
#define RowExclusiveLock
Definition: lockdefs.h:38
LockWaitPolicy
Definition: lockoptions.h:37
LockClauseStrength
Definition: lockoptions.h:22
@ LCS_FORUPDATE
Definition: lockoptions.h:27
@ LCS_NONE
Definition: lockoptions.h:23
@ LCS_FORSHARE
Definition: lockoptions.h:25
@ LCS_FORKEYSHARE
Definition: lockoptions.h:24
@ LCS_FORNOKEYUPDATE
Definition: lockoptions.h:26
Alias * makeAlias(const char *aliasname, List *colnames)
Definition: makefuncs.c:438
Var * makeVarFromTargetEntry(int varno, TargetEntry *tle)
Definition: makefuncs.c:107
FromExpr * makeFromExpr(List *fromlist, Node *quals)
Definition: makefuncs.c:336
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition: makefuncs.c:66
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition: makefuncs.c:388
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:289
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void * palloc0(Size size)
Definition: mcxt.c:1395
void * palloc(Size size)
Definition: mcxt.c:1365
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:301
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:821
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1388
#define raw_expression_tree_walker(n, w, c)
Definition: nodeFuncs.h:176
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define copyObject(obj)
Definition: nodes.h:232
#define nodeTag(nodeptr)
Definition: nodes.h:139
@ ONCONFLICT_UPDATE
Definition: nodes.h:430
@ CMD_UTILITY
Definition: nodes.h:280
@ CMD_INSERT
Definition: nodes.h:277
@ CMD_DELETE
Definition: nodes.h:278
@ CMD_UPDATE
Definition: nodes.h:276
@ CMD_SELECT
Definition: nodes.h:275
#define makeNode(_type_)
Definition: nodes.h:161
#define castNode(_type_, nodeptr)
Definition: nodes.h:182
@ JOIN_INNER
Definition: nodes.h:303
void(* ParserSetupHook)(ParseState *pstate, void *arg)
Definition: params.h:107
void parseCheckAggregates(ParseState *pstate, Query *qry)
Definition: parse_agg.c:1111
List * transformGroupClause(ParseState *pstate, List *grouplist, List **groupingSets, List **targetlist, List *sortClause, ParseExprKind exprKind, bool useSQL99)
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
List * transformSortClause(ParseState *pstate, List *orderlist, List **targetlist, ParseExprKind exprKind, bool useSQL99)
List * transformDistinctOnClause(ParseState *pstate, List *distinctlist, List **targetlist, List *sortClause)
List * transformWindowDefinitions(ParseState *pstate, List *windowdefs, List **targetlist)
void transformFromClause(ParseState *pstate, List *frmList)
Definition: parse_clause.c:112
List * transformDistinctClause(ParseState *pstate, List **targetlist, List *sortClause, bool is_agg)
Node * transformLimitClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName, LimitOption limitOption)
void transformOnConflictArbiter(ParseState *pstate, OnConflictClause *onConflictClause, List **arbiterExpr, Node **arbiterWhere, Oid *constraint)
int setTargetTable(ParseState *pstate, RangeVar *relation, bool inh, bool alsoSource, AclMode requiredPerms)
Definition: parse_clause.c:178
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
int32 select_common_typmod(ParseState *pstate, List *exprs, Oid common_type)
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:78
void assign_list_collations(ParseState *pstate, List *exprs)
Oid select_common_collation(ParseState *pstate, List *exprs, bool none_ok)
void assign_query_collations(ParseState *pstate, Query *query)
void assign_expr_collations(ParseState *pstate, Node *expr)
void analyzeCTETargetList(ParseState *pstate, CommonTableExpr *cte, List *tlist)
Definition: parse_cte.c:571
List * transformWithClause(ParseState *pstate, WithClause *withClause)
Definition: parse_cte.c:110
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:117
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, Node *last_srf, FuncCall *fn, bool proc_call, int location)
Definition: parse_func.c:92
Query * transformMergeStmt(ParseState *pstate, MergeStmt *stmt)
Definition: parse_merge.c:107
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:156
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:72
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:140
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:39
ParseExprKind
Definition: parse_node.h:39
@ EXPR_KIND_VALUES
Definition: parse_node.h:66
@ EXPR_KIND_ORDER_BY
Definition: parse_node.h:60
@ EXPR_KIND_OFFSET
Definition: parse_node.h:63
@ EXPR_KIND_HAVING
Definition: parse_node.h:47
@ EXPR_KIND_INSERT_TARGET
Definition: parse_node.h:55
@ EXPR_KIND_LIMIT
Definition: parse_node.h:62
@ EXPR_KIND_WHERE
Definition: parse_node.h:46
@ EXPR_KIND_UPDATE_TARGET
Definition: parse_node.h:57
@ EXPR_KIND_SELECT_TARGET
Definition: parse_node.h:54
@ EXPR_KIND_RETURNING
Definition: parse_node.h:64
@ EXPR_KIND_NONE
Definition: parse_node.h:40
@ EXPR_KIND_CALL_ARGUMENT
Definition: parse_node.h:81
@ EXPR_KIND_GROUP_BY
Definition: parse_node.h:59
@ EXPR_KIND_UPDATE_SOURCE
Definition: parse_node.h:56
@ EXPR_KIND_VALUES_SINGLE
Definition: parse_node.h:67
struct ParseNamespaceColumn ParseNamespaceColumn
Definition: parse_node.h:25
void get_sort_group_operators(Oid argtype, bool needLT, bool needEQ, bool needGT, Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, bool *isHashable)
Definition: parse_oper.c:181
void check_variable_parameters(ParseState *pstate, Query *query)
Definition: parse_param.c:269
bool query_contains_extern_params(Query *query)
Definition: parse_param.c:331
void setup_parse_variable_parameters(ParseState *pstate, Oid **paramTypes, int *numParams)
Definition: parse_param.c:84
void setup_parse_fixed_parameters(ParseState *pstate, const Oid *paramTypes, int numParams)
Definition: parse_param.c:68
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
RowMarkClause * get_parse_rowmark(Query *qry, Index rtindex)
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
List * expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location, List **colnames)
void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
ParseNamespaceItem * addRangeTableEntryForSubquery(ParseState *pstate, Query *subquery, Alias *alias, bool lateral, bool inFromCl)
ParseNamespaceItem * addRangeTableEntryForJoin(ParseState *pstate, List *colnames, ParseNamespaceColumn *nscolumns, JoinType jointype, int nummergedcols, List *aliasvars, List *leftcols, List *rightcols, Alias *join_using_alias, Alias *alias, bool inFromCl)
List * expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, bool require_col_privs, int location)
bool isQueryUsingTempRelation(Query *query)
ParseNamespaceItem * refnameNamespaceItem(ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
RangeTblEntry * GetRTEByRangeTablePosn(ParseState *pstate, int varno, int sublevels_up)
int attnameAttNum(Relation rd, const char *attname, bool sysColOK)
ParseNamespaceItem * addRangeTableEntryForValues(ParseState *pstate, List *exprs, List *coltypes, List *coltypmods, List *colcollations, Alias *alias, bool lateral, bool inFromCl)
Expr * transformAssignedExpr(ParseState *pstate, Expr *expr, ParseExprKind exprKind, const char *colname, int attrno, List *indirection, int location)
Definition: parse_target.c:454
List * transformExpressionList(ParseState *pstate, List *exprlist, ParseExprKind exprKind, bool allowDefault)
Definition: parse_target.c:219
Node * transformAssignmentIndirection(ParseState *pstate, Node *basenode, const char *targetName, bool targetIsSubscripting, Oid targetTypeId, int32 targetTypMod, Oid targetCollation, List *indirection, ListCell *indirection_cell, Node *rhs, CoercionContext ccontext, int location)
Definition: parse_target.c:685
void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, char *colname, int attrno, List *indirection, int location)
Definition: parse_target.c:621
List * transformTargetList(ParseState *pstate, List *targetlist, ParseExprKind exprKind)
Definition: parse_target.c:120
void resolveTargetListUnknowns(ParseState *pstate, List *targetlist)
Definition: parse_target.c:287
void markTargetListOrigins(ParseState *pstate, List *targetlist)
Definition: parse_target.c:317
List * checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
#define ISCOMPLEX(typeid)
Definition: parse_type.h:59
#define CURSOR_OPT_INSENSITIVE
Definition: parsenodes.h:3386
#define CURSOR_OPT_SCROLL
Definition: parsenodes.h:3384
#define ACL_DELETE
Definition: parsenodes.h:79
@ SETOP_INTERSECT
Definition: parsenodes.h:2176
@ SETOP_UNION
Definition: parsenodes.h:2175
@ SETOP_NONE
Definition: parsenodes.h:2174
uint64 AclMode
Definition: parsenodes.h:74
#define ACL_INSERT
Definition: parsenodes.h:76
#define ACL_UPDATE
Definition: parsenodes.h:78
@ QSRC_ORIGINAL
Definition: parsenodes.h:36
@ RTE_JOIN
Definition: parsenodes.h:1043
@ RTE_CTE
Definition: parsenodes.h:1047
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1048
@ RTE_VALUES
Definition: parsenodes.h:1046
@ RTE_SUBQUERY
Definition: parsenodes.h:1042
@ RTE_FUNCTION
Definition: parsenodes.h:1044
@ RTE_TABLEFUNC
Definition: parsenodes.h:1045
@ RTE_RELATION
Definition: parsenodes.h:1041
@ OBJECT_MATVIEW
Definition: parsenodes.h:2345
@ OBJECT_TABLE
Definition: parsenodes.h:2363
#define CURSOR_OPT_HOLD
Definition: parsenodes.h:3388
#define ACL_SELECT_FOR_UPDATE
Definition: parsenodes.h:94
#define CURSOR_OPT_ASENSITIVE
Definition: parsenodes.h:3387
@ RETURNING_OPTION_NEW
Definition: parsenodes.h:1767
@ RETURNING_OPTION_OLD
Definition: parsenodes.h:1766
#define CURSOR_OPT_NO_SCROLL
Definition: parsenodes.h:3385
static OnConflictExpr * transformOnConflictClause(ParseState *pstate, OnConflictClause *onConflictClause)
Definition: analyze.c:1173
static Query * transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
Definition: analyze.c:284
static void transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, bool pushedDown)
Definition: analyze.c:3407
static Query * transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
Definition: analyze.c:564
void CheckSelectLocking(Query *qry, LockClauseStrength strength)
Definition: analyze.c:3343
SortGroupClause * makeSortGroupClauseForSetOp(Oid rescoltype, bool require_hash)
Definition: analyze.c:2027
static Node * transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, bool isTopLevel, List **targetlist)
Definition: analyze.c:2075
struct SelectStmtPassthrough SelectStmtPassthrough
Query * parse_analyze_withcb(RawStmt *parseTree, const char *sourceText, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
Definition: analyze.c:197
bool analyze_requires_snapshot(RawStmt *parseTree)
Definition: analyze.c:502
List * transformInsertRow(ParseState *pstate, List *exprlist, List *stmtcols, List *icolumns, List *attrnos, bool strip_indirection)
Definition: analyze.c:1063
void applyLockingClause(Query *qry, Index rtindex, LockClauseStrength strength, LockWaitPolicy waitPolicy, bool pushedDown)
Definition: analyze.c:3634
static void determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
Definition: analyze.c:2403
static Query * transformReturnStmt(ParseState *pstate, ReturnStmt *stmt)
Definition: analyze.c:2457
static void addNSItemForReturning(ParseState *pstate, const char *aliasname, VarReturningType returning_type)
Definition: analyze.c:2629
void transformReturningClause(ParseState *pstate, Query *qry, ReturningClause *returningClause, ParseExprKind exprKind)
Definition: analyze.c:2669
static Query * transformPLAssignStmt(ParseState *pstate, PLAssignStmt *stmt)
Definition: analyze.c:2791
static Query * transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
Definition: analyze.c:3118
post_parse_analyze_hook_type post_parse_analyze_hook
Definition: analyze.c:67
static Query * transformCallStmt(ParseState *pstate, CallStmt *stmt)
Definition: analyze.c:3193
List * transformUpdateTargetList(ParseState *pstate, List *origTlist)
Definition: analyze.c:2554
static Query * transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1770
bool query_requires_rewrite_plan(Query *query)
Definition: analyze.c:531
static Query * transformSelectStmt(ParseState *pstate, SelectStmt *stmt, SelectStmtPassthrough *passthru)
Definition: analyze.c:1399
Query * transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
Definition: analyze.c:260
const char * LCS_asString(LockClauseStrength strength)
Definition: analyze.c:3318
Query * parse_analyze_fixedparams(RawStmt *parseTree, const char *sourceText, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
Definition: analyze.c:116
static Query * transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
Definition: analyze.c:2488
Query * parse_sub_analyze(Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent, bool resolve_unknowns)
Definition: analyze.c:233
static Query * transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
Definition: analyze.c:3066
List * BuildOnConflictExcludedTargetlist(Relation targetrel, Index exclRelIndex)
Definition: analyze.c:1280
static List * transformPLAssignStmtTarget(ParseState *pstate, List *tlist, SelectStmtPassthrough *passthru)
Definition: analyze.c:2866
static int count_rowexpr_columns(ParseState *pstate, Node *expr)
Definition: analyze.c:1350
Query * parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv)
Definition: analyze.c:156
bool stmt_requires_parse_analysis(RawStmt *parseTree)
Definition: analyze.c:458
static Query * transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
Definition: analyze.c:2973
static Query * transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
Definition: analyze.c:636
static Query * transformValuesClause(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1551
Query * transformStmt(ParseState *pstate, Node *parseTree)
Definition: analyze.c:323
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
#define lfirst(lc)
Definition: pg_list.h:172
#define llast(l)
Definition: pg_list.h:198
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial_node(type, l)
Definition: pg_list.h:181
#define NIL
Definition: pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
#define lfirst_int(lc)
Definition: pg_list.h:173
#define list_make1(x1)
Definition: pg_list.h:212
#define forthree(cell1, list1, cell2, list2, cell3, list3)
Definition: pg_list.h:563
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
#define linitial(l)
Definition: pg_list.h:178
#define foreach_node(type, var, lst)
Definition: pg_list.h:496
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
Definition: pg_list.h:575
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
#define lfirst_oid(lc)
Definition: pg_list.h:174
#define list_make2(x1, x2)
Definition: pg_list.h:214
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:79
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
uint64_t Datum
Definition: postgres.h:70
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
VarReturningType
Definition: primnodes.h:255
@ VAR_RETURNING_OLD
Definition: primnodes.h:257
@ VAR_RETURNING_NEW
Definition: primnodes.h:258
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:755
@ COERCION_PLPGSQL
Definition: primnodes.h:735
static bool IsQueryIdEnabled(void)
Definition: queryjumble.h:104
JumbleState * JumbleQuery(Query *query)
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:520
#define RelationGetRelationName(relation)
Definition: rel.h:548
void check_stack_depth(void)
Definition: stack_depth.c:95
char * aliasname
Definition: primnodes.h:51
ParseLoc location
Definition: parsenodes.h:311
List * fields
Definition: parsenodes.h:310
IntoClause * into
Definition: parsenodes.h:4025
ObjectType objtype
Definition: parsenodes.h:4026
char * defname
Definition: parsenodes.h:841
List * newvals
Definition: primnodes.h:1179
Oid funcid
Definition: primnodes.h:769
List * args
Definition: primnodes.h:787
Definition: pg_list.h:54
List * lockedRels
Definition: parsenodes.h:860
LockClauseStrength strength
Definition: parsenodes.h:861
LockWaitPolicy waitPolicy
Definition: parsenodes.h:862
Definition: nodes.h:135
OnConflictAction action
Definition: parsenodes.h:1653
List * arbiterElems
Definition: primnodes.h:2362
OnConflictAction action
Definition: primnodes.h:2359
List * onConflictSet
Definition: primnodes.h:2368
List * exclRelTlist
Definition: primnodes.h:2371
Node * onConflictWhere
Definition: primnodes.h:2369
Node * arbiterWhere
Definition: primnodes.h:2364
AttrNumber p_varattno
Definition: parse_node.h:331
AttrNumber p_varattnosyn
Definition: parse_node.h:337
RangeTblEntry * p_rte
Definition: parse_node.h:295
ParseNamespaceColumn * p_nscolumns
Definition: parse_node.h:299
RTEPermissionInfo * p_perminfo
Definition: parse_node.h:297
VarReturningType p_returning_type
Definition: parse_node.h:304
bool p_hasTargetSRFs
Definition: parse_node.h:228
List * p_ctenamespace
Definition: parse_node.h:206
bool p_hasWindowFuncs
Definition: parse_node.h:227
ParseNamespaceItem * p_target_nsitem
Definition: parse_node.h:210
ParseExprKind p_expr_kind
Definition: parse_node.h:214
bool p_locked_from_parent
Definition: parse_node.h:218
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:240
List * p_nullingrels
Definition: parse_node.h:200
List * p_namespace
Definition: parse_node.h:203
bool p_is_insert
Definition: parse_node.h:212
QueryEnvironment * p_queryEnv
Definition: parse_node.h:223
const char * p_sourcetext
Definition: parse_node.h:195
List * p_windowdefs
Definition: parse_node.h:213
bool p_resolve_unknowns
Definition: parse_node.h:220
int p_next_resno
Definition: parse_node.h:215
bool p_hasModifyingCTE
Definition: parse_node.h:230
List * p_rteperminfos
Definition: parse_node.h:197
List * p_joinexprs
Definition: parse_node.h:199
Relation p_target_relation
Definition: parse_node.h:209
CommonTableExpr * p_parent_cte
Definition: parse_node.h:208
bool p_hasSubLinks
Definition: parse_node.h:229
Node * p_last_srf
Definition: parse_node.h:232
List * p_joinlist
Definition: parse_node.h:201
List * p_locking_clause
Definition: parse_node.h:217
List * p_rtable
Definition: parse_node.h:196
bool p_hasAggs
Definition: parse_node.h:226
List * rowMarks
Definition: parsenodes.h:233
bool groupDistinct
Definition: parsenodes.h:217
Node * limitCount
Definition: parsenodes.h:230
FromExpr * jointree
Definition: parsenodes.h:182
List * returningList
Definition: parsenodes.h:214
Node * setOperations
Definition: parsenodes.h:235
List * cteList
Definition: parsenodes.h:173
List * groupClause
Definition: parsenodes.h:216
Node * havingQual
Definition: parsenodes.h:221
List * rtable
Definition: parsenodes.h:175
Node * limitOffset
Definition: parsenodes.h:229
CmdType commandType
Definition: parsenodes.h:121
LimitOption limitOption
Definition: parsenodes.h:231
Node * utilityStmt
Definition: parsenodes.h:141
List * windowClause
Definition: parsenodes.h:223
List * targetList
Definition: parsenodes.h:198
List * groupingSets
Definition: parsenodes.h:219
List * distinctClause
Definition: parsenodes.h:225
List * sortClause
Definition: parsenodes.h:227
ParseLoc stmt_location
Definition: parsenodes.h:254
AclMode requiredPerms
Definition: parsenodes.h:1320
Bitmapset * updatedCols
Definition: parsenodes.h:1324
Query * subquery
Definition: parsenodes.h:1133
RTEKind rtekind
Definition: parsenodes.h:1076
char * relname
Definition: primnodes.h:83
char * catalogname
Definition: primnodes.h:77
ParseLoc location
Definition: primnodes.h:95
char * schemaname
Definition: primnodes.h:80
ParseLoc stmt_location
Definition: parsenodes.h:2087
ParseLoc stmt_len
Definition: parsenodes.h:2088
Node * stmt
Definition: parsenodes.h:2086
TupleDesc rd_att
Definition: rel.h:112
Form_pg_class rd_rel
Definition: rel.h:111
ParseLoc location
Definition: parsenodes.h:546
List * indirection
Definition: parsenodes.h:544
char * name
Definition: parsenodes.h:543
LockClauseStrength strength
Definition: parsenodes.h:1609
LockWaitPolicy waitPolicy
Definition: parsenodes.h:1610
PLAssignStmt * stmt
Definition: analyze.c:61
List * sortClause
Definition: parsenodes.h:2212
IntoClause * intoClause
Definition: parsenodes.h:2189
Node * limitOffset
Definition: parsenodes.h:2213
List * lockingClause
Definition: parsenodes.h:2216
Node * limitCount
Definition: parsenodes.h:2214
List * valuesLists
Definition: parsenodes.h:2206
struct SelectStmt * larg
Definition: parsenodes.h:2224
SetOperation op
Definition: parsenodes.h:2222
WithClause * withClause
Definition: parsenodes.h:2217
SetOperation op
Definition: parsenodes.h:2252
ParseLoc location
Definition: primnodes.h:2089
Index tleSortGroupRef
Definition: parsenodes.h:1467
Definition: value.h:64
Expr * refassgnexpr
Definition: primnodes.h:722
Expr * expr
Definition: primnodes.h:2225
AttrNumber resno
Definition: primnodes.h:2227
Definition: primnodes.h:262
ParseLoc location
Definition: primnodes.h:310
AttrNumber varattno
Definition: primnodes.h:274
int varno
Definition: primnodes.h:269
Index varlevelsup
Definition: primnodes.h:294
bool recursive
Definition: parsenodes.h:1625
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:595
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
String * makeString(char *str)
Definition: value.c:63
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:444
int locate_var_of_level(Node *node, int levelsup)
Definition: var.c:555
const char * name