00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "postgres.h"
00026
00027 #include "access/sysattr.h"
00028 #include "catalog/pg_type.h"
00029 #include "miscadmin.h"
00030 #include "nodes/makefuncs.h"
00031 #include "nodes/nodeFuncs.h"
00032 #include "optimizer/var.h"
00033 #include "parser/analyze.h"
00034 #include "parser/parse_agg.h"
00035 #include "parser/parse_clause.h"
00036 #include "parser/parse_coerce.h"
00037 #include "parser/parse_collate.h"
00038 #include "parser/parse_cte.h"
00039 #include "parser/parse_oper.h"
00040 #include "parser/parse_param.h"
00041 #include "parser/parse_relation.h"
00042 #include "parser/parse_target.h"
00043 #include "parser/parsetree.h"
00044 #include "rewrite/rewriteManip.h"
00045 #include "utils/rel.h"
00046
00047
00048
00049 post_parse_analyze_hook_type post_parse_analyze_hook = NULL;
00050
00051 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
00052 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
00053 static List *transformInsertRow(ParseState *pstate, List *exprlist,
00054 List *stmtcols, List *icolumns, List *attrnos);
00055 static int count_rowexpr_columns(ParseState *pstate, Node *expr);
00056 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
00057 static Query *transformValuesClause(ParseState *pstate, SelectStmt *stmt);
00058 static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
00059 static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
00060 bool isTopLevel, List **targetlist);
00061 static void determineRecursiveColTypes(ParseState *pstate,
00062 Node *larg, List *nrtargetlist);
00063 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
00064 static List *transformReturningList(ParseState *pstate, List *returningList);
00065 static Query *transformDeclareCursorStmt(ParseState *pstate,
00066 DeclareCursorStmt *stmt);
00067 static Query *transformExplainStmt(ParseState *pstate,
00068 ExplainStmt *stmt);
00069 static Query *transformCreateTableAsStmt(ParseState *pstate,
00070 CreateTableAsStmt *stmt);
00071 static void transformLockingClause(ParseState *pstate, Query *qry,
00072 LockingClause *lc, bool pushedDown);
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 Query *
00087 parse_analyze(Node *parseTree, const char *sourceText,
00088 Oid *paramTypes, int numParams)
00089 {
00090 ParseState *pstate = make_parsestate(NULL);
00091 Query *query;
00092
00093 Assert(sourceText != NULL);
00094
00095 pstate->p_sourcetext = sourceText;
00096
00097 if (numParams > 0)
00098 parse_fixed_parameters(pstate, paramTypes, numParams);
00099
00100 query = transformTopLevelStmt(pstate, parseTree);
00101
00102 if (post_parse_analyze_hook)
00103 (*post_parse_analyze_hook) (pstate, query);
00104
00105 free_parsestate(pstate);
00106
00107 return query;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117 Query *
00118 parse_analyze_varparams(Node *parseTree, const char *sourceText,
00119 Oid **paramTypes, int *numParams)
00120 {
00121 ParseState *pstate = make_parsestate(NULL);
00122 Query *query;
00123
00124 Assert(sourceText != NULL);
00125
00126 pstate->p_sourcetext = sourceText;
00127
00128 parse_variable_parameters(pstate, paramTypes, numParams);
00129
00130 query = transformTopLevelStmt(pstate, parseTree);
00131
00132
00133 check_variable_parameters(pstate, query);
00134
00135 if (post_parse_analyze_hook)
00136 (*post_parse_analyze_hook) (pstate, query);
00137
00138 free_parsestate(pstate);
00139
00140 return query;
00141 }
00142
00143
00144
00145
00146
00147 Query *
00148 parse_sub_analyze(Node *parseTree, ParseState *parentParseState,
00149 CommonTableExpr *parentCTE,
00150 bool locked_from_parent)
00151 {
00152 ParseState *pstate = make_parsestate(parentParseState);
00153 Query *query;
00154
00155 pstate->p_parent_cte = parentCTE;
00156 pstate->p_locked_from_parent = locked_from_parent;
00157
00158 query = transformStmt(pstate, parseTree);
00159
00160 free_parsestate(pstate);
00161
00162 return query;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 Query *
00176 transformTopLevelStmt(ParseState *pstate, Node *parseTree)
00177 {
00178 if (IsA(parseTree, SelectStmt))
00179 {
00180 SelectStmt *stmt = (SelectStmt *) parseTree;
00181
00182
00183 while (stmt && stmt->op != SETOP_NONE)
00184 stmt = stmt->larg;
00185 Assert(stmt && IsA(stmt, SelectStmt) &&stmt->larg == NULL);
00186
00187 if (stmt->intoClause)
00188 {
00189 CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
00190
00191 ctas->query = parseTree;
00192 ctas->into = stmt->intoClause;
00193 ctas->relkind = OBJECT_TABLE;
00194 ctas->is_select_into = true;
00195
00196
00197
00198
00199
00200
00201 stmt->intoClause = NULL;
00202
00203 parseTree = (Node *) ctas;
00204 }
00205 }
00206
00207 return transformStmt(pstate, parseTree);
00208 }
00209
00210
00211
00212
00213
00214 Query *
00215 transformStmt(ParseState *pstate, Node *parseTree)
00216 {
00217 Query *result;
00218
00219 switch (nodeTag(parseTree))
00220 {
00221
00222
00223
00224 case T_InsertStmt:
00225 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
00226 break;
00227
00228 case T_DeleteStmt:
00229 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
00230 break;
00231
00232 case T_UpdateStmt:
00233 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
00234 break;
00235
00236 case T_SelectStmt:
00237 {
00238 SelectStmt *n = (SelectStmt *) parseTree;
00239
00240 if (n->valuesLists)
00241 result = transformValuesClause(pstate, n);
00242 else if (n->op == SETOP_NONE)
00243 result = transformSelectStmt(pstate, n);
00244 else
00245 result = transformSetOperationStmt(pstate, n);
00246 }
00247 break;
00248
00249
00250
00251
00252 case T_DeclareCursorStmt:
00253 result = transformDeclareCursorStmt(pstate,
00254 (DeclareCursorStmt *) parseTree);
00255 break;
00256
00257 case T_ExplainStmt:
00258 result = transformExplainStmt(pstate,
00259 (ExplainStmt *) parseTree);
00260 break;
00261
00262 case T_CreateTableAsStmt:
00263 result = transformCreateTableAsStmt(pstate,
00264 (CreateTableAsStmt *) parseTree);
00265 break;
00266
00267 default:
00268
00269
00270
00271
00272
00273 result = makeNode(Query);
00274 result->commandType = CMD_UTILITY;
00275 result->utilityStmt = (Node *) parseTree;
00276 break;
00277 }
00278
00279
00280 result->querySource = QSRC_ORIGINAL;
00281 result->canSetTag = true;
00282
00283 return result;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 bool
00295 analyze_requires_snapshot(Node *parseTree)
00296 {
00297 bool result;
00298
00299 if (parseTree == NULL)
00300 return false;
00301
00302 switch (nodeTag(parseTree))
00303 {
00304
00305
00306
00307 case T_InsertStmt:
00308 case T_DeleteStmt:
00309 case T_UpdateStmt:
00310 case T_SelectStmt:
00311 result = true;
00312 break;
00313
00314
00315
00316
00317 case T_DeclareCursorStmt:
00318
00319 result = true;
00320 break;
00321
00322 case T_ExplainStmt:
00323 case T_CreateTableAsStmt:
00324
00325 result = true;
00326 break;
00327
00328 default:
00329
00330 result = false;
00331 break;
00332 }
00333
00334 return result;
00335 }
00336
00337
00338
00339
00340
00341 static Query *
00342 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
00343 {
00344 Query *qry = makeNode(Query);
00345 Node *qual;
00346
00347 qry->commandType = CMD_DELETE;
00348
00349
00350 if (stmt->withClause)
00351 {
00352 qry->hasRecursive = stmt->withClause->recursive;
00353 qry->cteList = transformWithClause(pstate, stmt->withClause);
00354 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
00355 }
00356
00357
00358 qry->resultRelation = setTargetTable(pstate, stmt->relation,
00359 interpretInhOption(stmt->relation->inhOpt),
00360 true,
00361 ACL_DELETE);
00362
00363 qry->distinctClause = NIL;
00364
00365
00366
00367
00368
00369
00370
00371 transformFromClause(pstate, stmt->usingClause);
00372
00373 qual = transformWhereClause(pstate, stmt->whereClause,
00374 EXPR_KIND_WHERE, "WHERE");
00375
00376 qry->returningList = transformReturningList(pstate, stmt->returningList);
00377
00378
00379 qry->rtable = pstate->p_rtable;
00380 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
00381
00382 qry->hasSubLinks = pstate->p_hasSubLinks;
00383 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
00384 qry->hasAggs = pstate->p_hasAggs;
00385 if (pstate->p_hasAggs)
00386 parseCheckAggregates(pstate, qry);
00387
00388 assign_query_collations(pstate, qry);
00389
00390 return qry;
00391 }
00392
00393
00394
00395
00396
00397 static Query *
00398 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
00399 {
00400 Query *qry = makeNode(Query);
00401 SelectStmt *selectStmt = (SelectStmt *) stmt->selectStmt;
00402 List *exprList = NIL;
00403 bool isGeneralSelect;
00404 List *sub_rtable;
00405 List *sub_namespace;
00406 List *icolumns;
00407 List *attrnos;
00408 RangeTblEntry *rte;
00409 RangeTblRef *rtr;
00410 ListCell *icols;
00411 ListCell *attnos;
00412 ListCell *lc;
00413
00414
00415 Assert(pstate->p_ctenamespace == NIL);
00416
00417 qry->commandType = CMD_INSERT;
00418 pstate->p_is_insert = true;
00419
00420
00421 if (stmt->withClause)
00422 {
00423 qry->hasRecursive = stmt->withClause->recursive;
00424 qry->cteList = transformWithClause(pstate, stmt->withClause);
00425 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 isGeneralSelect = (selectStmt && (selectStmt->valuesLists == NIL ||
00438 selectStmt->sortClause != NIL ||
00439 selectStmt->limitOffset != NULL ||
00440 selectStmt->limitCount != NULL ||
00441 selectStmt->lockingClause != NIL ||
00442 selectStmt->withClause != NULL));
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 if (isGeneralSelect)
00454 {
00455 sub_rtable = pstate->p_rtable;
00456 pstate->p_rtable = NIL;
00457 sub_namespace = pstate->p_namespace;
00458 pstate->p_namespace = NIL;
00459 }
00460 else
00461 {
00462 sub_rtable = NIL;
00463 sub_namespace = NIL;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472 qry->resultRelation = setTargetTable(pstate, stmt->relation,
00473 false, false, ACL_INSERT);
00474
00475
00476 icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
00477 Assert(list_length(icolumns) == list_length(attrnos));
00478
00479
00480
00481
00482 if (selectStmt == NULL)
00483 {
00484
00485
00486
00487
00488
00489 exprList = NIL;
00490 }
00491 else if (isGeneralSelect)
00492 {
00493
00494
00495
00496
00497
00498
00499
00500 ParseState *sub_pstate = make_parsestate(pstate);
00501 Query *selectQuery;
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 sub_pstate->p_rtable = sub_rtable;
00512 sub_pstate->p_joinexprs = NIL;
00513 sub_pstate->p_namespace = sub_namespace;
00514
00515 selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
00516
00517 free_parsestate(sub_pstate);
00518
00519
00520 if (!IsA(selectQuery, Query) ||
00521 selectQuery->commandType != CMD_SELECT ||
00522 selectQuery->utilityStmt != NULL)
00523 elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT");
00524
00525
00526
00527
00528
00529 rte = addRangeTableEntryForSubquery(pstate,
00530 selectQuery,
00531 makeAlias("*SELECT*", NIL),
00532 false,
00533 false);
00534 rtr = makeNode(RangeTblRef);
00535
00536 rtr->rtindex = list_length(pstate->p_rtable);
00537 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
00538 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 exprList = NIL;
00555 foreach(lc, selectQuery->targetList)
00556 {
00557 TargetEntry *tle = (TargetEntry *) lfirst(lc);
00558 Expr *expr;
00559
00560 if (tle->resjunk)
00561 continue;
00562 if (tle->expr &&
00563 (IsA(tle->expr, Const) ||IsA(tle->expr, Param)) &&
00564 exprType((Node *) tle->expr) == UNKNOWNOID)
00565 expr = tle->expr;
00566 else
00567 {
00568 Var *var = makeVarFromTargetEntry(rtr->rtindex, tle);
00569
00570 var->location = exprLocation((Node *) tle->expr);
00571 expr = (Expr *) var;
00572 }
00573 exprList = lappend(exprList, expr);
00574 }
00575
00576
00577 exprList = transformInsertRow(pstate, exprList,
00578 stmt->cols,
00579 icolumns, attrnos);
00580 }
00581 else if (list_length(selectStmt->valuesLists) > 1)
00582 {
00583
00584
00585
00586
00587
00588
00589 List *exprsLists = NIL;
00590 List *collations = NIL;
00591 int sublist_length = -1;
00592 bool lateral = false;
00593 int i;
00594
00595 Assert(selectStmt->intoClause == NULL);
00596
00597 foreach(lc, selectStmt->valuesLists)
00598 {
00599 List *sublist = (List *) lfirst(lc);
00600
00601
00602 sublist = transformExpressionList(pstate, sublist, EXPR_KIND_VALUES);
00603
00604
00605
00606
00607
00608
00609 if (sublist_length < 0)
00610 {
00611
00612 sublist_length = list_length(sublist);
00613 }
00614 else if (sublist_length != list_length(sublist))
00615 {
00616 ereport(ERROR,
00617 (errcode(ERRCODE_SYNTAX_ERROR),
00618 errmsg("VALUES lists must all be the same length"),
00619 parser_errposition(pstate,
00620 exprLocation((Node *) sublist))));
00621 }
00622
00623
00624 sublist = transformInsertRow(pstate, sublist,
00625 stmt->cols,
00626 icolumns, attrnos);
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 assign_list_collations(pstate, sublist);
00641
00642 exprsLists = lappend(exprsLists, sublist);
00643 }
00644
00645
00646
00647
00648
00649 for (i = 0; i < sublist_length; i++)
00650 collations = lappend_oid(collations, InvalidOid);
00651
00652
00653
00654
00655
00656
00657
00658 if (list_length(pstate->p_rtable) != 1 &&
00659 contain_vars_of_level((Node *) exprsLists, 0))
00660 lateral = true;
00661
00662
00663
00664
00665 rte = addRangeTableEntryForValues(pstate, exprsLists, collations,
00666 NULL, lateral, true);
00667 rtr = makeNode(RangeTblRef);
00668
00669 rtr->rtindex = list_length(pstate->p_rtable);
00670 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
00671 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
00672
00673
00674
00675
00676 expandRTE(rte, rtr->rtindex, 0, -1, false, NULL, &exprList);
00677 }
00678 else
00679 {
00680
00681
00682
00683
00684
00685
00686 List *valuesLists = selectStmt->valuesLists;
00687
00688 Assert(list_length(valuesLists) == 1);
00689 Assert(selectStmt->intoClause == NULL);
00690
00691
00692 exprList = transformExpressionList(pstate,
00693 (List *) linitial(valuesLists),
00694 EXPR_KIND_VALUES);
00695
00696
00697 exprList = transformInsertRow(pstate, exprList,
00698 stmt->cols,
00699 icolumns, attrnos);
00700 }
00701
00702
00703
00704
00705
00706 rte = pstate->p_target_rangetblentry;
00707 qry->targetList = NIL;
00708 icols = list_head(icolumns);
00709 attnos = list_head(attrnos);
00710 foreach(lc, exprList)
00711 {
00712 Expr *expr = (Expr *) lfirst(lc);
00713 ResTarget *col;
00714 AttrNumber attr_num;
00715 TargetEntry *tle;
00716
00717 col = (ResTarget *) lfirst(icols);
00718 Assert(IsA(col, ResTarget));
00719 attr_num = (AttrNumber) lfirst_int(attnos);
00720
00721 tle = makeTargetEntry(expr,
00722 attr_num,
00723 col->name,
00724 false);
00725 qry->targetList = lappend(qry->targetList, tle);
00726
00727 rte->modifiedCols = bms_add_member(rte->modifiedCols,
00728 attr_num - FirstLowInvalidHeapAttributeNumber);
00729
00730 icols = lnext(icols);
00731 attnos = lnext(attnos);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740 if (stmt->returningList)
00741 {
00742 pstate->p_namespace = NIL;
00743 addRTEtoQuery(pstate, pstate->p_target_rangetblentry,
00744 false, true, true);
00745 qry->returningList = transformReturningList(pstate,
00746 stmt->returningList);
00747 }
00748
00749
00750 qry->rtable = pstate->p_rtable;
00751 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
00752
00753 qry->hasSubLinks = pstate->p_hasSubLinks;
00754
00755 assign_query_collations(pstate, qry);
00756
00757 return qry;
00758 }
00759
00760
00761
00762
00763
00764
00765
00766 static List *
00767 transformInsertRow(ParseState *pstate, List *exprlist,
00768 List *stmtcols, List *icolumns, List *attrnos)
00769 {
00770 List *result;
00771 ListCell *lc;
00772 ListCell *icols;
00773 ListCell *attnos;
00774
00775
00776
00777
00778
00779
00780
00781
00782 if (list_length(exprlist) > list_length(icolumns))
00783 ereport(ERROR,
00784 (errcode(ERRCODE_SYNTAX_ERROR),
00785 errmsg("INSERT has more expressions than target columns"),
00786 parser_errposition(pstate,
00787 exprLocation(list_nth(exprlist,
00788 list_length(icolumns))))));
00789 if (stmtcols != NIL &&
00790 list_length(exprlist) < list_length(icolumns))
00791 {
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 ereport(ERROR,
00802 (errcode(ERRCODE_SYNTAX_ERROR),
00803 errmsg("INSERT has more target columns than expressions"),
00804 ((list_length(exprlist) == 1 &&
00805 count_rowexpr_columns(pstate, linitial(exprlist)) ==
00806 list_length(icolumns)) ?
00807 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),
00808 parser_errposition(pstate,
00809 exprLocation(list_nth(icolumns,
00810 list_length(exprlist))))));
00811 }
00812
00813
00814
00815
00816 result = NIL;
00817 icols = list_head(icolumns);
00818 attnos = list_head(attrnos);
00819 foreach(lc, exprlist)
00820 {
00821 Expr *expr = (Expr *) lfirst(lc);
00822 ResTarget *col;
00823
00824 col = (ResTarget *) lfirst(icols);
00825 Assert(IsA(col, ResTarget));
00826
00827 expr = transformAssignedExpr(pstate, expr,
00828 EXPR_KIND_INSERT_TARGET,
00829 col->name,
00830 lfirst_int(attnos),
00831 col->indirection,
00832 col->location);
00833
00834 result = lappend(result, expr);
00835
00836 icols = lnext(icols);
00837 attnos = lnext(attnos);
00838 }
00839
00840 return result;
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 static int
00853 count_rowexpr_columns(ParseState *pstate, Node *expr)
00854 {
00855 if (expr == NULL)
00856 return -1;
00857 if (IsA(expr, RowExpr))
00858 return list_length(((RowExpr *) expr)->args);
00859 if (IsA(expr, Var))
00860 {
00861 Var *var = (Var *) expr;
00862 AttrNumber attnum = var->varattno;
00863
00864 if (attnum > 0 && var->vartype == RECORDOID)
00865 {
00866 RangeTblEntry *rte;
00867
00868 rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
00869 if (rte->rtekind == RTE_SUBQUERY)
00870 {
00871
00872 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
00873 attnum);
00874
00875 if (ste == NULL || ste->resjunk)
00876 return -1;
00877 expr = (Node *) ste->expr;
00878 if (IsA(expr, RowExpr))
00879 return list_length(((RowExpr *) expr)->args);
00880 }
00881 }
00882 }
00883 return -1;
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 static Query *
00895 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
00896 {
00897 Query *qry = makeNode(Query);
00898 Node *qual;
00899 ListCell *l;
00900
00901 qry->commandType = CMD_SELECT;
00902
00903
00904 if (stmt->withClause)
00905 {
00906 qry->hasRecursive = stmt->withClause->recursive;
00907 qry->cteList = transformWithClause(pstate, stmt->withClause);
00908 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
00909 }
00910
00911
00912 if (stmt->intoClause)
00913 ereport(ERROR,
00914 (errcode(ERRCODE_SYNTAX_ERROR),
00915 errmsg("SELECT ... INTO is not allowed here"),
00916 parser_errposition(pstate,
00917 exprLocation((Node *) stmt->intoClause))));
00918
00919
00920 pstate->p_locking_clause = stmt->lockingClause;
00921
00922
00923 pstate->p_windowdefs = stmt->windowClause;
00924
00925
00926 transformFromClause(pstate, stmt->fromClause);
00927
00928
00929 qry->targetList = transformTargetList(pstate, stmt->targetList,
00930 EXPR_KIND_SELECT_TARGET);
00931
00932
00933 markTargetListOrigins(pstate, qry->targetList);
00934
00935
00936 qual = transformWhereClause(pstate, stmt->whereClause,
00937 EXPR_KIND_WHERE, "WHERE");
00938
00939
00940 qry->havingQual = transformWhereClause(pstate, stmt->havingClause,
00941 EXPR_KIND_HAVING, "HAVING");
00942
00943
00944
00945
00946
00947
00948
00949 qry->sortClause = transformSortClause(pstate,
00950 stmt->sortClause,
00951 &qry->targetList,
00952 EXPR_KIND_ORDER_BY,
00953 true ,
00954 false );
00955
00956 qry->groupClause = transformGroupClause(pstate,
00957 stmt->groupClause,
00958 &qry->targetList,
00959 qry->sortClause,
00960 EXPR_KIND_GROUP_BY,
00961 false );
00962
00963 if (stmt->distinctClause == NIL)
00964 {
00965 qry->distinctClause = NIL;
00966 qry->hasDistinctOn = false;
00967 }
00968 else if (linitial(stmt->distinctClause) == NULL)
00969 {
00970
00971 qry->distinctClause = transformDistinctClause(pstate,
00972 &qry->targetList,
00973 qry->sortClause,
00974 false);
00975 qry->hasDistinctOn = false;
00976 }
00977 else
00978 {
00979
00980 qry->distinctClause = transformDistinctOnClause(pstate,
00981 stmt->distinctClause,
00982 &qry->targetList,
00983 qry->sortClause);
00984 qry->hasDistinctOn = true;
00985 }
00986
00987
00988 qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
00989 EXPR_KIND_OFFSET, "OFFSET");
00990 qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
00991 EXPR_KIND_LIMIT, "LIMIT");
00992
00993
00994 qry->windowClause = transformWindowDefinitions(pstate,
00995 pstate->p_windowdefs,
00996 &qry->targetList);
00997
00998 qry->rtable = pstate->p_rtable;
00999 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
01000
01001 qry->hasSubLinks = pstate->p_hasSubLinks;
01002 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
01003 qry->hasAggs = pstate->p_hasAggs;
01004 if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
01005 parseCheckAggregates(pstate, qry);
01006
01007 foreach(l, stmt->lockingClause)
01008 {
01009 transformLockingClause(pstate, qry,
01010 (LockingClause *) lfirst(l), false);
01011 }
01012
01013 assign_query_collations(pstate, qry);
01014
01015 return qry;
01016 }
01017
01018
01019
01020
01021
01022
01023
01024
01025 static Query *
01026 transformValuesClause(ParseState *pstate, SelectStmt *stmt)
01027 {
01028 Query *qry = makeNode(Query);
01029 List *exprsLists;
01030 List *collations;
01031 List **colexprs = NULL;
01032 int sublist_length = -1;
01033 bool lateral = false;
01034 RangeTblEntry *rte;
01035 int rtindex;
01036 ListCell *lc;
01037 ListCell *lc2;
01038 int i;
01039
01040 qry->commandType = CMD_SELECT;
01041
01042
01043 Assert(stmt->distinctClause == NIL);
01044 Assert(stmt->intoClause == NULL);
01045 Assert(stmt->targetList == NIL);
01046 Assert(stmt->fromClause == NIL);
01047 Assert(stmt->whereClause == NULL);
01048 Assert(stmt->groupClause == NIL);
01049 Assert(stmt->havingClause == NULL);
01050 Assert(stmt->windowClause == NIL);
01051 Assert(stmt->op == SETOP_NONE);
01052
01053
01054 if (stmt->withClause)
01055 {
01056 qry->hasRecursive = stmt->withClause->recursive;
01057 qry->cteList = transformWithClause(pstate, stmt->withClause);
01058 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 foreach(lc, stmt->valuesLists)
01071 {
01072 List *sublist = (List *) lfirst(lc);
01073
01074
01075 sublist = transformExpressionList(pstate, sublist, EXPR_KIND_VALUES);
01076
01077
01078
01079
01080
01081
01082 if (sublist_length < 0)
01083 {
01084
01085 sublist_length = list_length(sublist);
01086
01087 colexprs = (List **) palloc0(sublist_length * sizeof(List *));
01088 }
01089 else if (sublist_length != list_length(sublist))
01090 {
01091 ereport(ERROR,
01092 (errcode(ERRCODE_SYNTAX_ERROR),
01093 errmsg("VALUES lists must all be the same length"),
01094 parser_errposition(pstate,
01095 exprLocation((Node *) sublist))));
01096 }
01097
01098
01099 i = 0;
01100 foreach(lc2, sublist)
01101 {
01102 Node *col = (Node *) lfirst(lc2);
01103
01104 if (IsA(col, SetToDefault))
01105 ereport(ERROR,
01106 (errcode(ERRCODE_SYNTAX_ERROR),
01107 errmsg("DEFAULT can only appear in a VALUES list within INSERT"),
01108 parser_errposition(pstate, exprLocation(col))));
01109 colexprs[i] = lappend(colexprs[i], col);
01110 i++;
01111 }
01112
01113
01114 list_free(sublist);
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 collations = NIL;
01132 for (i = 0; i < sublist_length; i++)
01133 {
01134 Oid coltype;
01135 Oid colcoll;
01136
01137 coltype = select_common_type(pstate, colexprs[i], "VALUES", NULL);
01138
01139 foreach(lc, colexprs[i])
01140 {
01141 Node *col = (Node *) lfirst(lc);
01142
01143 col = coerce_to_common_type(pstate, col, coltype, "VALUES");
01144 lfirst(lc) = (void *) col;
01145 }
01146
01147 colcoll = select_common_collation(pstate, colexprs[i], true);
01148
01149 collations = lappend_oid(collations, colcoll);
01150 }
01151
01152
01153
01154
01155 exprsLists = NIL;
01156 foreach(lc, colexprs[0])
01157 {
01158 Node *col = (Node *) lfirst(lc);
01159 List *sublist;
01160
01161 sublist = list_make1(col);
01162 exprsLists = lappend(exprsLists, sublist);
01163 }
01164 list_free(colexprs[0]);
01165 for (i = 1; i < sublist_length; i++)
01166 {
01167 forboth(lc, colexprs[i], lc2, exprsLists)
01168 {
01169 Node *col = (Node *) lfirst(lc);
01170 List *sublist = lfirst(lc2);
01171
01172
01173 (void) lappend(sublist, col);
01174 }
01175 list_free(colexprs[i]);
01176 }
01177
01178
01179
01180
01181
01182
01183
01184 if (pstate->p_rtable != NIL &&
01185 contain_vars_of_level((Node *) exprsLists, 0))
01186 lateral = true;
01187
01188
01189
01190
01191 rte = addRangeTableEntryForValues(pstate, exprsLists, collations,
01192 NULL, lateral, true);
01193 addRTEtoQuery(pstate, rte, true, true, true);
01194
01195
01196 rtindex = list_length(pstate->p_rtable);
01197 Assert(rte == rt_fetch(rtindex, pstate->p_rtable));
01198
01199
01200
01201
01202 Assert(pstate->p_next_resno == 1);
01203 qry->targetList = expandRelAttrs(pstate, rte, rtindex, 0, -1);
01204
01205
01206
01207
01208
01209 qry->sortClause = transformSortClause(pstate,
01210 stmt->sortClause,
01211 &qry->targetList,
01212 EXPR_KIND_ORDER_BY,
01213 true ,
01214 false );
01215
01216 qry->limitOffset = transformLimitClause(pstate, stmt->limitOffset,
01217 EXPR_KIND_OFFSET, "OFFSET");
01218 qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
01219 EXPR_KIND_LIMIT, "LIMIT");
01220
01221 if (stmt->lockingClause)
01222 ereport(ERROR,
01223 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01224 errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES")));
01225
01226 qry->rtable = pstate->p_rtable;
01227 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
01228
01229 qry->hasSubLinks = pstate->p_hasSubLinks;
01230
01231 assign_query_collations(pstate, qry);
01232
01233 return qry;
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 static Query *
01247 transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
01248 {
01249 Query *qry = makeNode(Query);
01250 SelectStmt *leftmostSelect;
01251 int leftmostRTI;
01252 Query *leftmostQuery;
01253 SetOperationStmt *sostmt;
01254 List *sortClause;
01255 Node *limitOffset;
01256 Node *limitCount;
01257 List *lockingClause;
01258 WithClause *withClause;
01259 Node *node;
01260 ListCell *left_tlist,
01261 *lct,
01262 *lcm,
01263 *lcc,
01264 *l;
01265 List *targetvars,
01266 *targetnames,
01267 *sv_namespace;
01268 int sv_rtable_length;
01269 RangeTblEntry *jrte;
01270 int tllen;
01271
01272 qry->commandType = CMD_SELECT;
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 leftmostSelect = stmt->larg;
01283 while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
01284 leftmostSelect = leftmostSelect->larg;
01285 Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
01286 leftmostSelect->larg == NULL);
01287 if (leftmostSelect->intoClause)
01288 ereport(ERROR,
01289 (errcode(ERRCODE_SYNTAX_ERROR),
01290 errmsg("SELECT ... INTO is not allowed here"),
01291 parser_errposition(pstate,
01292 exprLocation((Node *) leftmostSelect->intoClause))));
01293
01294
01295
01296
01297
01298
01299 sortClause = stmt->sortClause;
01300 limitOffset = stmt->limitOffset;
01301 limitCount = stmt->limitCount;
01302 lockingClause = stmt->lockingClause;
01303 withClause = stmt->withClause;
01304
01305 stmt->sortClause = NIL;
01306 stmt->limitOffset = NULL;
01307 stmt->limitCount = NULL;
01308 stmt->lockingClause = NIL;
01309 stmt->withClause = NULL;
01310
01311
01312 if (lockingClause)
01313 ereport(ERROR,
01314 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01315 errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
01316
01317
01318 if (withClause)
01319 {
01320 qry->hasRecursive = withClause->recursive;
01321 qry->cteList = transformWithClause(pstate, withClause);
01322 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
01323 }
01324
01325
01326
01327
01328 sostmt = (SetOperationStmt *) transformSetOperationTree(pstate, stmt,
01329 true,
01330 NULL);
01331 Assert(sostmt && IsA(sostmt, SetOperationStmt));
01332 qry->setOperations = (Node *) sostmt;
01333
01334
01335
01336
01337 node = sostmt->larg;
01338 while (node && IsA(node, SetOperationStmt))
01339 node = ((SetOperationStmt *) node)->larg;
01340 Assert(node && IsA(node, RangeTblRef));
01341 leftmostRTI = ((RangeTblRef *) node)->rtindex;
01342 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
01343 Assert(leftmostQuery != NULL);
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356 qry->targetList = NIL;
01357 targetvars = NIL;
01358 targetnames = NIL;
01359 left_tlist = list_head(leftmostQuery->targetList);
01360
01361 forthree(lct, sostmt->colTypes,
01362 lcm, sostmt->colTypmods,
01363 lcc, sostmt->colCollations)
01364 {
01365 Oid colType = lfirst_oid(lct);
01366 int32 colTypmod = lfirst_int(lcm);
01367 Oid colCollation = lfirst_oid(lcc);
01368 TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
01369 char *colName;
01370 TargetEntry *tle;
01371 Var *var;
01372
01373 Assert(!lefttle->resjunk);
01374 colName = pstrdup(lefttle->resname);
01375 var = makeVar(leftmostRTI,
01376 lefttle->resno,
01377 colType,
01378 colTypmod,
01379 colCollation,
01380 0);
01381 var->location = exprLocation((Node *) lefttle->expr);
01382 tle = makeTargetEntry((Expr *) var,
01383 (AttrNumber) pstate->p_next_resno++,
01384 colName,
01385 false);
01386 qry->targetList = lappend(qry->targetList, tle);
01387 targetvars = lappend(targetvars, var);
01388 targetnames = lappend(targetnames, makeString(colName));
01389 left_tlist = lnext(left_tlist);
01390 }
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402 sv_rtable_length = list_length(pstate->p_rtable);
01403
01404 jrte = addRangeTableEntryForJoin(pstate,
01405 targetnames,
01406 JOIN_INNER,
01407 targetvars,
01408 NULL,
01409 false);
01410
01411 sv_namespace = pstate->p_namespace;
01412 pstate->p_namespace = NIL;
01413
01414
01415 addRTEtoQuery(pstate, jrte, false, false, true);
01416
01417
01418
01419
01420
01421
01422
01423 tllen = list_length(qry->targetList);
01424
01425 qry->sortClause = transformSortClause(pstate,
01426 sortClause,
01427 &qry->targetList,
01428 EXPR_KIND_ORDER_BY,
01429 false ,
01430 false );
01431
01432
01433 pstate->p_namespace = sv_namespace;
01434 pstate->p_rtable = list_truncate(pstate->p_rtable, sv_rtable_length);
01435
01436 if (tllen != list_length(qry->targetList))
01437 ereport(ERROR,
01438 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01439 errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause"),
01440 errdetail("Only result column names can be used, not expressions or functions."),
01441 errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
01442 parser_errposition(pstate,
01443 exprLocation(list_nth(qry->targetList, tllen)))));
01444
01445 qry->limitOffset = transformLimitClause(pstate, limitOffset,
01446 EXPR_KIND_OFFSET, "OFFSET");
01447 qry->limitCount = transformLimitClause(pstate, limitCount,
01448 EXPR_KIND_LIMIT, "LIMIT");
01449
01450 qry->rtable = pstate->p_rtable;
01451 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
01452
01453 qry->hasSubLinks = pstate->p_hasSubLinks;
01454 qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
01455 qry->hasAggs = pstate->p_hasAggs;
01456 if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
01457 parseCheckAggregates(pstate, qry);
01458
01459 foreach(l, lockingClause)
01460 {
01461 transformLockingClause(pstate, qry,
01462 (LockingClause *) lfirst(l), false);
01463 }
01464
01465 assign_query_collations(pstate, qry);
01466
01467 return qry;
01468 }
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484 static Node *
01485 transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
01486 bool isTopLevel, List **targetlist)
01487 {
01488 bool isLeaf;
01489
01490 Assert(stmt && IsA(stmt, SelectStmt));
01491
01492
01493 check_stack_depth();
01494
01495
01496
01497
01498 if (stmt->intoClause)
01499 ereport(ERROR,
01500 (errcode(ERRCODE_SYNTAX_ERROR),
01501 errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
01502 parser_errposition(pstate,
01503 exprLocation((Node *) stmt->intoClause))));
01504
01505
01506 if (stmt->lockingClause)
01507 ereport(ERROR,
01508 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01509 errmsg("SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT")));
01510
01511
01512
01513
01514
01515
01516
01517 if (stmt->op == SETOP_NONE)
01518 {
01519 Assert(stmt->larg == NULL && stmt->rarg == NULL);
01520 isLeaf = true;
01521 }
01522 else
01523 {
01524 Assert(stmt->larg != NULL && stmt->rarg != NULL);
01525 if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
01526 stmt->lockingClause || stmt->withClause)
01527 isLeaf = true;
01528 else
01529 isLeaf = false;
01530 }
01531
01532 if (isLeaf)
01533 {
01534
01535 Query *selectQuery;
01536 char selectName[32];
01537 RangeTblEntry *rte PG_USED_FOR_ASSERTS_ONLY;
01538 RangeTblRef *rtr;
01539 ListCell *tl;
01540
01541
01542
01543
01544
01545
01546
01547
01548 selectQuery = parse_sub_analyze((Node *) stmt, pstate, NULL, false);
01549
01550
01551
01552
01553
01554
01555
01556 if (pstate->p_namespace)
01557 {
01558 if (contain_vars_of_level((Node *) selectQuery, 1))
01559 ereport(ERROR,
01560 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01561 errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
01562 parser_errposition(pstate,
01563 locate_var_of_level((Node *) selectQuery, 1))));
01564 }
01565
01566
01567
01568
01569 if (targetlist)
01570 {
01571 *targetlist = NIL;
01572 foreach(tl, selectQuery->targetList)
01573 {
01574 TargetEntry *tle = (TargetEntry *) lfirst(tl);
01575
01576 if (!tle->resjunk)
01577 *targetlist = lappend(*targetlist, tle);
01578 }
01579 }
01580
01581
01582
01583
01584 snprintf(selectName, sizeof(selectName), "*SELECT* %d",
01585 list_length(pstate->p_rtable) + 1);
01586 rte = addRangeTableEntryForSubquery(pstate,
01587 selectQuery,
01588 makeAlias(selectName, NIL),
01589 false,
01590 false);
01591
01592
01593
01594
01595 rtr = makeNode(RangeTblRef);
01596
01597 rtr->rtindex = list_length(pstate->p_rtable);
01598 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
01599 return (Node *) rtr;
01600 }
01601 else
01602 {
01603
01604 SetOperationStmt *op = makeNode(SetOperationStmt);
01605 List *ltargetlist;
01606 List *rtargetlist;
01607 ListCell *ltl;
01608 ListCell *rtl;
01609 const char *context;
01610
01611 context = (stmt->op == SETOP_UNION ? "UNION" :
01612 (stmt->op == SETOP_INTERSECT ? "INTERSECT" :
01613 "EXCEPT"));
01614
01615 op->op = stmt->op;
01616 op->all = stmt->all;
01617
01618
01619
01620
01621 op->larg = transformSetOperationTree(pstate, stmt->larg,
01622 false,
01623 <argetlist);
01624
01625
01626
01627
01628
01629
01630
01631 if (isTopLevel &&
01632 pstate->p_parent_cte &&
01633 pstate->p_parent_cte->cterecursive)
01634 determineRecursiveColTypes(pstate, op->larg, ltargetlist);
01635
01636
01637
01638
01639 op->rarg = transformSetOperationTree(pstate, stmt->rarg,
01640 false,
01641 &rtargetlist);
01642
01643
01644
01645
01646
01647 if (list_length(ltargetlist) != list_length(rtargetlist))
01648 ereport(ERROR,
01649 (errcode(ERRCODE_SYNTAX_ERROR),
01650 errmsg("each %s query must have the same number of columns",
01651 context),
01652 parser_errposition(pstate,
01653 exprLocation((Node *) rtargetlist))));
01654
01655 if (targetlist)
01656 *targetlist = NIL;
01657 op->colTypes = NIL;
01658 op->colTypmods = NIL;
01659 op->colCollations = NIL;
01660 op->groupClauses = NIL;
01661 forboth(ltl, ltargetlist, rtl, rtargetlist)
01662 {
01663 TargetEntry *ltle = (TargetEntry *) lfirst(ltl);
01664 TargetEntry *rtle = (TargetEntry *) lfirst(rtl);
01665 Node *lcolnode = (Node *) ltle->expr;
01666 Node *rcolnode = (Node *) rtle->expr;
01667 Oid lcoltype = exprType(lcolnode);
01668 Oid rcoltype = exprType(rcolnode);
01669 int32 lcoltypmod = exprTypmod(lcolnode);
01670 int32 rcoltypmod = exprTypmod(rcolnode);
01671 Node *bestexpr;
01672 int bestlocation;
01673 Oid rescoltype;
01674 int32 rescoltypmod;
01675 Oid rescolcoll;
01676
01677
01678 rescoltype = select_common_type(pstate,
01679 list_make2(lcolnode, rcolnode),
01680 context,
01681 &bestexpr);
01682 bestlocation = exprLocation(bestexpr);
01683
01684 if (lcoltype == rcoltype && lcoltypmod == rcoltypmod)
01685 rescoltypmod = lcoltypmod;
01686 else
01687 rescoltypmod = -1;
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716 if (lcoltype != UNKNOWNOID)
01717 lcolnode = coerce_to_common_type(pstate, lcolnode,
01718 rescoltype, context);
01719 else if (IsA(lcolnode, Const) ||
01720 IsA(lcolnode, Param))
01721 {
01722 lcolnode = coerce_to_common_type(pstate, lcolnode,
01723 rescoltype, context);
01724 ltle->expr = (Expr *) lcolnode;
01725 }
01726
01727 if (rcoltype != UNKNOWNOID)
01728 rcolnode = coerce_to_common_type(pstate, rcolnode,
01729 rescoltype, context);
01730 else if (IsA(rcolnode, Const) ||
01731 IsA(rcolnode, Param))
01732 {
01733 rcolnode = coerce_to_common_type(pstate, rcolnode,
01734 rescoltype, context);
01735 rtle->expr = (Expr *) rcolnode;
01736 }
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747 rescolcoll = select_common_collation(pstate,
01748 list_make2(lcolnode, rcolnode),
01749 (op->op == SETOP_UNION && op->all));
01750
01751
01752 op->colTypes = lappend_oid(op->colTypes, rescoltype);
01753 op->colTypmods = lappend_int(op->colTypmods, rescoltypmod);
01754 op->colCollations = lappend_oid(op->colCollations, rescolcoll);
01755
01756
01757
01758
01759
01760
01761 if (op->op != SETOP_UNION || !op->all)
01762 {
01763 SortGroupClause *grpcl = makeNode(SortGroupClause);
01764 Oid sortop;
01765 Oid eqop;
01766 bool hashable;
01767 ParseCallbackState pcbstate;
01768
01769 setup_parser_errposition_callback(&pcbstate, pstate,
01770 bestlocation);
01771
01772
01773 get_sort_group_operators(rescoltype,
01774 false, true, false,
01775 &sortop, &eqop, NULL,
01776 &hashable);
01777
01778 cancel_parser_errposition_callback(&pcbstate);
01779
01780
01781 grpcl->tleSortGroupRef = 0;
01782 grpcl->eqop = eqop;
01783 grpcl->sortop = sortop;
01784 grpcl->nulls_first = false;
01785 grpcl->hashable = hashable;
01786
01787 op->groupClauses = lappend(op->groupClauses, grpcl);
01788 }
01789
01790
01791
01792
01793
01794
01795 if (targetlist)
01796 {
01797 SetToDefault *rescolnode = makeNode(SetToDefault);
01798 TargetEntry *restle;
01799
01800 rescolnode->typeId = rescoltype;
01801 rescolnode->typeMod = rescoltypmod;
01802 rescolnode->collation = rescolcoll;
01803 rescolnode->location = bestlocation;
01804 restle = makeTargetEntry((Expr *) rescolnode,
01805 0,
01806 NULL,
01807 false);
01808 *targetlist = lappend(*targetlist, restle);
01809 }
01810 }
01811
01812 return (Node *) op;
01813 }
01814 }
01815
01816
01817
01818
01819
01820 static void
01821 determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
01822 {
01823 Node *node;
01824 int leftmostRTI;
01825 Query *leftmostQuery;
01826 List *targetList;
01827 ListCell *left_tlist;
01828 ListCell *nrtl;
01829 int next_resno;
01830
01831
01832
01833
01834 node = larg;
01835 while (node && IsA(node, SetOperationStmt))
01836 node = ((SetOperationStmt *) node)->larg;
01837 Assert(node && IsA(node, RangeTblRef));
01838 leftmostRTI = ((RangeTblRef *) node)->rtindex;
01839 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
01840 Assert(leftmostQuery != NULL);
01841
01842
01843
01844
01845
01846 targetList = NIL;
01847 left_tlist = list_head(leftmostQuery->targetList);
01848 next_resno = 1;
01849
01850 foreach(nrtl, nrtargetlist)
01851 {
01852 TargetEntry *nrtle = (TargetEntry *) lfirst(nrtl);
01853 TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
01854 char *colName;
01855 TargetEntry *tle;
01856
01857 Assert(!lefttle->resjunk);
01858 colName = pstrdup(lefttle->resname);
01859 tle = makeTargetEntry(nrtle->expr,
01860 next_resno++,
01861 colName,
01862 false);
01863 targetList = lappend(targetList, tle);
01864 left_tlist = lnext(left_tlist);
01865 }
01866
01867
01868 analyzeCTETargetList(pstate, pstate->p_parent_cte, targetList);
01869 }
01870
01871
01872
01873
01874
01875
01876 static Query *
01877 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
01878 {
01879 Query *qry = makeNode(Query);
01880 RangeTblEntry *target_rte;
01881 Node *qual;
01882 ListCell *origTargetList;
01883 ListCell *tl;
01884
01885 qry->commandType = CMD_UPDATE;
01886 pstate->p_is_update = true;
01887
01888
01889 if (stmt->withClause)
01890 {
01891 qry->hasRecursive = stmt->withClause->recursive;
01892 qry->cteList = transformWithClause(pstate, stmt->withClause);
01893 qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
01894 }
01895
01896 qry->resultRelation = setTargetTable(pstate, stmt->relation,
01897 interpretInhOption(stmt->relation->inhOpt),
01898 true,
01899 ACL_UPDATE);
01900
01901
01902
01903
01904
01905 transformFromClause(pstate, stmt->fromClause);
01906
01907 qry->targetList = transformTargetList(pstate, stmt->targetList,
01908 EXPR_KIND_UPDATE_SOURCE);
01909
01910 qual = transformWhereClause(pstate, stmt->whereClause,
01911 EXPR_KIND_WHERE, "WHERE");
01912
01913 qry->returningList = transformReturningList(pstate, stmt->returningList);
01914
01915 qry->rtable = pstate->p_rtable;
01916 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
01917
01918 qry->hasSubLinks = pstate->p_hasSubLinks;
01919
01920
01921
01922
01923
01924
01925
01926 if (pstate->p_next_resno <= pstate->p_target_relation->rd_rel->relnatts)
01927 pstate->p_next_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
01928
01929
01930 target_rte = pstate->p_target_rangetblentry;
01931 origTargetList = list_head(stmt->targetList);
01932
01933 foreach(tl, qry->targetList)
01934 {
01935 TargetEntry *tle = (TargetEntry *) lfirst(tl);
01936 ResTarget *origTarget;
01937 int attrno;
01938
01939 if (tle->resjunk)
01940 {
01941
01942
01943
01944
01945
01946
01947 tle->resno = (AttrNumber) pstate->p_next_resno++;
01948 tle->resname = NULL;
01949 continue;
01950 }
01951 if (origTargetList == NULL)
01952 elog(ERROR, "UPDATE target count mismatch --- internal error");
01953 origTarget = (ResTarget *) lfirst(origTargetList);
01954 Assert(IsA(origTarget, ResTarget));
01955
01956 attrno = attnameAttNum(pstate->p_target_relation,
01957 origTarget->name, true);
01958 if (attrno == InvalidAttrNumber)
01959 ereport(ERROR,
01960 (errcode(ERRCODE_UNDEFINED_COLUMN),
01961 errmsg("column \"%s\" of relation \"%s\" does not exist",
01962 origTarget->name,
01963 RelationGetRelationName(pstate->p_target_relation)),
01964 parser_errposition(pstate, origTarget->location)));
01965
01966 updateTargetListEntry(pstate, tle, origTarget->name,
01967 attrno,
01968 origTarget->indirection,
01969 origTarget->location);
01970
01971
01972 target_rte->modifiedCols = bms_add_member(target_rte->modifiedCols,
01973 attrno - FirstLowInvalidHeapAttributeNumber);
01974
01975 origTargetList = lnext(origTargetList);
01976 }
01977 if (origTargetList != NULL)
01978 elog(ERROR, "UPDATE target count mismatch --- internal error");
01979
01980 assign_query_collations(pstate, qry);
01981
01982 return qry;
01983 }
01984
01985
01986
01987
01988
01989 static List *
01990 transformReturningList(ParseState *pstate, List *returningList)
01991 {
01992 List *rlist;
01993 int save_next_resno;
01994
01995 if (returningList == NIL)
01996 return NIL;
01997
01998
01999
02000
02001
02002
02003 save_next_resno = pstate->p_next_resno;
02004 pstate->p_next_resno = 1;
02005
02006
02007 rlist = transformTargetList(pstate, returningList, EXPR_KIND_RETURNING);
02008
02009
02010 markTargetListOrigins(pstate, rlist);
02011
02012
02013 pstate->p_next_resno = save_next_resno;
02014
02015 return rlist;
02016 }
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030 static Query *
02031 transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
02032 {
02033 Query *result;
02034
02035
02036
02037
02038 if ((stmt->options & CURSOR_OPT_SCROLL) &&
02039 (stmt->options & CURSOR_OPT_NO_SCROLL))
02040 ereport(ERROR,
02041 (errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
02042 errmsg("cannot specify both SCROLL and NO SCROLL")));
02043
02044 result = transformStmt(pstate, stmt->query);
02045
02046
02047 if (!IsA(result, Query) ||
02048 result->commandType != CMD_SELECT ||
02049 result->utilityStmt != NULL)
02050 elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR");
02051
02052
02053
02054
02055
02056
02057 if (result->hasModifyingCTE)
02058 ereport(ERROR,
02059 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02060 errmsg("DECLARE CURSOR must not contain data-modifying statements in WITH")));
02061
02062
02063 if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD))
02064 ereport(ERROR,
02065 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02066 errmsg("DECLARE CURSOR WITH HOLD ... FOR UPDATE/SHARE is not supported"),
02067 errdetail("Holdable cursors must be READ ONLY.")));
02068
02069
02070 if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_SCROLL))
02071 ereport(ERROR,
02072 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02073 errmsg("DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported"),
02074 errdetail("Scrollable cursors must be READ ONLY.")));
02075
02076
02077 if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_INSENSITIVE))
02078 ereport(ERROR,
02079 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02080 errmsg("DECLARE INSENSITIVE CURSOR ... FOR UPDATE/SHARE is not supported"),
02081 errdetail("Insensitive cursors must be READ ONLY.")));
02082
02083
02084 stmt->query = NULL;
02085
02086 result->utilityStmt = (Node *) stmt;
02087
02088 return result;
02089 }
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102 static Query *
02103 transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
02104 {
02105 Query *result;
02106
02107
02108 stmt->query = (Node *) transformTopLevelStmt(pstate, stmt->query);
02109
02110
02111 result = makeNode(Query);
02112 result->commandType = CMD_UTILITY;
02113 result->utilityStmt = (Node *) stmt;
02114
02115 return result;
02116 }
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126 static Query *
02127 transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
02128 {
02129 Query *result;
02130 Query *query;
02131
02132
02133 query = transformStmt(pstate, stmt->query);
02134 stmt->query = (Node *) query;
02135
02136
02137 if (stmt->relkind == OBJECT_MATVIEW)
02138 {
02139
02140
02141
02142
02143
02144 if (query->hasModifyingCTE)
02145 ereport(ERROR,
02146 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02147 errmsg("materialized views must not use data-modifying statements in WITH")));
02148
02149
02150
02151
02152
02153
02154 if (isQueryUsingTempRelation(query))
02155 ereport(ERROR,
02156 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02157 errmsg("materialized views must not use temporary tables or views")));
02158
02159
02160
02161
02162
02163
02164 if (query_contains_extern_params(query))
02165 ereport(ERROR,
02166 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02167 errmsg("materialized views may not be defined using bound parameters")));
02168
02169
02170
02171
02172
02173
02174
02175 stmt->into->viewQuery = copyObject(query);
02176 }
02177
02178
02179 result = makeNode(Query);
02180 result->commandType = CMD_UTILITY;
02181 result->utilityStmt = (Node *) stmt;
02182
02183 return result;
02184 }
02185
02186
02187
02188
02189
02190
02191
02192 void
02193 CheckSelectLocking(Query *qry)
02194 {
02195 if (qry->setOperations)
02196 ereport(ERROR,
02197 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02198 errmsg("row-level locks are not allowed with UNION/INTERSECT/EXCEPT")));
02199 if (qry->distinctClause != NIL)
02200 ereport(ERROR,
02201 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02202 errmsg("row-level locks are not allowed with DISTINCT clause")));
02203 if (qry->groupClause != NIL)
02204 ereport(ERROR,
02205 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02206 errmsg("row-level locks are not allowed with GROUP BY clause")));
02207 if (qry->havingQual != NULL)
02208 ereport(ERROR,
02209 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02210 errmsg("row-level locks are not allowed with HAVING clause")));
02211 if (qry->hasAggs)
02212 ereport(ERROR,
02213 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02214 errmsg("row-level locks are not allowed with aggregate functions")));
02215 if (qry->hasWindowFuncs)
02216 ereport(ERROR,
02217 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02218 errmsg("row-level locks are not allowed with window functions")));
02219 if (expression_returns_set((Node *) qry->targetList))
02220 ereport(ERROR,
02221 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02222 errmsg("row-level locks are not allowed with set-returning functions in the target list")));
02223 }
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233 static void
02234 transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
02235 bool pushedDown)
02236 {
02237 List *lockedRels = lc->lockedRels;
02238 ListCell *l;
02239 ListCell *rt;
02240 Index i;
02241 LockingClause *allrels;
02242
02243 CheckSelectLocking(qry);
02244
02245
02246 allrels = makeNode(LockingClause);
02247 allrels->lockedRels = NIL;
02248 allrels->strength = lc->strength;
02249 allrels->noWait = lc->noWait;
02250
02251 if (lockedRels == NIL)
02252 {
02253
02254 i = 0;
02255 foreach(rt, qry->rtable)
02256 {
02257 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
02258
02259 ++i;
02260 switch (rte->rtekind)
02261 {
02262 case RTE_RELATION:
02263 applyLockingClause(qry, i,
02264 lc->strength, lc->noWait, pushedDown);
02265 rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
02266 break;
02267 case RTE_SUBQUERY:
02268 applyLockingClause(qry, i,
02269 lc->strength, lc->noWait, pushedDown);
02270
02271
02272
02273
02274
02275
02276
02277
02278 transformLockingClause(pstate, rte->subquery,
02279 allrels, true);
02280 break;
02281 default:
02282
02283 break;
02284 }
02285 }
02286 }
02287 else
02288 {
02289
02290 foreach(l, lockedRels)
02291 {
02292 RangeVar *thisrel = (RangeVar *) lfirst(l);
02293
02294
02295 if (thisrel->catalogname || thisrel->schemaname)
02296 ereport(ERROR,
02297 (errcode(ERRCODE_SYNTAX_ERROR),
02298 errmsg("row-level locks must specify unqualified relation names"),
02299 parser_errposition(pstate, thisrel->location)));
02300
02301 i = 0;
02302 foreach(rt, qry->rtable)
02303 {
02304 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
02305
02306 ++i;
02307 if (strcmp(rte->eref->aliasname, thisrel->relname) == 0)
02308 {
02309 switch (rte->rtekind)
02310 {
02311 case RTE_RELATION:
02312 applyLockingClause(qry, i,
02313 lc->strength, lc->noWait,
02314 pushedDown);
02315 rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
02316 break;
02317 case RTE_SUBQUERY:
02318 applyLockingClause(qry, i,
02319 lc->strength, lc->noWait,
02320 pushedDown);
02321
02322 transformLockingClause(pstate, rte->subquery,
02323 allrels, true);
02324 break;
02325 case RTE_JOIN:
02326 ereport(ERROR,
02327 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02328 errmsg("row-level locks cannot be applied to a join"),
02329 parser_errposition(pstate, thisrel->location)));
02330 break;
02331 case RTE_FUNCTION:
02332 ereport(ERROR,
02333 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02334 errmsg("row-level locks cannot be applied to a function"),
02335 parser_errposition(pstate, thisrel->location)));
02336 break;
02337 case RTE_VALUES:
02338 ereport(ERROR,
02339 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02340 errmsg("row-level locks cannot be applied to VALUES"),
02341 parser_errposition(pstate, thisrel->location)));
02342 break;
02343 case RTE_CTE:
02344 ereport(ERROR,
02345 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02346 errmsg("row-level locks cannot be applied to a WITH query"),
02347 parser_errposition(pstate, thisrel->location)));
02348 break;
02349 default:
02350 elog(ERROR, "unrecognized RTE type: %d",
02351 (int) rte->rtekind);
02352 break;
02353 }
02354 break;
02355 }
02356 }
02357 if (rt == NULL)
02358 ereport(ERROR,
02359 (errcode(ERRCODE_UNDEFINED_TABLE),
02360 errmsg("relation \"%s\" in row-level lock clause not found in FROM clause",
02361 thisrel->relname),
02362 parser_errposition(pstate, thisrel->location)));
02363 }
02364 }
02365 }
02366
02367
02368
02369
02370 void
02371 applyLockingClause(Query *qry, Index rtindex,
02372 LockClauseStrength strength, bool noWait, bool pushedDown)
02373 {
02374 RowMarkClause *rc;
02375
02376
02377 if (!pushedDown)
02378 qry->hasForUpdate = true;
02379
02380
02381 if ((rc = get_parse_rowmark(qry, rtindex)) != NULL)
02382 {
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396 rc->strength = Max(rc->strength, strength);
02397 rc->noWait |= noWait;
02398 rc->pushedDown &= pushedDown;
02399 return;
02400 }
02401
02402
02403 rc = makeNode(RowMarkClause);
02404 rc->rti = rtindex;
02405 rc->strength = strength;
02406 rc->noWait = noWait;
02407 rc->pushedDown = pushedDown;
02408 qry->rowMarks = lappend(qry->rowMarks, rc);
02409 }