00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017 #include "catalog/pg_collation.h"
00018 #include "catalog/pg_type.h"
00019 #include "miscadmin.h"
00020 #include "nodes/makefuncs.h"
00021 #include "nodes/nodeFuncs.h"
00022 #include "nodes/relation.h"
00023 #include "utils/builtins.h"
00024 #include "utils/lsyscache.h"
00025
00026
00027 static bool expression_returns_set_walker(Node *node, void *context);
00028 static int leftmostLoc(int loc1, int loc2);
00029
00030
00031
00032
00033
00034
00035 Oid
00036 exprType(const Node *expr)
00037 {
00038 Oid type;
00039
00040 if (!expr)
00041 return InvalidOid;
00042
00043 switch (nodeTag(expr))
00044 {
00045 case T_Var:
00046 type = ((const Var *) expr)->vartype;
00047 break;
00048 case T_Const:
00049 type = ((const Const *) expr)->consttype;
00050 break;
00051 case T_Param:
00052 type = ((const Param *) expr)->paramtype;
00053 break;
00054 case T_Aggref:
00055 type = ((const Aggref *) expr)->aggtype;
00056 break;
00057 case T_WindowFunc:
00058 type = ((const WindowFunc *) expr)->wintype;
00059 break;
00060 case T_ArrayRef:
00061 {
00062 const ArrayRef *arrayref = (const ArrayRef *) expr;
00063
00064
00065 if (arrayref->reflowerindexpr || arrayref->refassgnexpr)
00066 type = arrayref->refarraytype;
00067 else
00068 type = arrayref->refelemtype;
00069 }
00070 break;
00071 case T_FuncExpr:
00072 type = ((const FuncExpr *) expr)->funcresulttype;
00073 break;
00074 case T_NamedArgExpr:
00075 type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
00076 break;
00077 case T_OpExpr:
00078 type = ((const OpExpr *) expr)->opresulttype;
00079 break;
00080 case T_DistinctExpr:
00081 type = ((const DistinctExpr *) expr)->opresulttype;
00082 break;
00083 case T_NullIfExpr:
00084 type = ((const NullIfExpr *) expr)->opresulttype;
00085 break;
00086 case T_ScalarArrayOpExpr:
00087 type = BOOLOID;
00088 break;
00089 case T_BoolExpr:
00090 type = BOOLOID;
00091 break;
00092 case T_SubLink:
00093 {
00094 const SubLink *sublink = (const SubLink *) expr;
00095
00096 if (sublink->subLinkType == EXPR_SUBLINK ||
00097 sublink->subLinkType == ARRAY_SUBLINK)
00098 {
00099
00100 Query *qtree = (Query *) sublink->subselect;
00101 TargetEntry *tent;
00102
00103 if (!qtree || !IsA(qtree, Query))
00104 elog(ERROR, "cannot get type for untransformed sublink");
00105 tent = (TargetEntry *) linitial(qtree->targetList);
00106 Assert(IsA(tent, TargetEntry));
00107 Assert(!tent->resjunk);
00108 type = exprType((Node *) tent->expr);
00109 if (sublink->subLinkType == ARRAY_SUBLINK)
00110 {
00111 type = get_array_type(type);
00112 if (!OidIsValid(type))
00113 ereport(ERROR,
00114 (errcode(ERRCODE_UNDEFINED_OBJECT),
00115 errmsg("could not find array type for data type %s",
00116 format_type_be(exprType((Node *) tent->expr)))));
00117 }
00118 }
00119 else
00120 {
00121
00122 type = BOOLOID;
00123 }
00124 }
00125 break;
00126 case T_SubPlan:
00127 {
00128 const SubPlan *subplan = (const SubPlan *) expr;
00129
00130 if (subplan->subLinkType == EXPR_SUBLINK ||
00131 subplan->subLinkType == ARRAY_SUBLINK)
00132 {
00133
00134 type = subplan->firstColType;
00135 if (subplan->subLinkType == ARRAY_SUBLINK)
00136 {
00137 type = get_array_type(type);
00138 if (!OidIsValid(type))
00139 ereport(ERROR,
00140 (errcode(ERRCODE_UNDEFINED_OBJECT),
00141 errmsg("could not find array type for data type %s",
00142 format_type_be(subplan->firstColType))));
00143 }
00144 }
00145 else
00146 {
00147
00148 type = BOOLOID;
00149 }
00150 }
00151 break;
00152 case T_AlternativeSubPlan:
00153 {
00154 const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
00155
00156
00157 type = exprType((Node *) linitial(asplan->subplans));
00158 }
00159 break;
00160 case T_FieldSelect:
00161 type = ((const FieldSelect *) expr)->resulttype;
00162 break;
00163 case T_FieldStore:
00164 type = ((const FieldStore *) expr)->resulttype;
00165 break;
00166 case T_RelabelType:
00167 type = ((const RelabelType *) expr)->resulttype;
00168 break;
00169 case T_CoerceViaIO:
00170 type = ((const CoerceViaIO *) expr)->resulttype;
00171 break;
00172 case T_ArrayCoerceExpr:
00173 type = ((const ArrayCoerceExpr *) expr)->resulttype;
00174 break;
00175 case T_ConvertRowtypeExpr:
00176 type = ((const ConvertRowtypeExpr *) expr)->resulttype;
00177 break;
00178 case T_CollateExpr:
00179 type = exprType((Node *) ((const CollateExpr *) expr)->arg);
00180 break;
00181 case T_CaseExpr:
00182 type = ((const CaseExpr *) expr)->casetype;
00183 break;
00184 case T_CaseTestExpr:
00185 type = ((const CaseTestExpr *) expr)->typeId;
00186 break;
00187 case T_ArrayExpr:
00188 type = ((const ArrayExpr *) expr)->array_typeid;
00189 break;
00190 case T_RowExpr:
00191 type = ((const RowExpr *) expr)->row_typeid;
00192 break;
00193 case T_RowCompareExpr:
00194 type = BOOLOID;
00195 break;
00196 case T_CoalesceExpr:
00197 type = ((const CoalesceExpr *) expr)->coalescetype;
00198 break;
00199 case T_MinMaxExpr:
00200 type = ((const MinMaxExpr *) expr)->minmaxtype;
00201 break;
00202 case T_XmlExpr:
00203 if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
00204 type = BOOLOID;
00205 else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
00206 type = TEXTOID;
00207 else
00208 type = XMLOID;
00209 break;
00210 case T_NullTest:
00211 type = BOOLOID;
00212 break;
00213 case T_BooleanTest:
00214 type = BOOLOID;
00215 break;
00216 case T_CoerceToDomain:
00217 type = ((const CoerceToDomain *) expr)->resulttype;
00218 break;
00219 case T_CoerceToDomainValue:
00220 type = ((const CoerceToDomainValue *) expr)->typeId;
00221 break;
00222 case T_SetToDefault:
00223 type = ((const SetToDefault *) expr)->typeId;
00224 break;
00225 case T_CurrentOfExpr:
00226 type = BOOLOID;
00227 break;
00228 case T_PlaceHolderVar:
00229 type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
00230 break;
00231 default:
00232 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
00233 type = InvalidOid;
00234 break;
00235 }
00236 return type;
00237 }
00238
00239
00240
00241
00242
00243
00244 int32
00245 exprTypmod(const Node *expr)
00246 {
00247 if (!expr)
00248 return -1;
00249
00250 switch (nodeTag(expr))
00251 {
00252 case T_Var:
00253 return ((const Var *) expr)->vartypmod;
00254 case T_Const:
00255 return ((const Const *) expr)->consttypmod;
00256 case T_Param:
00257 return ((const Param *) expr)->paramtypmod;
00258 case T_ArrayRef:
00259
00260 return ((const ArrayRef *) expr)->reftypmod;
00261 case T_FuncExpr:
00262 {
00263 int32 coercedTypmod;
00264
00265
00266 if (exprIsLengthCoercion(expr, &coercedTypmod))
00267 return coercedTypmod;
00268 }
00269 break;
00270 case T_NamedArgExpr:
00271 return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg);
00272 case T_NullIfExpr:
00273 {
00274
00275
00276
00277
00278 const NullIfExpr *nexpr = (const NullIfExpr *) expr;
00279
00280 return exprTypmod((Node *) linitial(nexpr->args));
00281 }
00282 break;
00283 case T_SubLink:
00284 {
00285 const SubLink *sublink = (const SubLink *) expr;
00286
00287 if (sublink->subLinkType == EXPR_SUBLINK ||
00288 sublink->subLinkType == ARRAY_SUBLINK)
00289 {
00290
00291 Query *qtree = (Query *) sublink->subselect;
00292 TargetEntry *tent;
00293
00294 if (!qtree || !IsA(qtree, Query))
00295 elog(ERROR, "cannot get type for untransformed sublink");
00296 tent = (TargetEntry *) linitial(qtree->targetList);
00297 Assert(IsA(tent, TargetEntry));
00298 Assert(!tent->resjunk);
00299 return exprTypmod((Node *) tent->expr);
00300
00301 }
00302 }
00303 break;
00304 case T_SubPlan:
00305 {
00306 const SubPlan *subplan = (const SubPlan *) expr;
00307
00308 if (subplan->subLinkType == EXPR_SUBLINK ||
00309 subplan->subLinkType == ARRAY_SUBLINK)
00310 {
00311
00312
00313 return subplan->firstColTypmod;
00314 }
00315 else
00316 {
00317
00318 return -1;
00319 }
00320 }
00321 break;
00322 case T_AlternativeSubPlan:
00323 {
00324 const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
00325
00326
00327 return exprTypmod((Node *) linitial(asplan->subplans));
00328 }
00329 break;
00330 case T_FieldSelect:
00331 return ((const FieldSelect *) expr)->resulttypmod;
00332 case T_RelabelType:
00333 return ((const RelabelType *) expr)->resulttypmod;
00334 case T_ArrayCoerceExpr:
00335 return ((const ArrayCoerceExpr *) expr)->resulttypmod;
00336 case T_CollateExpr:
00337 return exprTypmod((Node *) ((const CollateExpr *) expr)->arg);
00338 case T_CaseExpr:
00339 {
00340
00341
00342
00343
00344 const CaseExpr *cexpr = (const CaseExpr *) expr;
00345 Oid casetype = cexpr->casetype;
00346 int32 typmod;
00347 ListCell *arg;
00348
00349 if (!cexpr->defresult)
00350 return -1;
00351 if (exprType((Node *) cexpr->defresult) != casetype)
00352 return -1;
00353 typmod = exprTypmod((Node *) cexpr->defresult);
00354 if (typmod < 0)
00355 return -1;
00356 foreach(arg, cexpr->args)
00357 {
00358 CaseWhen *w = (CaseWhen *) lfirst(arg);
00359
00360 Assert(IsA(w, CaseWhen));
00361 if (exprType((Node *) w->result) != casetype)
00362 return -1;
00363 if (exprTypmod((Node *) w->result) != typmod)
00364 return -1;
00365 }
00366 return typmod;
00367 }
00368 break;
00369 case T_CaseTestExpr:
00370 return ((const CaseTestExpr *) expr)->typeMod;
00371 case T_ArrayExpr:
00372 {
00373
00374
00375
00376
00377 const ArrayExpr *arrayexpr = (const ArrayExpr *) expr;
00378 Oid commontype;
00379 int32 typmod;
00380 ListCell *elem;
00381
00382 if (arrayexpr->elements == NIL)
00383 return -1;
00384 typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
00385 if (typmod < 0)
00386 return -1;
00387 if (arrayexpr->multidims)
00388 commontype = arrayexpr->array_typeid;
00389 else
00390 commontype = arrayexpr->element_typeid;
00391 foreach(elem, arrayexpr->elements)
00392 {
00393 Node *e = (Node *) lfirst(elem);
00394
00395 if (exprType(e) != commontype)
00396 return -1;
00397 if (exprTypmod(e) != typmod)
00398 return -1;
00399 }
00400 return typmod;
00401 }
00402 break;
00403 case T_CoalesceExpr:
00404 {
00405
00406
00407
00408
00409 const CoalesceExpr *cexpr = (const CoalesceExpr *) expr;
00410 Oid coalescetype = cexpr->coalescetype;
00411 int32 typmod;
00412 ListCell *arg;
00413
00414 if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
00415 return -1;
00416 typmod = exprTypmod((Node *) linitial(cexpr->args));
00417 if (typmod < 0)
00418 return -1;
00419 for_each_cell(arg, lnext(list_head(cexpr->args)))
00420 {
00421 Node *e = (Node *) lfirst(arg);
00422
00423 if (exprType(e) != coalescetype)
00424 return -1;
00425 if (exprTypmod(e) != typmod)
00426 return -1;
00427 }
00428 return typmod;
00429 }
00430 break;
00431 case T_MinMaxExpr:
00432 {
00433
00434
00435
00436
00437 const MinMaxExpr *mexpr = (const MinMaxExpr *) expr;
00438 Oid minmaxtype = mexpr->minmaxtype;
00439 int32 typmod;
00440 ListCell *arg;
00441
00442 if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
00443 return -1;
00444 typmod = exprTypmod((Node *) linitial(mexpr->args));
00445 if (typmod < 0)
00446 return -1;
00447 for_each_cell(arg, lnext(list_head(mexpr->args)))
00448 {
00449 Node *e = (Node *) lfirst(arg);
00450
00451 if (exprType(e) != minmaxtype)
00452 return -1;
00453 if (exprTypmod(e) != typmod)
00454 return -1;
00455 }
00456 return typmod;
00457 }
00458 break;
00459 case T_CoerceToDomain:
00460 return ((const CoerceToDomain *) expr)->resulttypmod;
00461 case T_CoerceToDomainValue:
00462 return ((const CoerceToDomainValue *) expr)->typeMod;
00463 case T_SetToDefault:
00464 return ((const SetToDefault *) expr)->typeMod;
00465 case T_PlaceHolderVar:
00466 return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
00467 default:
00468 break;
00469 }
00470 return -1;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 bool
00485 exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod)
00486 {
00487 if (coercedTypmod != NULL)
00488 *coercedTypmod = -1;
00489
00490
00491
00492
00493
00494 if (expr && IsA(expr, FuncExpr))
00495 {
00496 const FuncExpr *func = (const FuncExpr *) expr;
00497 int nargs;
00498 Const *second_arg;
00499
00500
00501
00502
00503 if (func->funcformat != COERCE_EXPLICIT_CAST &&
00504 func->funcformat != COERCE_IMPLICIT_CAST)
00505 return false;
00506
00507
00508
00509
00510
00511
00512 nargs = list_length(func->args);
00513 if (nargs < 2 || nargs > 3)
00514 return false;
00515
00516 second_arg = (Const *) lsecond(func->args);
00517 if (!IsA(second_arg, Const) ||
00518 second_arg->consttype != INT4OID ||
00519 second_arg->constisnull)
00520 return false;
00521
00522
00523
00524
00525 if (coercedTypmod != NULL)
00526 *coercedTypmod = DatumGetInt32(second_arg->constvalue);
00527
00528 return true;
00529 }
00530
00531 if (expr && IsA(expr, ArrayCoerceExpr))
00532 {
00533 const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
00534
00535
00536 if (acoerce->resulttypmod < 0)
00537 return false;
00538
00539
00540
00541
00542 if (coercedTypmod != NULL)
00543 *coercedTypmod = acoerce->resulttypmod;
00544
00545 return true;
00546 }
00547
00548 return false;
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 Node *
00560 relabel_to_typmod(Node *expr, int32 typmod)
00561 {
00562 Oid type = exprType(expr);
00563 Oid coll = exprCollation(expr);
00564
00565
00566 while (expr && IsA(expr, RelabelType))
00567 expr = (Node *) ((RelabelType *) expr)->arg;
00568
00569
00570 return (Node *) makeRelabelType((Expr *) expr, type, typmod, coll,
00571 COERCE_EXPLICIT_CAST);
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 bool
00583 expression_returns_set(Node *clause)
00584 {
00585 return expression_returns_set_walker(clause, NULL);
00586 }
00587
00588 static bool
00589 expression_returns_set_walker(Node *node, void *context)
00590 {
00591 if (node == NULL)
00592 return false;
00593 if (IsA(node, FuncExpr))
00594 {
00595 FuncExpr *expr = (FuncExpr *) node;
00596
00597 if (expr->funcretset)
00598 return true;
00599
00600 }
00601 if (IsA(node, OpExpr))
00602 {
00603 OpExpr *expr = (OpExpr *) node;
00604
00605 if (expr->opretset)
00606 return true;
00607
00608 }
00609
00610
00611 if (IsA(node, Aggref))
00612 return false;
00613 if (IsA(node, WindowFunc))
00614 return false;
00615 if (IsA(node, DistinctExpr))
00616 return false;
00617 if (IsA(node, NullIfExpr))
00618 return false;
00619 if (IsA(node, ScalarArrayOpExpr))
00620 return false;
00621 if (IsA(node, BoolExpr))
00622 return false;
00623 if (IsA(node, SubLink))
00624 return false;
00625 if (IsA(node, SubPlan))
00626 return false;
00627 if (IsA(node, AlternativeSubPlan))
00628 return false;
00629 if (IsA(node, ArrayExpr))
00630 return false;
00631 if (IsA(node, RowExpr))
00632 return false;
00633 if (IsA(node, RowCompareExpr))
00634 return false;
00635 if (IsA(node, CoalesceExpr))
00636 return false;
00637 if (IsA(node, MinMaxExpr))
00638 return false;
00639 if (IsA(node, XmlExpr))
00640 return false;
00641
00642 return expression_tree_walker(node, expression_returns_set_walker,
00643 context);
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 Oid
00659 exprCollation(const Node *expr)
00660 {
00661 Oid coll;
00662
00663 if (!expr)
00664 return InvalidOid;
00665
00666 switch (nodeTag(expr))
00667 {
00668 case T_Var:
00669 coll = ((const Var *) expr)->varcollid;
00670 break;
00671 case T_Const:
00672 coll = ((const Const *) expr)->constcollid;
00673 break;
00674 case T_Param:
00675 coll = ((const Param *) expr)->paramcollid;
00676 break;
00677 case T_Aggref:
00678 coll = ((const Aggref *) expr)->aggcollid;
00679 break;
00680 case T_WindowFunc:
00681 coll = ((const WindowFunc *) expr)->wincollid;
00682 break;
00683 case T_ArrayRef:
00684 coll = ((const ArrayRef *) expr)->refcollid;
00685 break;
00686 case T_FuncExpr:
00687 coll = ((const FuncExpr *) expr)->funccollid;
00688 break;
00689 case T_NamedArgExpr:
00690 coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
00691 break;
00692 case T_OpExpr:
00693 coll = ((const OpExpr *) expr)->opcollid;
00694 break;
00695 case T_DistinctExpr:
00696 coll = ((const DistinctExpr *) expr)->opcollid;
00697 break;
00698 case T_NullIfExpr:
00699 coll = ((const NullIfExpr *) expr)->opcollid;
00700 break;
00701 case T_ScalarArrayOpExpr:
00702 coll = InvalidOid;
00703 break;
00704 case T_BoolExpr:
00705 coll = InvalidOid;
00706 break;
00707 case T_SubLink:
00708 {
00709 const SubLink *sublink = (const SubLink *) expr;
00710
00711 if (sublink->subLinkType == EXPR_SUBLINK ||
00712 sublink->subLinkType == ARRAY_SUBLINK)
00713 {
00714
00715 Query *qtree = (Query *) sublink->subselect;
00716 TargetEntry *tent;
00717
00718 if (!qtree || !IsA(qtree, Query))
00719 elog(ERROR, "cannot get collation for untransformed sublink");
00720 tent = (TargetEntry *) linitial(qtree->targetList);
00721 Assert(IsA(tent, TargetEntry));
00722 Assert(!tent->resjunk);
00723 coll = exprCollation((Node *) tent->expr);
00724
00725 }
00726 else
00727 {
00728
00729 coll = InvalidOid;
00730 }
00731 }
00732 break;
00733 case T_SubPlan:
00734 {
00735 const SubPlan *subplan = (const SubPlan *) expr;
00736
00737 if (subplan->subLinkType == EXPR_SUBLINK ||
00738 subplan->subLinkType == ARRAY_SUBLINK)
00739 {
00740
00741 coll = subplan->firstColCollation;
00742
00743 }
00744 else
00745 {
00746
00747 coll = InvalidOid;
00748 }
00749 }
00750 break;
00751 case T_AlternativeSubPlan:
00752 {
00753 const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
00754
00755
00756 coll = exprCollation((Node *) linitial(asplan->subplans));
00757 }
00758 break;
00759 case T_FieldSelect:
00760 coll = ((const FieldSelect *) expr)->resultcollid;
00761 break;
00762 case T_FieldStore:
00763 coll = InvalidOid;
00764 break;
00765 case T_RelabelType:
00766 coll = ((const RelabelType *) expr)->resultcollid;
00767 break;
00768 case T_CoerceViaIO:
00769 coll = ((const CoerceViaIO *) expr)->resultcollid;
00770 break;
00771 case T_ArrayCoerceExpr:
00772 coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
00773 break;
00774 case T_ConvertRowtypeExpr:
00775 coll = InvalidOid;
00776 break;
00777 case T_CollateExpr:
00778 coll = ((const CollateExpr *) expr)->collOid;
00779 break;
00780 case T_CaseExpr:
00781 coll = ((const CaseExpr *) expr)->casecollid;
00782 break;
00783 case T_CaseTestExpr:
00784 coll = ((const CaseTestExpr *) expr)->collation;
00785 break;
00786 case T_ArrayExpr:
00787 coll = ((const ArrayExpr *) expr)->array_collid;
00788 break;
00789 case T_RowExpr:
00790 coll = InvalidOid;
00791 break;
00792 case T_RowCompareExpr:
00793 coll = InvalidOid;
00794 break;
00795 case T_CoalesceExpr:
00796 coll = ((const CoalesceExpr *) expr)->coalescecollid;
00797 break;
00798 case T_MinMaxExpr:
00799 coll = ((const MinMaxExpr *) expr)->minmaxcollid;
00800 break;
00801 case T_XmlExpr:
00802
00803
00804
00805
00806
00807
00808 if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
00809 coll = DEFAULT_COLLATION_OID;
00810 else
00811 coll = InvalidOid;
00812 break;
00813 case T_NullTest:
00814 coll = InvalidOid;
00815 break;
00816 case T_BooleanTest:
00817 coll = InvalidOid;
00818 break;
00819 case T_CoerceToDomain:
00820 coll = ((const CoerceToDomain *) expr)->resultcollid;
00821 break;
00822 case T_CoerceToDomainValue:
00823 coll = ((const CoerceToDomainValue *) expr)->collation;
00824 break;
00825 case T_SetToDefault:
00826 coll = ((const SetToDefault *) expr)->collation;
00827 break;
00828 case T_CurrentOfExpr:
00829 coll = InvalidOid;
00830 break;
00831 case T_PlaceHolderVar:
00832 coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
00833 break;
00834 default:
00835 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
00836 coll = InvalidOid;
00837 break;
00838 }
00839 return coll;
00840 }
00841
00842
00843
00844
00845
00846
00847
00848 Oid
00849 exprInputCollation(const Node *expr)
00850 {
00851 Oid coll;
00852
00853 if (!expr)
00854 return InvalidOid;
00855
00856 switch (nodeTag(expr))
00857 {
00858 case T_Aggref:
00859 coll = ((const Aggref *) expr)->inputcollid;
00860 break;
00861 case T_WindowFunc:
00862 coll = ((const WindowFunc *) expr)->inputcollid;
00863 break;
00864 case T_FuncExpr:
00865 coll = ((const FuncExpr *) expr)->inputcollid;
00866 break;
00867 case T_OpExpr:
00868 coll = ((const OpExpr *) expr)->inputcollid;
00869 break;
00870 case T_DistinctExpr:
00871 coll = ((const DistinctExpr *) expr)->inputcollid;
00872 break;
00873 case T_NullIfExpr:
00874 coll = ((const NullIfExpr *) expr)->inputcollid;
00875 break;
00876 case T_ScalarArrayOpExpr:
00877 coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
00878 break;
00879 case T_MinMaxExpr:
00880 coll = ((const MinMaxExpr *) expr)->inputcollid;
00881 break;
00882 default:
00883 coll = InvalidOid;
00884 break;
00885 }
00886 return coll;
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896 void
00897 exprSetCollation(Node *expr, Oid collation)
00898 {
00899 switch (nodeTag(expr))
00900 {
00901 case T_Var:
00902 ((Var *) expr)->varcollid = collation;
00903 break;
00904 case T_Const:
00905 ((Const *) expr)->constcollid = collation;
00906 break;
00907 case T_Param:
00908 ((Param *) expr)->paramcollid = collation;
00909 break;
00910 case T_Aggref:
00911 ((Aggref *) expr)->aggcollid = collation;
00912 break;
00913 case T_WindowFunc:
00914 ((WindowFunc *) expr)->wincollid = collation;
00915 break;
00916 case T_ArrayRef:
00917 ((ArrayRef *) expr)->refcollid = collation;
00918 break;
00919 case T_FuncExpr:
00920 ((FuncExpr *) expr)->funccollid = collation;
00921 break;
00922 case T_NamedArgExpr:
00923 Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
00924 break;
00925 case T_OpExpr:
00926 ((OpExpr *) expr)->opcollid = collation;
00927 break;
00928 case T_DistinctExpr:
00929 ((DistinctExpr *) expr)->opcollid = collation;
00930 break;
00931 case T_NullIfExpr:
00932 ((NullIfExpr *) expr)->opcollid = collation;
00933 break;
00934 case T_ScalarArrayOpExpr:
00935 Assert(!OidIsValid(collation));
00936 break;
00937 case T_BoolExpr:
00938 Assert(!OidIsValid(collation));
00939 break;
00940 case T_SubLink:
00941 #ifdef USE_ASSERT_CHECKING
00942 {
00943 SubLink *sublink = (SubLink *) expr;
00944
00945 if (sublink->subLinkType == EXPR_SUBLINK ||
00946 sublink->subLinkType == ARRAY_SUBLINK)
00947 {
00948
00949 Query *qtree = (Query *) sublink->subselect;
00950 TargetEntry *tent;
00951
00952 if (!qtree || !IsA(qtree, Query))
00953 elog(ERROR, "cannot set collation for untransformed sublink");
00954 tent = (TargetEntry *) linitial(qtree->targetList);
00955 Assert(IsA(tent, TargetEntry));
00956 Assert(!tent->resjunk);
00957 Assert(collation == exprCollation((Node *) tent->expr));
00958 }
00959 else
00960 {
00961
00962 Assert(!OidIsValid(collation));
00963 }
00964 }
00965 #endif
00966 break;
00967 case T_FieldSelect:
00968 ((FieldSelect *) expr)->resultcollid = collation;
00969 break;
00970 case T_FieldStore:
00971 Assert(!OidIsValid(collation));
00972 break;
00973 case T_RelabelType:
00974 ((RelabelType *) expr)->resultcollid = collation;
00975 break;
00976 case T_CoerceViaIO:
00977 ((CoerceViaIO *) expr)->resultcollid = collation;
00978 break;
00979 case T_ArrayCoerceExpr:
00980 ((ArrayCoerceExpr *) expr)->resultcollid = collation;
00981 break;
00982 case T_ConvertRowtypeExpr:
00983 Assert(!OidIsValid(collation));
00984 break;
00985 case T_CaseExpr:
00986 ((CaseExpr *) expr)->casecollid = collation;
00987 break;
00988 case T_ArrayExpr:
00989 ((ArrayExpr *) expr)->array_collid = collation;
00990 break;
00991 case T_RowExpr:
00992 Assert(!OidIsValid(collation));
00993 break;
00994 case T_RowCompareExpr:
00995 Assert(!OidIsValid(collation));
00996 break;
00997 case T_CoalesceExpr:
00998 ((CoalesceExpr *) expr)->coalescecollid = collation;
00999 break;
01000 case T_MinMaxExpr:
01001 ((MinMaxExpr *) expr)->minmaxcollid = collation;
01002 break;
01003 case T_XmlExpr:
01004 Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
01005 (collation == DEFAULT_COLLATION_OID) :
01006 (collation == InvalidOid));
01007 break;
01008 case T_NullTest:
01009 Assert(!OidIsValid(collation));
01010 break;
01011 case T_BooleanTest:
01012 Assert(!OidIsValid(collation));
01013 break;
01014 case T_CoerceToDomain:
01015 ((CoerceToDomain *) expr)->resultcollid = collation;
01016 break;
01017 case T_CoerceToDomainValue:
01018 ((CoerceToDomainValue *) expr)->collation = collation;
01019 break;
01020 case T_SetToDefault:
01021 ((SetToDefault *) expr)->collation = collation;
01022 break;
01023 case T_CurrentOfExpr:
01024 Assert(!OidIsValid(collation));
01025 break;
01026 default:
01027 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
01028 break;
01029 }
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 void
01041 exprSetInputCollation(Node *expr, Oid inputcollation)
01042 {
01043 switch (nodeTag(expr))
01044 {
01045 case T_Aggref:
01046 ((Aggref *) expr)->inputcollid = inputcollation;
01047 break;
01048 case T_WindowFunc:
01049 ((WindowFunc *) expr)->inputcollid = inputcollation;
01050 break;
01051 case T_FuncExpr:
01052 ((FuncExpr *) expr)->inputcollid = inputcollation;
01053 break;
01054 case T_OpExpr:
01055 ((OpExpr *) expr)->inputcollid = inputcollation;
01056 break;
01057 case T_DistinctExpr:
01058 ((DistinctExpr *) expr)->inputcollid = inputcollation;
01059 break;
01060 case T_NullIfExpr:
01061 ((NullIfExpr *) expr)->inputcollid = inputcollation;
01062 break;
01063 case T_ScalarArrayOpExpr:
01064 ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
01065 break;
01066 case T_MinMaxExpr:
01067 ((MinMaxExpr *) expr)->inputcollid = inputcollation;
01068 break;
01069 default:
01070 break;
01071 }
01072 }
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104 int
01105 exprLocation(const Node *expr)
01106 {
01107 int loc;
01108
01109 if (expr == NULL)
01110 return -1;
01111 switch (nodeTag(expr))
01112 {
01113 case T_RangeVar:
01114 loc = ((const RangeVar *) expr)->location;
01115 break;
01116 case T_Var:
01117 loc = ((const Var *) expr)->location;
01118 break;
01119 case T_Const:
01120 loc = ((const Const *) expr)->location;
01121 break;
01122 case T_Param:
01123 loc = ((const Param *) expr)->location;
01124 break;
01125 case T_Aggref:
01126
01127 loc = ((const Aggref *) expr)->location;
01128 break;
01129 case T_WindowFunc:
01130
01131 loc = ((const WindowFunc *) expr)->location;
01132 break;
01133 case T_ArrayRef:
01134
01135 loc = exprLocation((Node *) ((const ArrayRef *) expr)->refexpr);
01136 break;
01137 case T_FuncExpr:
01138 {
01139 const FuncExpr *fexpr = (const FuncExpr *) expr;
01140
01141
01142 loc = leftmostLoc(fexpr->location,
01143 exprLocation((Node *) fexpr->args));
01144 }
01145 break;
01146 case T_NamedArgExpr:
01147 {
01148 const NamedArgExpr *na = (const NamedArgExpr *) expr;
01149
01150
01151 loc = leftmostLoc(na->location,
01152 exprLocation((Node *) na->arg));
01153 }
01154 break;
01155 case T_OpExpr:
01156 case T_DistinctExpr:
01157 case T_NullIfExpr:
01158 {
01159 const OpExpr *opexpr = (const OpExpr *) expr;
01160
01161
01162 loc = leftmostLoc(opexpr->location,
01163 exprLocation((Node *) opexpr->args));
01164 }
01165 break;
01166 case T_ScalarArrayOpExpr:
01167 {
01168 const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
01169
01170
01171 loc = leftmostLoc(saopexpr->location,
01172 exprLocation((Node *) saopexpr->args));
01173 }
01174 break;
01175 case T_BoolExpr:
01176 {
01177 const BoolExpr *bexpr = (const BoolExpr *) expr;
01178
01179
01180
01181
01182
01183
01184 loc = leftmostLoc(bexpr->location,
01185 exprLocation((Node *) bexpr->args));
01186 }
01187 break;
01188 case T_SubLink:
01189 {
01190 const SubLink *sublink = (const SubLink *) expr;
01191
01192
01193 loc = leftmostLoc(exprLocation(sublink->testexpr),
01194 sublink->location);
01195 }
01196 break;
01197 case T_FieldSelect:
01198
01199 loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
01200 break;
01201 case T_FieldStore:
01202
01203 loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
01204 break;
01205 case T_RelabelType:
01206 {
01207 const RelabelType *rexpr = (const RelabelType *) expr;
01208
01209
01210 loc = leftmostLoc(rexpr->location,
01211 exprLocation((Node *) rexpr->arg));
01212 }
01213 break;
01214 case T_CoerceViaIO:
01215 {
01216 const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
01217
01218
01219 loc = leftmostLoc(cexpr->location,
01220 exprLocation((Node *) cexpr->arg));
01221 }
01222 break;
01223 case T_ArrayCoerceExpr:
01224 {
01225 const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
01226
01227
01228 loc = leftmostLoc(cexpr->location,
01229 exprLocation((Node *) cexpr->arg));
01230 }
01231 break;
01232 case T_ConvertRowtypeExpr:
01233 {
01234 const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
01235
01236
01237 loc = leftmostLoc(cexpr->location,
01238 exprLocation((Node *) cexpr->arg));
01239 }
01240 break;
01241 case T_CollateExpr:
01242
01243 loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
01244 break;
01245 case T_CaseExpr:
01246
01247 loc = ((const CaseExpr *) expr)->location;
01248 break;
01249 case T_CaseWhen:
01250
01251 loc = ((const CaseWhen *) expr)->location;
01252 break;
01253 case T_ArrayExpr:
01254
01255 loc = ((const ArrayExpr *) expr)->location;
01256 break;
01257 case T_RowExpr:
01258
01259 loc = ((const RowExpr *) expr)->location;
01260 break;
01261 case T_RowCompareExpr:
01262
01263 loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
01264 break;
01265 case T_CoalesceExpr:
01266
01267 loc = ((const CoalesceExpr *) expr)->location;
01268 break;
01269 case T_MinMaxExpr:
01270
01271 loc = ((const MinMaxExpr *) expr)->location;
01272 break;
01273 case T_XmlExpr:
01274 {
01275 const XmlExpr *xexpr = (const XmlExpr *) expr;
01276
01277
01278 loc = leftmostLoc(xexpr->location,
01279 exprLocation((Node *) xexpr->args));
01280 }
01281 break;
01282 case T_NullTest:
01283
01284 loc = exprLocation((Node *) ((const NullTest *) expr)->arg);
01285 break;
01286 case T_BooleanTest:
01287
01288 loc = exprLocation((Node *) ((const BooleanTest *) expr)->arg);
01289 break;
01290 case T_CoerceToDomain:
01291 {
01292 const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
01293
01294
01295 loc = leftmostLoc(cexpr->location,
01296 exprLocation((Node *) cexpr->arg));
01297 }
01298 break;
01299 case T_CoerceToDomainValue:
01300 loc = ((const CoerceToDomainValue *) expr)->location;
01301 break;
01302 case T_SetToDefault:
01303 loc = ((const SetToDefault *) expr)->location;
01304 break;
01305 case T_TargetEntry:
01306
01307 loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
01308 break;
01309 case T_IntoClause:
01310
01311 loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
01312 break;
01313 case T_List:
01314 {
01315
01316 ListCell *lc;
01317
01318 loc = -1;
01319 foreach(lc, (const List *) expr)
01320 {
01321 loc = exprLocation((Node *) lfirst(lc));
01322 if (loc >= 0)
01323 break;
01324 }
01325 }
01326 break;
01327 case T_A_Expr:
01328 {
01329 const A_Expr *aexpr = (const A_Expr *) expr;
01330
01331
01332
01333 loc = leftmostLoc(aexpr->location,
01334 exprLocation(aexpr->lexpr));
01335 }
01336 break;
01337 case T_ColumnRef:
01338 loc = ((const ColumnRef *) expr)->location;
01339 break;
01340 case T_ParamRef:
01341 loc = ((const ParamRef *) expr)->location;
01342 break;
01343 case T_A_Const:
01344 loc = ((const A_Const *) expr)->location;
01345 break;
01346 case T_FuncCall:
01347 {
01348 const FuncCall *fc = (const FuncCall *) expr;
01349
01350
01351
01352 loc = leftmostLoc(fc->location,
01353 exprLocation((Node *) fc->args));
01354 }
01355 break;
01356 case T_A_ArrayExpr:
01357
01358 loc = ((const A_ArrayExpr *) expr)->location;
01359 break;
01360 case T_ResTarget:
01361
01362 loc = ((const ResTarget *) expr)->location;
01363 break;
01364 case T_TypeCast:
01365 {
01366 const TypeCast *tc = (const TypeCast *) expr;
01367
01368
01369
01370
01371
01372 loc = exprLocation(tc->arg);
01373 loc = leftmostLoc(loc, tc->typeName->location);
01374 loc = leftmostLoc(loc, tc->location);
01375 }
01376 break;
01377 case T_CollateClause:
01378
01379 loc = exprLocation(((const CollateClause *) expr)->arg);
01380 break;
01381 case T_SortBy:
01382
01383 loc = exprLocation(((const SortBy *) expr)->node);
01384 break;
01385 case T_WindowDef:
01386 loc = ((const WindowDef *) expr)->location;
01387 break;
01388 case T_TypeName:
01389 loc = ((const TypeName *) expr)->location;
01390 break;
01391 case T_Constraint:
01392 loc = ((const Constraint *) expr)->location;
01393 break;
01394 case T_XmlSerialize:
01395
01396 loc = ((const XmlSerialize *) expr)->location;
01397 break;
01398 case T_WithClause:
01399 loc = ((const WithClause *) expr)->location;
01400 break;
01401 case T_CommonTableExpr:
01402 loc = ((const CommonTableExpr *) expr)->location;
01403 break;
01404 case T_PlaceHolderVar:
01405
01406 loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
01407 break;
01408 default:
01409
01410 loc = -1;
01411 break;
01412 }
01413 return loc;
01414 }
01415
01416
01417
01418
01419
01420
01421 static int
01422 leftmostLoc(int loc1, int loc2)
01423 {
01424 if (loc1 < 0)
01425 return loc2;
01426 else if (loc2 < 0)
01427 return loc1;
01428 else
01429 return Min(loc1, loc2);
01430 }
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525 bool
01526 expression_tree_walker(Node *node,
01527 bool (*walker) (),
01528 void *context)
01529 {
01530 ListCell *temp;
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540 if (node == NULL)
01541 return false;
01542
01543
01544 check_stack_depth();
01545
01546 switch (nodeTag(node))
01547 {
01548 case T_Var:
01549 case T_Const:
01550 case T_Param:
01551 case T_CoerceToDomainValue:
01552 case T_CaseTestExpr:
01553 case T_SetToDefault:
01554 case T_CurrentOfExpr:
01555 case T_RangeTblRef:
01556 case T_SortGroupClause:
01557
01558 break;
01559 case T_Aggref:
01560 {
01561 Aggref *expr = (Aggref *) node;
01562
01563
01564 if (expression_tree_walker((Node *) expr->args,
01565 walker, context))
01566 return true;
01567 if (expression_tree_walker((Node *) expr->aggorder,
01568 walker, context))
01569 return true;
01570 if (expression_tree_walker((Node *) expr->aggdistinct,
01571 walker, context))
01572 return true;
01573 }
01574 break;
01575 case T_WindowFunc:
01576 {
01577 WindowFunc *expr = (WindowFunc *) node;
01578
01579
01580 if (expression_tree_walker((Node *) expr->args,
01581 walker, context))
01582 return true;
01583 }
01584 break;
01585 case T_ArrayRef:
01586 {
01587 ArrayRef *aref = (ArrayRef *) node;
01588
01589
01590 if (expression_tree_walker((Node *) aref->refupperindexpr,
01591 walker, context))
01592 return true;
01593 if (expression_tree_walker((Node *) aref->reflowerindexpr,
01594 walker, context))
01595 return true;
01596
01597 if (walker(aref->refexpr, context))
01598 return true;
01599 if (walker(aref->refassgnexpr, context))
01600 return true;
01601 }
01602 break;
01603 case T_FuncExpr:
01604 {
01605 FuncExpr *expr = (FuncExpr *) node;
01606
01607 if (expression_tree_walker((Node *) expr->args,
01608 walker, context))
01609 return true;
01610 }
01611 break;
01612 case T_NamedArgExpr:
01613 return walker(((NamedArgExpr *) node)->arg, context);
01614 case T_OpExpr:
01615 case T_DistinctExpr:
01616 case T_NullIfExpr:
01617 {
01618 OpExpr *expr = (OpExpr *) node;
01619
01620 if (expression_tree_walker((Node *) expr->args,
01621 walker, context))
01622 return true;
01623 }
01624 break;
01625 case T_ScalarArrayOpExpr:
01626 {
01627 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
01628
01629 if (expression_tree_walker((Node *) expr->args,
01630 walker, context))
01631 return true;
01632 }
01633 break;
01634 case T_BoolExpr:
01635 {
01636 BoolExpr *expr = (BoolExpr *) node;
01637
01638 if (expression_tree_walker((Node *) expr->args,
01639 walker, context))
01640 return true;
01641 }
01642 break;
01643 case T_SubLink:
01644 {
01645 SubLink *sublink = (SubLink *) node;
01646
01647 if (walker(sublink->testexpr, context))
01648 return true;
01649
01650
01651
01652
01653
01654 return walker(sublink->subselect, context);
01655 }
01656 break;
01657 case T_SubPlan:
01658 {
01659 SubPlan *subplan = (SubPlan *) node;
01660
01661
01662 if (walker(subplan->testexpr, context))
01663 return true;
01664
01665 if (expression_tree_walker((Node *) subplan->args,
01666 walker, context))
01667 return true;
01668 }
01669 break;
01670 case T_AlternativeSubPlan:
01671 return walker(((AlternativeSubPlan *) node)->subplans, context);
01672 case T_FieldSelect:
01673 return walker(((FieldSelect *) node)->arg, context);
01674 case T_FieldStore:
01675 {
01676 FieldStore *fstore = (FieldStore *) node;
01677
01678 if (walker(fstore->arg, context))
01679 return true;
01680 if (walker(fstore->newvals, context))
01681 return true;
01682 }
01683 break;
01684 case T_RelabelType:
01685 return walker(((RelabelType *) node)->arg, context);
01686 case T_CoerceViaIO:
01687 return walker(((CoerceViaIO *) node)->arg, context);
01688 case T_ArrayCoerceExpr:
01689 return walker(((ArrayCoerceExpr *) node)->arg, context);
01690 case T_ConvertRowtypeExpr:
01691 return walker(((ConvertRowtypeExpr *) node)->arg, context);
01692 case T_CollateExpr:
01693 return walker(((CollateExpr *) node)->arg, context);
01694 case T_CaseExpr:
01695 {
01696 CaseExpr *caseexpr = (CaseExpr *) node;
01697
01698 if (walker(caseexpr->arg, context))
01699 return true;
01700
01701 foreach(temp, caseexpr->args)
01702 {
01703 CaseWhen *when = (CaseWhen *) lfirst(temp);
01704
01705 Assert(IsA(when, CaseWhen));
01706 if (walker(when->expr, context))
01707 return true;
01708 if (walker(when->result, context))
01709 return true;
01710 }
01711 if (walker(caseexpr->defresult, context))
01712 return true;
01713 }
01714 break;
01715 case T_ArrayExpr:
01716 return walker(((ArrayExpr *) node)->elements, context);
01717 case T_RowExpr:
01718
01719 return walker(((RowExpr *) node)->args, context);
01720 case T_RowCompareExpr:
01721 {
01722 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
01723
01724 if (walker(rcexpr->largs, context))
01725 return true;
01726 if (walker(rcexpr->rargs, context))
01727 return true;
01728 }
01729 break;
01730 case T_CoalesceExpr:
01731 return walker(((CoalesceExpr *) node)->args, context);
01732 case T_MinMaxExpr:
01733 return walker(((MinMaxExpr *) node)->args, context);
01734 case T_XmlExpr:
01735 {
01736 XmlExpr *xexpr = (XmlExpr *) node;
01737
01738 if (walker(xexpr->named_args, context))
01739 return true;
01740
01741 if (walker(xexpr->args, context))
01742 return true;
01743 }
01744 break;
01745 case T_NullTest:
01746 return walker(((NullTest *) node)->arg, context);
01747 case T_BooleanTest:
01748 return walker(((BooleanTest *) node)->arg, context);
01749 case T_CoerceToDomain:
01750 return walker(((CoerceToDomain *) node)->arg, context);
01751 case T_TargetEntry:
01752 return walker(((TargetEntry *) node)->expr, context);
01753 case T_Query:
01754
01755 break;
01756 case T_WindowClause:
01757 {
01758 WindowClause *wc = (WindowClause *) node;
01759
01760 if (walker(wc->partitionClause, context))
01761 return true;
01762 if (walker(wc->orderClause, context))
01763 return true;
01764 if (walker(wc->startOffset, context))
01765 return true;
01766 if (walker(wc->endOffset, context))
01767 return true;
01768 }
01769 break;
01770 case T_CommonTableExpr:
01771 {
01772 CommonTableExpr *cte = (CommonTableExpr *) node;
01773
01774
01775
01776
01777
01778 return walker(cte->ctequery, context);
01779 }
01780 break;
01781 case T_List:
01782 foreach(temp, (List *) node)
01783 {
01784 if (walker((Node *) lfirst(temp), context))
01785 return true;
01786 }
01787 break;
01788 case T_FromExpr:
01789 {
01790 FromExpr *from = (FromExpr *) node;
01791
01792 if (walker(from->fromlist, context))
01793 return true;
01794 if (walker(from->quals, context))
01795 return true;
01796 }
01797 break;
01798 case T_JoinExpr:
01799 {
01800 JoinExpr *join = (JoinExpr *) node;
01801
01802 if (walker(join->larg, context))
01803 return true;
01804 if (walker(join->rarg, context))
01805 return true;
01806 if (walker(join->quals, context))
01807 return true;
01808
01809
01810
01811
01812 }
01813 break;
01814 case T_SetOperationStmt:
01815 {
01816 SetOperationStmt *setop = (SetOperationStmt *) node;
01817
01818 if (walker(setop->larg, context))
01819 return true;
01820 if (walker(setop->rarg, context))
01821 return true;
01822
01823
01824 }
01825 break;
01826 case T_PlaceHolderVar:
01827 return walker(((PlaceHolderVar *) node)->phexpr, context);
01828 case T_AppendRelInfo:
01829 {
01830 AppendRelInfo *appinfo = (AppendRelInfo *) node;
01831
01832 if (expression_tree_walker((Node *) appinfo->translated_vars,
01833 walker, context))
01834 return true;
01835 }
01836 break;
01837 case T_PlaceHolderInfo:
01838 return walker(((PlaceHolderInfo *) node)->ph_var, context);
01839 default:
01840 elog(ERROR, "unrecognized node type: %d",
01841 (int) nodeTag(node));
01842 break;
01843 }
01844 return false;
01845 }
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862 bool
01863 query_tree_walker(Query *query,
01864 bool (*walker) (),
01865 void *context,
01866 int flags)
01867 {
01868 Assert(query != NULL && IsA(query, Query));
01869
01870 if (walker((Node *) query->targetList, context))
01871 return true;
01872 if (walker((Node *) query->returningList, context))
01873 return true;
01874 if (walker((Node *) query->jointree, context))
01875 return true;
01876 if (walker(query->setOperations, context))
01877 return true;
01878 if (walker(query->havingQual, context))
01879 return true;
01880 if (walker(query->limitOffset, context))
01881 return true;
01882 if (walker(query->limitCount, context))
01883 return true;
01884 if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
01885 {
01886 if (walker((Node *) query->cteList, context))
01887 return true;
01888 }
01889 if (!(flags & QTW_IGNORE_RANGE_TABLE))
01890 {
01891 if (range_table_walker(query->rtable, walker, context, flags))
01892 return true;
01893 }
01894 return false;
01895 }
01896
01897
01898
01899
01900
01901
01902 bool
01903 range_table_walker(List *rtable,
01904 bool (*walker) (),
01905 void *context,
01906 int flags)
01907 {
01908 ListCell *rt;
01909
01910 foreach(rt, rtable)
01911 {
01912 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
01913
01914
01915 if (flags & QTW_EXAMINE_RTES)
01916 if (walker(rte, context))
01917 return true;
01918
01919 switch (rte->rtekind)
01920 {
01921 case RTE_RELATION:
01922 case RTE_CTE:
01923
01924 break;
01925 case RTE_SUBQUERY:
01926 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
01927 if (walker(rte->subquery, context))
01928 return true;
01929 break;
01930 case RTE_JOIN:
01931 if (!(flags & QTW_IGNORE_JOINALIASES))
01932 if (walker(rte->joinaliasvars, context))
01933 return true;
01934 break;
01935 case RTE_FUNCTION:
01936 if (walker(rte->funcexpr, context))
01937 return true;
01938 break;
01939 case RTE_VALUES:
01940 if (walker(rte->values_lists, context))
01941 return true;
01942 break;
01943 }
01944 }
01945 return false;
01946 }
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011 Node *
02012 expression_tree_mutator(Node *node,
02013 Node *(*mutator) (),
02014 void *context)
02015 {
02016
02017
02018
02019
02020
02021 #define FLATCOPY(newnode, node, nodetype) \
02022 ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
02023 memcpy((newnode), (node), sizeof(nodetype)) )
02024
02025 #define CHECKFLATCOPY(newnode, node, nodetype) \
02026 ( AssertMacro(IsA((node), nodetype)), \
02027 (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
02028 memcpy((newnode), (node), sizeof(nodetype)) )
02029
02030 #define MUTATE(newfield, oldfield, fieldtype) \
02031 ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
02032
02033 if (node == NULL)
02034 return NULL;
02035
02036
02037 check_stack_depth();
02038
02039 switch (nodeTag(node))
02040 {
02041
02042
02043
02044
02045
02046 case T_Var:
02047 {
02048 Var *var = (Var *) node;
02049 Var *newnode;
02050
02051 FLATCOPY(newnode, var, Var);
02052 return (Node *) newnode;
02053 }
02054 break;
02055 case T_Const:
02056 {
02057 Const *oldnode = (Const *) node;
02058 Const *newnode;
02059
02060 FLATCOPY(newnode, oldnode, Const);
02061
02062 return (Node *) newnode;
02063 }
02064 break;
02065 case T_Param:
02066 case T_CoerceToDomainValue:
02067 case T_CaseTestExpr:
02068 case T_SetToDefault:
02069 case T_CurrentOfExpr:
02070 case T_RangeTblRef:
02071 case T_SortGroupClause:
02072 return (Node *) copyObject(node);
02073 case T_Aggref:
02074 {
02075 Aggref *aggref = (Aggref *) node;
02076 Aggref *newnode;
02077
02078 FLATCOPY(newnode, aggref, Aggref);
02079 MUTATE(newnode->args, aggref->args, List *);
02080 MUTATE(newnode->aggorder, aggref->aggorder, List *);
02081 MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
02082 return (Node *) newnode;
02083 }
02084 break;
02085 case T_WindowFunc:
02086 {
02087 WindowFunc *wfunc = (WindowFunc *) node;
02088 WindowFunc *newnode;
02089
02090 FLATCOPY(newnode, wfunc, WindowFunc);
02091 MUTATE(newnode->args, wfunc->args, List *);
02092 return (Node *) newnode;
02093 }
02094 break;
02095 case T_ArrayRef:
02096 {
02097 ArrayRef *arrayref = (ArrayRef *) node;
02098 ArrayRef *newnode;
02099
02100 FLATCOPY(newnode, arrayref, ArrayRef);
02101 MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr,
02102 List *);
02103 MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr,
02104 List *);
02105 MUTATE(newnode->refexpr, arrayref->refexpr,
02106 Expr *);
02107 MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr,
02108 Expr *);
02109 return (Node *) newnode;
02110 }
02111 break;
02112 case T_FuncExpr:
02113 {
02114 FuncExpr *expr = (FuncExpr *) node;
02115 FuncExpr *newnode;
02116
02117 FLATCOPY(newnode, expr, FuncExpr);
02118 MUTATE(newnode->args, expr->args, List *);
02119 return (Node *) newnode;
02120 }
02121 break;
02122 case T_NamedArgExpr:
02123 {
02124 NamedArgExpr *nexpr = (NamedArgExpr *) node;
02125 NamedArgExpr *newnode;
02126
02127 FLATCOPY(newnode, nexpr, NamedArgExpr);
02128 MUTATE(newnode->arg, nexpr->arg, Expr *);
02129 return (Node *) newnode;
02130 }
02131 break;
02132 case T_OpExpr:
02133 {
02134 OpExpr *expr = (OpExpr *) node;
02135 OpExpr *newnode;
02136
02137 FLATCOPY(newnode, expr, OpExpr);
02138 MUTATE(newnode->args, expr->args, List *);
02139 return (Node *) newnode;
02140 }
02141 break;
02142 case T_DistinctExpr:
02143 {
02144 DistinctExpr *expr = (DistinctExpr *) node;
02145 DistinctExpr *newnode;
02146
02147 FLATCOPY(newnode, expr, DistinctExpr);
02148 MUTATE(newnode->args, expr->args, List *);
02149 return (Node *) newnode;
02150 }
02151 break;
02152 case T_NullIfExpr:
02153 {
02154 NullIfExpr *expr = (NullIfExpr *) node;
02155 NullIfExpr *newnode;
02156
02157 FLATCOPY(newnode, expr, NullIfExpr);
02158 MUTATE(newnode->args, expr->args, List *);
02159 return (Node *) newnode;
02160 }
02161 break;
02162 case T_ScalarArrayOpExpr:
02163 {
02164 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
02165 ScalarArrayOpExpr *newnode;
02166
02167 FLATCOPY(newnode, expr, ScalarArrayOpExpr);
02168 MUTATE(newnode->args, expr->args, List *);
02169 return (Node *) newnode;
02170 }
02171 break;
02172 case T_BoolExpr:
02173 {
02174 BoolExpr *expr = (BoolExpr *) node;
02175 BoolExpr *newnode;
02176
02177 FLATCOPY(newnode, expr, BoolExpr);
02178 MUTATE(newnode->args, expr->args, List *);
02179 return (Node *) newnode;
02180 }
02181 break;
02182 case T_SubLink:
02183 {
02184 SubLink *sublink = (SubLink *) node;
02185 SubLink *newnode;
02186
02187 FLATCOPY(newnode, sublink, SubLink);
02188 MUTATE(newnode->testexpr, sublink->testexpr, Node *);
02189
02190
02191
02192
02193
02194 MUTATE(newnode->subselect, sublink->subselect, Node *);
02195 return (Node *) newnode;
02196 }
02197 break;
02198 case T_SubPlan:
02199 {
02200 SubPlan *subplan = (SubPlan *) node;
02201 SubPlan *newnode;
02202
02203 FLATCOPY(newnode, subplan, SubPlan);
02204
02205 MUTATE(newnode->testexpr, subplan->testexpr, Node *);
02206
02207 MUTATE(newnode->args, subplan->args, List *);
02208
02209 return (Node *) newnode;
02210 }
02211 break;
02212 case T_AlternativeSubPlan:
02213 {
02214 AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
02215 AlternativeSubPlan *newnode;
02216
02217 FLATCOPY(newnode, asplan, AlternativeSubPlan);
02218 MUTATE(newnode->subplans, asplan->subplans, List *);
02219 return (Node *) newnode;
02220 }
02221 break;
02222 case T_FieldSelect:
02223 {
02224 FieldSelect *fselect = (FieldSelect *) node;
02225 FieldSelect *newnode;
02226
02227 FLATCOPY(newnode, fselect, FieldSelect);
02228 MUTATE(newnode->arg, fselect->arg, Expr *);
02229 return (Node *) newnode;
02230 }
02231 break;
02232 case T_FieldStore:
02233 {
02234 FieldStore *fstore = (FieldStore *) node;
02235 FieldStore *newnode;
02236
02237 FLATCOPY(newnode, fstore, FieldStore);
02238 MUTATE(newnode->arg, fstore->arg, Expr *);
02239 MUTATE(newnode->newvals, fstore->newvals, List *);
02240 newnode->fieldnums = list_copy(fstore->fieldnums);
02241 return (Node *) newnode;
02242 }
02243 break;
02244 case T_RelabelType:
02245 {
02246 RelabelType *relabel = (RelabelType *) node;
02247 RelabelType *newnode;
02248
02249 FLATCOPY(newnode, relabel, RelabelType);
02250 MUTATE(newnode->arg, relabel->arg, Expr *);
02251 return (Node *) newnode;
02252 }
02253 break;
02254 case T_CoerceViaIO:
02255 {
02256 CoerceViaIO *iocoerce = (CoerceViaIO *) node;
02257 CoerceViaIO *newnode;
02258
02259 FLATCOPY(newnode, iocoerce, CoerceViaIO);
02260 MUTATE(newnode->arg, iocoerce->arg, Expr *);
02261 return (Node *) newnode;
02262 }
02263 break;
02264 case T_ArrayCoerceExpr:
02265 {
02266 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
02267 ArrayCoerceExpr *newnode;
02268
02269 FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
02270 MUTATE(newnode->arg, acoerce->arg, Expr *);
02271 return (Node *) newnode;
02272 }
02273 break;
02274 case T_ConvertRowtypeExpr:
02275 {
02276 ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
02277 ConvertRowtypeExpr *newnode;
02278
02279 FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
02280 MUTATE(newnode->arg, convexpr->arg, Expr *);
02281 return (Node *) newnode;
02282 }
02283 break;
02284 case T_CollateExpr:
02285 {
02286 CollateExpr *collate = (CollateExpr *) node;
02287 CollateExpr *newnode;
02288
02289 FLATCOPY(newnode, collate, CollateExpr);
02290 MUTATE(newnode->arg, collate->arg, Expr *);
02291 return (Node *) newnode;
02292 }
02293 break;
02294 case T_CaseExpr:
02295 {
02296 CaseExpr *caseexpr = (CaseExpr *) node;
02297 CaseExpr *newnode;
02298
02299 FLATCOPY(newnode, caseexpr, CaseExpr);
02300 MUTATE(newnode->arg, caseexpr->arg, Expr *);
02301 MUTATE(newnode->args, caseexpr->args, List *);
02302 MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
02303 return (Node *) newnode;
02304 }
02305 break;
02306 case T_CaseWhen:
02307 {
02308 CaseWhen *casewhen = (CaseWhen *) node;
02309 CaseWhen *newnode;
02310
02311 FLATCOPY(newnode, casewhen, CaseWhen);
02312 MUTATE(newnode->expr, casewhen->expr, Expr *);
02313 MUTATE(newnode->result, casewhen->result, Expr *);
02314 return (Node *) newnode;
02315 }
02316 break;
02317 case T_ArrayExpr:
02318 {
02319 ArrayExpr *arrayexpr = (ArrayExpr *) node;
02320 ArrayExpr *newnode;
02321
02322 FLATCOPY(newnode, arrayexpr, ArrayExpr);
02323 MUTATE(newnode->elements, arrayexpr->elements, List *);
02324 return (Node *) newnode;
02325 }
02326 break;
02327 case T_RowExpr:
02328 {
02329 RowExpr *rowexpr = (RowExpr *) node;
02330 RowExpr *newnode;
02331
02332 FLATCOPY(newnode, rowexpr, RowExpr);
02333 MUTATE(newnode->args, rowexpr->args, List *);
02334
02335 return (Node *) newnode;
02336 }
02337 break;
02338 case T_RowCompareExpr:
02339 {
02340 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
02341 RowCompareExpr *newnode;
02342
02343 FLATCOPY(newnode, rcexpr, RowCompareExpr);
02344 MUTATE(newnode->largs, rcexpr->largs, List *);
02345 MUTATE(newnode->rargs, rcexpr->rargs, List *);
02346 return (Node *) newnode;
02347 }
02348 break;
02349 case T_CoalesceExpr:
02350 {
02351 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
02352 CoalesceExpr *newnode;
02353
02354 FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
02355 MUTATE(newnode->args, coalesceexpr->args, List *);
02356 return (Node *) newnode;
02357 }
02358 break;
02359 case T_MinMaxExpr:
02360 {
02361 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
02362 MinMaxExpr *newnode;
02363
02364 FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
02365 MUTATE(newnode->args, minmaxexpr->args, List *);
02366 return (Node *) newnode;
02367 }
02368 break;
02369 case T_XmlExpr:
02370 {
02371 XmlExpr *xexpr = (XmlExpr *) node;
02372 XmlExpr *newnode;
02373
02374 FLATCOPY(newnode, xexpr, XmlExpr);
02375 MUTATE(newnode->named_args, xexpr->named_args, List *);
02376
02377 MUTATE(newnode->args, xexpr->args, List *);
02378 return (Node *) newnode;
02379 }
02380 break;
02381 case T_NullTest:
02382 {
02383 NullTest *ntest = (NullTest *) node;
02384 NullTest *newnode;
02385
02386 FLATCOPY(newnode, ntest, NullTest);
02387 MUTATE(newnode->arg, ntest->arg, Expr *);
02388 return (Node *) newnode;
02389 }
02390 break;
02391 case T_BooleanTest:
02392 {
02393 BooleanTest *btest = (BooleanTest *) node;
02394 BooleanTest *newnode;
02395
02396 FLATCOPY(newnode, btest, BooleanTest);
02397 MUTATE(newnode->arg, btest->arg, Expr *);
02398 return (Node *) newnode;
02399 }
02400 break;
02401 case T_CoerceToDomain:
02402 {
02403 CoerceToDomain *ctest = (CoerceToDomain *) node;
02404 CoerceToDomain *newnode;
02405
02406 FLATCOPY(newnode, ctest, CoerceToDomain);
02407 MUTATE(newnode->arg, ctest->arg, Expr *);
02408 return (Node *) newnode;
02409 }
02410 break;
02411 case T_TargetEntry:
02412 {
02413 TargetEntry *targetentry = (TargetEntry *) node;
02414 TargetEntry *newnode;
02415
02416 FLATCOPY(newnode, targetentry, TargetEntry);
02417 MUTATE(newnode->expr, targetentry->expr, Expr *);
02418 return (Node *) newnode;
02419 }
02420 break;
02421 case T_Query:
02422
02423 return node;
02424 case T_WindowClause:
02425 {
02426 WindowClause *wc = (WindowClause *) node;
02427 WindowClause *newnode;
02428
02429 FLATCOPY(newnode, wc, WindowClause);
02430 MUTATE(newnode->partitionClause, wc->partitionClause, List *);
02431 MUTATE(newnode->orderClause, wc->orderClause, List *);
02432 MUTATE(newnode->startOffset, wc->startOffset, Node *);
02433 MUTATE(newnode->endOffset, wc->endOffset, Node *);
02434 return (Node *) newnode;
02435 }
02436 break;
02437 case T_CommonTableExpr:
02438 {
02439 CommonTableExpr *cte = (CommonTableExpr *) node;
02440 CommonTableExpr *newnode;
02441
02442 FLATCOPY(newnode, cte, CommonTableExpr);
02443
02444
02445
02446
02447
02448 MUTATE(newnode->ctequery, cte->ctequery, Node *);
02449 return (Node *) newnode;
02450 }
02451 break;
02452 case T_List:
02453 {
02454
02455
02456
02457
02458
02459 List *resultlist;
02460 ListCell *temp;
02461
02462 resultlist = NIL;
02463 foreach(temp, (List *) node)
02464 {
02465 resultlist = lappend(resultlist,
02466 mutator((Node *) lfirst(temp),
02467 context));
02468 }
02469 return (Node *) resultlist;
02470 }
02471 break;
02472 case T_FromExpr:
02473 {
02474 FromExpr *from = (FromExpr *) node;
02475 FromExpr *newnode;
02476
02477 FLATCOPY(newnode, from, FromExpr);
02478 MUTATE(newnode->fromlist, from->fromlist, List *);
02479 MUTATE(newnode->quals, from->quals, Node *);
02480 return (Node *) newnode;
02481 }
02482 break;
02483 case T_JoinExpr:
02484 {
02485 JoinExpr *join = (JoinExpr *) node;
02486 JoinExpr *newnode;
02487
02488 FLATCOPY(newnode, join, JoinExpr);
02489 MUTATE(newnode->larg, join->larg, Node *);
02490 MUTATE(newnode->rarg, join->rarg, Node *);
02491 MUTATE(newnode->quals, join->quals, Node *);
02492
02493 return (Node *) newnode;
02494 }
02495 break;
02496 case T_SetOperationStmt:
02497 {
02498 SetOperationStmt *setop = (SetOperationStmt *) node;
02499 SetOperationStmt *newnode;
02500
02501 FLATCOPY(newnode, setop, SetOperationStmt);
02502 MUTATE(newnode->larg, setop->larg, Node *);
02503 MUTATE(newnode->rarg, setop->rarg, Node *);
02504
02505 return (Node *) newnode;
02506 }
02507 break;
02508 case T_PlaceHolderVar:
02509 {
02510 PlaceHolderVar *phv = (PlaceHolderVar *) node;
02511 PlaceHolderVar *newnode;
02512
02513 FLATCOPY(newnode, phv, PlaceHolderVar);
02514 MUTATE(newnode->phexpr, phv->phexpr, Expr *);
02515
02516 return (Node *) newnode;
02517 }
02518 break;
02519 case T_AppendRelInfo:
02520 {
02521 AppendRelInfo *appinfo = (AppendRelInfo *) node;
02522 AppendRelInfo *newnode;
02523
02524 FLATCOPY(newnode, appinfo, AppendRelInfo);
02525 MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
02526 return (Node *) newnode;
02527 }
02528 break;
02529 case T_PlaceHolderInfo:
02530 {
02531 PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
02532 PlaceHolderInfo *newnode;
02533
02534 FLATCOPY(newnode, phinfo, PlaceHolderInfo);
02535 MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
02536
02537 return (Node *) newnode;
02538 }
02539 break;
02540 default:
02541 elog(ERROR, "unrecognized node type: %d",
02542 (int) nodeTag(node));
02543 break;
02544 }
02545
02546 return NULL;
02547 }
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569 Query *
02570 query_tree_mutator(Query *query,
02571 Node *(*mutator) (),
02572 void *context,
02573 int flags)
02574 {
02575 Assert(query != NULL && IsA(query, Query));
02576
02577 if (!(flags & QTW_DONT_COPY_QUERY))
02578 {
02579 Query *newquery;
02580
02581 FLATCOPY(newquery, query, Query);
02582 query = newquery;
02583 }
02584
02585 MUTATE(query->targetList, query->targetList, List *);
02586 MUTATE(query->returningList, query->returningList, List *);
02587 MUTATE(query->jointree, query->jointree, FromExpr *);
02588 MUTATE(query->setOperations, query->setOperations, Node *);
02589 MUTATE(query->havingQual, query->havingQual, Node *);
02590 MUTATE(query->limitOffset, query->limitOffset, Node *);
02591 MUTATE(query->limitCount, query->limitCount, Node *);
02592 if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
02593 MUTATE(query->cteList, query->cteList, List *);
02594 else
02595 query->cteList = copyObject(query->cteList);
02596 query->rtable = range_table_mutator(query->rtable,
02597 mutator, context, flags);
02598 return query;
02599 }
02600
02601
02602
02603
02604
02605
02606 List *
02607 range_table_mutator(List *rtable,
02608 Node *(*mutator) (),
02609 void *context,
02610 int flags)
02611 {
02612 List *newrt = NIL;
02613 ListCell *rt;
02614
02615 foreach(rt, rtable)
02616 {
02617 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
02618 RangeTblEntry *newrte;
02619
02620 FLATCOPY(newrte, rte, RangeTblEntry);
02621 switch (rte->rtekind)
02622 {
02623 case RTE_RELATION:
02624 case RTE_CTE:
02625
02626 break;
02627 case RTE_SUBQUERY:
02628 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
02629 {
02630 CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
02631 MUTATE(newrte->subquery, newrte->subquery, Query *);
02632 }
02633 else
02634 {
02635
02636 newrte->subquery = copyObject(rte->subquery);
02637 }
02638 break;
02639 case RTE_JOIN:
02640 if (!(flags & QTW_IGNORE_JOINALIASES))
02641 MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
02642 else
02643 {
02644
02645 newrte->joinaliasvars = copyObject(rte->joinaliasvars);
02646 }
02647 break;
02648 case RTE_FUNCTION:
02649 MUTATE(newrte->funcexpr, rte->funcexpr, Node *);
02650 break;
02651 case RTE_VALUES:
02652 MUTATE(newrte->values_lists, rte->values_lists, List *);
02653 break;
02654 }
02655 newrt = lappend(newrt, newrte);
02656 }
02657 return newrt;
02658 }
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668 bool
02669 query_or_expression_tree_walker(Node *node,
02670 bool (*walker) (),
02671 void *context,
02672 int flags)
02673 {
02674 if (node && IsA(node, Query))
02675 return query_tree_walker((Query *) node,
02676 walker,
02677 context,
02678 flags);
02679 else
02680 return walker(node, context);
02681 }
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691 Node *
02692 query_or_expression_tree_mutator(Node *node,
02693 Node *(*mutator) (),
02694 void *context,
02695 int flags)
02696 {
02697 if (node && IsA(node, Query))
02698 return (Node *) query_tree_mutator((Query *) node,
02699 mutator,
02700 context,
02701 flags);
02702 else
02703 return mutator(node, context);
02704 }
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720 bool
02721 raw_expression_tree_walker(Node *node,
02722 bool (*walker) (),
02723 void *context)
02724 {
02725 ListCell *temp;
02726
02727
02728
02729
02730
02731 if (node == NULL)
02732 return false;
02733
02734
02735 check_stack_depth();
02736
02737 switch (nodeTag(node))
02738 {
02739 case T_SetToDefault:
02740 case T_CurrentOfExpr:
02741 case T_Integer:
02742 case T_Float:
02743 case T_String:
02744 case T_BitString:
02745 case T_Null:
02746 case T_ParamRef:
02747 case T_A_Const:
02748 case T_A_Star:
02749
02750 break;
02751 case T_Alias:
02752
02753 break;
02754 case T_RangeVar:
02755 return walker(((RangeVar *) node)->alias, context);
02756 case T_SubLink:
02757 {
02758 SubLink *sublink = (SubLink *) node;
02759
02760 if (walker(sublink->testexpr, context))
02761 return true;
02762
02763 if (walker(sublink->subselect, context))
02764 return true;
02765 }
02766 break;
02767 case T_CaseExpr:
02768 {
02769 CaseExpr *caseexpr = (CaseExpr *) node;
02770
02771 if (walker(caseexpr->arg, context))
02772 return true;
02773
02774 foreach(temp, caseexpr->args)
02775 {
02776 CaseWhen *when = (CaseWhen *) lfirst(temp);
02777
02778 Assert(IsA(when, CaseWhen));
02779 if (walker(when->expr, context))
02780 return true;
02781 if (walker(when->result, context))
02782 return true;
02783 }
02784 if (walker(caseexpr->defresult, context))
02785 return true;
02786 }
02787 break;
02788 case T_RowExpr:
02789
02790 return walker(((RowExpr *) node)->args, context);
02791 case T_CoalesceExpr:
02792 return walker(((CoalesceExpr *) node)->args, context);
02793 case T_MinMaxExpr:
02794 return walker(((MinMaxExpr *) node)->args, context);
02795 case T_XmlExpr:
02796 {
02797 XmlExpr *xexpr = (XmlExpr *) node;
02798
02799 if (walker(xexpr->named_args, context))
02800 return true;
02801
02802 if (walker(xexpr->args, context))
02803 return true;
02804 }
02805 break;
02806 case T_NullTest:
02807 return walker(((NullTest *) node)->arg, context);
02808 case T_BooleanTest:
02809 return walker(((BooleanTest *) node)->arg, context);
02810 case T_JoinExpr:
02811 {
02812 JoinExpr *join = (JoinExpr *) node;
02813
02814 if (walker(join->larg, context))
02815 return true;
02816 if (walker(join->rarg, context))
02817 return true;
02818 if (walker(join->quals, context))
02819 return true;
02820 if (walker(join->alias, context))
02821 return true;
02822
02823 }
02824 break;
02825 case T_IntoClause:
02826 {
02827 IntoClause *into = (IntoClause *) node;
02828
02829 if (walker(into->rel, context))
02830 return true;
02831
02832
02833 if (walker(into->viewQuery, context))
02834 return true;
02835 }
02836 break;
02837 case T_List:
02838 foreach(temp, (List *) node)
02839 {
02840 if (walker((Node *) lfirst(temp), context))
02841 return true;
02842 }
02843 break;
02844 case T_InsertStmt:
02845 {
02846 InsertStmt *stmt = (InsertStmt *) node;
02847
02848 if (walker(stmt->relation, context))
02849 return true;
02850 if (walker(stmt->cols, context))
02851 return true;
02852 if (walker(stmt->selectStmt, context))
02853 return true;
02854 if (walker(stmt->returningList, context))
02855 return true;
02856 if (walker(stmt->withClause, context))
02857 return true;
02858 }
02859 break;
02860 case T_DeleteStmt:
02861 {
02862 DeleteStmt *stmt = (DeleteStmt *) node;
02863
02864 if (walker(stmt->relation, context))
02865 return true;
02866 if (walker(stmt->usingClause, context))
02867 return true;
02868 if (walker(stmt->whereClause, context))
02869 return true;
02870 if (walker(stmt->returningList, context))
02871 return true;
02872 if (walker(stmt->withClause, context))
02873 return true;
02874 }
02875 break;
02876 case T_UpdateStmt:
02877 {
02878 UpdateStmt *stmt = (UpdateStmt *) node;
02879
02880 if (walker(stmt->relation, context))
02881 return true;
02882 if (walker(stmt->targetList, context))
02883 return true;
02884 if (walker(stmt->whereClause, context))
02885 return true;
02886 if (walker(stmt->fromClause, context))
02887 return true;
02888 if (walker(stmt->returningList, context))
02889 return true;
02890 if (walker(stmt->withClause, context))
02891 return true;
02892 }
02893 break;
02894 case T_SelectStmt:
02895 {
02896 SelectStmt *stmt = (SelectStmt *) node;
02897
02898 if (walker(stmt->distinctClause, context))
02899 return true;
02900 if (walker(stmt->intoClause, context))
02901 return true;
02902 if (walker(stmt->targetList, context))
02903 return true;
02904 if (walker(stmt->fromClause, context))
02905 return true;
02906 if (walker(stmt->whereClause, context))
02907 return true;
02908 if (walker(stmt->groupClause, context))
02909 return true;
02910 if (walker(stmt->havingClause, context))
02911 return true;
02912 if (walker(stmt->windowClause, context))
02913 return true;
02914 if (walker(stmt->valuesLists, context))
02915 return true;
02916 if (walker(stmt->sortClause, context))
02917 return true;
02918 if (walker(stmt->limitOffset, context))
02919 return true;
02920 if (walker(stmt->limitCount, context))
02921 return true;
02922 if (walker(stmt->lockingClause, context))
02923 return true;
02924 if (walker(stmt->withClause, context))
02925 return true;
02926 if (walker(stmt->larg, context))
02927 return true;
02928 if (walker(stmt->rarg, context))
02929 return true;
02930 }
02931 break;
02932 case T_A_Expr:
02933 {
02934 A_Expr *expr = (A_Expr *) node;
02935
02936 if (walker(expr->lexpr, context))
02937 return true;
02938 if (walker(expr->rexpr, context))
02939 return true;
02940
02941 }
02942 break;
02943 case T_ColumnRef:
02944
02945 break;
02946 case T_FuncCall:
02947 {
02948 FuncCall *fcall = (FuncCall *) node;
02949
02950 if (walker(fcall->args, context))
02951 return true;
02952 if (walker(fcall->agg_order, context))
02953 return true;
02954 if (walker(fcall->over, context))
02955 return true;
02956
02957 }
02958 break;
02959 case T_NamedArgExpr:
02960 return walker(((NamedArgExpr *) node)->arg, context);
02961 case T_A_Indices:
02962 {
02963 A_Indices *indices = (A_Indices *) node;
02964
02965 if (walker(indices->lidx, context))
02966 return true;
02967 if (walker(indices->uidx, context))
02968 return true;
02969 }
02970 break;
02971 case T_A_Indirection:
02972 {
02973 A_Indirection *indir = (A_Indirection *) node;
02974
02975 if (walker(indir->arg, context))
02976 return true;
02977 if (walker(indir->indirection, context))
02978 return true;
02979 }
02980 break;
02981 case T_A_ArrayExpr:
02982 return walker(((A_ArrayExpr *) node)->elements, context);
02983 case T_ResTarget:
02984 {
02985 ResTarget *rt = (ResTarget *) node;
02986
02987 if (walker(rt->indirection, context))
02988 return true;
02989 if (walker(rt->val, context))
02990 return true;
02991 }
02992 break;
02993 case T_TypeCast:
02994 {
02995 TypeCast *tc = (TypeCast *) node;
02996
02997 if (walker(tc->arg, context))
02998 return true;
02999 if (walker(tc->typeName, context))
03000 return true;
03001 }
03002 break;
03003 case T_CollateClause:
03004 return walker(((CollateClause *) node)->arg, context);
03005 case T_SortBy:
03006 return walker(((SortBy *) node)->node, context);
03007 case T_WindowDef:
03008 {
03009 WindowDef *wd = (WindowDef *) node;
03010
03011 if (walker(wd->partitionClause, context))
03012 return true;
03013 if (walker(wd->orderClause, context))
03014 return true;
03015 if (walker(wd->startOffset, context))
03016 return true;
03017 if (walker(wd->endOffset, context))
03018 return true;
03019 }
03020 break;
03021 case T_RangeSubselect:
03022 {
03023 RangeSubselect *rs = (RangeSubselect *) node;
03024
03025 if (walker(rs->subquery, context))
03026 return true;
03027 if (walker(rs->alias, context))
03028 return true;
03029 }
03030 break;
03031 case T_RangeFunction:
03032 {
03033 RangeFunction *rf = (RangeFunction *) node;
03034
03035 if (walker(rf->funccallnode, context))
03036 return true;
03037 if (walker(rf->alias, context))
03038 return true;
03039 }
03040 break;
03041 case T_TypeName:
03042 {
03043 TypeName *tn = (TypeName *) node;
03044
03045 if (walker(tn->typmods, context))
03046 return true;
03047 if (walker(tn->arrayBounds, context))
03048 return true;
03049
03050 }
03051 break;
03052 case T_ColumnDef:
03053 {
03054 ColumnDef *coldef = (ColumnDef *) node;
03055
03056 if (walker(coldef->typeName, context))
03057 return true;
03058 if (walker(coldef->raw_default, context))
03059 return true;
03060 if (walker(coldef->collClause, context))
03061 return true;
03062
03063 }
03064 break;
03065 case T_LockingClause:
03066 return walker(((LockingClause *) node)->lockedRels, context);
03067 case T_XmlSerialize:
03068 {
03069 XmlSerialize *xs = (XmlSerialize *) node;
03070
03071 if (walker(xs->expr, context))
03072 return true;
03073 if (walker(xs->typeName, context))
03074 return true;
03075 }
03076 break;
03077 case T_WithClause:
03078 return walker(((WithClause *) node)->ctes, context);
03079 case T_CommonTableExpr:
03080 return walker(((CommonTableExpr *) node)->ctequery, context);
03081 default:
03082 elog(ERROR, "unrecognized node type: %d",
03083 (int) nodeTag(node));
03084 break;
03085 }
03086 return false;
03087 }