00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include "access/heapam.h"
00019 #include "catalog/heap.h"
00020 #include "catalog/pg_type.h"
00021 #include "commands/defrem.h"
00022 #include "nodes/makefuncs.h"
00023 #include "nodes/nodeFuncs.h"
00024 #include "optimizer/clauses.h"
00025 #include "optimizer/tlist.h"
00026 #include "parser/analyze.h"
00027 #include "parser/parsetree.h"
00028 #include "parser/parse_clause.h"
00029 #include "parser/parse_coerce.h"
00030 #include "parser/parse_collate.h"
00031 #include "parser/parse_expr.h"
00032 #include "parser/parse_oper.h"
00033 #include "parser/parse_relation.h"
00034 #include "parser/parse_target.h"
00035 #include "rewrite/rewriteManip.h"
00036 #include "utils/guc.h"
00037 #include "utils/lsyscache.h"
00038 #include "utils/rel.h"
00039
00040
00041
00042 #define makeDefaultNSItem(rte) makeNamespaceItem(rte, true, true, false, true)
00043
00044 static void extractRemainingColumns(List *common_colnames,
00045 List *src_colnames, List *src_colvars,
00046 List **res_colnames, List **res_colvars);
00047 static Node *transformJoinUsingClause(ParseState *pstate,
00048 RangeTblEntry *leftRTE, RangeTblEntry *rightRTE,
00049 List *leftVars, List *rightVars);
00050 static Node *transformJoinOnClause(ParseState *pstate, JoinExpr *j,
00051 List *namespace);
00052 static RangeTblEntry *transformTableEntry(ParseState *pstate, RangeVar *r);
00053 static RangeTblEntry *transformCTEReference(ParseState *pstate, RangeVar *r,
00054 CommonTableExpr *cte, Index levelsup);
00055 static RangeTblEntry *transformRangeSubselect(ParseState *pstate,
00056 RangeSubselect *r);
00057 static RangeTblEntry *transformRangeFunction(ParseState *pstate,
00058 RangeFunction *r);
00059 static Node *transformFromClauseItem(ParseState *pstate, Node *n,
00060 RangeTblEntry **top_rte, int *top_rti,
00061 List **namespace);
00062 static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype,
00063 Var *l_colvar, Var *r_colvar);
00064 static ParseNamespaceItem *makeNamespaceItem(RangeTblEntry *rte,
00065 bool rel_visible, bool cols_visible,
00066 bool lateral_only, bool lateral_ok);
00067 static void setNamespaceColumnVisibility(List *namespace, bool cols_visible);
00068 static void setNamespaceLateralState(List *namespace,
00069 bool lateral_only, bool lateral_ok);
00070 static void checkExprIsVarFree(ParseState *pstate, Node *n,
00071 const char *constructName);
00072 static TargetEntry *findTargetlistEntrySQL92(ParseState *pstate, Node *node,
00073 List **tlist, ParseExprKind exprKind);
00074 static TargetEntry *findTargetlistEntrySQL99(ParseState *pstate, Node *node,
00075 List **tlist, ParseExprKind exprKind);
00076 static int get_matching_location(int sortgroupref,
00077 List *sortgrouprefs, List *exprs);
00078 static List *addTargetToSortList(ParseState *pstate, TargetEntry *tle,
00079 List *sortlist, List *targetlist, SortBy *sortby,
00080 bool resolveUnknown);
00081 static List *addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
00082 List *grouplist, List *targetlist, int location,
00083 bool resolveUnknown);
00084 static WindowClause *findWindowClause(List *wclist, const char *name);
00085 static Node *transformFrameOffset(ParseState *pstate, int frameOptions,
00086 Node *clause);
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 void
00100 transformFromClause(ParseState *pstate, List *frmList)
00101 {
00102 ListCell *fl;
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 foreach(fl, frmList)
00114 {
00115 Node *n = lfirst(fl);
00116 RangeTblEntry *rte;
00117 int rtindex;
00118 List *namespace;
00119
00120 n = transformFromClauseItem(pstate, n,
00121 &rte,
00122 &rtindex,
00123 &namespace);
00124
00125 checkNameSpaceConflicts(pstate, pstate->p_namespace, namespace);
00126
00127
00128 setNamespaceLateralState(namespace, true, true);
00129
00130 pstate->p_joinlist = lappend(pstate->p_joinlist, n);
00131 pstate->p_namespace = list_concat(pstate->p_namespace, namespace);
00132 }
00133
00134
00135
00136
00137
00138
00139
00140 setNamespaceLateralState(pstate->p_namespace, false, true);
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 int
00166 setTargetTable(ParseState *pstate, RangeVar *relation,
00167 bool inh, bool alsoSource, AclMode requiredPerms)
00168 {
00169 RangeTblEntry *rte;
00170 int rtindex;
00171
00172
00173 if (pstate->p_target_relation != NULL)
00174 heap_close(pstate->p_target_relation, NoLock);
00175
00176
00177
00178
00179
00180
00181
00182
00183 pstate->p_target_relation = parserOpenTable(pstate, relation,
00184 RowExclusiveLock);
00185
00186
00187
00188
00189 rte = addRangeTableEntryForRelation(pstate, pstate->p_target_relation,
00190 relation->alias, inh, false);
00191 pstate->p_target_rangetblentry = rte;
00192
00193
00194 rtindex = list_length(pstate->p_rtable);
00195 Assert(rte == rt_fetch(rtindex, pstate->p_rtable));
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 rte->requiredPerms = requiredPerms;
00207
00208
00209
00210
00211 if (alsoSource)
00212 addRTEtoQuery(pstate, rte, true, true, true);
00213
00214 return rtindex;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 bool
00226 interpretInhOption(InhOption inhOpt)
00227 {
00228 switch (inhOpt)
00229 {
00230 case INH_NO:
00231 return false;
00232 case INH_YES:
00233 return true;
00234 case INH_DEFAULT:
00235 return SQL_inheritance;
00236 }
00237 elog(ERROR, "bogus InhOption value: %d", inhOpt);
00238 return false;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 bool
00252 interpretOidsOption(List *defList, bool allowOids)
00253 {
00254 ListCell *cell;
00255
00256
00257 foreach(cell, defList)
00258 {
00259 DefElem *def = (DefElem *) lfirst(cell);
00260
00261 if (def->defnamespace == NULL &&
00262 pg_strcasecmp(def->defname, "oids") == 0)
00263 {
00264 if (!allowOids)
00265 ereport(ERROR,
00266 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00267 errmsg("unrecognized parameter \"%s\"",
00268 def->defname)));
00269 return defGetBoolean(def);
00270 }
00271 }
00272
00273
00274 if (!allowOids)
00275 return false;
00276
00277
00278 return default_with_oids;
00279 }
00280
00281
00282
00283
00284 static void
00285 extractRemainingColumns(List *common_colnames,
00286 List *src_colnames, List *src_colvars,
00287 List **res_colnames, List **res_colvars)
00288 {
00289 List *new_colnames = NIL;
00290 List *new_colvars = NIL;
00291 ListCell *lnames,
00292 *lvars;
00293
00294 Assert(list_length(src_colnames) == list_length(src_colvars));
00295
00296 forboth(lnames, src_colnames, lvars, src_colvars)
00297 {
00298 char *colname = strVal(lfirst(lnames));
00299 bool match = false;
00300 ListCell *cnames;
00301
00302 foreach(cnames, common_colnames)
00303 {
00304 char *ccolname = strVal(lfirst(cnames));
00305
00306 if (strcmp(colname, ccolname) == 0)
00307 {
00308 match = true;
00309 break;
00310 }
00311 }
00312
00313 if (!match)
00314 {
00315 new_colnames = lappend(new_colnames, lfirst(lnames));
00316 new_colvars = lappend(new_colvars, lfirst(lvars));
00317 }
00318 }
00319
00320 *res_colnames = new_colnames;
00321 *res_colvars = new_colvars;
00322 }
00323
00324
00325
00326
00327
00328
00329 static Node *
00330 transformJoinUsingClause(ParseState *pstate,
00331 RangeTblEntry *leftRTE, RangeTblEntry *rightRTE,
00332 List *leftVars, List *rightVars)
00333 {
00334 Node *result = NULL;
00335 ListCell *lvars,
00336 *rvars;
00337
00338
00339
00340
00341
00342
00343
00344
00345 forboth(lvars, leftVars, rvars, rightVars)
00346 {
00347 Var *lvar = (Var *) lfirst(lvars);
00348 Var *rvar = (Var *) lfirst(rvars);
00349 A_Expr *e;
00350
00351
00352 markVarForSelectPriv(pstate, lvar, leftRTE);
00353 markVarForSelectPriv(pstate, rvar, rightRTE);
00354
00355
00356 e = makeSimpleA_Expr(AEXPR_OP, "=",
00357 copyObject(lvar), copyObject(rvar),
00358 -1);
00359
00360
00361 if (result == NULL)
00362 result = (Node *) e;
00363 else
00364 {
00365 A_Expr *a;
00366
00367 a = makeA_Expr(AEXPR_AND, NIL, result, (Node *) e, -1);
00368 result = (Node *) a;
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 result = transformExpr(pstate, result, EXPR_KIND_JOIN_USING);
00379
00380 result = coerce_to_boolean(pstate, result, "JOIN/USING");
00381
00382 return result;
00383 }
00384
00385
00386
00387
00388
00389 static Node *
00390 transformJoinOnClause(ParseState *pstate, JoinExpr *j, List *namespace)
00391 {
00392 Node *result;
00393 List *save_namespace;
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 setNamespaceLateralState(namespace, false, true);
00404
00405 save_namespace = pstate->p_namespace;
00406 pstate->p_namespace = namespace;
00407
00408 result = transformWhereClause(pstate, j->quals,
00409 EXPR_KIND_JOIN_ON, "JOIN/ON");
00410
00411 pstate->p_namespace = save_namespace;
00412
00413 return result;
00414 }
00415
00416
00417
00418
00419 static RangeTblEntry *
00420 transformTableEntry(ParseState *pstate, RangeVar *r)
00421 {
00422 RangeTblEntry *rte;
00423
00424
00425 rte = addRangeTableEntry(pstate, r, r->alias,
00426 interpretInhOption(r->inhOpt), true);
00427
00428 return rte;
00429 }
00430
00431
00432
00433
00434
00435 static RangeTblEntry *
00436 transformCTEReference(ParseState *pstate, RangeVar *r,
00437 CommonTableExpr *cte, Index levelsup)
00438 {
00439 RangeTblEntry *rte;
00440
00441 rte = addRangeTableEntryForCTE(pstate, cte, levelsup, r, true);
00442
00443 return rte;
00444 }
00445
00446
00447
00448
00449 static RangeTblEntry *
00450 transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
00451 {
00452 Query *query;
00453 RangeTblEntry *rte;
00454
00455
00456
00457
00458
00459
00460
00461
00462 if (r->alias == NULL)
00463 elog(ERROR, "subquery in FROM must have an alias");
00464
00465
00466
00467
00468
00469
00470 Assert(pstate->p_expr_kind == EXPR_KIND_NONE);
00471 pstate->p_expr_kind = EXPR_KIND_FROM_SUBSELECT;
00472
00473
00474
00475
00476
00477
00478 Assert(!pstate->p_lateral_active);
00479 pstate->p_lateral_active = r->lateral;
00480
00481
00482
00483
00484 query = parse_sub_analyze(r->subquery, pstate, NULL,
00485 isLockedRefname(pstate, r->alias->aliasname));
00486
00487
00488 pstate->p_lateral_active = false;
00489 pstate->p_expr_kind = EXPR_KIND_NONE;
00490
00491
00492
00493
00494
00495 if (!IsA(query, Query) ||
00496 query->commandType != CMD_SELECT ||
00497 query->utilityStmt != NULL)
00498 elog(ERROR, "unexpected non-SELECT command in subquery in FROM");
00499
00500
00501
00502
00503 rte = addRangeTableEntryForSubquery(pstate,
00504 query,
00505 r->alias,
00506 r->lateral,
00507 true);
00508
00509 return rte;
00510 }
00511
00512
00513
00514
00515
00516 static RangeTblEntry *
00517 transformRangeFunction(ParseState *pstate, RangeFunction *r)
00518 {
00519 Node *funcexpr;
00520 char *funcname;
00521 bool is_lateral;
00522 RangeTblEntry *rte;
00523
00524
00525
00526
00527
00528
00529
00530 funcname = FigureColname(r->funccallnode);
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 Assert(!pstate->p_lateral_active);
00542 pstate->p_lateral_active = true;
00543
00544
00545
00546
00547 funcexpr = transformExpr(pstate, r->funccallnode, EXPR_KIND_FROM_FUNCTION);
00548
00549 pstate->p_lateral_active = false;
00550
00551
00552
00553
00554 assign_expr_collations(pstate, funcexpr);
00555
00556
00557
00558
00559
00560 is_lateral = r->lateral || contain_vars_of_level(funcexpr, 0);
00561
00562
00563
00564
00565 rte = addRangeTableEntryForFunction(pstate, funcname, funcexpr,
00566 r, is_lateral, true);
00567
00568
00569
00570
00571
00572
00573
00574 if (r->coldeflist)
00575 {
00576 TupleDesc tupdesc;
00577
00578 tupdesc = BuildDescFromLists(rte->eref->colnames,
00579 rte->funccoltypes,
00580 rte->funccoltypmods,
00581 rte->funccolcollations);
00582 CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE, false);
00583 }
00584
00585 return rte;
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 static Node *
00611 transformFromClauseItem(ParseState *pstate, Node *n,
00612 RangeTblEntry **top_rte, int *top_rti,
00613 List **namespace)
00614 {
00615 if (IsA(n, RangeVar))
00616 {
00617
00618 RangeVar *rv = (RangeVar *) n;
00619 RangeTblRef *rtr;
00620 RangeTblEntry *rte = NULL;
00621 int rtindex;
00622
00623
00624 if (!rv->schemaname)
00625 {
00626 CommonTableExpr *cte;
00627 Index levelsup;
00628
00629 cte = scanNameSpaceForCTE(pstate, rv->relname, &levelsup);
00630 if (cte)
00631 rte = transformCTEReference(pstate, rv, cte, levelsup);
00632 }
00633
00634
00635 if (!rte)
00636 rte = transformTableEntry(pstate, rv);
00637
00638
00639 rtindex = list_length(pstate->p_rtable);
00640 Assert(rte == rt_fetch(rtindex, pstate->p_rtable));
00641 *top_rte = rte;
00642 *top_rti = rtindex;
00643 *namespace = list_make1(makeDefaultNSItem(rte));
00644 rtr = makeNode(RangeTblRef);
00645 rtr->rtindex = rtindex;
00646 return (Node *) rtr;
00647 }
00648 else if (IsA(n, RangeSubselect))
00649 {
00650
00651 RangeTblRef *rtr;
00652 RangeTblEntry *rte;
00653 int rtindex;
00654
00655 rte = transformRangeSubselect(pstate, (RangeSubselect *) n);
00656
00657 rtindex = list_length(pstate->p_rtable);
00658 Assert(rte == rt_fetch(rtindex, pstate->p_rtable));
00659 *top_rte = rte;
00660 *top_rti = rtindex;
00661 *namespace = list_make1(makeDefaultNSItem(rte));
00662 rtr = makeNode(RangeTblRef);
00663 rtr->rtindex = rtindex;
00664 return (Node *) rtr;
00665 }
00666 else if (IsA(n, RangeFunction))
00667 {
00668
00669 RangeTblRef *rtr;
00670 RangeTblEntry *rte;
00671 int rtindex;
00672
00673 rte = transformRangeFunction(pstate, (RangeFunction *) n);
00674
00675 rtindex = list_length(pstate->p_rtable);
00676 Assert(rte == rt_fetch(rtindex, pstate->p_rtable));
00677 *top_rte = rte;
00678 *top_rti = rtindex;
00679 *namespace = list_make1(makeDefaultNSItem(rte));
00680 rtr = makeNode(RangeTblRef);
00681 rtr->rtindex = rtindex;
00682 return (Node *) rtr;
00683 }
00684 else if (IsA(n, JoinExpr))
00685 {
00686
00687 JoinExpr *j = (JoinExpr *) n;
00688 RangeTblEntry *l_rte;
00689 RangeTblEntry *r_rte;
00690 int l_rtindex;
00691 int r_rtindex;
00692 List *l_namespace,
00693 *r_namespace,
00694 *my_namespace,
00695 *l_colnames,
00696 *r_colnames,
00697 *res_colnames,
00698 *l_colvars,
00699 *r_colvars,
00700 *res_colvars;
00701 bool lateral_ok;
00702 int sv_namespace_length;
00703 RangeTblEntry *rte;
00704 int k;
00705
00706
00707
00708
00709
00710 j->larg = transformFromClauseItem(pstate, j->larg,
00711 &l_rte,
00712 &l_rtindex,
00713 &l_namespace);
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 lateral_ok = (j->jointype == JOIN_INNER || j->jointype == JOIN_LEFT);
00728 setNamespaceLateralState(l_namespace, true, lateral_ok);
00729
00730 checkNameSpaceConflicts(pstate, pstate->p_namespace, l_namespace);
00731
00732 sv_namespace_length = list_length(pstate->p_namespace);
00733 pstate->p_namespace = list_concat(pstate->p_namespace, l_namespace);
00734
00735
00736 j->rarg = transformFromClauseItem(pstate, j->rarg,
00737 &r_rte,
00738 &r_rtindex,
00739 &r_namespace);
00740
00741
00742 pstate->p_namespace = list_truncate(pstate->p_namespace,
00743 sv_namespace_length);
00744
00745
00746
00747
00748
00749
00750 checkNameSpaceConflicts(pstate, l_namespace, r_namespace);
00751
00752
00753
00754
00755 my_namespace = list_concat(l_namespace, r_namespace);
00756
00757
00758
00759
00760
00761
00762 expandRTE(l_rte, l_rtindex, 0, -1, false,
00763 &l_colnames, &l_colvars);
00764 expandRTE(r_rte, r_rtindex, 0, -1, false,
00765 &r_colnames, &r_colvars);
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 if (j->isNatural)
00777 {
00778 List *rlist = NIL;
00779 ListCell *lx,
00780 *rx;
00781
00782 Assert(j->usingClause == NIL);
00783
00784 foreach(lx, l_colnames)
00785 {
00786 char *l_colname = strVal(lfirst(lx));
00787 Value *m_name = NULL;
00788
00789 foreach(rx, r_colnames)
00790 {
00791 char *r_colname = strVal(lfirst(rx));
00792
00793 if (strcmp(l_colname, r_colname) == 0)
00794 {
00795 m_name = makeString(l_colname);
00796 break;
00797 }
00798 }
00799
00800
00801 if (m_name != NULL)
00802 rlist = lappend(rlist, m_name);
00803 }
00804
00805 j->usingClause = rlist;
00806 }
00807
00808
00809
00810
00811 res_colnames = NIL;
00812 res_colvars = NIL;
00813
00814 if (j->usingClause)
00815 {
00816
00817
00818
00819
00820
00821 List *ucols = j->usingClause;
00822 List *l_usingvars = NIL;
00823 List *r_usingvars = NIL;
00824 ListCell *ucol;
00825
00826 Assert(j->quals == NULL);
00827
00828 foreach(ucol, ucols)
00829 {
00830 char *u_colname = strVal(lfirst(ucol));
00831 ListCell *col;
00832 int ndx;
00833 int l_index = -1;
00834 int r_index = -1;
00835 Var *l_colvar,
00836 *r_colvar;
00837
00838
00839 foreach(col, res_colnames)
00840 {
00841 char *res_colname = strVal(lfirst(col));
00842
00843 if (strcmp(res_colname, u_colname) == 0)
00844 ereport(ERROR,
00845 (errcode(ERRCODE_DUPLICATE_COLUMN),
00846 errmsg("column name \"%s\" appears more than once in USING clause",
00847 u_colname)));
00848 }
00849
00850
00851 ndx = 0;
00852 foreach(col, l_colnames)
00853 {
00854 char *l_colname = strVal(lfirst(col));
00855
00856 if (strcmp(l_colname, u_colname) == 0)
00857 {
00858 if (l_index >= 0)
00859 ereport(ERROR,
00860 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00861 errmsg("common column name \"%s\" appears more than once in left table",
00862 u_colname)));
00863 l_index = ndx;
00864 }
00865 ndx++;
00866 }
00867 if (l_index < 0)
00868 ereport(ERROR,
00869 (errcode(ERRCODE_UNDEFINED_COLUMN),
00870 errmsg("column \"%s\" specified in USING clause does not exist in left table",
00871 u_colname)));
00872
00873
00874 ndx = 0;
00875 foreach(col, r_colnames)
00876 {
00877 char *r_colname = strVal(lfirst(col));
00878
00879 if (strcmp(r_colname, u_colname) == 0)
00880 {
00881 if (r_index >= 0)
00882 ereport(ERROR,
00883 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00884 errmsg("common column name \"%s\" appears more than once in right table",
00885 u_colname)));
00886 r_index = ndx;
00887 }
00888 ndx++;
00889 }
00890 if (r_index < 0)
00891 ereport(ERROR,
00892 (errcode(ERRCODE_UNDEFINED_COLUMN),
00893 errmsg("column \"%s\" specified in USING clause does not exist in right table",
00894 u_colname)));
00895
00896 l_colvar = list_nth(l_colvars, l_index);
00897 l_usingvars = lappend(l_usingvars, l_colvar);
00898 r_colvar = list_nth(r_colvars, r_index);
00899 r_usingvars = lappend(r_usingvars, r_colvar);
00900
00901 res_colnames = lappend(res_colnames, lfirst(ucol));
00902 res_colvars = lappend(res_colvars,
00903 buildMergedJoinVar(pstate,
00904 j->jointype,
00905 l_colvar,
00906 r_colvar));
00907 }
00908
00909 j->quals = transformJoinUsingClause(pstate,
00910 l_rte,
00911 r_rte,
00912 l_usingvars,
00913 r_usingvars);
00914 }
00915 else if (j->quals)
00916 {
00917
00918 j->quals = transformJoinOnClause(pstate, j, my_namespace);
00919 }
00920 else
00921 {
00922
00923 }
00924
00925
00926 extractRemainingColumns(res_colnames,
00927 l_colnames, l_colvars,
00928 &l_colnames, &l_colvars);
00929 extractRemainingColumns(res_colnames,
00930 r_colnames, r_colvars,
00931 &r_colnames, &r_colvars);
00932 res_colnames = list_concat(res_colnames, l_colnames);
00933 res_colvars = list_concat(res_colvars, l_colvars);
00934 res_colnames = list_concat(res_colnames, r_colnames);
00935 res_colvars = list_concat(res_colvars, r_colvars);
00936
00937
00938
00939
00940 if (j->alias)
00941 {
00942 if (j->alias->colnames != NIL)
00943 {
00944 if (list_length(j->alias->colnames) > list_length(res_colnames))
00945 ereport(ERROR,
00946 (errcode(ERRCODE_SYNTAX_ERROR),
00947 errmsg("column alias list for \"%s\" has too many entries",
00948 j->alias->aliasname)));
00949 }
00950 }
00951
00952
00953
00954
00955 rte = addRangeTableEntryForJoin(pstate,
00956 res_colnames,
00957 j->jointype,
00958 res_colvars,
00959 j->alias,
00960 true);
00961
00962
00963 j->rtindex = list_length(pstate->p_rtable);
00964 Assert(rte == rt_fetch(j->rtindex, pstate->p_rtable));
00965
00966 *top_rte = rte;
00967 *top_rti = j->rtindex;
00968
00969
00970 for (k = list_length(pstate->p_joinexprs) + 1; k < j->rtindex; k++)
00971 pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
00972 pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
00973 Assert(list_length(pstate->p_joinexprs) == j->rtindex);
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 if (j->alias != NULL)
00987 my_namespace = NIL;
00988 else
00989 setNamespaceColumnVisibility(my_namespace, false);
00990
00991
00992
00993
00994
00995 *namespace = lappend(my_namespace,
00996 makeNamespaceItem(rte,
00997 (j->alias != NULL),
00998 true,
00999 false,
01000 true));
01001
01002 return (Node *) j;
01003 }
01004 else
01005 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(n));
01006 return NULL;
01007 }
01008
01009
01010
01011
01012
01013 static Node *
01014 buildMergedJoinVar(ParseState *pstate, JoinType jointype,
01015 Var *l_colvar, Var *r_colvar)
01016 {
01017 Oid outcoltype;
01018 int32 outcoltypmod;
01019 Node *l_node,
01020 *r_node,
01021 *res_node;
01022
01023
01024
01025
01026 outcoltype = l_colvar->vartype;
01027 outcoltypmod = l_colvar->vartypmod;
01028 if (outcoltype != r_colvar->vartype)
01029 {
01030 outcoltype = select_common_type(pstate,
01031 list_make2(l_colvar, r_colvar),
01032 "JOIN/USING",
01033 NULL);
01034 outcoltypmod = -1;
01035 }
01036 else if (outcoltypmod != r_colvar->vartypmod)
01037 {
01038
01039 outcoltypmod = -1;
01040 }
01041
01042
01043
01044
01045
01046
01047
01048 if (l_colvar->vartype != outcoltype)
01049 l_node = coerce_type(pstate, (Node *) l_colvar, l_colvar->vartype,
01050 outcoltype, outcoltypmod,
01051 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
01052 else if (l_colvar->vartypmod != outcoltypmod)
01053 l_node = (Node *) makeRelabelType((Expr *) l_colvar,
01054 outcoltype, outcoltypmod,
01055 InvalidOid,
01056 COERCE_IMPLICIT_CAST);
01057 else
01058 l_node = (Node *) l_colvar;
01059
01060 if (r_colvar->vartype != outcoltype)
01061 r_node = coerce_type(pstate, (Node *) r_colvar, r_colvar->vartype,
01062 outcoltype, outcoltypmod,
01063 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
01064 else if (r_colvar->vartypmod != outcoltypmod)
01065 r_node = (Node *) makeRelabelType((Expr *) r_colvar,
01066 outcoltype, outcoltypmod,
01067 InvalidOid,
01068 COERCE_IMPLICIT_CAST);
01069 else
01070 r_node = (Node *) r_colvar;
01071
01072
01073
01074
01075 switch (jointype)
01076 {
01077 case JOIN_INNER:
01078
01079
01080
01081
01082 if (IsA(l_node, Var))
01083 res_node = l_node;
01084 else if (IsA(r_node, Var))
01085 res_node = r_node;
01086 else
01087 res_node = l_node;
01088 break;
01089 case JOIN_LEFT:
01090
01091 res_node = l_node;
01092 break;
01093 case JOIN_RIGHT:
01094
01095 res_node = r_node;
01096 break;
01097 case JOIN_FULL:
01098 {
01099
01100
01101
01102
01103 CoalesceExpr *c = makeNode(CoalesceExpr);
01104
01105 c->coalescetype = outcoltype;
01106
01107 c->args = list_make2(l_node, r_node);
01108 c->location = -1;
01109 res_node = (Node *) c;
01110 break;
01111 }
01112 default:
01113 elog(ERROR, "unrecognized join type: %d", (int) jointype);
01114 res_node = NULL;
01115 break;
01116 }
01117
01118
01119
01120
01121
01122
01123 assign_expr_collations(pstate, res_node);
01124
01125 return res_node;
01126 }
01127
01128
01129
01130
01131
01132 static ParseNamespaceItem *
01133 makeNamespaceItem(RangeTblEntry *rte, bool rel_visible, bool cols_visible,
01134 bool lateral_only, bool lateral_ok)
01135 {
01136 ParseNamespaceItem *nsitem;
01137
01138 nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
01139 nsitem->p_rte = rte;
01140 nsitem->p_rel_visible = rel_visible;
01141 nsitem->p_cols_visible = cols_visible;
01142 nsitem->p_lateral_only = lateral_only;
01143 nsitem->p_lateral_ok = lateral_ok;
01144 return nsitem;
01145 }
01146
01147
01148
01149
01150
01151 static void
01152 setNamespaceColumnVisibility(List *namespace, bool cols_visible)
01153 {
01154 ListCell *lc;
01155
01156 foreach(lc, namespace)
01157 {
01158 ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);
01159
01160 nsitem->p_cols_visible = cols_visible;
01161 }
01162 }
01163
01164
01165
01166
01167
01168 static void
01169 setNamespaceLateralState(List *namespace, bool lateral_only, bool lateral_ok)
01170 {
01171 ListCell *lc;
01172
01173 foreach(lc, namespace)
01174 {
01175 ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);
01176
01177 nsitem->p_lateral_only = lateral_only;
01178 nsitem->p_lateral_ok = lateral_ok;
01179 }
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 Node *
01191 transformWhereClause(ParseState *pstate, Node *clause,
01192 ParseExprKind exprKind, const char *constructName)
01193 {
01194 Node *qual;
01195
01196 if (clause == NULL)
01197 return NULL;
01198
01199 qual = transformExpr(pstate, clause, exprKind);
01200
01201 qual = coerce_to_boolean(pstate, qual, constructName);
01202
01203 return qual;
01204 }
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 Node *
01218 transformLimitClause(ParseState *pstate, Node *clause,
01219 ParseExprKind exprKind, const char *constructName)
01220 {
01221 Node *qual;
01222
01223 if (clause == NULL)
01224 return NULL;
01225
01226 qual = transformExpr(pstate, clause, exprKind);
01227
01228 qual = coerce_to_specific_type(pstate, qual, INT8OID, constructName);
01229
01230
01231 checkExprIsVarFree(pstate, qual, constructName);
01232
01233 return qual;
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 static void
01249 checkExprIsVarFree(ParseState *pstate, Node *n, const char *constructName)
01250 {
01251 if (contain_vars_of_level(n, 0))
01252 {
01253 ereport(ERROR,
01254 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01255
01256 errmsg("argument of %s must not contain variables",
01257 constructName),
01258 parser_errposition(pstate,
01259 locate_var_of_level(n, 0))));
01260 }
01261 }
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273 static void
01274 checkTargetlistEntrySQL92(ParseState *pstate, TargetEntry *tle,
01275 ParseExprKind exprKind)
01276 {
01277 switch (exprKind)
01278 {
01279 case EXPR_KIND_GROUP_BY:
01280
01281 if (pstate->p_hasAggs &&
01282 contain_aggs_of_level((Node *) tle->expr, 0))
01283 ereport(ERROR,
01284 (errcode(ERRCODE_GROUPING_ERROR),
01285
01286 errmsg("aggregate functions are not allowed in %s",
01287 ParseExprKindName(exprKind)),
01288 parser_errposition(pstate,
01289 locate_agg_of_level((Node *) tle->expr, 0))));
01290 if (pstate->p_hasWindowFuncs &&
01291 contain_windowfuncs((Node *) tle->expr))
01292 ereport(ERROR,
01293 (errcode(ERRCODE_WINDOWING_ERROR),
01294
01295 errmsg("window functions are not allowed in %s",
01296 ParseExprKindName(exprKind)),
01297 parser_errposition(pstate,
01298 locate_windowfunc((Node *) tle->expr))));
01299 break;
01300 case EXPR_KIND_ORDER_BY:
01301
01302 break;
01303 case EXPR_KIND_DISTINCT_ON:
01304
01305 break;
01306 default:
01307 elog(ERROR, "unexpected exprKind in checkTargetlistEntrySQL92");
01308 break;
01309 }
01310 }
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329 static TargetEntry *
01330 findTargetlistEntrySQL92(ParseState *pstate, Node *node, List **tlist,
01331 ParseExprKind exprKind)
01332 {
01333 ListCell *tl;
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373 if (IsA(node, ColumnRef) &&
01374 list_length(((ColumnRef *) node)->fields) == 1 &&
01375 IsA(linitial(((ColumnRef *) node)->fields), String))
01376 {
01377 char *name = strVal(linitial(((ColumnRef *) node)->fields));
01378 int location = ((ColumnRef *) node)->location;
01379
01380 if (exprKind == EXPR_KIND_GROUP_BY)
01381 {
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 if (colNameToVar(pstate, name, true, location) != NULL)
01399 name = NULL;
01400 }
01401
01402 if (name != NULL)
01403 {
01404 TargetEntry *target_result = NULL;
01405
01406 foreach(tl, *tlist)
01407 {
01408 TargetEntry *tle = (TargetEntry *) lfirst(tl);
01409
01410 if (!tle->resjunk &&
01411 strcmp(tle->resname, name) == 0)
01412 {
01413 if (target_result != NULL)
01414 {
01415 if (!equal(target_result->expr, tle->expr))
01416 ereport(ERROR,
01417 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
01418
01419
01420
01421 errmsg("%s \"%s\" is ambiguous",
01422 ParseExprKindName(exprKind),
01423 name),
01424 parser_errposition(pstate, location)));
01425 }
01426 else
01427 target_result = tle;
01428
01429 }
01430 }
01431 if (target_result != NULL)
01432 {
01433
01434 checkTargetlistEntrySQL92(pstate, target_result, exprKind);
01435 return target_result;
01436 }
01437 }
01438 }
01439 if (IsA(node, A_Const))
01440 {
01441 Value *val = &((A_Const *) node)->val;
01442 int location = ((A_Const *) node)->location;
01443 int targetlist_pos = 0;
01444 int target_pos;
01445
01446 if (!IsA(val, Integer))
01447 ereport(ERROR,
01448 (errcode(ERRCODE_SYNTAX_ERROR),
01449
01450 errmsg("non-integer constant in %s",
01451 ParseExprKindName(exprKind)),
01452 parser_errposition(pstate, location)));
01453
01454 target_pos = intVal(val);
01455 foreach(tl, *tlist)
01456 {
01457 TargetEntry *tle = (TargetEntry *) lfirst(tl);
01458
01459 if (!tle->resjunk)
01460 {
01461 if (++targetlist_pos == target_pos)
01462 {
01463
01464 checkTargetlistEntrySQL92(pstate, tle, exprKind);
01465 return tle;
01466 }
01467 }
01468 }
01469 ereport(ERROR,
01470 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01471
01472 errmsg("%s position %d is not in select list",
01473 ParseExprKindName(exprKind), target_pos),
01474 parser_errposition(pstate, location)));
01475 }
01476
01477
01478
01479
01480 return findTargetlistEntrySQL99(pstate, node, tlist, exprKind);
01481 }
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496 static TargetEntry *
01497 findTargetlistEntrySQL99(ParseState *pstate, Node *node, List **tlist,
01498 ParseExprKind exprKind)
01499 {
01500 TargetEntry *target_result;
01501 ListCell *tl;
01502 Node *expr;
01503
01504
01505
01506
01507
01508
01509
01510
01511 expr = transformExpr(pstate, node, exprKind);
01512
01513 foreach(tl, *tlist)
01514 {
01515 TargetEntry *tle = (TargetEntry *) lfirst(tl);
01516 Node *texpr;
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527 texpr = strip_implicit_coercions((Node *) tle->expr);
01528
01529 if (equal(expr, texpr))
01530 return tle;
01531 }
01532
01533
01534
01535
01536
01537
01538 target_result = transformTargetEntry(pstate, node, expr, exprKind,
01539 NULL, true);
01540
01541 *tlist = lappend(*tlist, target_result);
01542
01543 return target_result;
01544 }
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 List *
01557 transformGroupClause(ParseState *pstate, List *grouplist,
01558 List **targetlist, List *sortClause,
01559 ParseExprKind exprKind, bool useSQL99)
01560 {
01561 List *result = NIL;
01562 ListCell *gl;
01563
01564 foreach(gl, grouplist)
01565 {
01566 Node *gexpr = (Node *) lfirst(gl);
01567 TargetEntry *tle;
01568 bool found = false;
01569
01570 if (useSQL99)
01571 tle = findTargetlistEntrySQL99(pstate, gexpr,
01572 targetlist, exprKind);
01573 else
01574 tle = findTargetlistEntrySQL92(pstate, gexpr,
01575 targetlist, exprKind);
01576
01577
01578 if (targetIsInSortList(tle, InvalidOid, result))
01579 continue;
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592 if (tle->ressortgroupref > 0)
01593 {
01594 ListCell *sl;
01595
01596 foreach(sl, sortClause)
01597 {
01598 SortGroupClause *sc = (SortGroupClause *) lfirst(sl);
01599
01600 if (sc->tleSortGroupRef == tle->ressortgroupref)
01601 {
01602 result = lappend(result, copyObject(sc));
01603 found = true;
01604 break;
01605 }
01606 }
01607 }
01608
01609
01610
01611
01612
01613 if (!found)
01614 result = addTargetToGroupList(pstate, tle,
01615 result, *targetlist,
01616 exprLocation(gexpr),
01617 true);
01618 }
01619
01620 return result;
01621 }
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633 List *
01634 transformSortClause(ParseState *pstate,
01635 List *orderlist,
01636 List **targetlist,
01637 ParseExprKind exprKind,
01638 bool resolveUnknown,
01639 bool useSQL99)
01640 {
01641 List *sortlist = NIL;
01642 ListCell *olitem;
01643
01644 foreach(olitem, orderlist)
01645 {
01646 SortBy *sortby = (SortBy *) lfirst(olitem);
01647 TargetEntry *tle;
01648
01649 if (useSQL99)
01650 tle = findTargetlistEntrySQL99(pstate, sortby->node,
01651 targetlist, exprKind);
01652 else
01653 tle = findTargetlistEntrySQL92(pstate, sortby->node,
01654 targetlist, exprKind);
01655
01656 sortlist = addTargetToSortList(pstate, tle,
01657 sortlist, *targetlist, sortby,
01658 resolveUnknown);
01659 }
01660
01661 return sortlist;
01662 }
01663
01664
01665
01666
01667
01668 List *
01669 transformWindowDefinitions(ParseState *pstate,
01670 List *windowdefs,
01671 List **targetlist)
01672 {
01673 List *result = NIL;
01674 Index winref = 0;
01675 ListCell *lc;
01676
01677 foreach(lc, windowdefs)
01678 {
01679 WindowDef *windef = (WindowDef *) lfirst(lc);
01680 WindowClause *refwc = NULL;
01681 List *partitionClause;
01682 List *orderClause;
01683 WindowClause *wc;
01684
01685 winref++;
01686
01687
01688
01689
01690 if (windef->name &&
01691 findWindowClause(result, windef->name) != NULL)
01692 ereport(ERROR,
01693 (errcode(ERRCODE_WINDOWING_ERROR),
01694 errmsg("window \"%s\" is already defined", windef->name),
01695 parser_errposition(pstate, windef->location)));
01696
01697
01698
01699
01700 if (windef->refname)
01701 {
01702 refwc = findWindowClause(result, windef->refname);
01703 if (refwc == NULL)
01704 ereport(ERROR,
01705 (errcode(ERRCODE_UNDEFINED_OBJECT),
01706 errmsg("window \"%s\" does not exist",
01707 windef->refname),
01708 parser_errposition(pstate, windef->location)));
01709 }
01710
01711
01712
01713
01714
01715
01716 orderClause = transformSortClause(pstate,
01717 windef->orderClause,
01718 targetlist,
01719 EXPR_KIND_WINDOW_ORDER,
01720 true ,
01721 true );
01722 partitionClause = transformGroupClause(pstate,
01723 windef->partitionClause,
01724 targetlist,
01725 orderClause,
01726 EXPR_KIND_WINDOW_PARTITION,
01727 true );
01728
01729
01730
01731
01732 wc = makeNode(WindowClause);
01733 wc->name = windef->name;
01734 wc->refname = windef->refname;
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 if (refwc)
01746 {
01747 if (partitionClause)
01748 ereport(ERROR,
01749 (errcode(ERRCODE_WINDOWING_ERROR),
01750 errmsg("cannot override PARTITION BY clause of window \"%s\"",
01751 windef->refname),
01752 parser_errposition(pstate, windef->location)));
01753 wc->partitionClause = copyObject(refwc->partitionClause);
01754 }
01755 else
01756 wc->partitionClause = partitionClause;
01757 if (refwc)
01758 {
01759 if (orderClause && refwc->orderClause)
01760 ereport(ERROR,
01761 (errcode(ERRCODE_WINDOWING_ERROR),
01762 errmsg("cannot override ORDER BY clause of window \"%s\"",
01763 windef->refname),
01764 parser_errposition(pstate, windef->location)));
01765 if (orderClause)
01766 {
01767 wc->orderClause = orderClause;
01768 wc->copiedOrder = false;
01769 }
01770 else
01771 {
01772 wc->orderClause = copyObject(refwc->orderClause);
01773 wc->copiedOrder = true;
01774 }
01775 }
01776 else
01777 {
01778 wc->orderClause = orderClause;
01779 wc->copiedOrder = false;
01780 }
01781 if (refwc && refwc->frameOptions != FRAMEOPTION_DEFAULTS)
01782 ereport(ERROR,
01783 (errcode(ERRCODE_WINDOWING_ERROR),
01784 errmsg("cannot override frame clause of window \"%s\"",
01785 windef->refname),
01786 parser_errposition(pstate, windef->location)));
01787 wc->frameOptions = windef->frameOptions;
01788
01789 wc->startOffset = transformFrameOffset(pstate, wc->frameOptions,
01790 windef->startOffset);
01791 wc->endOffset = transformFrameOffset(pstate, wc->frameOptions,
01792 windef->endOffset);
01793 wc->winref = winref;
01794
01795 result = lappend(result, wc);
01796 }
01797
01798 return result;
01799 }
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818 List *
01819 transformDistinctClause(ParseState *pstate,
01820 List **targetlist, List *sortClause, bool is_agg)
01821 {
01822 List *result = NIL;
01823 ListCell *slitem;
01824 ListCell *tlitem;
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841 foreach(slitem, sortClause)
01842 {
01843 SortGroupClause *scl = (SortGroupClause *) lfirst(slitem);
01844 TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist);
01845
01846 if (tle->resjunk)
01847 ereport(ERROR,
01848 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01849 is_agg ?
01850 errmsg("in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list") :
01851 errmsg("for SELECT DISTINCT, ORDER BY expressions must appear in select list"),
01852 parser_errposition(pstate,
01853 exprLocation((Node *) tle->expr))));
01854 result = lappend(result, copyObject(scl));
01855 }
01856
01857
01858
01859
01860
01861 foreach(tlitem, *targetlist)
01862 {
01863 TargetEntry *tle = (TargetEntry *) lfirst(tlitem);
01864
01865 if (tle->resjunk)
01866 continue;
01867 result = addTargetToGroupList(pstate, tle,
01868 result, *targetlist,
01869 exprLocation((Node *) tle->expr),
01870 true);
01871 }
01872
01873 return result;
01874 }
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889 List *
01890 transformDistinctOnClause(ParseState *pstate, List *distinctlist,
01891 List **targetlist, List *sortClause)
01892 {
01893 List *result = NIL;
01894 List *sortgrouprefs = NIL;
01895 bool skipped_sortitem;
01896 ListCell *lc;
01897 ListCell *lc2;
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907 foreach(lc, distinctlist)
01908 {
01909 Node *dexpr = (Node *) lfirst(lc);
01910 int sortgroupref;
01911 TargetEntry *tle;
01912
01913 tle = findTargetlistEntrySQL92(pstate, dexpr, targetlist,
01914 EXPR_KIND_DISTINCT_ON);
01915 sortgroupref = assignSortGroupRef(tle, *targetlist);
01916 sortgrouprefs = lappend_int(sortgrouprefs, sortgroupref);
01917 }
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927 skipped_sortitem = false;
01928 foreach(lc, sortClause)
01929 {
01930 SortGroupClause *scl = (SortGroupClause *) lfirst(lc);
01931
01932 if (list_member_int(sortgrouprefs, scl->tleSortGroupRef))
01933 {
01934 if (skipped_sortitem)
01935 ereport(ERROR,
01936 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01937 errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
01938 parser_errposition(pstate,
01939 get_matching_location(scl->tleSortGroupRef,
01940 sortgrouprefs,
01941 distinctlist))));
01942 else
01943 result = lappend(result, copyObject(scl));
01944 }
01945 else
01946 skipped_sortitem = true;
01947 }
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958 forboth(lc, distinctlist, lc2, sortgrouprefs)
01959 {
01960 Node *dexpr = (Node *) lfirst(lc);
01961 int sortgroupref = lfirst_int(lc2);
01962 TargetEntry *tle = get_sortgroupref_tle(sortgroupref, *targetlist);
01963
01964 if (targetIsInSortList(tle, InvalidOid, result))
01965 continue;
01966 if (skipped_sortitem)
01967 ereport(ERROR,
01968 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01969 errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
01970 parser_errposition(pstate, exprLocation(dexpr))));
01971 result = addTargetToGroupList(pstate, tle,
01972 result, *targetlist,
01973 exprLocation(dexpr),
01974 true);
01975 }
01976
01977 return result;
01978 }
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991 static int
01992 get_matching_location(int sortgroupref, List *sortgrouprefs, List *exprs)
01993 {
01994 ListCell *lcs;
01995 ListCell *lce;
01996
01997 forboth(lcs, sortgrouprefs, lce, exprs)
01998 {
01999 if (lfirst_int(lcs) == sortgroupref)
02000 return exprLocation((Node *) lfirst(lce));
02001 }
02002
02003 elog(ERROR, "get_matching_location: no matching sortgroupref");
02004 return -1;
02005 }
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020 static List *
02021 addTargetToSortList(ParseState *pstate, TargetEntry *tle,
02022 List *sortlist, List *targetlist, SortBy *sortby,
02023 bool resolveUnknown)
02024 {
02025 Oid restype = exprType((Node *) tle->expr);
02026 Oid sortop;
02027 Oid eqop;
02028 bool hashable;
02029 bool reverse;
02030 int location;
02031 ParseCallbackState pcbstate;
02032
02033
02034 if (restype == UNKNOWNOID && resolveUnknown)
02035 {
02036 tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
02037 restype, TEXTOID, -1,
02038 COERCION_IMPLICIT,
02039 COERCE_IMPLICIT_CAST,
02040 -1);
02041 restype = TEXTOID;
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052 location = sortby->location;
02053 if (location < 0)
02054 location = exprLocation(sortby->node);
02055 setup_parser_errposition_callback(&pcbstate, pstate, location);
02056
02057
02058 switch (sortby->sortby_dir)
02059 {
02060 case SORTBY_DEFAULT:
02061 case SORTBY_ASC:
02062 get_sort_group_operators(restype,
02063 true, true, false,
02064 &sortop, &eqop, NULL,
02065 &hashable);
02066 reverse = false;
02067 break;
02068 case SORTBY_DESC:
02069 get_sort_group_operators(restype,
02070 false, true, true,
02071 NULL, &eqop, &sortop,
02072 &hashable);
02073 reverse = true;
02074 break;
02075 case SORTBY_USING:
02076 Assert(sortby->useOp != NIL);
02077 sortop = compatible_oper_opid(sortby->useOp,
02078 restype,
02079 restype,
02080 false);
02081
02082
02083
02084
02085
02086
02087 eqop = get_equality_op_for_ordering_op(sortop, &reverse);
02088 if (!OidIsValid(eqop))
02089 ereport(ERROR,
02090 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
02091 errmsg("operator %s is not a valid ordering operator",
02092 strVal(llast(sortby->useOp))),
02093 errhint("Ordering operators must be \"<\" or \">\" members of btree operator families.")));
02094
02095
02096
02097
02098 hashable = op_hashjoinable(eqop, restype);
02099 break;
02100 default:
02101 elog(ERROR, "unrecognized sortby_dir: %d", sortby->sortby_dir);
02102 sortop = InvalidOid;
02103 eqop = InvalidOid;
02104 hashable = false;
02105 reverse = false;
02106 break;
02107 }
02108
02109 cancel_parser_errposition_callback(&pcbstate);
02110
02111
02112 if (!targetIsInSortList(tle, sortop, sortlist))
02113 {
02114 SortGroupClause *sortcl = makeNode(SortGroupClause);
02115
02116 sortcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
02117
02118 sortcl->eqop = eqop;
02119 sortcl->sortop = sortop;
02120 sortcl->hashable = hashable;
02121
02122 switch (sortby->sortby_nulls)
02123 {
02124 case SORTBY_NULLS_DEFAULT:
02125
02126 sortcl->nulls_first = reverse;
02127 break;
02128 case SORTBY_NULLS_FIRST:
02129 sortcl->nulls_first = true;
02130 break;
02131 case SORTBY_NULLS_LAST:
02132 sortcl->nulls_first = false;
02133 break;
02134 default:
02135 elog(ERROR, "unrecognized sortby_nulls: %d",
02136 sortby->sortby_nulls);
02137 break;
02138 }
02139
02140 sortlist = lappend(sortlist, sortcl);
02141 }
02142
02143 return sortlist;
02144 }
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169 static List *
02170 addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
02171 List *grouplist, List *targetlist, int location,
02172 bool resolveUnknown)
02173 {
02174 Oid restype = exprType((Node *) tle->expr);
02175
02176
02177 if (restype == UNKNOWNOID && resolveUnknown)
02178 {
02179 tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
02180 restype, TEXTOID, -1,
02181 COERCION_IMPLICIT,
02182 COERCE_IMPLICIT_CAST,
02183 -1);
02184 restype = TEXTOID;
02185 }
02186
02187
02188 if (!targetIsInSortList(tle, InvalidOid, grouplist))
02189 {
02190 SortGroupClause *grpcl = makeNode(SortGroupClause);
02191 Oid sortop;
02192 Oid eqop;
02193 bool hashable;
02194 ParseCallbackState pcbstate;
02195
02196 setup_parser_errposition_callback(&pcbstate, pstate, location);
02197
02198
02199 get_sort_group_operators(restype,
02200 false, true, false,
02201 &sortop, &eqop, NULL,
02202 &hashable);
02203
02204 cancel_parser_errposition_callback(&pcbstate);
02205
02206 grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
02207 grpcl->eqop = eqop;
02208 grpcl->sortop = sortop;
02209 grpcl->nulls_first = false;
02210 grpcl->hashable = hashable;
02211
02212 grouplist = lappend(grouplist, grpcl);
02213 }
02214
02215 return grouplist;
02216 }
02217
02218
02219
02220
02221
02222
02223
02224
02225 Index
02226 assignSortGroupRef(TargetEntry *tle, List *tlist)
02227 {
02228 Index maxRef;
02229 ListCell *l;
02230
02231 if (tle->ressortgroupref)
02232 return tle->ressortgroupref;
02233
02234
02235 maxRef = 0;
02236 foreach(l, tlist)
02237 {
02238 Index ref = ((TargetEntry *) lfirst(l))->ressortgroupref;
02239
02240 if (ref > maxRef)
02241 maxRef = ref;
02242 }
02243 tle->ressortgroupref = maxRef + 1;
02244 return tle->ressortgroupref;
02245 }
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266 bool
02267 targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList)
02268 {
02269 Index ref = tle->ressortgroupref;
02270 ListCell *l;
02271
02272
02273 if (ref == 0)
02274 return false;
02275
02276 foreach(l, sortList)
02277 {
02278 SortGroupClause *scl = (SortGroupClause *) lfirst(l);
02279
02280 if (scl->tleSortGroupRef == ref &&
02281 (sortop == InvalidOid ||
02282 sortop == scl->sortop ||
02283 sortop == get_commutator(scl->sortop)))
02284 return true;
02285 }
02286 return false;
02287 }
02288
02289
02290
02291
02292
02293 static WindowClause *
02294 findWindowClause(List *wclist, const char *name)
02295 {
02296 ListCell *l;
02297
02298 foreach(l, wclist)
02299 {
02300 WindowClause *wc = (WindowClause *) lfirst(l);
02301
02302 if (wc->name && strcmp(wc->name, name) == 0)
02303 return wc;
02304 }
02305
02306 return NULL;
02307 }
02308
02309
02310
02311
02312
02313 static Node *
02314 transformFrameOffset(ParseState *pstate, int frameOptions, Node *clause)
02315 {
02316 const char *constructName = NULL;
02317 Node *node;
02318
02319
02320 if (clause == NULL)
02321 return NULL;
02322
02323 if (frameOptions & FRAMEOPTION_ROWS)
02324 {
02325
02326 node = transformExpr(pstate, clause, EXPR_KIND_WINDOW_FRAME_ROWS);
02327
02328
02329
02330
02331 constructName = "ROWS";
02332 node = coerce_to_specific_type(pstate, node, INT8OID, constructName);
02333 }
02334 else if (frameOptions & FRAMEOPTION_RANGE)
02335 {
02336
02337 node = transformExpr(pstate, clause, EXPR_KIND_WINDOW_FRAME_RANGE);
02338
02339
02340
02341
02342
02343 constructName = "RANGE";
02344
02345 elog(ERROR, "window frame with value offset is not implemented");
02346 }
02347 else
02348 {
02349 Assert(false);
02350 node = NULL;
02351 }
02352
02353
02354 checkExprIsVarFree(pstate, node, constructName);
02355
02356 return node;
02357 }