00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include "catalog/pg_type.h"
00018 #include "commands/dbcommands.h"
00019 #include "funcapi.h"
00020 #include "miscadmin.h"
00021 #include "nodes/makefuncs.h"
00022 #include "nodes/nodeFuncs.h"
00023 #include "parser/parsetree.h"
00024 #include "parser/parse_coerce.h"
00025 #include "parser/parse_expr.h"
00026 #include "parser/parse_func.h"
00027 #include "parser/parse_relation.h"
00028 #include "parser/parse_target.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/typcache.h"
00034
00035
00036 static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
00037 Var *var, int levelsup);
00038 static Node *transformAssignmentIndirection(ParseState *pstate,
00039 Node *basenode,
00040 const char *targetName,
00041 bool targetIsArray,
00042 Oid targetTypeId,
00043 int32 targetTypMod,
00044 Oid targetCollation,
00045 ListCell *indirection,
00046 Node *rhs,
00047 int location);
00048 static Node *transformAssignmentSubscripts(ParseState *pstate,
00049 Node *basenode,
00050 const char *targetName,
00051 Oid targetTypeId,
00052 int32 targetTypMod,
00053 Oid targetCollation,
00054 List *subscripts,
00055 bool isSlice,
00056 ListCell *next_indirection,
00057 Node *rhs,
00058 int location);
00059 static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
00060 bool make_target_entry);
00061 static List *ExpandAllTables(ParseState *pstate, int location);
00062 static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
00063 bool make_target_entry, ParseExprKind exprKind);
00064 static List *ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte,
00065 int location, bool make_target_entry);
00066 static List *ExpandRowReference(ParseState *pstate, Node *expr,
00067 bool make_target_entry);
00068 static int FigureColnameInternal(Node *node, char **name);
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 TargetEntry *
00085 transformTargetEntry(ParseState *pstate,
00086 Node *node,
00087 Node *expr,
00088 ParseExprKind exprKind,
00089 char *colname,
00090 bool resjunk)
00091 {
00092
00093 if (expr == NULL)
00094 expr = transformExpr(pstate, node, exprKind);
00095
00096 if (colname == NULL && !resjunk)
00097 {
00098
00099
00100
00101
00102 colname = FigureColname(node);
00103 }
00104
00105 return makeTargetEntry((Expr *) expr,
00106 (AttrNumber) pstate->p_next_resno++,
00107 colname,
00108 resjunk);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 List *
00121 transformTargetList(ParseState *pstate, List *targetlist,
00122 ParseExprKind exprKind)
00123 {
00124 List *p_target = NIL;
00125 ListCell *o_target;
00126
00127 foreach(o_target, targetlist)
00128 {
00129 ResTarget *res = (ResTarget *) lfirst(o_target);
00130
00131
00132
00133
00134
00135
00136 if (IsA(res->val, ColumnRef))
00137 {
00138 ColumnRef *cref = (ColumnRef *) res->val;
00139
00140 if (IsA(llast(cref->fields), A_Star))
00141 {
00142
00143 p_target = list_concat(p_target,
00144 ExpandColumnRefStar(pstate, cref,
00145 true));
00146 continue;
00147 }
00148 }
00149 else if (IsA(res->val, A_Indirection))
00150 {
00151 A_Indirection *ind = (A_Indirection *) res->val;
00152
00153 if (IsA(llast(ind->indirection), A_Star))
00154 {
00155
00156 p_target = list_concat(p_target,
00157 ExpandIndirectionStar(pstate, ind,
00158 true, exprKind));
00159 continue;
00160 }
00161 }
00162
00163
00164
00165
00166 p_target = lappend(p_target,
00167 transformTargetEntry(pstate,
00168 res->val,
00169 NULL,
00170 exprKind,
00171 res->name,
00172 false));
00173 }
00174
00175 return p_target;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 List *
00188 transformExpressionList(ParseState *pstate, List *exprlist,
00189 ParseExprKind exprKind)
00190 {
00191 List *result = NIL;
00192 ListCell *lc;
00193
00194 foreach(lc, exprlist)
00195 {
00196 Node *e = (Node *) lfirst(lc);
00197
00198
00199
00200
00201
00202
00203 if (IsA(e, ColumnRef))
00204 {
00205 ColumnRef *cref = (ColumnRef *) e;
00206
00207 if (IsA(llast(cref->fields), A_Star))
00208 {
00209
00210 result = list_concat(result,
00211 ExpandColumnRefStar(pstate, cref,
00212 false));
00213 continue;
00214 }
00215 }
00216 else if (IsA(e, A_Indirection))
00217 {
00218 A_Indirection *ind = (A_Indirection *) e;
00219
00220 if (IsA(llast(ind->indirection), A_Star))
00221 {
00222
00223 result = list_concat(result,
00224 ExpandIndirectionStar(pstate, ind,
00225 false, exprKind));
00226 continue;
00227 }
00228 }
00229
00230
00231
00232
00233 result = lappend(result,
00234 transformExpr(pstate, e, exprKind));
00235 }
00236
00237 return result;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 void
00250 markTargetListOrigins(ParseState *pstate, List *targetlist)
00251 {
00252 ListCell *l;
00253
00254 foreach(l, targetlist)
00255 {
00256 TargetEntry *tle = (TargetEntry *) lfirst(l);
00257
00258 markTargetListOrigin(pstate, tle, (Var *) tle->expr, 0);
00259 }
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 static void
00272 markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
00273 Var *var, int levelsup)
00274 {
00275 int netlevelsup;
00276 RangeTblEntry *rte;
00277 AttrNumber attnum;
00278
00279 if (var == NULL || !IsA(var, Var))
00280 return;
00281 netlevelsup = var->varlevelsup + levelsup;
00282 rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
00283 attnum = var->varattno;
00284
00285 switch (rte->rtekind)
00286 {
00287 case RTE_RELATION:
00288
00289 tle->resorigtbl = rte->relid;
00290 tle->resorigcol = attnum;
00291 break;
00292 case RTE_SUBQUERY:
00293
00294 if (attnum != InvalidAttrNumber)
00295 {
00296 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
00297 attnum);
00298
00299 if (ste == NULL || ste->resjunk)
00300 elog(ERROR, "subquery %s does not have attribute %d",
00301 rte->eref->aliasname, attnum);
00302 tle->resorigtbl = ste->resorigtbl;
00303 tle->resorigcol = ste->resorigcol;
00304 }
00305 break;
00306 case RTE_JOIN:
00307
00308 if (attnum != InvalidAttrNumber)
00309 {
00310 Var *aliasvar;
00311
00312 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
00313 aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
00314 markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
00315 }
00316 break;
00317 case RTE_FUNCTION:
00318 case RTE_VALUES:
00319
00320 break;
00321 case RTE_CTE:
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 if (attnum != InvalidAttrNumber && !rte->self_reference)
00332 {
00333 CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
00334 TargetEntry *ste;
00335
00336 ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
00337 if (ste == NULL || ste->resjunk)
00338 elog(ERROR, "subquery %s does not have attribute %d",
00339 rte->eref->aliasname, attnum);
00340 tle->resorigtbl = ste->resorigtbl;
00341 tle->resorigcol = ste->resorigcol;
00342 }
00343 break;
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 Expr *
00373 transformAssignedExpr(ParseState *pstate,
00374 Expr *expr,
00375 ParseExprKind exprKind,
00376 char *colname,
00377 int attrno,
00378 List *indirection,
00379 int location)
00380 {
00381 Relation rd = pstate->p_target_relation;
00382 Oid type_id;
00383 Oid attrtype;
00384 int32 attrtypmod;
00385 Oid attrcollation;
00386 ParseExprKind sv_expr_kind;
00387
00388
00389
00390
00391
00392
00393 Assert(exprKind != EXPR_KIND_NONE);
00394 sv_expr_kind = pstate->p_expr_kind;
00395 pstate->p_expr_kind = exprKind;
00396
00397 Assert(rd != NULL);
00398 if (attrno <= 0)
00399 ereport(ERROR,
00400 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00401 errmsg("cannot assign to system column \"%s\"",
00402 colname),
00403 parser_errposition(pstate, location)));
00404 attrtype = attnumTypeId(rd, attrno);
00405 attrtypmod = rd->rd_att->attrs[attrno - 1]->atttypmod;
00406 attrcollation = rd->rd_att->attrs[attrno - 1]->attcollation;
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 if (expr && IsA(expr, SetToDefault))
00418 {
00419 SetToDefault *def = (SetToDefault *) expr;
00420
00421 def->typeId = attrtype;
00422 def->typeMod = attrtypmod;
00423 def->collation = attrcollation;
00424 if (indirection)
00425 {
00426 if (IsA(linitial(indirection), A_Indices))
00427 ereport(ERROR,
00428 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00429 errmsg("cannot set an array element to DEFAULT"),
00430 parser_errposition(pstate, location)));
00431 else
00432 ereport(ERROR,
00433 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00434 errmsg("cannot set a subfield to DEFAULT"),
00435 parser_errposition(pstate, location)));
00436 }
00437 }
00438
00439
00440 type_id = exprType((Node *) expr);
00441
00442
00443
00444
00445
00446
00447
00448 if (indirection)
00449 {
00450 Node *colVar;
00451
00452 if (pstate->p_is_insert)
00453 {
00454
00455
00456
00457
00458
00459 colVar = (Node *) makeNullConst(attrtype, attrtypmod,
00460 attrcollation);
00461 }
00462 else
00463 {
00464
00465
00466
00467 colVar = (Node *) make_var(pstate,
00468 pstate->p_target_rangetblentry,
00469 attrno,
00470 location);
00471 }
00472
00473 expr = (Expr *)
00474 transformAssignmentIndirection(pstate,
00475 colVar,
00476 colname,
00477 false,
00478 attrtype,
00479 attrtypmod,
00480 attrcollation,
00481 list_head(indirection),
00482 (Node *) expr,
00483 location);
00484 }
00485 else
00486 {
00487
00488
00489
00490
00491 Node *orig_expr = (Node *) expr;
00492
00493 expr = (Expr *)
00494 coerce_to_target_type(pstate,
00495 orig_expr, type_id,
00496 attrtype, attrtypmod,
00497 COERCION_ASSIGNMENT,
00498 COERCE_IMPLICIT_CAST,
00499 -1);
00500 if (expr == NULL)
00501 ereport(ERROR,
00502 (errcode(ERRCODE_DATATYPE_MISMATCH),
00503 errmsg("column \"%s\" is of type %s"
00504 " but expression is of type %s",
00505 colname,
00506 format_type_be(attrtype),
00507 format_type_be(type_id)),
00508 errhint("You will need to rewrite or cast the expression."),
00509 parser_errposition(pstate, exprLocation(orig_expr))));
00510 }
00511
00512 pstate->p_expr_kind = sv_expr_kind;
00513
00514 return expr;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 void
00534 updateTargetListEntry(ParseState *pstate,
00535 TargetEntry *tle,
00536 char *colname,
00537 int attrno,
00538 List *indirection,
00539 int location)
00540 {
00541
00542 tle->expr = transformAssignedExpr(pstate,
00543 tle->expr,
00544 EXPR_KIND_UPDATE_TARGET,
00545 colname,
00546 attrno,
00547 indirection,
00548 location);
00549
00550
00551
00552
00553
00554
00555
00556 tle->resno = (AttrNumber) attrno;
00557 tle->resname = colname;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 static Node *
00593 transformAssignmentIndirection(ParseState *pstate,
00594 Node *basenode,
00595 const char *targetName,
00596 bool targetIsArray,
00597 Oid targetTypeId,
00598 int32 targetTypMod,
00599 Oid targetCollation,
00600 ListCell *indirection,
00601 Node *rhs,
00602 int location)
00603 {
00604 Node *result;
00605 List *subscripts = NIL;
00606 bool isSlice = false;
00607 ListCell *i;
00608
00609 if (indirection && !basenode)
00610 {
00611
00612 CaseTestExpr *ctest = makeNode(CaseTestExpr);
00613
00614 ctest->typeId = targetTypeId;
00615 ctest->typeMod = targetTypMod;
00616 ctest->collation = targetCollation;
00617 basenode = (Node *) ctest;
00618 }
00619
00620
00621
00622
00623
00624
00625 for_each_cell(i, indirection)
00626 {
00627 Node *n = lfirst(i);
00628
00629 if (IsA(n, A_Indices))
00630 {
00631 subscripts = lappend(subscripts, n);
00632 if (((A_Indices *) n)->lidx != NULL)
00633 isSlice = true;
00634 }
00635 else if (IsA(n, A_Star))
00636 {
00637 ereport(ERROR,
00638 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00639 errmsg("row expansion via \"*\" is not supported here"),
00640 parser_errposition(pstate, location)));
00641 }
00642 else
00643 {
00644 FieldStore *fstore;
00645 Oid typrelid;
00646 AttrNumber attnum;
00647 Oid fieldTypeId;
00648 int32 fieldTypMod;
00649 Oid fieldCollation;
00650
00651 Assert(IsA(n, String));
00652
00653
00654 if (subscripts)
00655 {
00656
00657 return transformAssignmentSubscripts(pstate,
00658 basenode,
00659 targetName,
00660 targetTypeId,
00661 targetTypMod,
00662 targetCollation,
00663 subscripts,
00664 isSlice,
00665 i,
00666 rhs,
00667 location);
00668 }
00669
00670
00671
00672 typrelid = typeidTypeRelid(targetTypeId);
00673 if (!typrelid)
00674 ereport(ERROR,
00675 (errcode(ERRCODE_DATATYPE_MISMATCH),
00676 errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type",
00677 strVal(n), targetName,
00678 format_type_be(targetTypeId)),
00679 parser_errposition(pstate, location)));
00680
00681 attnum = get_attnum(typrelid, strVal(n));
00682 if (attnum == InvalidAttrNumber)
00683 ereport(ERROR,
00684 (errcode(ERRCODE_UNDEFINED_COLUMN),
00685 errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
00686 strVal(n), targetName,
00687 format_type_be(targetTypeId)),
00688 parser_errposition(pstate, location)));
00689 if (attnum < 0)
00690 ereport(ERROR,
00691 (errcode(ERRCODE_UNDEFINED_COLUMN),
00692 errmsg("cannot assign to system column \"%s\"",
00693 strVal(n)),
00694 parser_errposition(pstate, location)));
00695
00696 get_atttypetypmodcoll(typrelid, attnum,
00697 &fieldTypeId, &fieldTypMod, &fieldCollation);
00698
00699
00700 rhs = transformAssignmentIndirection(pstate,
00701 NULL,
00702 strVal(n),
00703 false,
00704 fieldTypeId,
00705 fieldTypMod,
00706 fieldCollation,
00707 lnext(i),
00708 rhs,
00709 location);
00710
00711
00712 fstore = makeNode(FieldStore);
00713 fstore->arg = (Expr *) basenode;
00714 fstore->newvals = list_make1(rhs);
00715 fstore->fieldnums = list_make1_int(attnum);
00716 fstore->resulttype = targetTypeId;
00717
00718 return (Node *) fstore;
00719 }
00720 }
00721
00722
00723 if (subscripts)
00724 {
00725
00726 return transformAssignmentSubscripts(pstate,
00727 basenode,
00728 targetName,
00729 targetTypeId,
00730 targetTypMod,
00731 targetCollation,
00732 subscripts,
00733 isSlice,
00734 NULL,
00735 rhs,
00736 location);
00737 }
00738
00739
00740
00741 result = coerce_to_target_type(pstate,
00742 rhs, exprType(rhs),
00743 targetTypeId, targetTypMod,
00744 COERCION_ASSIGNMENT,
00745 COERCE_IMPLICIT_CAST,
00746 -1);
00747 if (result == NULL)
00748 {
00749 if (targetIsArray)
00750 ereport(ERROR,
00751 (errcode(ERRCODE_DATATYPE_MISMATCH),
00752 errmsg("array assignment to \"%s\" requires type %s"
00753 " but expression is of type %s",
00754 targetName,
00755 format_type_be(targetTypeId),
00756 format_type_be(exprType(rhs))),
00757 errhint("You will need to rewrite or cast the expression."),
00758 parser_errposition(pstate, location)));
00759 else
00760 ereport(ERROR,
00761 (errcode(ERRCODE_DATATYPE_MISMATCH),
00762 errmsg("subfield \"%s\" is of type %s"
00763 " but expression is of type %s",
00764 targetName,
00765 format_type_be(targetTypeId),
00766 format_type_be(exprType(rhs))),
00767 errhint("You will need to rewrite or cast the expression."),
00768 parser_errposition(pstate, location)));
00769 }
00770
00771 return result;
00772 }
00773
00774
00775
00776
00777 static Node *
00778 transformAssignmentSubscripts(ParseState *pstate,
00779 Node *basenode,
00780 const char *targetName,
00781 Oid targetTypeId,
00782 int32 targetTypMod,
00783 Oid targetCollation,
00784 List *subscripts,
00785 bool isSlice,
00786 ListCell *next_indirection,
00787 Node *rhs,
00788 int location)
00789 {
00790 Node *result;
00791 Oid arrayType;
00792 int32 arrayTypMod;
00793 Oid elementTypeId;
00794 Oid typeNeeded;
00795 Oid collationNeeded;
00796
00797 Assert(subscripts != NIL);
00798
00799
00800 arrayType = targetTypeId;
00801 arrayTypMod = targetTypMod;
00802 elementTypeId = transformArrayType(&arrayType, &arrayTypMod);
00803
00804
00805 typeNeeded = isSlice ? arrayType : elementTypeId;
00806
00807
00808
00809
00810
00811
00812 if (arrayType == targetTypeId)
00813 collationNeeded = targetCollation;
00814 else
00815 collationNeeded = get_typcollation(arrayType);
00816
00817
00818 rhs = transformAssignmentIndirection(pstate,
00819 NULL,
00820 targetName,
00821 true,
00822 typeNeeded,
00823 arrayTypMod,
00824 collationNeeded,
00825 next_indirection,
00826 rhs,
00827 location);
00828
00829
00830 result = (Node *) transformArraySubscripts(pstate,
00831 basenode,
00832 arrayType,
00833 elementTypeId,
00834 arrayTypMod,
00835 subscripts,
00836 rhs);
00837
00838
00839 if (arrayType != targetTypeId)
00840 {
00841 result = coerce_to_target_type(pstate,
00842 result, exprType(result),
00843 targetTypeId, targetTypMod,
00844 COERCION_ASSIGNMENT,
00845 COERCE_IMPLICIT_CAST,
00846 -1);
00847
00848 if (result == NULL)
00849 ereport(ERROR,
00850 (errcode(ERRCODE_CANNOT_COERCE),
00851 errmsg("cannot cast type %s to %s",
00852 format_type_be(exprType(result)),
00853 format_type_be(targetTypeId)),
00854 parser_errposition(pstate, location)));
00855 }
00856
00857 return result;
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867 List *
00868 checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
00869 {
00870 *attrnos = NIL;
00871
00872 if (cols == NIL)
00873 {
00874
00875
00876
00877 Form_pg_attribute *attr = pstate->p_target_relation->rd_att->attrs;
00878 int numcol = pstate->p_target_relation->rd_rel->relnatts;
00879 int i;
00880
00881 for (i = 0; i < numcol; i++)
00882 {
00883 ResTarget *col;
00884
00885 if (attr[i]->attisdropped)
00886 continue;
00887
00888 col = makeNode(ResTarget);
00889 col->name = pstrdup(NameStr(attr[i]->attname));
00890 col->indirection = NIL;
00891 col->val = NULL;
00892 col->location = -1;
00893 cols = lappend(cols, col);
00894 *attrnos = lappend_int(*attrnos, i + 1);
00895 }
00896 }
00897 else
00898 {
00899
00900
00901
00902 Bitmapset *wholecols = NULL;
00903 Bitmapset *partialcols = NULL;
00904 ListCell *tl;
00905
00906 foreach(tl, cols)
00907 {
00908 ResTarget *col = (ResTarget *) lfirst(tl);
00909 char *name = col->name;
00910 int attrno;
00911
00912
00913 attrno = attnameAttNum(pstate->p_target_relation, name, false);
00914 if (attrno == InvalidAttrNumber)
00915 ereport(ERROR,
00916 (errcode(ERRCODE_UNDEFINED_COLUMN),
00917 errmsg("column \"%s\" of relation \"%s\" does not exist",
00918 name,
00919 RelationGetRelationName(pstate->p_target_relation)),
00920 parser_errposition(pstate, col->location)));
00921
00922
00923
00924
00925
00926 if (col->indirection == NIL)
00927 {
00928
00929 if (bms_is_member(attrno, wholecols) ||
00930 bms_is_member(attrno, partialcols))
00931 ereport(ERROR,
00932 (errcode(ERRCODE_DUPLICATE_COLUMN),
00933 errmsg("column \"%s\" specified more than once",
00934 name),
00935 parser_errposition(pstate, col->location)));
00936 wholecols = bms_add_member(wholecols, attrno);
00937 }
00938 else
00939 {
00940
00941 if (bms_is_member(attrno, wholecols))
00942 ereport(ERROR,
00943 (errcode(ERRCODE_DUPLICATE_COLUMN),
00944 errmsg("column \"%s\" specified more than once",
00945 name),
00946 parser_errposition(pstate, col->location)));
00947 partialcols = bms_add_member(partialcols, attrno);
00948 }
00949
00950 *attrnos = lappend_int(*attrnos, attrno);
00951 }
00952 }
00953
00954 return cols;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 static List *
00970 ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
00971 bool make_target_entry)
00972 {
00973 List *fields = cref->fields;
00974 int numnames = list_length(fields);
00975
00976 if (numnames == 1)
00977 {
00978
00979
00980
00981
00982
00983
00984
00985
00986 Assert(make_target_entry);
00987 return ExpandAllTables(pstate, cref->location);
00988 }
00989 else
00990 {
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 char *nspname = NULL;
01006 char *relname = NULL;
01007 RangeTblEntry *rte = NULL;
01008 int levels_up;
01009 enum
01010 {
01011 CRSERR_NO_RTE,
01012 CRSERR_WRONG_DB,
01013 CRSERR_TOO_MANY
01014 } crserr = CRSERR_NO_RTE;
01015
01016
01017
01018
01019
01020 if (pstate->p_pre_columnref_hook != NULL)
01021 {
01022 Node *node;
01023
01024 node = (*pstate->p_pre_columnref_hook) (pstate, cref);
01025 if (node != NULL)
01026 return ExpandRowReference(pstate, node, make_target_entry);
01027 }
01028
01029 switch (numnames)
01030 {
01031 case 2:
01032 relname = strVal(linitial(fields));
01033 rte = refnameRangeTblEntry(pstate, nspname, relname,
01034 cref->location,
01035 &levels_up);
01036 break;
01037 case 3:
01038 nspname = strVal(linitial(fields));
01039 relname = strVal(lsecond(fields));
01040 rte = refnameRangeTblEntry(pstate, nspname, relname,
01041 cref->location,
01042 &levels_up);
01043 break;
01044 case 4:
01045 {
01046 char *catname = strVal(linitial(fields));
01047
01048
01049
01050
01051 if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
01052 {
01053 crserr = CRSERR_WRONG_DB;
01054 break;
01055 }
01056 nspname = strVal(lsecond(fields));
01057 relname = strVal(lthird(fields));
01058 rte = refnameRangeTblEntry(pstate, nspname, relname,
01059 cref->location,
01060 &levels_up);
01061 break;
01062 }
01063 default:
01064 crserr = CRSERR_TOO_MANY;
01065 break;
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075 if (pstate->p_post_columnref_hook != NULL)
01076 {
01077 Node *node;
01078
01079 node = (*pstate->p_post_columnref_hook) (pstate, cref,
01080 (Node *) rte);
01081 if (node != NULL)
01082 {
01083 if (rte != NULL)
01084 ereport(ERROR,
01085 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
01086 errmsg("column reference \"%s\" is ambiguous",
01087 NameListToString(cref->fields)),
01088 parser_errposition(pstate, cref->location)));
01089 return ExpandRowReference(pstate, node, make_target_entry);
01090 }
01091 }
01092
01093
01094
01095
01096 if (rte == NULL)
01097 {
01098 switch (crserr)
01099 {
01100 case CRSERR_NO_RTE:
01101 errorMissingRTE(pstate, makeRangeVar(nspname, relname,
01102 cref->location));
01103 break;
01104 case CRSERR_WRONG_DB:
01105 ereport(ERROR,
01106 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01107 errmsg("cross-database references are not implemented: %s",
01108 NameListToString(cref->fields)),
01109 parser_errposition(pstate, cref->location)));
01110 break;
01111 case CRSERR_TOO_MANY:
01112 ereport(ERROR,
01113 (errcode(ERRCODE_SYNTAX_ERROR),
01114 errmsg("improper qualified name (too many dotted names): %s",
01115 NameListToString(cref->fields)),
01116 parser_errposition(pstate, cref->location)));
01117 break;
01118 }
01119 }
01120
01121
01122
01123
01124 return ExpandSingleTable(pstate, rte, cref->location, make_target_entry);
01125 }
01126 }
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 static List *
01140 ExpandAllTables(ParseState *pstate, int location)
01141 {
01142 List *target = NIL;
01143 bool found_table = false;
01144 ListCell *l;
01145
01146 foreach(l, pstate->p_namespace)
01147 {
01148 ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);
01149 RangeTblEntry *rte = nsitem->p_rte;
01150
01151
01152 if (!nsitem->p_cols_visible)
01153 continue;
01154
01155 Assert(!nsitem->p_lateral_only);
01156
01157 found_table = true;
01158
01159 target = list_concat(target,
01160 expandRelAttrs(pstate,
01161 rte,
01162 RTERangeTablePosn(pstate, rte,
01163 NULL),
01164 0,
01165 location));
01166 }
01167
01168
01169
01170
01171
01172
01173 if (!found_table)
01174 ereport(ERROR,
01175 (errcode(ERRCODE_SYNTAX_ERROR),
01176 errmsg("SELECT * with no tables specified is not valid"),
01177 parser_errposition(pstate, location)));
01178
01179 return target;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193 static List *
01194 ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
01195 bool make_target_entry, ParseExprKind exprKind)
01196 {
01197 Node *expr;
01198
01199
01200 ind = copyObject(ind);
01201 ind->indirection = list_truncate(ind->indirection,
01202 list_length(ind->indirection) - 1);
01203
01204
01205 expr = transformExpr(pstate, (Node *) ind, exprKind);
01206
01207
01208 return ExpandRowReference(pstate, expr, make_target_entry);
01209 }
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220 static List *
01221 ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte,
01222 int location, bool make_target_entry)
01223 {
01224 int sublevels_up;
01225 int rtindex;
01226
01227 rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
01228
01229 if (make_target_entry)
01230 {
01231
01232 return expandRelAttrs(pstate, rte, rtindex, sublevels_up,
01233 location);
01234 }
01235 else
01236 {
01237 List *vars;
01238 ListCell *l;
01239
01240 expandRTE(rte, rtindex, sublevels_up, location, false,
01241 NULL, &vars);
01242
01243
01244
01245
01246
01247
01248 rte->requiredPerms |= ACL_SELECT;
01249
01250
01251 foreach(l, vars)
01252 {
01253 Var *var = (Var *) lfirst(l);
01254
01255 markVarForSelectPriv(pstate, var, rte);
01256 }
01257
01258 return vars;
01259 }
01260 }
01261
01262
01263
01264
01265
01266
01267
01268
01269 static List *
01270 ExpandRowReference(ParseState *pstate, Node *expr,
01271 bool make_target_entry)
01272 {
01273 List *result = NIL;
01274 TupleDesc tupleDesc;
01275 int numAttrs;
01276 int i;
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 if (IsA(expr, Var) &&
01288 ((Var *) expr)->varattno == InvalidAttrNumber)
01289 {
01290 Var *var = (Var *) expr;
01291 RangeTblEntry *rte;
01292
01293 rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
01294 return ExpandSingleTable(pstate, rte, var->location, make_target_entry);
01295 }
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313 if (IsA(expr, Var) &&
01314 ((Var *) expr)->vartype == RECORDOID)
01315 tupleDesc = expandRecordVariable(pstate, (Var *) expr, 0);
01316 else if (get_expr_result_type(expr, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
01317 tupleDesc = lookup_rowtype_tupdesc_copy(exprType(expr),
01318 exprTypmod(expr));
01319 Assert(tupleDesc);
01320
01321
01322 numAttrs = tupleDesc->natts;
01323 for (i = 0; i < numAttrs; i++)
01324 {
01325 Form_pg_attribute att = tupleDesc->attrs[i];
01326 FieldSelect *fselect;
01327
01328 if (att->attisdropped)
01329 continue;
01330
01331 fselect = makeNode(FieldSelect);
01332 fselect->arg = (Expr *) copyObject(expr);
01333 fselect->fieldnum = i + 1;
01334 fselect->resulttype = att->atttypid;
01335 fselect->resulttypmod = att->atttypmod;
01336
01337 fselect->resultcollid = att->attcollation;
01338
01339 if (make_target_entry)
01340 {
01341
01342 TargetEntry *te;
01343
01344 te = makeTargetEntry((Expr *) fselect,
01345 (AttrNumber) pstate->p_next_resno++,
01346 pstrdup(NameStr(att->attname)),
01347 false);
01348 result = lappend(result, te);
01349 }
01350 else
01351 result = lappend(result, fselect);
01352 }
01353
01354 return result;
01355 }
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 TupleDesc
01369 expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
01370 {
01371 TupleDesc tupleDesc;
01372 int netlevelsup;
01373 RangeTblEntry *rte;
01374 AttrNumber attnum;
01375 Node *expr;
01376
01377
01378 Assert(IsA(var, Var));
01379 Assert(var->vartype == RECORDOID);
01380
01381 netlevelsup = var->varlevelsup + levelsup;
01382 rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
01383 attnum = var->varattno;
01384
01385 if (attnum == InvalidAttrNumber)
01386 {
01387
01388 List *names,
01389 *vars;
01390 ListCell *lname,
01391 *lvar;
01392 int i;
01393
01394 expandRTE(rte, var->varno, 0, var->location, false,
01395 &names, &vars);
01396
01397 tupleDesc = CreateTemplateTupleDesc(list_length(vars), false);
01398 i = 1;
01399 forboth(lname, names, lvar, vars)
01400 {
01401 char *label = strVal(lfirst(lname));
01402 Node *varnode = (Node *) lfirst(lvar);
01403
01404 TupleDescInitEntry(tupleDesc, i,
01405 label,
01406 exprType(varnode),
01407 exprTypmod(varnode),
01408 0);
01409 TupleDescInitEntryCollation(tupleDesc, i,
01410 exprCollation(varnode));
01411 i++;
01412 }
01413 Assert(lname == NULL && lvar == NULL);
01414
01415 return tupleDesc;
01416 }
01417
01418 expr = (Node *) var;
01419
01420 switch (rte->rtekind)
01421 {
01422 case RTE_RELATION:
01423 case RTE_VALUES:
01424
01425
01426
01427
01428
01429
01430 break;
01431 case RTE_SUBQUERY:
01432 {
01433
01434 TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
01435 attnum);
01436
01437 if (ste == NULL || ste->resjunk)
01438 elog(ERROR, "subquery %s does not have attribute %d",
01439 rte->eref->aliasname, attnum);
01440 expr = (Node *) ste->expr;
01441 if (IsA(expr, Var))
01442 {
01443
01444
01445
01446
01447
01448 ParseState mypstate;
01449
01450 MemSet(&mypstate, 0, sizeof(mypstate));
01451 mypstate.parentParseState = pstate;
01452 mypstate.p_rtable = rte->subquery->rtable;
01453
01454
01455 return expandRecordVariable(&mypstate, (Var *) expr, 0);
01456 }
01457
01458 }
01459 break;
01460 case RTE_JOIN:
01461
01462 Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
01463 expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
01464 if (IsA(expr, Var))
01465 return expandRecordVariable(pstate, (Var *) expr, netlevelsup);
01466
01467 break;
01468 case RTE_FUNCTION:
01469
01470
01471
01472
01473
01474 break;
01475 case RTE_CTE:
01476
01477 if (!rte->self_reference)
01478 {
01479 CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
01480 TargetEntry *ste;
01481
01482 ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
01483 if (ste == NULL || ste->resjunk)
01484 elog(ERROR, "subquery %s does not have attribute %d",
01485 rte->eref->aliasname, attnum);
01486 expr = (Node *) ste->expr;
01487 if (IsA(expr, Var))
01488 {
01489
01490
01491
01492
01493
01494
01495 ParseState mypstate;
01496 Index levelsup;
01497
01498 MemSet(&mypstate, 0, sizeof(mypstate));
01499
01500 for (levelsup = 0;
01501 levelsup < rte->ctelevelsup + netlevelsup;
01502 levelsup++)
01503 pstate = pstate->parentParseState;
01504 mypstate.parentParseState = pstate;
01505 mypstate.p_rtable = ((Query *) cte->ctequery)->rtable;
01506
01507
01508 return expandRecordVariable(&mypstate, (Var *) expr, 0);
01509 }
01510
01511 }
01512 break;
01513 }
01514
01515
01516
01517
01518
01519
01520
01521 if (get_expr_result_type(expr, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
01522 tupleDesc = lookup_rowtype_tupdesc_copy(exprType(expr),
01523 exprTypmod(expr));
01524
01525 return tupleDesc;
01526 }
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 char *
01539 FigureColname(Node *node)
01540 {
01541 char *name = NULL;
01542
01543 (void) FigureColnameInternal(node, &name);
01544 if (name != NULL)
01545 return name;
01546
01547 return "?column?";
01548 }
01549
01550
01551
01552
01553
01554
01555
01556
01557 char *
01558 FigureIndexColname(Node *node)
01559 {
01560 char *name = NULL;
01561
01562 (void) FigureColnameInternal(node, &name);
01563 return name;
01564 }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577 static int
01578 FigureColnameInternal(Node *node, char **name)
01579 {
01580 int strength = 0;
01581
01582 if (node == NULL)
01583 return strength;
01584
01585 switch (nodeTag(node))
01586 {
01587 case T_ColumnRef:
01588 {
01589 char *fname = NULL;
01590 ListCell *l;
01591
01592
01593 foreach(l, ((ColumnRef *) node)->fields)
01594 {
01595 Node *i = lfirst(l);
01596
01597 if (IsA(i, String))
01598 fname = strVal(i);
01599 }
01600 if (fname)
01601 {
01602 *name = fname;
01603 return 2;
01604 }
01605 }
01606 break;
01607 case T_A_Indirection:
01608 {
01609 A_Indirection *ind = (A_Indirection *) node;
01610 char *fname = NULL;
01611 ListCell *l;
01612
01613
01614 foreach(l, ind->indirection)
01615 {
01616 Node *i = lfirst(l);
01617
01618 if (IsA(i, String))
01619 fname = strVal(i);
01620 }
01621 if (fname)
01622 {
01623 *name = fname;
01624 return 2;
01625 }
01626 return FigureColnameInternal(ind->arg, name);
01627 }
01628 break;
01629 case T_FuncCall:
01630 *name = strVal(llast(((FuncCall *) node)->funcname));
01631 return 2;
01632 case T_A_Expr:
01633
01634 if (((A_Expr *) node)->kind == AEXPR_NULLIF)
01635 {
01636 *name = "nullif";
01637 return 2;
01638 }
01639 break;
01640 case T_TypeCast:
01641 strength = FigureColnameInternal(((TypeCast *) node)->arg,
01642 name);
01643 if (strength <= 1)
01644 {
01645 if (((TypeCast *) node)->typeName != NULL)
01646 {
01647 *name = strVal(llast(((TypeCast *) node)->typeName->names));
01648 return 1;
01649 }
01650 }
01651 break;
01652 case T_CollateClause:
01653 return FigureColnameInternal(((CollateClause *) node)->arg, name);
01654 case T_SubLink:
01655 switch (((SubLink *) node)->subLinkType)
01656 {
01657 case EXISTS_SUBLINK:
01658 *name = "exists";
01659 return 2;
01660 case ARRAY_SUBLINK:
01661 *name = "array";
01662 return 2;
01663 case EXPR_SUBLINK:
01664 {
01665
01666 SubLink *sublink = (SubLink *) node;
01667 Query *query = (Query *) sublink->subselect;
01668
01669
01670
01671
01672
01673
01674
01675
01676 if (IsA(query, Query))
01677 {
01678 TargetEntry *te = (TargetEntry *) linitial(query->targetList);
01679
01680 if (te->resname)
01681 {
01682 *name = te->resname;
01683 return 2;
01684 }
01685 }
01686 }
01687 break;
01688
01689 case ALL_SUBLINK:
01690 case ANY_SUBLINK:
01691 case ROWCOMPARE_SUBLINK:
01692 case CTE_SUBLINK:
01693 break;
01694 }
01695 break;
01696 case T_CaseExpr:
01697 strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
01698 name);
01699 if (strength <= 1)
01700 {
01701 *name = "case";
01702 return 1;
01703 }
01704 break;
01705 case T_A_ArrayExpr:
01706
01707 *name = "array";
01708 return 2;
01709 case T_RowExpr:
01710
01711 *name = "row";
01712 return 2;
01713 case T_CoalesceExpr:
01714
01715 *name = "coalesce";
01716 return 2;
01717 case T_MinMaxExpr:
01718
01719 switch (((MinMaxExpr *) node)->op)
01720 {
01721 case IS_GREATEST:
01722 *name = "greatest";
01723 return 2;
01724 case IS_LEAST:
01725 *name = "least";
01726 return 2;
01727 }
01728 break;
01729 case T_XmlExpr:
01730
01731 switch (((XmlExpr *) node)->op)
01732 {
01733 case IS_XMLCONCAT:
01734 *name = "xmlconcat";
01735 return 2;
01736 case IS_XMLELEMENT:
01737 *name = "xmlelement";
01738 return 2;
01739 case IS_XMLFOREST:
01740 *name = "xmlforest";
01741 return 2;
01742 case IS_XMLPARSE:
01743 *name = "xmlparse";
01744 return 2;
01745 case IS_XMLPI:
01746 *name = "xmlpi";
01747 return 2;
01748 case IS_XMLROOT:
01749 *name = "xmlroot";
01750 return 2;
01751 case IS_XMLSERIALIZE:
01752 *name = "xmlserialize";
01753 return 2;
01754 case IS_DOCUMENT:
01755
01756 break;
01757 }
01758 break;
01759 case T_XmlSerialize:
01760 *name = "xmlserialize";
01761 return 2;
01762 default:
01763 break;
01764 }
01765
01766 return strength;
01767 }