00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include <ctype.h>
00018
00019 #include "access/htup_details.h"
00020 #include "access/sysattr.h"
00021 #include "catalog/heap.h"
00022 #include "catalog/namespace.h"
00023 #include "catalog/pg_type.h"
00024 #include "funcapi.h"
00025 #include "nodes/makefuncs.h"
00026 #include "nodes/nodeFuncs.h"
00027 #include "parser/parsetree.h"
00028 #include "parser/parse_relation.h"
00029 #include "parser/parse_type.h"
00030 #include "utils/builtins.h"
00031 #include "utils/lsyscache.h"
00032 #include "utils/rel.h"
00033 #include "utils/syscache.h"
00034
00035
00036 static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
00037 const char *refname, int location);
00038 static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
00039 int location);
00040 static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
00041 int rtindex, AttrNumber col);
00042 static void expandRelation(Oid relid, Alias *eref,
00043 int rtindex, int sublevels_up,
00044 int location, bool include_dropped,
00045 List **colnames, List **colvars);
00046 static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
00047 int rtindex, int sublevels_up,
00048 int location, bool include_dropped,
00049 List **colnames, List **colvars);
00050 static int specialAttNum(const char *attname);
00051 static bool isQueryUsingTempRelation_walker(Node *node, void *context);
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 RangeTblEntry *
00076 refnameRangeTblEntry(ParseState *pstate,
00077 const char *schemaname,
00078 const char *refname,
00079 int location,
00080 int *sublevels_up)
00081 {
00082 Oid relId = InvalidOid;
00083
00084 if (sublevels_up)
00085 *sublevels_up = 0;
00086
00087 if (schemaname != NULL)
00088 {
00089 Oid namespaceId;
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 namespaceId = LookupNamespaceNoError(schemaname);
00100 if (!OidIsValid(namespaceId))
00101 return NULL;
00102 relId = get_relname_relid(refname, namespaceId);
00103 if (!OidIsValid(relId))
00104 return NULL;
00105 }
00106
00107 while (pstate != NULL)
00108 {
00109 RangeTblEntry *result;
00110
00111 if (OidIsValid(relId))
00112 result = scanNameSpaceForRelid(pstate, relId, location);
00113 else
00114 result = scanNameSpaceForRefname(pstate, refname, location);
00115
00116 if (result)
00117 return result;
00118
00119 if (sublevels_up)
00120 (*sublevels_up)++;
00121 else
00122 break;
00123
00124 pstate = pstate->parentParseState;
00125 }
00126 return NULL;
00127 }
00128
00129
00130
00131
00132
00133
00134 static RangeTblEntry *
00135 scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)
00136 {
00137 RangeTblEntry *result = NULL;
00138 ListCell *l;
00139
00140 foreach(l, pstate->p_namespace)
00141 {
00142 ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
00143 RangeTblEntry *rte = nsitem->p_rte;
00144
00145
00146 if (!nsitem->p_rel_visible)
00147 continue;
00148
00149 if (nsitem->p_lateral_only && !pstate->p_lateral_active)
00150 continue;
00151
00152 if (strcmp(rte->eref->aliasname, refname) == 0)
00153 {
00154 if (result)
00155 ereport(ERROR,
00156 (errcode(ERRCODE_AMBIGUOUS_ALIAS),
00157 errmsg("table reference \"%s\" is ambiguous",
00158 refname),
00159 parser_errposition(pstate, location)));
00160
00161 if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
00162 ereport(ERROR,
00163 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00164 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
00165 refname),
00166 errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
00167 parser_errposition(pstate, location)));
00168 result = rte;
00169 }
00170 }
00171 return result;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static RangeTblEntry *
00184 scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
00185 {
00186 RangeTblEntry *result = NULL;
00187 ListCell *l;
00188
00189 foreach(l, pstate->p_namespace)
00190 {
00191 ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
00192 RangeTblEntry *rte = nsitem->p_rte;
00193
00194
00195 if (!nsitem->p_rel_visible)
00196 continue;
00197
00198 if (nsitem->p_lateral_only && !pstate->p_lateral_active)
00199 continue;
00200
00201
00202 if (rte->rtekind == RTE_RELATION &&
00203 rte->relid == relid &&
00204 rte->alias == NULL)
00205 {
00206 if (result)
00207 ereport(ERROR,
00208 (errcode(ERRCODE_AMBIGUOUS_ALIAS),
00209 errmsg("table reference %u is ambiguous",
00210 relid),
00211 parser_errposition(pstate, location)));
00212
00213 if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
00214 ereport(ERROR,
00215 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00216 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
00217 rte->eref->aliasname),
00218 errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
00219 parser_errposition(pstate, location)));
00220 result = rte;
00221 }
00222 }
00223 return result;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 CommonTableExpr *
00233 scanNameSpaceForCTE(ParseState *pstate, const char *refname,
00234 Index *ctelevelsup)
00235 {
00236 Index levelsup;
00237
00238 for (levelsup = 0;
00239 pstate != NULL;
00240 pstate = pstate->parentParseState, levelsup++)
00241 {
00242 ListCell *lc;
00243
00244 foreach(lc, pstate->p_ctenamespace)
00245 {
00246 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00247
00248 if (strcmp(cte->ctename, refname) == 0)
00249 {
00250 *ctelevelsup = levelsup;
00251 return cte;
00252 }
00253 }
00254 }
00255 return NULL;
00256 }
00257
00258
00259
00260
00261
00262
00263 static bool
00264 isFutureCTE(ParseState *pstate, const char *refname)
00265 {
00266 for (; pstate != NULL; pstate = pstate->parentParseState)
00267 {
00268 ListCell *lc;
00269
00270 foreach(lc, pstate->p_future_ctes)
00271 {
00272 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00273
00274 if (strcmp(cte->ctename, refname) == 0)
00275 return true;
00276 }
00277 }
00278 return false;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 static RangeTblEntry *
00297 searchRangeTableForRel(ParseState *pstate, RangeVar *relation)
00298 {
00299 const char *refname = relation->relname;
00300 Oid relId = InvalidOid;
00301 CommonTableExpr *cte = NULL;
00302 Index ctelevelsup = 0;
00303 Index levelsup;
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 if (!relation->schemaname)
00318 cte = scanNameSpaceForCTE(pstate, refname, &ctelevelsup);
00319 if (!cte)
00320 relId = RangeVarGetRelid(relation, NoLock, true);
00321
00322
00323 for (levelsup = 0;
00324 pstate != NULL;
00325 pstate = pstate->parentParseState, levelsup++)
00326 {
00327 ListCell *l;
00328
00329 foreach(l, pstate->p_rtable)
00330 {
00331 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
00332
00333 if (rte->rtekind == RTE_RELATION &&
00334 OidIsValid(relId) &&
00335 rte->relid == relId)
00336 return rte;
00337 if (rte->rtekind == RTE_CTE &&
00338 cte != NULL &&
00339 rte->ctelevelsup + levelsup == ctelevelsup &&
00340 strcmp(rte->ctename, refname) == 0)
00341 return rte;
00342 if (strcmp(rte->eref->aliasname, refname) == 0)
00343 return rte;
00344 }
00345 }
00346 return NULL;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 void
00365 checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
00366 List *namespace2)
00367 {
00368 ListCell *l1;
00369
00370 foreach(l1, namespace1)
00371 {
00372 ParseNamespaceItem *nsitem1 = (ParseNamespaceItem *) lfirst(l1);
00373 RangeTblEntry *rte1 = nsitem1->p_rte;
00374 const char *aliasname1 = rte1->eref->aliasname;
00375 ListCell *l2;
00376
00377 if (!nsitem1->p_rel_visible)
00378 continue;
00379
00380 foreach(l2, namespace2)
00381 {
00382 ParseNamespaceItem *nsitem2 = (ParseNamespaceItem *) lfirst(l2);
00383 RangeTblEntry *rte2 = nsitem2->p_rte;
00384
00385 if (!nsitem2->p_rel_visible)
00386 continue;
00387 if (strcmp(rte2->eref->aliasname, aliasname1) != 0)
00388 continue;
00389 if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
00390 rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
00391 rte1->relid != rte2->relid)
00392 continue;
00393 ereport(ERROR,
00394 (errcode(ERRCODE_DUPLICATE_ALIAS),
00395 errmsg("table name \"%s\" specified more than once",
00396 aliasname1)));
00397 }
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407 int
00408 RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
00409 {
00410 int index;
00411 ListCell *l;
00412
00413 if (sublevels_up)
00414 *sublevels_up = 0;
00415
00416 while (pstate != NULL)
00417 {
00418 index = 1;
00419 foreach(l, pstate->p_rtable)
00420 {
00421 if (rte == (RangeTblEntry *) lfirst(l))
00422 return index;
00423 index++;
00424 }
00425 pstate = pstate->parentParseState;
00426 if (sublevels_up)
00427 (*sublevels_up)++;
00428 else
00429 break;
00430 }
00431
00432 elog(ERROR, "RTE not found (internal error)");
00433 return 0;
00434 }
00435
00436
00437
00438
00439
00440 RangeTblEntry *
00441 GetRTEByRangeTablePosn(ParseState *pstate,
00442 int varno,
00443 int sublevels_up)
00444 {
00445 while (sublevels_up-- > 0)
00446 {
00447 pstate = pstate->parentParseState;
00448 Assert(pstate != NULL);
00449 }
00450 Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
00451 return rt_fetch(varno, pstate->p_rtable);
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461 CommonTableExpr *
00462 GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
00463 {
00464 Index levelsup;
00465 ListCell *lc;
00466
00467
00468 if (rtelevelsup < 0)
00469 (void) RTERangeTablePosn(pstate, rte, &rtelevelsup);
00470
00471 Assert(rte->rtekind == RTE_CTE);
00472 levelsup = rte->ctelevelsup + rtelevelsup;
00473 while (levelsup-- > 0)
00474 {
00475 pstate = pstate->parentParseState;
00476 if (!pstate)
00477 elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
00478 }
00479 foreach(lc, pstate->p_ctenamespace)
00480 {
00481 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00482
00483 if (strcmp(cte->ctename, rte->ctename) == 0)
00484 return cte;
00485 }
00486
00487 elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
00488 return NULL;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 Node *
00501 scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
00502 int location)
00503 {
00504 Node *result = NULL;
00505 int attnum = 0;
00506 Var *var;
00507 ListCell *c;
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 foreach(c, rte->eref->colnames)
00523 {
00524 attnum++;
00525 if (strcmp(strVal(lfirst(c)), colname) == 0)
00526 {
00527 if (result)
00528 ereport(ERROR,
00529 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00530 errmsg("column reference \"%s\" is ambiguous",
00531 colname),
00532 parser_errposition(pstate, location)));
00533 var = make_var(pstate, rte, attnum, location);
00534
00535 markVarForSelectPriv(pstate, var, rte);
00536 result = (Node *) var;
00537 }
00538 }
00539
00540
00541
00542
00543
00544 if (result)
00545 return result;
00546
00547
00548
00549
00550 if (rte->rtekind == RTE_RELATION)
00551 {
00552
00553 attnum = specialAttNum(colname);
00554 if (attnum != InvalidAttrNumber)
00555 {
00556
00557 if (SearchSysCacheExists2(ATTNUM,
00558 ObjectIdGetDatum(rte->relid),
00559 Int16GetDatum(attnum)))
00560 {
00561 var = make_var(pstate, rte, attnum, location);
00562
00563 markVarForSelectPriv(pstate, var, rte);
00564 result = (Node *) var;
00565 }
00566 }
00567 }
00568
00569 return result;
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579 Node *
00580 colNameToVar(ParseState *pstate, char *colname, bool localonly,
00581 int location)
00582 {
00583 Node *result = NULL;
00584 ParseState *orig_pstate = pstate;
00585
00586 while (pstate != NULL)
00587 {
00588 ListCell *l;
00589
00590 foreach(l, pstate->p_namespace)
00591 {
00592 ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
00593 RangeTblEntry *rte = nsitem->p_rte;
00594 Node *newresult;
00595
00596
00597 if (!nsitem->p_cols_visible)
00598 continue;
00599
00600 if (nsitem->p_lateral_only && !pstate->p_lateral_active)
00601 continue;
00602
00603
00604 newresult = scanRTEForColumn(orig_pstate, rte, colname, location);
00605
00606 if (newresult)
00607 {
00608 if (result)
00609 ereport(ERROR,
00610 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00611 errmsg("column reference \"%s\" is ambiguous",
00612 colname),
00613 parser_errposition(orig_pstate, location)));
00614
00615 if (nsitem->p_lateral_only && !nsitem->p_lateral_ok)
00616 ereport(ERROR,
00617 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00618 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
00619 rte->eref->aliasname),
00620 errdetail("The combining JOIN type must be INNER or LEFT for a LATERAL reference."),
00621 parser_errposition(orig_pstate, location)));
00622 result = newresult;
00623 }
00624 }
00625
00626 if (result != NULL || localonly)
00627 break;
00628
00629 pstate = pstate->parentParseState;
00630 }
00631
00632 return result;
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 static RangeTblEntry *
00648 searchRangeTableForCol(ParseState *pstate, char *colname, int location)
00649 {
00650 ParseState *orig_pstate = pstate;
00651
00652 while (pstate != NULL)
00653 {
00654 ListCell *l;
00655
00656 foreach(l, pstate->p_rtable)
00657 {
00658 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
00659
00660 if (scanRTEForColumn(orig_pstate, rte, colname, location))
00661 return rte;
00662 }
00663
00664 pstate = pstate->parentParseState;
00665 }
00666 return NULL;
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 static void
00680 markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
00681 int rtindex, AttrNumber col)
00682 {
00683 if (rte == NULL)
00684 rte = rt_fetch(rtindex, pstate->p_rtable);
00685
00686 if (rte->rtekind == RTE_RELATION)
00687 {
00688
00689 rte->requiredPerms |= ACL_SELECT;
00690
00691 rte->selectedCols = bms_add_member(rte->selectedCols,
00692 col - FirstLowInvalidHeapAttributeNumber);
00693 }
00694 else if (rte->rtekind == RTE_JOIN)
00695 {
00696 if (col == InvalidAttrNumber)
00697 {
00698
00699
00700
00701
00702 JoinExpr *j;
00703
00704 if (rtindex > 0 && rtindex <= list_length(pstate->p_joinexprs))
00705 j = (JoinExpr *) list_nth(pstate->p_joinexprs, rtindex - 1);
00706 else
00707 j = NULL;
00708 if (j == NULL)
00709 elog(ERROR, "could not find JoinExpr for whole-row reference");
00710 Assert(IsA(j, JoinExpr));
00711
00712
00713 if (IsA(j->larg, RangeTblRef))
00714 {
00715 int varno = ((RangeTblRef *) j->larg)->rtindex;
00716
00717 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00718 }
00719 else if (IsA(j->larg, JoinExpr))
00720 {
00721 int varno = ((JoinExpr *) j->larg)->rtindex;
00722
00723 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00724 }
00725 else
00726 elog(ERROR, "unrecognized node type: %d",
00727 (int) nodeTag(j->larg));
00728 if (IsA(j->rarg, RangeTblRef))
00729 {
00730 int varno = ((RangeTblRef *) j->rarg)->rtindex;
00731
00732 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00733 }
00734 else if (IsA(j->rarg, JoinExpr))
00735 {
00736 int varno = ((JoinExpr *) j->rarg)->rtindex;
00737
00738 markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
00739 }
00740 else
00741 elog(ERROR, "unrecognized node type: %d",
00742 (int) nodeTag(j->rarg));
00743 }
00744 else
00745 {
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 Var *aliasvar;
00756
00757 Assert(col > 0 && col <= list_length(rte->joinaliasvars));
00758 aliasvar = (Var *) list_nth(rte->joinaliasvars, col - 1);
00759 if (IsA(aliasvar, Var))
00760 markVarForSelectPriv(pstate, aliasvar, NULL);
00761 }
00762 }
00763
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773 void
00774 markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte)
00775 {
00776 Index lv;
00777
00778 Assert(IsA(var, Var));
00779
00780 for (lv = 0; lv < var->varlevelsup; lv++)
00781 pstate = pstate->parentParseState;
00782 markRTEForSelectPriv(pstate, rte, var->varno, var->varattno);
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 static void
00800 buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
00801 {
00802 int maxattrs = tupdesc->natts;
00803 ListCell *aliaslc;
00804 int numaliases;
00805 int varattno;
00806 int numdropped = 0;
00807
00808 Assert(eref->colnames == NIL);
00809
00810 if (alias)
00811 {
00812 aliaslc = list_head(alias->colnames);
00813 numaliases = list_length(alias->colnames);
00814
00815 alias->colnames = NIL;
00816 }
00817 else
00818 {
00819 aliaslc = NULL;
00820 numaliases = 0;
00821 }
00822
00823 for (varattno = 0; varattno < maxattrs; varattno++)
00824 {
00825 Form_pg_attribute attr = tupdesc->attrs[varattno];
00826 Value *attrname;
00827
00828 if (attr->attisdropped)
00829 {
00830
00831 attrname = makeString(pstrdup(""));
00832 if (aliaslc)
00833 alias->colnames = lappend(alias->colnames, attrname);
00834 numdropped++;
00835 }
00836 else if (aliaslc)
00837 {
00838
00839 attrname = (Value *) lfirst(aliaslc);
00840 aliaslc = lnext(aliaslc);
00841 alias->colnames = lappend(alias->colnames, attrname);
00842 }
00843 else
00844 {
00845 attrname = makeString(pstrdup(NameStr(attr->attname)));
00846
00847 }
00848
00849 eref->colnames = lappend(eref->colnames, attrname);
00850 }
00851
00852
00853 if (aliaslc)
00854 ereport(ERROR,
00855 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00856 errmsg("table \"%s\" has %d columns available but %d columns specified",
00857 eref->aliasname, maxattrs - numdropped, numaliases)));
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 static void
00873 buildScalarFunctionAlias(Node *funcexpr, char *funcname,
00874 Alias *alias, Alias *eref)
00875 {
00876 char *pname;
00877
00878 Assert(eref->colnames == NIL);
00879
00880
00881 if (alias && alias->colnames != NIL)
00882 {
00883 if (list_length(alias->colnames) != 1)
00884 ereport(ERROR,
00885 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
00886 errmsg("too many column aliases specified for function %s",
00887 funcname)));
00888 eref->colnames = copyObject(alias->colnames);
00889 return;
00890 }
00891
00892
00893
00894
00895
00896 if (funcexpr && IsA(funcexpr, FuncExpr))
00897 {
00898 pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
00899 if (pname)
00900 {
00901 eref->colnames = list_make1(makeString(pname));
00902 return;
00903 }
00904 }
00905
00906
00907
00908
00909
00910 eref->colnames = list_make1(makeString(eref->aliasname));
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 Relation
00925 parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
00926 {
00927 Relation rel;
00928 ParseCallbackState pcbstate;
00929
00930 setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
00931 rel = heap_openrv_extended(relation, lockmode, true);
00932 if (rel == NULL)
00933 {
00934 if (relation->schemaname)
00935 ereport(ERROR,
00936 (errcode(ERRCODE_UNDEFINED_TABLE),
00937 errmsg("relation \"%s.%s\" does not exist",
00938 relation->schemaname, relation->relname)));
00939 else
00940 {
00941
00942
00943
00944
00945
00946
00947 if (isFutureCTE(pstate, relation->relname))
00948 ereport(ERROR,
00949 (errcode(ERRCODE_UNDEFINED_TABLE),
00950 errmsg("relation \"%s\" does not exist",
00951 relation->relname),
00952 errdetail("There is a WITH item named \"%s\", but it cannot be referenced from this part of the query.",
00953 relation->relname),
00954 errhint("Use WITH RECURSIVE, or re-order the WITH items to remove forward references.")));
00955 else
00956 ereport(ERROR,
00957 (errcode(ERRCODE_UNDEFINED_TABLE),
00958 errmsg("relation \"%s\" does not exist",
00959 relation->relname)));
00960 }
00961 }
00962 cancel_parser_errposition_callback(&pcbstate);
00963 return rel;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 RangeTblEntry *
00976 addRangeTableEntry(ParseState *pstate,
00977 RangeVar *relation,
00978 Alias *alias,
00979 bool inh,
00980 bool inFromCl)
00981 {
00982 RangeTblEntry *rte = makeNode(RangeTblEntry);
00983 char *refname = alias ? alias->aliasname : relation->relname;
00984 LOCKMODE lockmode;
00985 Relation rel;
00986
00987 rte->rtekind = RTE_RELATION;
00988 rte->alias = alias;
00989
00990
00991
00992
00993
00994
00995
00996 lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
00997 rel = parserOpenTable(pstate, relation, lockmode);
00998 rte->relid = RelationGetRelid(rel);
00999 rte->relkind = rel->rd_rel->relkind;
01000
01001
01002
01003
01004
01005 rte->eref = makeAlias(refname, NIL);
01006 buildRelationAliases(rel->rd_att, alias, rte->eref);
01007
01008
01009
01010
01011
01012
01013 heap_close(rel, NoLock);
01014
01015
01016
01017
01018
01019
01020
01021 rte->lateral = false;
01022 rte->inh = inh;
01023 rte->inFromCl = inFromCl;
01024
01025 rte->requiredPerms = ACL_SELECT;
01026 rte->checkAsUser = InvalidOid;
01027 rte->selectedCols = NULL;
01028 rte->modifiedCols = NULL;
01029
01030
01031
01032
01033
01034 if (pstate != NULL)
01035 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01036
01037 return rte;
01038 }
01039
01040
01041
01042
01043
01044
01045
01046 RangeTblEntry *
01047 addRangeTableEntryForRelation(ParseState *pstate,
01048 Relation rel,
01049 Alias *alias,
01050 bool inh,
01051 bool inFromCl)
01052 {
01053 RangeTblEntry *rte = makeNode(RangeTblEntry);
01054 char *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
01055
01056 rte->rtekind = RTE_RELATION;
01057 rte->alias = alias;
01058 rte->relid = RelationGetRelid(rel);
01059 rte->relkind = rel->rd_rel->relkind;
01060
01061
01062
01063
01064
01065 rte->eref = makeAlias(refname, NIL);
01066 buildRelationAliases(rel->rd_att, alias, rte->eref);
01067
01068
01069
01070
01071
01072
01073
01074 rte->lateral = false;
01075 rte->inh = inh;
01076 rte->inFromCl = inFromCl;
01077
01078 rte->requiredPerms = ACL_SELECT;
01079 rte->checkAsUser = InvalidOid;
01080 rte->selectedCols = NULL;
01081 rte->modifiedCols = NULL;
01082
01083
01084
01085
01086
01087 if (pstate != NULL)
01088 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01089
01090 return rte;
01091 }
01092
01093
01094
01095
01096
01097
01098
01099 RangeTblEntry *
01100 addRangeTableEntryForSubquery(ParseState *pstate,
01101 Query *subquery,
01102 Alias *alias,
01103 bool lateral,
01104 bool inFromCl)
01105 {
01106 RangeTblEntry *rte = makeNode(RangeTblEntry);
01107 char *refname = alias->aliasname;
01108 Alias *eref;
01109 int numaliases;
01110 int varattno;
01111 ListCell *tlistitem;
01112
01113 rte->rtekind = RTE_SUBQUERY;
01114 rte->relid = InvalidOid;
01115 rte->subquery = subquery;
01116 rte->alias = alias;
01117
01118 eref = copyObject(alias);
01119 numaliases = list_length(eref->colnames);
01120
01121
01122 varattno = 0;
01123 foreach(tlistitem, subquery->targetList)
01124 {
01125 TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
01126
01127 if (te->resjunk)
01128 continue;
01129 varattno++;
01130 Assert(varattno == te->resno);
01131 if (varattno > numaliases)
01132 {
01133 char *attrname;
01134
01135 attrname = pstrdup(te->resname);
01136 eref->colnames = lappend(eref->colnames, makeString(attrname));
01137 }
01138 }
01139 if (varattno < numaliases)
01140 ereport(ERROR,
01141 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01142 errmsg("table \"%s\" has %d columns available but %d columns specified",
01143 refname, varattno, numaliases)));
01144
01145 rte->eref = eref;
01146
01147
01148
01149
01150
01151
01152 rte->lateral = lateral;
01153 rte->inh = false;
01154 rte->inFromCl = inFromCl;
01155
01156 rte->requiredPerms = 0;
01157 rte->checkAsUser = InvalidOid;
01158 rte->selectedCols = NULL;
01159 rte->modifiedCols = NULL;
01160
01161
01162
01163
01164
01165 if (pstate != NULL)
01166 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01167
01168 return rte;
01169 }
01170
01171
01172
01173
01174
01175
01176 RangeTblEntry *
01177 addRangeTableEntryForFunction(ParseState *pstate,
01178 char *funcname,
01179 Node *funcexpr,
01180 RangeFunction *rangefunc,
01181 bool lateral,
01182 bool inFromCl)
01183 {
01184 RangeTblEntry *rte = makeNode(RangeTblEntry);
01185 TypeFuncClass functypclass;
01186 Oid funcrettype;
01187 TupleDesc tupdesc;
01188 Alias *alias = rangefunc->alias;
01189 List *coldeflist = rangefunc->coldeflist;
01190 Alias *eref;
01191
01192 rte->rtekind = RTE_FUNCTION;
01193 rte->relid = InvalidOid;
01194 rte->subquery = NULL;
01195 rte->funcexpr = funcexpr;
01196 rte->funccoltypes = NIL;
01197 rte->funccoltypmods = NIL;
01198 rte->funccolcollations = NIL;
01199 rte->alias = alias;
01200
01201 eref = makeAlias(alias ? alias->aliasname : funcname, NIL);
01202 rte->eref = eref;
01203
01204
01205
01206
01207 functypclass = get_expr_result_type(funcexpr,
01208 &funcrettype,
01209 &tupdesc);
01210
01211
01212
01213
01214
01215 if (coldeflist != NIL)
01216 {
01217 if (functypclass != TYPEFUNC_RECORD)
01218 ereport(ERROR,
01219 (errcode(ERRCODE_SYNTAX_ERROR),
01220 errmsg("a column definition list is only allowed for functions returning \"record\""),
01221 parser_errposition(pstate, exprLocation(funcexpr))));
01222 }
01223 else
01224 {
01225 if (functypclass == TYPEFUNC_RECORD)
01226 ereport(ERROR,
01227 (errcode(ERRCODE_SYNTAX_ERROR),
01228 errmsg("a column definition list is required for functions returning \"record\""),
01229 parser_errposition(pstate, exprLocation(funcexpr))));
01230 }
01231
01232 if (functypclass == TYPEFUNC_COMPOSITE)
01233 {
01234
01235 Assert(tupdesc);
01236
01237 buildRelationAliases(tupdesc, alias, eref);
01238 }
01239 else if (functypclass == TYPEFUNC_SCALAR)
01240 {
01241
01242 buildScalarFunctionAlias(funcexpr, funcname, alias, eref);
01243 }
01244 else if (functypclass == TYPEFUNC_RECORD)
01245 {
01246 ListCell *col;
01247
01248
01249
01250
01251
01252 foreach(col, coldeflist)
01253 {
01254 ColumnDef *n = (ColumnDef *) lfirst(col);
01255 char *attrname;
01256 Oid attrtype;
01257 int32 attrtypmod;
01258 Oid attrcollation;
01259
01260 attrname = pstrdup(n->colname);
01261 if (n->typeName->setof)
01262 ereport(ERROR,
01263 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
01264 errmsg("column \"%s\" cannot be declared SETOF",
01265 attrname),
01266 parser_errposition(pstate, n->typeName->location)));
01267 typenameTypeIdAndMod(pstate, n->typeName, &attrtype, &attrtypmod);
01268 attrcollation = GetColumnDefCollation(pstate, n, attrtype);
01269 eref->colnames = lappend(eref->colnames, makeString(attrname));
01270 rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype);
01271 rte->funccoltypmods = lappend_int(rte->funccoltypmods, attrtypmod);
01272 rte->funccolcollations = lappend_oid(rte->funccolcollations,
01273 attrcollation);
01274 }
01275 }
01276 else
01277 ereport(ERROR,
01278 (errcode(ERRCODE_DATATYPE_MISMATCH),
01279 errmsg("function \"%s\" in FROM has unsupported return type %s",
01280 funcname, format_type_be(funcrettype)),
01281 parser_errposition(pstate, exprLocation(funcexpr))));
01282
01283
01284
01285
01286
01287
01288
01289 rte->lateral = lateral;
01290 rte->inh = false;
01291 rte->inFromCl = inFromCl;
01292
01293 rte->requiredPerms = 0;
01294 rte->checkAsUser = InvalidOid;
01295 rte->selectedCols = NULL;
01296 rte->modifiedCols = NULL;
01297
01298
01299
01300
01301
01302 if (pstate != NULL)
01303 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01304
01305 return rte;
01306 }
01307
01308
01309
01310
01311
01312
01313 RangeTblEntry *
01314 addRangeTableEntryForValues(ParseState *pstate,
01315 List *exprs,
01316 List *collations,
01317 Alias *alias,
01318 bool lateral,
01319 bool inFromCl)
01320 {
01321 RangeTblEntry *rte = makeNode(RangeTblEntry);
01322 char *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
01323 Alias *eref;
01324 int numaliases;
01325 int numcolumns;
01326
01327 rte->rtekind = RTE_VALUES;
01328 rte->relid = InvalidOid;
01329 rte->subquery = NULL;
01330 rte->values_lists = exprs;
01331 rte->values_collations = collations;
01332 rte->alias = alias;
01333
01334 eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
01335
01336
01337 numcolumns = list_length((List *) linitial(exprs));
01338 numaliases = list_length(eref->colnames);
01339 while (numaliases < numcolumns)
01340 {
01341 char attrname[64];
01342
01343 numaliases++;
01344 snprintf(attrname, sizeof(attrname), "column%d", numaliases);
01345 eref->colnames = lappend(eref->colnames,
01346 makeString(pstrdup(attrname)));
01347 }
01348 if (numcolumns < numaliases)
01349 ereport(ERROR,
01350 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01351 errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
01352 refname, numcolumns, numaliases)));
01353
01354 rte->eref = eref;
01355
01356
01357
01358
01359
01360
01361 rte->lateral = lateral;
01362 rte->inh = false;
01363 rte->inFromCl = inFromCl;
01364
01365 rte->requiredPerms = 0;
01366 rte->checkAsUser = InvalidOid;
01367 rte->selectedCols = NULL;
01368 rte->modifiedCols = NULL;
01369
01370
01371
01372
01373
01374 if (pstate != NULL)
01375 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01376
01377 return rte;
01378 }
01379
01380
01381
01382
01383
01384
01385 RangeTblEntry *
01386 addRangeTableEntryForJoin(ParseState *pstate,
01387 List *colnames,
01388 JoinType jointype,
01389 List *aliasvars,
01390 Alias *alias,
01391 bool inFromCl)
01392 {
01393 RangeTblEntry *rte = makeNode(RangeTblEntry);
01394 Alias *eref;
01395 int numaliases;
01396
01397
01398
01399
01400
01401 if (list_length(aliasvars) > MaxAttrNumber)
01402 ereport(ERROR,
01403 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
01404 errmsg("joins can have at most %d columns",
01405 MaxAttrNumber)));
01406
01407 rte->rtekind = RTE_JOIN;
01408 rte->relid = InvalidOid;
01409 rte->subquery = NULL;
01410 rte->jointype = jointype;
01411 rte->joinaliasvars = aliasvars;
01412 rte->alias = alias;
01413
01414 eref = alias ? (Alias *) copyObject(alias) : makeAlias("unnamed_join", NIL);
01415 numaliases = list_length(eref->colnames);
01416
01417
01418 if (numaliases < list_length(colnames))
01419 eref->colnames = list_concat(eref->colnames,
01420 list_copy_tail(colnames, numaliases));
01421
01422 rte->eref = eref;
01423
01424
01425
01426
01427
01428
01429 rte->lateral = false;
01430 rte->inh = false;
01431 rte->inFromCl = inFromCl;
01432
01433 rte->requiredPerms = 0;
01434 rte->checkAsUser = InvalidOid;
01435 rte->selectedCols = NULL;
01436 rte->modifiedCols = NULL;
01437
01438
01439
01440
01441
01442 if (pstate != NULL)
01443 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01444
01445 return rte;
01446 }
01447
01448
01449
01450
01451
01452
01453 RangeTblEntry *
01454 addRangeTableEntryForCTE(ParseState *pstate,
01455 CommonTableExpr *cte,
01456 Index levelsup,
01457 RangeVar *rv,
01458 bool inFromCl)
01459 {
01460 RangeTblEntry *rte = makeNode(RangeTblEntry);
01461 Alias *alias = rv->alias;
01462 char *refname = alias ? alias->aliasname : cte->ctename;
01463 Alias *eref;
01464 int numaliases;
01465 int varattno;
01466 ListCell *lc;
01467
01468 rte->rtekind = RTE_CTE;
01469 rte->ctename = cte->ctename;
01470 rte->ctelevelsup = levelsup;
01471
01472
01473 rte->self_reference = !IsA(cte->ctequery, Query);
01474 Assert(cte->cterecursive || !rte->self_reference);
01475
01476 if (!rte->self_reference)
01477 cte->cterefcount++;
01478
01479
01480
01481
01482
01483
01484 if (IsA(cte->ctequery, Query))
01485 {
01486 Query *ctequery = (Query *) cte->ctequery;
01487
01488 if (ctequery->commandType != CMD_SELECT &&
01489 ctequery->returningList == NIL)
01490 ereport(ERROR,
01491 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01492 errmsg("WITH query \"%s\" does not have a RETURNING clause",
01493 cte->ctename),
01494 parser_errposition(pstate, rv->location)));
01495 }
01496
01497 rte->ctecoltypes = cte->ctecoltypes;
01498 rte->ctecoltypmods = cte->ctecoltypmods;
01499 rte->ctecolcollations = cte->ctecolcollations;
01500
01501 rte->alias = alias;
01502 if (alias)
01503 eref = copyObject(alias);
01504 else
01505 eref = makeAlias(refname, NIL);
01506 numaliases = list_length(eref->colnames);
01507
01508
01509 varattno = 0;
01510 foreach(lc, cte->ctecolnames)
01511 {
01512 varattno++;
01513 if (varattno > numaliases)
01514 eref->colnames = lappend(eref->colnames, lfirst(lc));
01515 }
01516 if (varattno < numaliases)
01517 ereport(ERROR,
01518 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
01519 errmsg("table \"%s\" has %d columns available but %d columns specified",
01520 refname, varattno, numaliases)));
01521
01522 rte->eref = eref;
01523
01524
01525
01526
01527
01528
01529 rte->lateral = false;
01530 rte->inh = false;
01531 rte->inFromCl = inFromCl;
01532
01533 rte->requiredPerms = 0;
01534 rte->checkAsUser = InvalidOid;
01535 rte->selectedCols = NULL;
01536 rte->modifiedCols = NULL;
01537
01538
01539
01540
01541
01542 if (pstate != NULL)
01543 pstate->p_rtable = lappend(pstate->p_rtable, rte);
01544
01545 return rte;
01546 }
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558 bool
01559 isLockedRefname(ParseState *pstate, const char *refname)
01560 {
01561 ListCell *l;
01562
01563
01564
01565
01566
01567 if (pstate->p_locked_from_parent)
01568 return true;
01569
01570 foreach(l, pstate->p_locking_clause)
01571 {
01572 LockingClause *lc = (LockingClause *) lfirst(l);
01573
01574 if (lc->lockedRels == NIL)
01575 {
01576
01577 return true;
01578 }
01579 else
01580 {
01581
01582 ListCell *l2;
01583
01584 foreach(l2, lc->lockedRels)
01585 {
01586 RangeVar *thisrel = (RangeVar *) lfirst(l2);
01587
01588 if (strcmp(refname, thisrel->relname) == 0)
01589 return true;
01590 }
01591 }
01592 }
01593 return false;
01594 }
01595
01596
01597
01598
01599
01600
01601
01602 void
01603 addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
01604 bool addToJoinList,
01605 bool addToRelNameSpace, bool addToVarNameSpace)
01606 {
01607 if (addToJoinList)
01608 {
01609 int rtindex = RTERangeTablePosn(pstate, rte, NULL);
01610 RangeTblRef *rtr = makeNode(RangeTblRef);
01611
01612 rtr->rtindex = rtindex;
01613 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
01614 }
01615 if (addToRelNameSpace || addToVarNameSpace)
01616 {
01617 ParseNamespaceItem *nsitem;
01618
01619 nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
01620 nsitem->p_rte = rte;
01621 nsitem->p_rel_visible = addToRelNameSpace;
01622 nsitem->p_cols_visible = addToVarNameSpace;
01623 nsitem->p_lateral_only = false;
01624 nsitem->p_lateral_ok = true;
01625 pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
01626 }
01627 }
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646 void
01647 expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
01648 int location, bool include_dropped,
01649 List **colnames, List **colvars)
01650 {
01651 int varattno;
01652
01653 if (colnames)
01654 *colnames = NIL;
01655 if (colvars)
01656 *colvars = NIL;
01657
01658 switch (rte->rtekind)
01659 {
01660 case RTE_RELATION:
01661
01662 expandRelation(rte->relid, rte->eref,
01663 rtindex, sublevels_up, location,
01664 include_dropped, colnames, colvars);
01665 break;
01666 case RTE_SUBQUERY:
01667 {
01668
01669 ListCell *aliasp_item = list_head(rte->eref->colnames);
01670 ListCell *tlistitem;
01671
01672 varattno = 0;
01673 foreach(tlistitem, rte->subquery->targetList)
01674 {
01675 TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
01676
01677 if (te->resjunk)
01678 continue;
01679 varattno++;
01680 Assert(varattno == te->resno);
01681
01682 if (colnames)
01683 {
01684
01685 char *label = strVal(lfirst(aliasp_item));
01686
01687 *colnames = lappend(*colnames, makeString(pstrdup(label)));
01688 aliasp_item = lnext(aliasp_item);
01689 }
01690
01691 if (colvars)
01692 {
01693 Var *varnode;
01694
01695 varnode = makeVar(rtindex, varattno,
01696 exprType((Node *) te->expr),
01697 exprTypmod((Node *) te->expr),
01698 exprCollation((Node *) te->expr),
01699 sublevels_up);
01700 varnode->location = location;
01701
01702 *colvars = lappend(*colvars, varnode);
01703 }
01704 }
01705 }
01706 break;
01707 case RTE_FUNCTION:
01708 {
01709
01710 TypeFuncClass functypclass;
01711 Oid funcrettype;
01712 TupleDesc tupdesc;
01713
01714 functypclass = get_expr_result_type(rte->funcexpr,
01715 &funcrettype,
01716 &tupdesc);
01717 if (functypclass == TYPEFUNC_COMPOSITE)
01718 {
01719
01720 Assert(tupdesc);
01721 expandTupleDesc(tupdesc, rte->eref,
01722 rtindex, sublevels_up, location,
01723 include_dropped, colnames, colvars);
01724 }
01725 else if (functypclass == TYPEFUNC_SCALAR)
01726 {
01727
01728 if (colnames)
01729 *colnames = lappend(*colnames,
01730 linitial(rte->eref->colnames));
01731
01732 if (colvars)
01733 {
01734 Var *varnode;
01735
01736 varnode = makeVar(rtindex, 1,
01737 funcrettype, -1,
01738 exprCollation(rte->funcexpr),
01739 sublevels_up);
01740 varnode->location = location;
01741
01742 *colvars = lappend(*colvars, varnode);
01743 }
01744 }
01745 else if (functypclass == TYPEFUNC_RECORD)
01746 {
01747 if (colnames)
01748 *colnames = copyObject(rte->eref->colnames);
01749 if (colvars)
01750 {
01751 ListCell *l1;
01752 ListCell *l2;
01753 ListCell *l3;
01754 int attnum = 0;
01755
01756 forthree(l1, rte->funccoltypes,
01757 l2, rte->funccoltypmods,
01758 l3, rte->funccolcollations)
01759 {
01760 Oid attrtype = lfirst_oid(l1);
01761 int32 attrtypmod = lfirst_int(l2);
01762 Oid attrcollation = lfirst_oid(l3);
01763 Var *varnode;
01764
01765 attnum++;
01766 varnode = makeVar(rtindex,
01767 attnum,
01768 attrtype,
01769 attrtypmod,
01770 attrcollation,
01771 sublevels_up);
01772 varnode->location = location;
01773 *colvars = lappend(*colvars, varnode);
01774 }
01775 }
01776 }
01777 else
01778 {
01779
01780 elog(ERROR, "function in FROM has unsupported return type");
01781 }
01782 }
01783 break;
01784 case RTE_VALUES:
01785 {
01786
01787 ListCell *aliasp_item = list_head(rte->eref->colnames);
01788 ListCell *lcv;
01789 ListCell *lcc;
01790
01791 varattno = 0;
01792 forboth(lcv, (List *) linitial(rte->values_lists),
01793 lcc, rte->values_collations)
01794 {
01795 Node *col = (Node *) lfirst(lcv);
01796 Oid colcollation = lfirst_oid(lcc);
01797
01798 varattno++;
01799 if (colnames)
01800 {
01801
01802 char *label = strVal(lfirst(aliasp_item));
01803
01804 *colnames = lappend(*colnames,
01805 makeString(pstrdup(label)));
01806 aliasp_item = lnext(aliasp_item);
01807 }
01808
01809 if (colvars)
01810 {
01811 Var *varnode;
01812
01813 varnode = makeVar(rtindex, varattno,
01814 exprType(col),
01815 exprTypmod(col),
01816 colcollation,
01817 sublevels_up);
01818 varnode->location = location;
01819 *colvars = lappend(*colvars, varnode);
01820 }
01821 }
01822 }
01823 break;
01824 case RTE_JOIN:
01825 {
01826
01827 ListCell *colname;
01828 ListCell *aliasvar;
01829
01830 Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
01831
01832 varattno = 0;
01833 forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
01834 {
01835 Node *avar = (Node *) lfirst(aliasvar);
01836
01837 varattno++;
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847 if (IsA(avar, Const))
01848 {
01849 if (include_dropped)
01850 {
01851 if (colnames)
01852 *colnames = lappend(*colnames,
01853 makeString(pstrdup("")));
01854 if (colvars)
01855 *colvars = lappend(*colvars,
01856 copyObject(avar));
01857 }
01858 continue;
01859 }
01860
01861 if (colnames)
01862 {
01863 char *label = strVal(lfirst(colname));
01864
01865 *colnames = lappend(*colnames,
01866 makeString(pstrdup(label)));
01867 }
01868
01869 if (colvars)
01870 {
01871 Var *varnode;
01872
01873 varnode = makeVar(rtindex, varattno,
01874 exprType(avar),
01875 exprTypmod(avar),
01876 exprCollation(avar),
01877 sublevels_up);
01878 varnode->location = location;
01879
01880 *colvars = lappend(*colvars, varnode);
01881 }
01882 }
01883 }
01884 break;
01885 case RTE_CTE:
01886 {
01887 ListCell *aliasp_item = list_head(rte->eref->colnames);
01888 ListCell *lct;
01889 ListCell *lcm;
01890 ListCell *lcc;
01891
01892 varattno = 0;
01893 forthree(lct, rte->ctecoltypes,
01894 lcm, rte->ctecoltypmods,
01895 lcc, rte->ctecolcollations)
01896 {
01897 Oid coltype = lfirst_oid(lct);
01898 int32 coltypmod = lfirst_int(lcm);
01899 Oid colcoll = lfirst_oid(lcc);
01900
01901 varattno++;
01902
01903 if (colnames)
01904 {
01905
01906 char *label = strVal(lfirst(aliasp_item));
01907
01908 *colnames = lappend(*colnames, makeString(pstrdup(label)));
01909 aliasp_item = lnext(aliasp_item);
01910 }
01911
01912 if (colvars)
01913 {
01914 Var *varnode;
01915
01916 varnode = makeVar(rtindex, varattno,
01917 coltype, coltypmod, colcoll,
01918 sublevels_up);
01919 *colvars = lappend(*colvars, varnode);
01920 }
01921 }
01922 }
01923 break;
01924 default:
01925 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
01926 }
01927 }
01928
01929
01930
01931
01932 static void
01933 expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
01934 int location, bool include_dropped,
01935 List **colnames, List **colvars)
01936 {
01937 Relation rel;
01938
01939
01940 rel = relation_open(relid, AccessShareLock);
01941 expandTupleDesc(rel->rd_att, eref, rtindex, sublevels_up,
01942 location, include_dropped,
01943 colnames, colvars);
01944 relation_close(rel, AccessShareLock);
01945 }
01946
01947
01948
01949
01950 static void
01951 expandTupleDesc(TupleDesc tupdesc, Alias *eref,
01952 int rtindex, int sublevels_up,
01953 int location, bool include_dropped,
01954 List **colnames, List **colvars)
01955 {
01956 int maxattrs = tupdesc->natts;
01957 int numaliases = list_length(eref->colnames);
01958 int varattno;
01959
01960 for (varattno = 0; varattno < maxattrs; varattno++)
01961 {
01962 Form_pg_attribute attr = tupdesc->attrs[varattno];
01963
01964 if (attr->attisdropped)
01965 {
01966 if (include_dropped)
01967 {
01968 if (colnames)
01969 *colnames = lappend(*colnames, makeString(pstrdup("")));
01970 if (colvars)
01971 {
01972
01973
01974
01975
01976 *colvars = lappend(*colvars,
01977 makeNullConst(INT4OID, -1, InvalidOid));
01978 }
01979 }
01980 continue;
01981 }
01982
01983 if (colnames)
01984 {
01985 char *label;
01986
01987 if (varattno < numaliases)
01988 label = strVal(list_nth(eref->colnames, varattno));
01989 else
01990 label = NameStr(attr->attname);
01991 *colnames = lappend(*colnames, makeString(pstrdup(label)));
01992 }
01993
01994 if (colvars)
01995 {
01996 Var *varnode;
01997
01998 varnode = makeVar(rtindex, attr->attnum,
01999 attr->atttypid, attr->atttypmod,
02000 attr->attcollation,
02001 sublevels_up);
02002 varnode->location = location;
02003
02004 *colvars = lappend(*colvars, varnode);
02005 }
02006 }
02007 }
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019 List *
02020 expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
02021 int rtindex, int sublevels_up, int location)
02022 {
02023 List *names,
02024 *vars;
02025 ListCell *name,
02026 *var;
02027 List *te_list = NIL;
02028
02029 expandRTE(rte, rtindex, sublevels_up, location, false,
02030 &names, &vars);
02031
02032
02033
02034
02035
02036
02037 rte->requiredPerms |= ACL_SELECT;
02038
02039 forboth(name, names, var, vars)
02040 {
02041 char *label = strVal(lfirst(name));
02042 Var *varnode = (Var *) lfirst(var);
02043 TargetEntry *te;
02044
02045 te = makeTargetEntry((Expr *) varnode,
02046 (AttrNumber) pstate->p_next_resno++,
02047 label,
02048 false);
02049 te_list = lappend(te_list, te);
02050
02051
02052 markVarForSelectPriv(pstate, varnode, rte);
02053 }
02054
02055 Assert(name == NULL && var == NULL);
02056
02057 return te_list;
02058 }
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071 char *
02072 get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
02073 {
02074 if (attnum == InvalidAttrNumber)
02075 return "*";
02076
02077
02078
02079
02080 if (rte->alias &&
02081 attnum > 0 && attnum <= list_length(rte->alias->colnames))
02082 return strVal(list_nth(rte->alias->colnames, attnum - 1));
02083
02084
02085
02086
02087
02088
02089
02090 if (rte->rtekind == RTE_RELATION)
02091 return get_relid_attribute_name(rte->relid, attnum);
02092
02093
02094
02095
02096 if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
02097 return strVal(list_nth(rte->eref->colnames, attnum - 1));
02098
02099
02100 elog(ERROR, "invalid attnum %d for rangetable entry %s",
02101 attnum, rte->eref->aliasname);
02102 return NULL;
02103 }
02104
02105
02106
02107
02108
02109 void
02110 get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
02111 Oid *vartype, int32 *vartypmod, Oid *varcollid)
02112 {
02113 switch (rte->rtekind)
02114 {
02115 case RTE_RELATION:
02116 {
02117
02118 HeapTuple tp;
02119 Form_pg_attribute att_tup;
02120
02121 tp = SearchSysCache2(ATTNUM,
02122 ObjectIdGetDatum(rte->relid),
02123 Int16GetDatum(attnum));
02124 if (!HeapTupleIsValid(tp))
02125 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
02126 attnum, rte->relid);
02127 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
02128
02129
02130
02131
02132
02133 if (att_tup->attisdropped)
02134 ereport(ERROR,
02135 (errcode(ERRCODE_UNDEFINED_COLUMN),
02136 errmsg("column \"%s\" of relation \"%s\" does not exist",
02137 NameStr(att_tup->attname),
02138 get_rel_name(rte->relid))));
02139 *vartype = att_tup->atttypid;
02140 *vartypmod = att_tup->atttypmod;
02141 *varcollid = att_tup->attcollation;
02142 ReleaseSysCache(tp);
02143 }
02144 break;
02145 case RTE_SUBQUERY:
02146 {
02147
02148 TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
02149 attnum);
02150
02151 if (te == NULL || te->resjunk)
02152 elog(ERROR, "subquery %s does not have attribute %d",
02153 rte->eref->aliasname, attnum);
02154 *vartype = exprType((Node *) te->expr);
02155 *vartypmod = exprTypmod((Node *) te->expr);
02156 *varcollid = exprCollation((Node *) te->expr);
02157 }
02158 break;
02159 case RTE_FUNCTION:
02160 {
02161
02162 TypeFuncClass functypclass;
02163 Oid funcrettype;
02164 TupleDesc tupdesc;
02165
02166 functypclass = get_expr_result_type(rte->funcexpr,
02167 &funcrettype,
02168 &tupdesc);
02169
02170 if (functypclass == TYPEFUNC_COMPOSITE)
02171 {
02172
02173 Form_pg_attribute att_tup;
02174
02175 Assert(tupdesc);
02176
02177 if (attnum < 1 || attnum > tupdesc->natts)
02178 ereport(ERROR,
02179 (errcode(ERRCODE_UNDEFINED_COLUMN),
02180 errmsg("column %d of relation \"%s\" does not exist",
02181 attnum,
02182 rte->eref->aliasname)));
02183
02184 att_tup = tupdesc->attrs[attnum - 1];
02185
02186
02187
02188
02189
02190 if (att_tup->attisdropped)
02191 ereport(ERROR,
02192 (errcode(ERRCODE_UNDEFINED_COLUMN),
02193 errmsg("column \"%s\" of relation \"%s\" does not exist",
02194 NameStr(att_tup->attname),
02195 rte->eref->aliasname)));
02196 *vartype = att_tup->atttypid;
02197 *vartypmod = att_tup->atttypmod;
02198 *varcollid = att_tup->attcollation;
02199 }
02200 else if (functypclass == TYPEFUNC_SCALAR)
02201 {
02202
02203 *vartype = funcrettype;
02204 *vartypmod = -1;
02205 *varcollid = exprCollation(rte->funcexpr);
02206 }
02207 else if (functypclass == TYPEFUNC_RECORD)
02208 {
02209 *vartype = list_nth_oid(rte->funccoltypes, attnum - 1);
02210 *vartypmod = list_nth_int(rte->funccoltypmods, attnum - 1);
02211 *varcollid = list_nth_oid(rte->funccolcollations, attnum - 1);
02212 }
02213 else
02214 {
02215
02216 elog(ERROR, "function in FROM has unsupported return type");
02217 }
02218 }
02219 break;
02220 case RTE_VALUES:
02221 {
02222
02223
02224 List *collist = (List *) linitial(rte->values_lists);
02225 Node *col;
02226
02227 if (attnum < 1 || attnum > list_length(collist))
02228 elog(ERROR, "values list %s does not have attribute %d",
02229 rte->eref->aliasname, attnum);
02230 col = (Node *) list_nth(collist, attnum - 1);
02231 *vartype = exprType(col);
02232 *vartypmod = exprTypmod(col);
02233 *varcollid = list_nth_oid(rte->values_collations, attnum - 1);
02234 }
02235 break;
02236 case RTE_JOIN:
02237 {
02238
02239
02240
02241 Node *aliasvar;
02242
02243 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
02244 aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
02245 *vartype = exprType(aliasvar);
02246 *vartypmod = exprTypmod(aliasvar);
02247 *varcollid = exprCollation(aliasvar);
02248 }
02249 break;
02250 case RTE_CTE:
02251 {
02252
02253 Assert(attnum > 0 && attnum <= list_length(rte->ctecoltypes));
02254 *vartype = list_nth_oid(rte->ctecoltypes, attnum - 1);
02255 *vartypmod = list_nth_int(rte->ctecoltypmods, attnum - 1);
02256 *varcollid = list_nth_oid(rte->ctecolcollations, attnum - 1);
02257 }
02258 break;
02259 default:
02260 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
02261 }
02262 }
02263
02264
02265
02266
02267
02268 bool
02269 get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
02270 {
02271 bool result;
02272
02273 switch (rte->rtekind)
02274 {
02275 case RTE_RELATION:
02276 {
02277
02278
02279
02280 HeapTuple tp;
02281 Form_pg_attribute att_tup;
02282
02283 tp = SearchSysCache2(ATTNUM,
02284 ObjectIdGetDatum(rte->relid),
02285 Int16GetDatum(attnum));
02286 if (!HeapTupleIsValid(tp))
02287 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
02288 attnum, rte->relid);
02289 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
02290 result = att_tup->attisdropped;
02291 ReleaseSysCache(tp);
02292 }
02293 break;
02294 case RTE_SUBQUERY:
02295 case RTE_VALUES:
02296 case RTE_CTE:
02297
02298 result = false;
02299 break;
02300 case RTE_JOIN:
02301 {
02302
02303
02304
02305
02306
02307
02308
02309 Var *aliasvar;
02310
02311 if (attnum <= 0 ||
02312 attnum > list_length(rte->joinaliasvars))
02313 elog(ERROR, "invalid varattno %d", attnum);
02314 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
02315
02316 result = IsA(aliasvar, Const);
02317 }
02318 break;
02319 case RTE_FUNCTION:
02320 {
02321
02322 Oid funcrettype = exprType(rte->funcexpr);
02323 Oid funcrelid = typeidTypeRelid(funcrettype);
02324
02325 if (OidIsValid(funcrelid))
02326 {
02327
02328
02329
02330
02331
02332 HeapTuple tp;
02333 Form_pg_attribute att_tup;
02334
02335 tp = SearchSysCache2(ATTNUM,
02336 ObjectIdGetDatum(funcrelid),
02337 Int16GetDatum(attnum));
02338 if (!HeapTupleIsValid(tp))
02339 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
02340 attnum, funcrelid);
02341 att_tup = (Form_pg_attribute) GETSTRUCT(tp);
02342 result = att_tup->attisdropped;
02343 ReleaseSysCache(tp);
02344 }
02345 else
02346 {
02347
02348
02349
02350 result = false;
02351 }
02352 }
02353 break;
02354 default:
02355 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
02356 result = false;
02357 }
02358
02359 return result;
02360 }
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370 TargetEntry *
02371 get_tle_by_resno(List *tlist, AttrNumber resno)
02372 {
02373 ListCell *l;
02374
02375 foreach(l, tlist)
02376 {
02377 TargetEntry *tle = (TargetEntry *) lfirst(l);
02378
02379 if (tle->resno == resno)
02380 return tle;
02381 }
02382 return NULL;
02383 }
02384
02385
02386
02387
02388
02389
02390 RowMarkClause *
02391 get_parse_rowmark(Query *qry, Index rtindex)
02392 {
02393 ListCell *l;
02394
02395 foreach(l, qry->rowMarks)
02396 {
02397 RowMarkClause *rc = (RowMarkClause *) lfirst(l);
02398
02399 if (rc->rti == rtindex)
02400 return rc;
02401 }
02402 return NULL;
02403 }
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414 int
02415 attnameAttNum(Relation rd, const char *attname, bool sysColOK)
02416 {
02417 int i;
02418
02419 for (i = 0; i < rd->rd_rel->relnatts; i++)
02420 {
02421 Form_pg_attribute att = rd->rd_att->attrs[i];
02422
02423 if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
02424 return i + 1;
02425 }
02426
02427 if (sysColOK)
02428 {
02429 if ((i = specialAttNum(attname)) != InvalidAttrNumber)
02430 {
02431 if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
02432 return i;
02433 }
02434 }
02435
02436
02437 return InvalidAttrNumber;
02438 }
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449 static int
02450 specialAttNum(const char *attname)
02451 {
02452 Form_pg_attribute sysatt;
02453
02454 sysatt = SystemAttributeByName(attname,
02455 true );
02456 if (sysatt != NULL)
02457 return sysatt->attnum;
02458 return InvalidAttrNumber;
02459 }
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469 Name
02470 attnumAttName(Relation rd, int attid)
02471 {
02472 if (attid <= 0)
02473 {
02474 Form_pg_attribute sysatt;
02475
02476 sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
02477 return &sysatt->attname;
02478 }
02479 if (attid > rd->rd_att->natts)
02480 elog(ERROR, "invalid attribute number %d", attid);
02481 return &rd->rd_att->attrs[attid - 1]->attname;
02482 }
02483
02484
02485
02486
02487
02488
02489
02490
02491 Oid
02492 attnumTypeId(Relation rd, int attid)
02493 {
02494 if (attid <= 0)
02495 {
02496 Form_pg_attribute sysatt;
02497
02498 sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
02499 return sysatt->atttypid;
02500 }
02501 if (attid > rd->rd_att->natts)
02502 elog(ERROR, "invalid attribute number %d", attid);
02503 return rd->rd_att->attrs[attid - 1]->atttypid;
02504 }
02505
02506
02507
02508
02509
02510
02511 Oid
02512 attnumCollationId(Relation rd, int attid)
02513 {
02514 if (attid <= 0)
02515 {
02516
02517 return InvalidOid;
02518 }
02519 if (attid > rd->rd_att->natts)
02520 elog(ERROR, "invalid attribute number %d", attid);
02521 return rd->rd_att->attrs[attid - 1]->attcollation;
02522 }
02523
02524
02525
02526
02527
02528
02529
02530 void
02531 errorMissingRTE(ParseState *pstate, RangeVar *relation)
02532 {
02533 RangeTblEntry *rte;
02534 int sublevels_up;
02535 const char *badAlias = NULL;
02536
02537
02538
02539
02540
02541
02542 rte = searchRangeTableForRel(pstate, relation);
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554 if (rte && rte->alias &&
02555 strcmp(rte->eref->aliasname, relation->relname) != 0 &&
02556 refnameRangeTblEntry(pstate, NULL, rte->eref->aliasname,
02557 relation->location,
02558 &sublevels_up) == rte)
02559 badAlias = rte->eref->aliasname;
02560
02561 if (rte)
02562 ereport(ERROR,
02563 (errcode(ERRCODE_UNDEFINED_TABLE),
02564 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
02565 relation->relname),
02566 (badAlias ?
02567 errhint("Perhaps you meant to reference the table alias \"%s\".",
02568 badAlias) :
02569 errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
02570 rte->eref->aliasname)),
02571 parser_errposition(pstate, relation->location)));
02572 else
02573 ereport(ERROR,
02574 (errcode(ERRCODE_UNDEFINED_TABLE),
02575 errmsg("missing FROM-clause entry for table \"%s\"",
02576 relation->relname),
02577 parser_errposition(pstate, relation->location)));
02578 }
02579
02580
02581
02582
02583
02584
02585
02586 void
02587 errorMissingColumn(ParseState *pstate,
02588 char *relname, char *colname, int location)
02589 {
02590 RangeTblEntry *rte;
02591
02592
02593
02594
02595
02596
02597 if (relname)
02598 ereport(ERROR,
02599 (errcode(ERRCODE_UNDEFINED_COLUMN),
02600 errmsg("column %s.%s does not exist", relname, colname),
02601 parser_errposition(pstate, location)));
02602
02603
02604
02605
02606
02607
02608
02609
02610 rte = searchRangeTableForCol(pstate, colname, location);
02611
02612 ereport(ERROR,
02613 (errcode(ERRCODE_UNDEFINED_COLUMN),
02614 errmsg("column \"%s\" does not exist", colname),
02615 rte ? errhint("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
02616 colname, rte->eref->aliasname) : 0,
02617 parser_errposition(pstate, location)));
02618 }
02619
02620
02621
02622
02623
02624
02625 bool
02626 isQueryUsingTempRelation(Query *query)
02627 {
02628 return isQueryUsingTempRelation_walker((Node *) query, NULL);
02629 }
02630
02631 static bool
02632 isQueryUsingTempRelation_walker(Node *node, void *context)
02633 {
02634 if (node == NULL)
02635 return false;
02636
02637 if (IsA(node, Query))
02638 {
02639 Query *query = (Query *) node;
02640 ListCell *rtable;
02641
02642 foreach(rtable, query->rtable)
02643 {
02644 RangeTblEntry *rte = lfirst(rtable);
02645
02646 if (rte->rtekind == RTE_RELATION)
02647 {
02648 Relation rel = heap_open(rte->relid, AccessShareLock);
02649 char relpersistence = rel->rd_rel->relpersistence;
02650
02651 heap_close(rel, AccessShareLock);
02652 if (relpersistence == RELPERSISTENCE_TEMP)
02653 return true;
02654 }
02655 }
02656
02657 return query_tree_walker(query,
02658 isQueryUsingTempRelation_walker,
02659 context,
02660 QTW_IGNORE_JOINALIASES);
02661 }
02662
02663 return expression_tree_walker(node,
02664 isQueryUsingTempRelation_walker,
02665 context);
02666 }