00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include "catalog/pg_type.h"
00019 #include "commands/dbcommands.h"
00020 #include "miscadmin.h"
00021 #include "nodes/makefuncs.h"
00022 #include "nodes/nodeFuncs.h"
00023 #include "optimizer/var.h"
00024 #include "parser/analyze.h"
00025 #include "parser/parse_coerce.h"
00026 #include "parser/parse_collate.h"
00027 #include "parser/parse_expr.h"
00028 #include "parser/parse_func.h"
00029 #include "parser/parse_oper.h"
00030 #include "parser/parse_relation.h"
00031 #include "parser/parse_target.h"
00032 #include "parser/parse_type.h"
00033 #include "utils/builtins.h"
00034 #include "utils/lsyscache.h"
00035 #include "utils/xml.h"
00036
00037
00038 bool Transform_null_equals = false;
00039
00040 static Node *transformExprRecurse(ParseState *pstate, Node *expr);
00041 static Node *transformParamRef(ParseState *pstate, ParamRef *pref);
00042 static Node *transformAExprOp(ParseState *pstate, A_Expr *a);
00043 static Node *transformAExprAnd(ParseState *pstate, A_Expr *a);
00044 static Node *transformAExprOr(ParseState *pstate, A_Expr *a);
00045 static Node *transformAExprNot(ParseState *pstate, A_Expr *a);
00046 static Node *transformAExprOpAny(ParseState *pstate, A_Expr *a);
00047 static Node *transformAExprOpAll(ParseState *pstate, A_Expr *a);
00048 static Node *transformAExprDistinct(ParseState *pstate, A_Expr *a);
00049 static Node *transformAExprNullIf(ParseState *pstate, A_Expr *a);
00050 static Node *transformAExprOf(ParseState *pstate, A_Expr *a);
00051 static Node *transformAExprIn(ParseState *pstate, A_Expr *a);
00052 static Node *transformFuncCall(ParseState *pstate, FuncCall *fn);
00053 static Node *transformCaseExpr(ParseState *pstate, CaseExpr *c);
00054 static Node *transformSubLink(ParseState *pstate, SubLink *sublink);
00055 static Node *transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
00056 Oid array_type, Oid element_type, int32 typmod);
00057 static Node *transformRowExpr(ParseState *pstate, RowExpr *r);
00058 static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
00059 static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
00060 static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x);
00061 static Node *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs);
00062 static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
00063 static Node *transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr);
00064 static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
00065 static Node *transformWholeRowRef(ParseState *pstate, RangeTblEntry *rte,
00066 int location);
00067 static Node *transformIndirection(ParseState *pstate, Node *basenode,
00068 List *indirection);
00069 static Node *transformTypeCast(ParseState *pstate, TypeCast *tc);
00070 static Node *transformCollateClause(ParseState *pstate, CollateClause *c);
00071 static Node *make_row_comparison_op(ParseState *pstate, List *opname,
00072 List *largs, List *rargs, int location);
00073 static Node *make_row_distinct_op(ParseState *pstate, List *opname,
00074 RowExpr *lrow, RowExpr *rrow, int location);
00075 static Expr *make_distinct_op(ParseState *pstate, List *opname,
00076 Node *ltree, Node *rtree, int location);
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 Node *
00106 transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
00107 {
00108 Node *result;
00109 ParseExprKind sv_expr_kind;
00110
00111
00112 Assert(exprKind != EXPR_KIND_NONE);
00113 sv_expr_kind = pstate->p_expr_kind;
00114 pstate->p_expr_kind = exprKind;
00115
00116 result = transformExprRecurse(pstate, expr);
00117
00118 pstate->p_expr_kind = sv_expr_kind;
00119
00120 return result;
00121 }
00122
00123 static Node *
00124 transformExprRecurse(ParseState *pstate, Node *expr)
00125 {
00126 Node *result;
00127
00128 if (expr == NULL)
00129 return NULL;
00130
00131
00132 check_stack_depth();
00133
00134 switch (nodeTag(expr))
00135 {
00136 case T_ColumnRef:
00137 result = transformColumnRef(pstate, (ColumnRef *) expr);
00138 break;
00139
00140 case T_ParamRef:
00141 result = transformParamRef(pstate, (ParamRef *) expr);
00142 break;
00143
00144 case T_A_Const:
00145 {
00146 A_Const *con = (A_Const *) expr;
00147 Value *val = &con->val;
00148
00149 result = (Node *) make_const(pstate, val, con->location);
00150 break;
00151 }
00152
00153 case T_A_Indirection:
00154 {
00155 A_Indirection *ind = (A_Indirection *) expr;
00156
00157 result = transformExprRecurse(pstate, ind->arg);
00158 result = transformIndirection(pstate, result,
00159 ind->indirection);
00160 break;
00161 }
00162
00163 case T_A_ArrayExpr:
00164 result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
00165 InvalidOid, InvalidOid, -1);
00166 break;
00167
00168 case T_TypeCast:
00169 {
00170 TypeCast *tc = (TypeCast *) expr;
00171
00172
00173
00174
00175
00176
00177
00178
00179 if (IsA(tc->arg, A_ArrayExpr))
00180 {
00181 Oid targetType;
00182 Oid elementType;
00183 int32 targetTypmod;
00184
00185 typenameTypeIdAndMod(pstate, tc->typeName,
00186 &targetType, &targetTypmod);
00187
00188
00189
00190
00191
00192
00193
00194 targetType = getBaseTypeAndTypmod(targetType,
00195 &targetTypmod);
00196 elementType = get_element_type(targetType);
00197 if (OidIsValid(elementType))
00198 {
00199 tc = copyObject(tc);
00200 tc->arg = transformArrayExpr(pstate,
00201 (A_ArrayExpr *) tc->arg,
00202 targetType,
00203 elementType,
00204 targetTypmod);
00205 }
00206 }
00207
00208 result = transformTypeCast(pstate, tc);
00209 break;
00210 }
00211
00212 case T_CollateClause:
00213 result = transformCollateClause(pstate, (CollateClause *) expr);
00214 break;
00215
00216 case T_A_Expr:
00217 {
00218 A_Expr *a = (A_Expr *) expr;
00219
00220 switch (a->kind)
00221 {
00222 case AEXPR_OP:
00223 result = transformAExprOp(pstate, a);
00224 break;
00225 case AEXPR_AND:
00226 result = transformAExprAnd(pstate, a);
00227 break;
00228 case AEXPR_OR:
00229 result = transformAExprOr(pstate, a);
00230 break;
00231 case AEXPR_NOT:
00232 result = transformAExprNot(pstate, a);
00233 break;
00234 case AEXPR_OP_ANY:
00235 result = transformAExprOpAny(pstate, a);
00236 break;
00237 case AEXPR_OP_ALL:
00238 result = transformAExprOpAll(pstate, a);
00239 break;
00240 case AEXPR_DISTINCT:
00241 result = transformAExprDistinct(pstate, a);
00242 break;
00243 case AEXPR_NULLIF:
00244 result = transformAExprNullIf(pstate, a);
00245 break;
00246 case AEXPR_OF:
00247 result = transformAExprOf(pstate, a);
00248 break;
00249 case AEXPR_IN:
00250 result = transformAExprIn(pstate, a);
00251 break;
00252 default:
00253 elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
00254 result = NULL;
00255 break;
00256 }
00257 break;
00258 }
00259
00260 case T_FuncCall:
00261 result = transformFuncCall(pstate, (FuncCall *) expr);
00262 break;
00263
00264 case T_NamedArgExpr:
00265 {
00266 NamedArgExpr *na = (NamedArgExpr *) expr;
00267
00268 na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
00269 result = expr;
00270 break;
00271 }
00272
00273 case T_SubLink:
00274 result = transformSubLink(pstate, (SubLink *) expr);
00275 break;
00276
00277 case T_CaseExpr:
00278 result = transformCaseExpr(pstate, (CaseExpr *) expr);
00279 break;
00280
00281 case T_RowExpr:
00282 result = transformRowExpr(pstate, (RowExpr *) expr);
00283 break;
00284
00285 case T_CoalesceExpr:
00286 result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
00287 break;
00288
00289 case T_MinMaxExpr:
00290 result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
00291 break;
00292
00293 case T_XmlExpr:
00294 result = transformXmlExpr(pstate, (XmlExpr *) expr);
00295 break;
00296
00297 case T_XmlSerialize:
00298 result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
00299 break;
00300
00301 case T_NullTest:
00302 {
00303 NullTest *n = (NullTest *) expr;
00304
00305 n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
00306
00307 n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
00308 result = expr;
00309 break;
00310 }
00311
00312 case T_BooleanTest:
00313 result = transformBooleanTest(pstate, (BooleanTest *) expr);
00314 break;
00315
00316 case T_CurrentOfExpr:
00317 result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
00318 break;
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 case T_Var:
00329 case T_Const:
00330 case T_Param:
00331 case T_Aggref:
00332 case T_WindowFunc:
00333 case T_ArrayRef:
00334 case T_FuncExpr:
00335 case T_OpExpr:
00336 case T_DistinctExpr:
00337 case T_NullIfExpr:
00338 case T_ScalarArrayOpExpr:
00339 case T_BoolExpr:
00340 case T_FieldSelect:
00341 case T_FieldStore:
00342 case T_RelabelType:
00343 case T_CoerceViaIO:
00344 case T_ArrayCoerceExpr:
00345 case T_ConvertRowtypeExpr:
00346 case T_CollateExpr:
00347 case T_CaseTestExpr:
00348 case T_ArrayExpr:
00349 case T_CoerceToDomain:
00350 case T_CoerceToDomainValue:
00351 case T_SetToDefault:
00352 {
00353 result = (Node *) expr;
00354 break;
00355 }
00356
00357 default:
00358
00359 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
00360 result = NULL;
00361 break;
00362 }
00363
00364 return result;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 static void
00374 unknown_attribute(ParseState *pstate, Node *relref, char *attname,
00375 int location)
00376 {
00377 RangeTblEntry *rte;
00378
00379 if (IsA(relref, Var) &&
00380 ((Var *) relref)->varattno == InvalidAttrNumber)
00381 {
00382
00383 rte = GetRTEByRangeTablePosn(pstate,
00384 ((Var *) relref)->varno,
00385 ((Var *) relref)->varlevelsup);
00386 ereport(ERROR,
00387 (errcode(ERRCODE_UNDEFINED_COLUMN),
00388 errmsg("column %s.%s does not exist",
00389 rte->eref->aliasname, attname),
00390 parser_errposition(pstate, location)));
00391 }
00392 else
00393 {
00394
00395 Oid relTypeId = exprType(relref);
00396
00397 if (ISCOMPLEX(relTypeId))
00398 ereport(ERROR,
00399 (errcode(ERRCODE_UNDEFINED_COLUMN),
00400 errmsg("column \"%s\" not found in data type %s",
00401 attname, format_type_be(relTypeId)),
00402 parser_errposition(pstate, location)));
00403 else if (relTypeId == RECORDOID)
00404 ereport(ERROR,
00405 (errcode(ERRCODE_UNDEFINED_COLUMN),
00406 errmsg("could not identify column \"%s\" in record data type",
00407 attname),
00408 parser_errposition(pstate, location)));
00409 else
00410 ereport(ERROR,
00411 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
00412 errmsg("column notation .%s applied to type %s, "
00413 "which is not a composite type",
00414 attname, format_type_be(relTypeId)),
00415 parser_errposition(pstate, location)));
00416 }
00417 }
00418
00419 static Node *
00420 transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
00421 {
00422 Node *result = basenode;
00423 List *subscripts = NIL;
00424 int location = exprLocation(basenode);
00425 ListCell *i;
00426
00427
00428
00429
00430
00431
00432 foreach(i, indirection)
00433 {
00434 Node *n = lfirst(i);
00435
00436 if (IsA(n, A_Indices))
00437 subscripts = lappend(subscripts, n);
00438 else if (IsA(n, A_Star))
00439 {
00440 ereport(ERROR,
00441 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00442 errmsg("row expansion via \"*\" is not supported here"),
00443 parser_errposition(pstate, location)));
00444 }
00445 else
00446 {
00447 Node *newresult;
00448
00449 Assert(IsA(n, String));
00450
00451
00452 if (subscripts)
00453 result = (Node *) transformArraySubscripts(pstate,
00454 result,
00455 exprType(result),
00456 InvalidOid,
00457 exprTypmod(result),
00458 subscripts,
00459 NULL);
00460 subscripts = NIL;
00461
00462 newresult = ParseFuncOrColumn(pstate,
00463 list_make1(n),
00464 list_make1(result),
00465 NIL, false, false, false,
00466 NULL, true, location);
00467 if (newresult == NULL)
00468 unknown_attribute(pstate, result, strVal(n), location);
00469 result = newresult;
00470 }
00471 }
00472
00473 if (subscripts)
00474 result = (Node *) transformArraySubscripts(pstate,
00475 result,
00476 exprType(result),
00477 InvalidOid,
00478 exprTypmod(result),
00479 subscripts,
00480 NULL);
00481
00482 return result;
00483 }
00484
00485
00486
00487
00488
00489
00490 static Node *
00491 transformColumnRef(ParseState *pstate, ColumnRef *cref)
00492 {
00493 Node *node = NULL;
00494 char *nspname = NULL;
00495 char *relname = NULL;
00496 char *colname = NULL;
00497 RangeTblEntry *rte;
00498 int levels_up;
00499 enum
00500 {
00501 CRERR_NO_COLUMN,
00502 CRERR_NO_RTE,
00503 CRERR_WRONG_DB,
00504 CRERR_TOO_MANY
00505 } crerr = CRERR_NO_COLUMN;
00506
00507
00508
00509
00510
00511 if (pstate->p_pre_columnref_hook != NULL)
00512 {
00513 node = (*pstate->p_pre_columnref_hook) (pstate, cref);
00514 if (node != NULL)
00515 return node;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 switch (list_length(cref->fields))
00542 {
00543 case 1:
00544 {
00545 Node *field1 = (Node *) linitial(cref->fields);
00546
00547 Assert(IsA(field1, String));
00548 colname = strVal(field1);
00549
00550
00551 node = colNameToVar(pstate, colname, false, cref->location);
00552
00553 if (node == NULL)
00554 {
00555
00556
00557
00558
00559
00560
00561
00562
00563 if (pstate->p_value_substitute != NULL &&
00564 strcmp(colname, "value") == 0)
00565 {
00566 node = (Node *) copyObject(pstate->p_value_substitute);
00567
00568
00569
00570
00571
00572
00573 if (IsA(node, CoerceToDomainValue))
00574 ((CoerceToDomainValue *) node)->location = cref->location;
00575 break;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 rte = refnameRangeTblEntry(pstate, NULL, colname,
00588 cref->location,
00589 &levels_up);
00590 if (rte)
00591 node = transformWholeRowRef(pstate, rte,
00592 cref->location);
00593 }
00594 break;
00595 }
00596 case 2:
00597 {
00598 Node *field1 = (Node *) linitial(cref->fields);
00599 Node *field2 = (Node *) lsecond(cref->fields);
00600
00601 Assert(IsA(field1, String));
00602 relname = strVal(field1);
00603
00604
00605 rte = refnameRangeTblEntry(pstate, nspname, relname,
00606 cref->location,
00607 &levels_up);
00608 if (rte == NULL)
00609 {
00610 crerr = CRERR_NO_RTE;
00611 break;
00612 }
00613
00614
00615 if (IsA(field2, A_Star))
00616 {
00617 node = transformWholeRowRef(pstate, rte, cref->location);
00618 break;
00619 }
00620
00621 Assert(IsA(field2, String));
00622 colname = strVal(field2);
00623
00624
00625 node = scanRTEForColumn(pstate, rte, colname, cref->location);
00626 if (node == NULL)
00627 {
00628
00629 node = transformWholeRowRef(pstate, rte, cref->location);
00630 node = ParseFuncOrColumn(pstate,
00631 list_make1(makeString(colname)),
00632 list_make1(node),
00633 NIL, false, false, false,
00634 NULL, true, cref->location);
00635 }
00636 break;
00637 }
00638 case 3:
00639 {
00640 Node *field1 = (Node *) linitial(cref->fields);
00641 Node *field2 = (Node *) lsecond(cref->fields);
00642 Node *field3 = (Node *) lthird(cref->fields);
00643
00644 Assert(IsA(field1, String));
00645 nspname = strVal(field1);
00646 Assert(IsA(field2, String));
00647 relname = strVal(field2);
00648
00649
00650 rte = refnameRangeTblEntry(pstate, nspname, relname,
00651 cref->location,
00652 &levels_up);
00653 if (rte == NULL)
00654 {
00655 crerr = CRERR_NO_RTE;
00656 break;
00657 }
00658
00659
00660 if (IsA(field3, A_Star))
00661 {
00662 node = transformWholeRowRef(pstate, rte, cref->location);
00663 break;
00664 }
00665
00666 Assert(IsA(field3, String));
00667 colname = strVal(field3);
00668
00669
00670 node = scanRTEForColumn(pstate, rte, colname, cref->location);
00671 if (node == NULL)
00672 {
00673
00674 node = transformWholeRowRef(pstate, rte, cref->location);
00675 node = ParseFuncOrColumn(pstate,
00676 list_make1(makeString(colname)),
00677 list_make1(node),
00678 NIL, false, false, false,
00679 NULL, true, cref->location);
00680 }
00681 break;
00682 }
00683 case 4:
00684 {
00685 Node *field1 = (Node *) linitial(cref->fields);
00686 Node *field2 = (Node *) lsecond(cref->fields);
00687 Node *field3 = (Node *) lthird(cref->fields);
00688 Node *field4 = (Node *) lfourth(cref->fields);
00689 char *catname;
00690
00691 Assert(IsA(field1, String));
00692 catname = strVal(field1);
00693 Assert(IsA(field2, String));
00694 nspname = strVal(field2);
00695 Assert(IsA(field3, String));
00696 relname = strVal(field3);
00697
00698
00699
00700
00701 if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
00702 {
00703 crerr = CRERR_WRONG_DB;
00704 break;
00705 }
00706
00707
00708 rte = refnameRangeTblEntry(pstate, nspname, relname,
00709 cref->location,
00710 &levels_up);
00711 if (rte == NULL)
00712 {
00713 crerr = CRERR_NO_RTE;
00714 break;
00715 }
00716
00717
00718 if (IsA(field4, A_Star))
00719 {
00720 node = transformWholeRowRef(pstate, rte, cref->location);
00721 break;
00722 }
00723
00724 Assert(IsA(field4, String));
00725 colname = strVal(field4);
00726
00727
00728 node = scanRTEForColumn(pstate, rte, colname, cref->location);
00729 if (node == NULL)
00730 {
00731
00732 node = transformWholeRowRef(pstate, rte, cref->location);
00733 node = ParseFuncOrColumn(pstate,
00734 list_make1(makeString(colname)),
00735 list_make1(node),
00736 NIL, false, false, false,
00737 NULL, true, cref->location);
00738 }
00739 break;
00740 }
00741 default:
00742 crerr = CRERR_TOO_MANY;
00743 break;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 if (pstate->p_post_columnref_hook != NULL)
00756 {
00757 Node *hookresult;
00758
00759 hookresult = (*pstate->p_post_columnref_hook) (pstate, cref, node);
00760 if (node == NULL)
00761 node = hookresult;
00762 else if (hookresult != NULL)
00763 ereport(ERROR,
00764 (errcode(ERRCODE_AMBIGUOUS_COLUMN),
00765 errmsg("column reference \"%s\" is ambiguous",
00766 NameListToString(cref->fields)),
00767 parser_errposition(pstate, cref->location)));
00768 }
00769
00770
00771
00772
00773 if (node == NULL)
00774 {
00775 switch (crerr)
00776 {
00777 case CRERR_NO_COLUMN:
00778 errorMissingColumn(pstate, relname, colname, cref->location);
00779 break;
00780 case CRERR_NO_RTE:
00781 errorMissingRTE(pstate, makeRangeVar(nspname, relname,
00782 cref->location));
00783 break;
00784 case CRERR_WRONG_DB:
00785 ereport(ERROR,
00786 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00787 errmsg("cross-database references are not implemented: %s",
00788 NameListToString(cref->fields)),
00789 parser_errposition(pstate, cref->location)));
00790 break;
00791 case CRERR_TOO_MANY:
00792 ereport(ERROR,
00793 (errcode(ERRCODE_SYNTAX_ERROR),
00794 errmsg("improper qualified name (too many dotted names): %s",
00795 NameListToString(cref->fields)),
00796 parser_errposition(pstate, cref->location)));
00797 break;
00798 }
00799 }
00800
00801 return node;
00802 }
00803
00804 static Node *
00805 transformParamRef(ParseState *pstate, ParamRef *pref)
00806 {
00807 Node *result;
00808
00809
00810
00811
00812
00813 if (pstate->p_paramref_hook != NULL)
00814 result = (*pstate->p_paramref_hook) (pstate, pref);
00815 else
00816 result = NULL;
00817
00818 if (result == NULL)
00819 ereport(ERROR,
00820 (errcode(ERRCODE_UNDEFINED_PARAMETER),
00821 errmsg("there is no parameter $%d", pref->number),
00822 parser_errposition(pstate, pref->location)));
00823
00824 return result;
00825 }
00826
00827
00828 static bool
00829 exprIsNullConstant(Node *arg)
00830 {
00831 if (arg && IsA(arg, A_Const))
00832 {
00833 A_Const *con = (A_Const *) arg;
00834
00835 if (con->val.type == T_Null)
00836 return true;
00837 }
00838 return false;
00839 }
00840
00841 static Node *
00842 transformAExprOp(ParseState *pstate, A_Expr *a)
00843 {
00844 Node *lexpr = a->lexpr;
00845 Node *rexpr = a->rexpr;
00846 Node *result;
00847
00848
00849
00850
00851
00852
00853
00854
00855 if (Transform_null_equals &&
00856 list_length(a->name) == 1 &&
00857 strcmp(strVal(linitial(a->name)), "=") == 0 &&
00858 (exprIsNullConstant(lexpr) || exprIsNullConstant(rexpr)) &&
00859 (!IsA(lexpr, CaseTestExpr) &&!IsA(rexpr, CaseTestExpr)))
00860 {
00861 NullTest *n = makeNode(NullTest);
00862
00863 n->nulltesttype = IS_NULL;
00864
00865 if (exprIsNullConstant(lexpr))
00866 n->arg = (Expr *) rexpr;
00867 else
00868 n->arg = (Expr *) lexpr;
00869
00870 result = transformExprRecurse(pstate, (Node *) n);
00871 }
00872 else if (lexpr && IsA(lexpr, RowExpr) &&
00873 rexpr && IsA(rexpr, SubLink) &&
00874 ((SubLink *) rexpr)->subLinkType == EXPR_SUBLINK)
00875 {
00876
00877
00878
00879
00880
00881 SubLink *s = (SubLink *) rexpr;
00882
00883 s->subLinkType = ROWCOMPARE_SUBLINK;
00884 s->testexpr = lexpr;
00885 s->operName = a->name;
00886 s->location = a->location;
00887 result = transformExprRecurse(pstate, (Node *) s);
00888 }
00889 else if (lexpr && IsA(lexpr, RowExpr) &&
00890 rexpr && IsA(rexpr, RowExpr))
00891 {
00892
00893 lexpr = transformExprRecurse(pstate, lexpr);
00894 rexpr = transformExprRecurse(pstate, rexpr);
00895 Assert(IsA(lexpr, RowExpr));
00896 Assert(IsA(rexpr, RowExpr));
00897
00898 result = make_row_comparison_op(pstate,
00899 a->name,
00900 ((RowExpr *) lexpr)->args,
00901 ((RowExpr *) rexpr)->args,
00902 a->location);
00903 }
00904 else
00905 {
00906
00907 lexpr = transformExprRecurse(pstate, lexpr);
00908 rexpr = transformExprRecurse(pstate, rexpr);
00909
00910 result = (Node *) make_op(pstate,
00911 a->name,
00912 lexpr,
00913 rexpr,
00914 a->location);
00915 }
00916
00917 return result;
00918 }
00919
00920 static Node *
00921 transformAExprAnd(ParseState *pstate, A_Expr *a)
00922 {
00923 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
00924 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
00925
00926 lexpr = coerce_to_boolean(pstate, lexpr, "AND");
00927 rexpr = coerce_to_boolean(pstate, rexpr, "AND");
00928
00929 return (Node *) makeBoolExpr(AND_EXPR,
00930 list_make2(lexpr, rexpr),
00931 a->location);
00932 }
00933
00934 static Node *
00935 transformAExprOr(ParseState *pstate, A_Expr *a)
00936 {
00937 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
00938 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
00939
00940 lexpr = coerce_to_boolean(pstate, lexpr, "OR");
00941 rexpr = coerce_to_boolean(pstate, rexpr, "OR");
00942
00943 return (Node *) makeBoolExpr(OR_EXPR,
00944 list_make2(lexpr, rexpr),
00945 a->location);
00946 }
00947
00948 static Node *
00949 transformAExprNot(ParseState *pstate, A_Expr *a)
00950 {
00951 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
00952
00953 rexpr = coerce_to_boolean(pstate, rexpr, "NOT");
00954
00955 return (Node *) makeBoolExpr(NOT_EXPR,
00956 list_make1(rexpr),
00957 a->location);
00958 }
00959
00960 static Node *
00961 transformAExprOpAny(ParseState *pstate, A_Expr *a)
00962 {
00963 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
00964 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
00965
00966 return (Node *) make_scalar_array_op(pstate,
00967 a->name,
00968 true,
00969 lexpr,
00970 rexpr,
00971 a->location);
00972 }
00973
00974 static Node *
00975 transformAExprOpAll(ParseState *pstate, A_Expr *a)
00976 {
00977 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
00978 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
00979
00980 return (Node *) make_scalar_array_op(pstate,
00981 a->name,
00982 false,
00983 lexpr,
00984 rexpr,
00985 a->location);
00986 }
00987
00988 static Node *
00989 transformAExprDistinct(ParseState *pstate, A_Expr *a)
00990 {
00991 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
00992 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
00993
00994 if (lexpr && IsA(lexpr, RowExpr) &&
00995 rexpr && IsA(rexpr, RowExpr))
00996 {
00997
00998 return make_row_distinct_op(pstate, a->name,
00999 (RowExpr *) lexpr,
01000 (RowExpr *) rexpr,
01001 a->location);
01002 }
01003 else
01004 {
01005
01006 return (Node *) make_distinct_op(pstate,
01007 a->name,
01008 lexpr,
01009 rexpr,
01010 a->location);
01011 }
01012 }
01013
01014 static Node *
01015 transformAExprNullIf(ParseState *pstate, A_Expr *a)
01016 {
01017 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
01018 Node *rexpr = transformExprRecurse(pstate, a->rexpr);
01019 OpExpr *result;
01020
01021 result = (OpExpr *) make_op(pstate,
01022 a->name,
01023 lexpr,
01024 rexpr,
01025 a->location);
01026
01027
01028
01029
01030 if (result->opresulttype != BOOLOID)
01031 ereport(ERROR,
01032 (errcode(ERRCODE_DATATYPE_MISMATCH),
01033 errmsg("NULLIF requires = operator to yield boolean"),
01034 parser_errposition(pstate, a->location)));
01035
01036
01037
01038
01039 result->opresulttype = exprType((Node *) linitial(result->args));
01040
01041
01042
01043
01044 NodeSetTag(result, T_NullIfExpr);
01045
01046 return (Node *) result;
01047 }
01048
01049 static Node *
01050 transformAExprOf(ParseState *pstate, A_Expr *a)
01051 {
01052
01053
01054
01055
01056 Node *lexpr = transformExprRecurse(pstate, a->lexpr);
01057 Const *result;
01058 ListCell *telem;
01059 Oid ltype,
01060 rtype;
01061 bool matched = false;
01062
01063 ltype = exprType(lexpr);
01064 foreach(telem, (List *) a->rexpr)
01065 {
01066 rtype = typenameTypeId(pstate, lfirst(telem));
01067 matched = (rtype == ltype);
01068 if (matched)
01069 break;
01070 }
01071
01072
01073
01074
01075
01076 if (strcmp(strVal(linitial(a->name)), "<>") == 0)
01077 matched = (!matched);
01078
01079 result = (Const *) makeBoolConst(matched, false);
01080
01081
01082 result->location = exprLocation((Node *) a);
01083
01084 return (Node *) result;
01085 }
01086
01087 static Node *
01088 transformAExprIn(ParseState *pstate, A_Expr *a)
01089 {
01090 Node *result = NULL;
01091 Node *lexpr;
01092 List *rexprs;
01093 List *rvars;
01094 List *rnonvars;
01095 bool useOr;
01096 bool haveRowExpr;
01097 ListCell *l;
01098
01099
01100
01101
01102 if (strcmp(strVal(linitial(a->name)), "<>") == 0)
01103 useOr = false;
01104 else
01105 useOr = true;
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119 lexpr = transformExprRecurse(pstate, a->lexpr);
01120 haveRowExpr = (lexpr && IsA(lexpr, RowExpr));
01121 rexprs = rvars = rnonvars = NIL;
01122 foreach(l, (List *) a->rexpr)
01123 {
01124 Node *rexpr = transformExprRecurse(pstate, lfirst(l));
01125
01126 haveRowExpr |= (rexpr && IsA(rexpr, RowExpr));
01127 rexprs = lappend(rexprs, rexpr);
01128 if (contain_vars_of_level(rexpr, 0))
01129 rvars = lappend(rvars, rexpr);
01130 else
01131 rnonvars = lappend(rnonvars, rexpr);
01132 }
01133
01134
01135
01136
01137
01138 if (!haveRowExpr && list_length(rnonvars) > 1)
01139 {
01140 List *allexprs;
01141 Oid scalar_type;
01142 Oid array_type;
01143
01144
01145
01146
01147
01148
01149
01150
01151 allexprs = list_concat(list_make1(lexpr), rnonvars);
01152 scalar_type = select_common_type(pstate, allexprs, NULL, NULL);
01153
01154
01155 if (OidIsValid(scalar_type))
01156 array_type = get_array_type(scalar_type);
01157 else
01158 array_type = InvalidOid;
01159 if (array_type != InvalidOid)
01160 {
01161
01162
01163
01164
01165 List *aexprs;
01166 ArrayExpr *newa;
01167
01168 aexprs = NIL;
01169 foreach(l, rnonvars)
01170 {
01171 Node *rexpr = (Node *) lfirst(l);
01172
01173 rexpr = coerce_to_common_type(pstate, rexpr,
01174 scalar_type,
01175 "IN");
01176 aexprs = lappend(aexprs, rexpr);
01177 }
01178 newa = makeNode(ArrayExpr);
01179 newa->array_typeid = array_type;
01180
01181 newa->element_typeid = scalar_type;
01182 newa->elements = aexprs;
01183 newa->multidims = false;
01184 newa->location = -1;
01185
01186 result = (Node *) make_scalar_array_op(pstate,
01187 a->name,
01188 useOr,
01189 lexpr,
01190 (Node *) newa,
01191 a->location);
01192
01193
01194 rexprs = rvars;
01195 }
01196 }
01197
01198
01199
01200
01201 foreach(l, rexprs)
01202 {
01203 Node *rexpr = (Node *) lfirst(l);
01204 Node *cmp;
01205
01206 if (haveRowExpr)
01207 {
01208 if (!IsA(lexpr, RowExpr) ||
01209 !IsA(rexpr, RowExpr))
01210 ereport(ERROR,
01211 (errcode(ERRCODE_SYNTAX_ERROR),
01212 errmsg("arguments of row IN must all be row expressions"),
01213 parser_errposition(pstate, a->location)));
01214 cmp = make_row_comparison_op(pstate,
01215 a->name,
01216 (List *) copyObject(((RowExpr *) lexpr)->args),
01217 ((RowExpr *) rexpr)->args,
01218 a->location);
01219 }
01220 else
01221 cmp = (Node *) make_op(pstate,
01222 a->name,
01223 copyObject(lexpr),
01224 rexpr,
01225 a->location);
01226
01227 cmp = coerce_to_boolean(pstate, cmp, "IN");
01228 if (result == NULL)
01229 result = cmp;
01230 else
01231 result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
01232 list_make2(result, cmp),
01233 a->location);
01234 }
01235
01236 return result;
01237 }
01238
01239 static Node *
01240 transformFuncCall(ParseState *pstate, FuncCall *fn)
01241 {
01242 List *targs;
01243 ListCell *args;
01244
01245
01246 targs = NIL;
01247 foreach(args, fn->args)
01248 {
01249 targs = lappend(targs, transformExprRecurse(pstate,
01250 (Node *) lfirst(args)));
01251 }
01252
01253
01254 return ParseFuncOrColumn(pstate,
01255 fn->funcname,
01256 targs,
01257 fn->agg_order,
01258 fn->agg_star,
01259 fn->agg_distinct,
01260 fn->func_variadic,
01261 fn->over,
01262 false,
01263 fn->location);
01264 }
01265
01266 static Node *
01267 transformCaseExpr(ParseState *pstate, CaseExpr *c)
01268 {
01269 CaseExpr *newc;
01270 Node *arg;
01271 CaseTestExpr *placeholder;
01272 List *newargs;
01273 List *resultexprs;
01274 ListCell *l;
01275 Node *defresult;
01276 Oid ptype;
01277
01278
01279 if (OidIsValid(c->casetype))
01280 return (Node *) c;
01281
01282 newc = makeNode(CaseExpr);
01283
01284
01285 arg = transformExprRecurse(pstate, (Node *) c->arg);
01286
01287
01288 if (arg)
01289 {
01290
01291
01292
01293
01294
01295
01296
01297 if (exprType(arg) == UNKNOWNOID)
01298 arg = coerce_to_common_type(pstate, arg, TEXTOID, "CASE");
01299
01300
01301
01302
01303
01304
01305
01306 assign_expr_collations(pstate, arg);
01307
01308 placeholder = makeNode(CaseTestExpr);
01309 placeholder->typeId = exprType(arg);
01310 placeholder->typeMod = exprTypmod(arg);
01311 placeholder->collation = exprCollation(arg);
01312 }
01313 else
01314 placeholder = NULL;
01315
01316 newc->arg = (Expr *) arg;
01317
01318
01319 newargs = NIL;
01320 resultexprs = NIL;
01321 foreach(l, c->args)
01322 {
01323 CaseWhen *w = (CaseWhen *) lfirst(l);
01324 CaseWhen *neww = makeNode(CaseWhen);
01325 Node *warg;
01326
01327 Assert(IsA(w, CaseWhen));
01328
01329 warg = (Node *) w->expr;
01330 if (placeholder)
01331 {
01332
01333 warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
01334 (Node *) placeholder,
01335 warg,
01336 w->location);
01337 }
01338 neww->expr = (Expr *) transformExprRecurse(pstate, warg);
01339
01340 neww->expr = (Expr *) coerce_to_boolean(pstate,
01341 (Node *) neww->expr,
01342 "CASE/WHEN");
01343
01344 warg = (Node *) w->result;
01345 neww->result = (Expr *) transformExprRecurse(pstate, warg);
01346 neww->location = w->location;
01347
01348 newargs = lappend(newargs, neww);
01349 resultexprs = lappend(resultexprs, neww->result);
01350 }
01351
01352 newc->args = newargs;
01353
01354
01355 defresult = (Node *) c->defresult;
01356 if (defresult == NULL)
01357 {
01358 A_Const *n = makeNode(A_Const);
01359
01360 n->val.type = T_Null;
01361 n->location = -1;
01362 defresult = (Node *) n;
01363 }
01364 newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
01365
01366
01367
01368
01369
01370
01371 resultexprs = lcons(newc->defresult, resultexprs);
01372
01373 ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
01374 Assert(OidIsValid(ptype));
01375 newc->casetype = ptype;
01376
01377
01378
01379 newc->defresult = (Expr *)
01380 coerce_to_common_type(pstate,
01381 (Node *) newc->defresult,
01382 ptype,
01383 "CASE/ELSE");
01384
01385
01386 foreach(l, newc->args)
01387 {
01388 CaseWhen *w = (CaseWhen *) lfirst(l);
01389
01390 w->result = (Expr *)
01391 coerce_to_common_type(pstate,
01392 (Node *) w->result,
01393 ptype,
01394 "CASE/WHEN");
01395 }
01396
01397 newc->location = c->location;
01398
01399 return (Node *) newc;
01400 }
01401
01402 static Node *
01403 transformSubLink(ParseState *pstate, SubLink *sublink)
01404 {
01405 Node *result = (Node *) sublink;
01406 Query *qtree;
01407 const char *err;
01408
01409
01410 if (IsA(sublink->subselect, Query))
01411 return result;
01412
01413
01414
01415
01416
01417
01418 err = NULL;
01419 switch (pstate->p_expr_kind)
01420 {
01421 case EXPR_KIND_NONE:
01422 Assert(false);
01423 break;
01424 case EXPR_KIND_OTHER:
01425
01426 break;
01427 case EXPR_KIND_JOIN_ON:
01428 case EXPR_KIND_JOIN_USING:
01429 case EXPR_KIND_FROM_SUBSELECT:
01430 case EXPR_KIND_FROM_FUNCTION:
01431 case EXPR_KIND_WHERE:
01432 case EXPR_KIND_HAVING:
01433 case EXPR_KIND_WINDOW_PARTITION:
01434 case EXPR_KIND_WINDOW_ORDER:
01435 case EXPR_KIND_WINDOW_FRAME_RANGE:
01436 case EXPR_KIND_WINDOW_FRAME_ROWS:
01437 case EXPR_KIND_SELECT_TARGET:
01438 case EXPR_KIND_INSERT_TARGET:
01439 case EXPR_KIND_UPDATE_SOURCE:
01440 case EXPR_KIND_UPDATE_TARGET:
01441 case EXPR_KIND_GROUP_BY:
01442 case EXPR_KIND_ORDER_BY:
01443 case EXPR_KIND_DISTINCT_ON:
01444 case EXPR_KIND_LIMIT:
01445 case EXPR_KIND_OFFSET:
01446 case EXPR_KIND_RETURNING:
01447 case EXPR_KIND_VALUES:
01448
01449 break;
01450 case EXPR_KIND_CHECK_CONSTRAINT:
01451 case EXPR_KIND_DOMAIN_CHECK:
01452 err = _("cannot use subquery in check constraint");
01453 break;
01454 case EXPR_KIND_COLUMN_DEFAULT:
01455 case EXPR_KIND_FUNCTION_DEFAULT:
01456 err = _("cannot use subquery in DEFAULT expression");
01457 break;
01458 case EXPR_KIND_INDEX_EXPRESSION:
01459 err = _("cannot use subquery in index expression");
01460 break;
01461 case EXPR_KIND_INDEX_PREDICATE:
01462 err = _("cannot use subquery in index predicate");
01463 break;
01464 case EXPR_KIND_ALTER_COL_TRANSFORM:
01465 err = _("cannot use subquery in transform expression");
01466 break;
01467 case EXPR_KIND_EXECUTE_PARAMETER:
01468 err = _("cannot use subquery in EXECUTE parameter");
01469 break;
01470 case EXPR_KIND_TRIGGER_WHEN:
01471 err = _("cannot use subquery in trigger WHEN condition");
01472 break;
01473
01474
01475
01476
01477
01478
01479
01480
01481 }
01482 if (err)
01483 ereport(ERROR,
01484 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01485 errmsg_internal("%s", err),
01486 parser_errposition(pstate, sublink->location)));
01487
01488 pstate->p_hasSubLinks = true;
01489
01490
01491
01492
01493 qtree = parse_sub_analyze(sublink->subselect, pstate, NULL, false);
01494
01495
01496
01497
01498
01499 if (!IsA(qtree, Query) ||
01500 qtree->commandType != CMD_SELECT ||
01501 qtree->utilityStmt != NULL)
01502 elog(ERROR, "unexpected non-SELECT command in SubLink");
01503
01504 sublink->subselect = (Node *) qtree;
01505
01506 if (sublink->subLinkType == EXISTS_SUBLINK)
01507 {
01508
01509
01510
01511
01512 sublink->testexpr = NULL;
01513 sublink->operName = NIL;
01514 }
01515 else if (sublink->subLinkType == EXPR_SUBLINK ||
01516 sublink->subLinkType == ARRAY_SUBLINK)
01517 {
01518 ListCell *tlist_item = list_head(qtree->targetList);
01519
01520
01521
01522
01523
01524 if (tlist_item == NULL ||
01525 ((TargetEntry *) lfirst(tlist_item))->resjunk)
01526 ereport(ERROR,
01527 (errcode(ERRCODE_SYNTAX_ERROR),
01528 errmsg("subquery must return a column"),
01529 parser_errposition(pstate, sublink->location)));
01530 while ((tlist_item = lnext(tlist_item)) != NULL)
01531 {
01532 if (!((TargetEntry *) lfirst(tlist_item))->resjunk)
01533 ereport(ERROR,
01534 (errcode(ERRCODE_SYNTAX_ERROR),
01535 errmsg("subquery must return only one column"),
01536 parser_errposition(pstate, sublink->location)));
01537 }
01538
01539
01540
01541
01542
01543 sublink->testexpr = NULL;
01544 sublink->operName = NIL;
01545 }
01546 else
01547 {
01548
01549 Node *lefthand;
01550 List *left_list;
01551 List *right_list;
01552 ListCell *l;
01553
01554
01555
01556
01557 lefthand = transformExprRecurse(pstate, sublink->testexpr);
01558 if (lefthand && IsA(lefthand, RowExpr))
01559 left_list = ((RowExpr *) lefthand)->args;
01560 else
01561 left_list = list_make1(lefthand);
01562
01563
01564
01565
01566
01567 right_list = NIL;
01568 foreach(l, qtree->targetList)
01569 {
01570 TargetEntry *tent = (TargetEntry *) lfirst(l);
01571 Param *param;
01572
01573 if (tent->resjunk)
01574 continue;
01575
01576 param = makeNode(Param);
01577 param->paramkind = PARAM_SUBLINK;
01578 param->paramid = tent->resno;
01579 param->paramtype = exprType((Node *) tent->expr);
01580 param->paramtypmod = exprTypmod((Node *) tent->expr);
01581 param->paramcollid = exprCollation((Node *) tent->expr);
01582 param->location = -1;
01583
01584 right_list = lappend(right_list, param);
01585 }
01586
01587
01588
01589
01590
01591
01592 if (list_length(left_list) < list_length(right_list))
01593 ereport(ERROR,
01594 (errcode(ERRCODE_SYNTAX_ERROR),
01595 errmsg("subquery has too many columns"),
01596 parser_errposition(pstate, sublink->location)));
01597 if (list_length(left_list) > list_length(right_list))
01598 ereport(ERROR,
01599 (errcode(ERRCODE_SYNTAX_ERROR),
01600 errmsg("subquery has too few columns"),
01601 parser_errposition(pstate, sublink->location)));
01602
01603
01604
01605
01606
01607 sublink->testexpr = make_row_comparison_op(pstate,
01608 sublink->operName,
01609 left_list,
01610 right_list,
01611 sublink->location);
01612 }
01613
01614 return result;
01615 }
01616
01617
01618
01619
01620
01621
01622
01623
01624 static Node *
01625 transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
01626 Oid array_type, Oid element_type, int32 typmod)
01627 {
01628 ArrayExpr *newa = makeNode(ArrayExpr);
01629 List *newelems = NIL;
01630 List *newcoercedelems = NIL;
01631 ListCell *element;
01632 Oid coerce_type;
01633 bool coerce_hard;
01634
01635
01636
01637
01638
01639
01640
01641 newa->multidims = false;
01642 foreach(element, a->elements)
01643 {
01644 Node *e = (Node *) lfirst(element);
01645 Node *newe;
01646
01647
01648
01649
01650
01651 if (IsA(e, A_ArrayExpr))
01652 {
01653 newe = transformArrayExpr(pstate,
01654 (A_ArrayExpr *) e,
01655 array_type,
01656 element_type,
01657 typmod);
01658
01659 Assert(array_type == InvalidOid || array_type == exprType(newe));
01660 newa->multidims = true;
01661 }
01662 else
01663 {
01664 newe = transformExprRecurse(pstate, e);
01665
01666
01667
01668
01669
01670 if (!newa->multidims && type_is_array(exprType(newe)))
01671 newa->multidims = true;
01672 }
01673
01674 newelems = lappend(newelems, newe);
01675 }
01676
01677
01678
01679
01680
01681
01682
01683 if (OidIsValid(array_type))
01684 {
01685
01686 Assert(OidIsValid(element_type));
01687 coerce_type = (newa->multidims ? array_type : element_type);
01688 coerce_hard = true;
01689 }
01690 else
01691 {
01692
01693 if (newelems == NIL)
01694 ereport(ERROR,
01695 (errcode(ERRCODE_INDETERMINATE_DATATYPE),
01696 errmsg("cannot determine type of empty array"),
01697 errhint("Explicitly cast to the desired type, "
01698 "for example ARRAY[]::integer[]."),
01699 parser_errposition(pstate, a->location)));
01700
01701
01702 coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
01703
01704 if (newa->multidims)
01705 {
01706 array_type = coerce_type;
01707 element_type = get_element_type(array_type);
01708 if (!OidIsValid(element_type))
01709 ereport(ERROR,
01710 (errcode(ERRCODE_UNDEFINED_OBJECT),
01711 errmsg("could not find element type for data type %s",
01712 format_type_be(array_type)),
01713 parser_errposition(pstate, a->location)));
01714 }
01715 else
01716 {
01717 element_type = coerce_type;
01718 array_type = get_array_type(element_type);
01719 if (!OidIsValid(array_type))
01720 ereport(ERROR,
01721 (errcode(ERRCODE_UNDEFINED_OBJECT),
01722 errmsg("could not find array type for data type %s",
01723 format_type_be(element_type)),
01724 parser_errposition(pstate, a->location)));
01725 }
01726 coerce_hard = false;
01727 }
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739 foreach(element, newelems)
01740 {
01741 Node *e = (Node *) lfirst(element);
01742 Node *newe;
01743
01744 if (coerce_hard)
01745 {
01746 newe = coerce_to_target_type(pstate, e,
01747 exprType(e),
01748 coerce_type,
01749 typmod,
01750 COERCION_EXPLICIT,
01751 COERCE_EXPLICIT_CAST,
01752 -1);
01753 if (newe == NULL)
01754 ereport(ERROR,
01755 (errcode(ERRCODE_CANNOT_COERCE),
01756 errmsg("cannot cast type %s to %s",
01757 format_type_be(exprType(e)),
01758 format_type_be(coerce_type)),
01759 parser_errposition(pstate, exprLocation(e))));
01760 }
01761 else
01762 newe = coerce_to_common_type(pstate, e,
01763 coerce_type,
01764 "ARRAY");
01765 newcoercedelems = lappend(newcoercedelems, newe);
01766 }
01767
01768 newa->array_typeid = array_type;
01769
01770 newa->element_typeid = element_type;
01771 newa->elements = newcoercedelems;
01772 newa->location = a->location;
01773
01774 return (Node *) newa;
01775 }
01776
01777 static Node *
01778 transformRowExpr(ParseState *pstate, RowExpr *r)
01779 {
01780 RowExpr *newr;
01781 char fname[16];
01782 int fnum;
01783 ListCell *lc;
01784
01785
01786 if (OidIsValid(r->row_typeid))
01787 return (Node *) r;
01788
01789 newr = makeNode(RowExpr);
01790
01791
01792 newr->args = transformExpressionList(pstate, r->args, pstate->p_expr_kind);
01793
01794
01795 newr->row_typeid = RECORDOID;
01796 newr->row_format = COERCE_IMPLICIT_CAST;
01797
01798
01799 newr->colnames = NIL;
01800 fnum = 1;
01801 foreach(lc, newr->args)
01802 {
01803 snprintf(fname, sizeof(fname), "f%d", fnum++);
01804 newr->colnames = lappend(newr->colnames, makeString(pstrdup(fname)));
01805 }
01806
01807 newr->location = r->location;
01808
01809 return (Node *) newr;
01810 }
01811
01812 static Node *
01813 transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
01814 {
01815 CoalesceExpr *newc = makeNode(CoalesceExpr);
01816 List *newargs = NIL;
01817 List *newcoercedargs = NIL;
01818 ListCell *args;
01819
01820 foreach(args, c->args)
01821 {
01822 Node *e = (Node *) lfirst(args);
01823 Node *newe;
01824
01825 newe = transformExprRecurse(pstate, e);
01826 newargs = lappend(newargs, newe);
01827 }
01828
01829 newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
01830
01831
01832
01833 foreach(args, newargs)
01834 {
01835 Node *e = (Node *) lfirst(args);
01836 Node *newe;
01837
01838 newe = coerce_to_common_type(pstate, e,
01839 newc->coalescetype,
01840 "COALESCE");
01841 newcoercedargs = lappend(newcoercedargs, newe);
01842 }
01843
01844 newc->args = newcoercedargs;
01845 newc->location = c->location;
01846 return (Node *) newc;
01847 }
01848
01849 static Node *
01850 transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
01851 {
01852 MinMaxExpr *newm = makeNode(MinMaxExpr);
01853 List *newargs = NIL;
01854 List *newcoercedargs = NIL;
01855 const char *funcname = (m->op == IS_GREATEST) ? "GREATEST" : "LEAST";
01856 ListCell *args;
01857
01858 newm->op = m->op;
01859 foreach(args, m->args)
01860 {
01861 Node *e = (Node *) lfirst(args);
01862 Node *newe;
01863
01864 newe = transformExprRecurse(pstate, e);
01865 newargs = lappend(newargs, newe);
01866 }
01867
01868 newm->minmaxtype = select_common_type(pstate, newargs, funcname, NULL);
01869
01870
01871
01872 foreach(args, newargs)
01873 {
01874 Node *e = (Node *) lfirst(args);
01875 Node *newe;
01876
01877 newe = coerce_to_common_type(pstate, e,
01878 newm->minmaxtype,
01879 funcname);
01880 newcoercedargs = lappend(newcoercedargs, newe);
01881 }
01882
01883 newm->args = newcoercedargs;
01884 newm->location = m->location;
01885 return (Node *) newm;
01886 }
01887
01888 static Node *
01889 transformXmlExpr(ParseState *pstate, XmlExpr *x)
01890 {
01891 XmlExpr *newx;
01892 ListCell *lc;
01893 int i;
01894
01895
01896 if (OidIsValid(x->type))
01897 return (Node *) x;
01898
01899 newx = makeNode(XmlExpr);
01900 newx->op = x->op;
01901 if (x->name)
01902 newx->name = map_sql_identifier_to_xml_name(x->name, false, false);
01903 else
01904 newx->name = NULL;
01905 newx->xmloption = x->xmloption;
01906 newx->type = XMLOID;
01907 newx->typmod = -1;
01908 newx->location = x->location;
01909
01910
01911
01912
01913
01914 newx->named_args = NIL;
01915 newx->arg_names = NIL;
01916
01917 foreach(lc, x->named_args)
01918 {
01919 ResTarget *r = (ResTarget *) lfirst(lc);
01920 Node *expr;
01921 char *argname;
01922
01923 Assert(IsA(r, ResTarget));
01924
01925 expr = transformExprRecurse(pstate, r->val);
01926
01927 if (r->name)
01928 argname = map_sql_identifier_to_xml_name(r->name, false, false);
01929 else if (IsA(r->val, ColumnRef))
01930 argname = map_sql_identifier_to_xml_name(FigureColname(r->val),
01931 true, false);
01932 else
01933 {
01934 ereport(ERROR,
01935 (errcode(ERRCODE_SYNTAX_ERROR),
01936 x->op == IS_XMLELEMENT
01937 ? errmsg("unnamed XML attribute value must be a column reference")
01938 : errmsg("unnamed XML element value must be a column reference"),
01939 parser_errposition(pstate, r->location)));
01940 argname = NULL;
01941 }
01942
01943
01944 if (x->op == IS_XMLELEMENT)
01945 {
01946 ListCell *lc2;
01947
01948 foreach(lc2, newx->arg_names)
01949 {
01950 if (strcmp(argname, strVal(lfirst(lc2))) == 0)
01951 ereport(ERROR,
01952 (errcode(ERRCODE_SYNTAX_ERROR),
01953 errmsg("XML attribute name \"%s\" appears more than once",
01954 argname),
01955 parser_errposition(pstate, r->location)));
01956 }
01957 }
01958
01959 newx->named_args = lappend(newx->named_args, expr);
01960 newx->arg_names = lappend(newx->arg_names, makeString(argname));
01961 }
01962
01963
01964 newx->args = NIL;
01965 i = 0;
01966 foreach(lc, x->args)
01967 {
01968 Node *e = (Node *) lfirst(lc);
01969 Node *newe;
01970
01971 newe = transformExprRecurse(pstate, e);
01972 switch (x->op)
01973 {
01974 case IS_XMLCONCAT:
01975 newe = coerce_to_specific_type(pstate, newe, XMLOID,
01976 "XMLCONCAT");
01977 break;
01978 case IS_XMLELEMENT:
01979
01980 break;
01981 case IS_XMLFOREST:
01982 newe = coerce_to_specific_type(pstate, newe, XMLOID,
01983 "XMLFOREST");
01984 break;
01985 case IS_XMLPARSE:
01986 if (i == 0)
01987 newe = coerce_to_specific_type(pstate, newe, TEXTOID,
01988 "XMLPARSE");
01989 else
01990 newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
01991 break;
01992 case IS_XMLPI:
01993 newe = coerce_to_specific_type(pstate, newe, TEXTOID,
01994 "XMLPI");
01995 break;
01996 case IS_XMLROOT:
01997 if (i == 0)
01998 newe = coerce_to_specific_type(pstate, newe, XMLOID,
01999 "XMLROOT");
02000 else if (i == 1)
02001 newe = coerce_to_specific_type(pstate, newe, TEXTOID,
02002 "XMLROOT");
02003 else
02004 newe = coerce_to_specific_type(pstate, newe, INT4OID,
02005 "XMLROOT");
02006 break;
02007 case IS_XMLSERIALIZE:
02008
02009 Assert(false);
02010 break;
02011 case IS_DOCUMENT:
02012 newe = coerce_to_specific_type(pstate, newe, XMLOID,
02013 "IS DOCUMENT");
02014 break;
02015 }
02016 newx->args = lappend(newx->args, newe);
02017 i++;
02018 }
02019
02020 return (Node *) newx;
02021 }
02022
02023 static Node *
02024 transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
02025 {
02026 Node *result;
02027 XmlExpr *xexpr;
02028 Oid targetType;
02029 int32 targetTypmod;
02030
02031 xexpr = makeNode(XmlExpr);
02032 xexpr->op = IS_XMLSERIALIZE;
02033 xexpr->args = list_make1(coerce_to_specific_type(pstate,
02034 transformExprRecurse(pstate, xs->expr),
02035 XMLOID,
02036 "XMLSERIALIZE"));
02037
02038 typenameTypeIdAndMod(pstate, xs->typeName, &targetType, &targetTypmod);
02039
02040 xexpr->xmloption = xs->xmloption;
02041 xexpr->location = xs->location;
02042
02043 xexpr->type = targetType;
02044 xexpr->typmod = targetTypmod;
02045
02046
02047
02048
02049
02050
02051
02052 result = coerce_to_target_type(pstate, (Node *) xexpr,
02053 TEXTOID, targetType, targetTypmod,
02054 COERCION_IMPLICIT,
02055 COERCE_IMPLICIT_CAST,
02056 -1);
02057 if (result == NULL)
02058 ereport(ERROR,
02059 (errcode(ERRCODE_CANNOT_COERCE),
02060 errmsg("cannot cast XMLSERIALIZE result to %s",
02061 format_type_be(targetType)),
02062 parser_errposition(pstate, xexpr->location)));
02063 return result;
02064 }
02065
02066 static Node *
02067 transformBooleanTest(ParseState *pstate, BooleanTest *b)
02068 {
02069 const char *clausename;
02070
02071 switch (b->booltesttype)
02072 {
02073 case IS_TRUE:
02074 clausename = "IS TRUE";
02075 break;
02076 case IS_NOT_TRUE:
02077 clausename = "IS NOT TRUE";
02078 break;
02079 case IS_FALSE:
02080 clausename = "IS FALSE";
02081 break;
02082 case IS_NOT_FALSE:
02083 clausename = "IS NOT FALSE";
02084 break;
02085 case IS_UNKNOWN:
02086 clausename = "IS UNKNOWN";
02087 break;
02088 case IS_NOT_UNKNOWN:
02089 clausename = "IS NOT UNKNOWN";
02090 break;
02091 default:
02092 elog(ERROR, "unrecognized booltesttype: %d",
02093 (int) b->booltesttype);
02094 clausename = NULL;
02095 }
02096
02097 b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
02098
02099 b->arg = (Expr *) coerce_to_boolean(pstate,
02100 (Node *) b->arg,
02101 clausename);
02102
02103 return (Node *) b;
02104 }
02105
02106 static Node *
02107 transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
02108 {
02109 int sublevels_up;
02110
02111
02112 Assert(pstate->p_target_rangetblentry != NULL);
02113 cexpr->cvarno = RTERangeTablePosn(pstate,
02114 pstate->p_target_rangetblentry,
02115 &sublevels_up);
02116 Assert(sublevels_up == 0);
02117
02118
02119
02120
02121
02122
02123 if (cexpr->cursor_name != NULL)
02124 {
02125 ColumnRef *cref = makeNode(ColumnRef);
02126 Node *node = NULL;
02127
02128
02129 cref->fields = list_make1(makeString(cexpr->cursor_name));
02130 cref->location = -1;
02131
02132
02133 if (pstate->p_pre_columnref_hook != NULL)
02134 node = (*pstate->p_pre_columnref_hook) (pstate, cref);
02135 if (node == NULL && pstate->p_post_columnref_hook != NULL)
02136 node = (*pstate->p_post_columnref_hook) (pstate, cref, NULL);
02137
02138
02139
02140
02141
02142
02143 if (node != NULL && IsA(node, Param))
02144 {
02145 Param *p = (Param *) node;
02146
02147 if (p->paramkind == PARAM_EXTERN &&
02148 p->paramtype == REFCURSOROID)
02149 {
02150
02151 cexpr->cursor_name = NULL;
02152 cexpr->cursor_param = p->paramid;
02153 }
02154 }
02155 }
02156
02157 return (Node *) cexpr;
02158 }
02159
02160
02161
02162
02163 static Node *
02164 transformWholeRowRef(ParseState *pstate, RangeTblEntry *rte, int location)
02165 {
02166 Var *result;
02167 int vnum;
02168 int sublevels_up;
02169
02170
02171 vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181 result = makeWholeRowVar(rte, vnum, sublevels_up, true);
02182
02183
02184 result->location = location;
02185
02186
02187 markVarForSelectPriv(pstate, result, rte);
02188
02189 return (Node *) result;
02190 }
02191
02192
02193
02194
02195
02196
02197
02198 static Node *
02199 transformTypeCast(ParseState *pstate, TypeCast *tc)
02200 {
02201 Node *result;
02202 Node *expr = transformExprRecurse(pstate, tc->arg);
02203 Oid inputType = exprType(expr);
02204 Oid targetType;
02205 int32 targetTypmod;
02206 int location;
02207
02208 typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
02209
02210 if (inputType == InvalidOid)
02211 return expr;
02212
02213
02214
02215
02216
02217
02218 location = tc->location;
02219 if (location < 0)
02220 location = tc->typeName->location;
02221
02222 result = coerce_to_target_type(pstate, expr, inputType,
02223 targetType, targetTypmod,
02224 COERCION_EXPLICIT,
02225 COERCE_EXPLICIT_CAST,
02226 location);
02227 if (result == NULL)
02228 ereport(ERROR,
02229 (errcode(ERRCODE_CANNOT_COERCE),
02230 errmsg("cannot cast type %s to %s",
02231 format_type_be(inputType),
02232 format_type_be(targetType)),
02233 parser_coercion_errposition(pstate, location, expr)));
02234
02235 return result;
02236 }
02237
02238
02239
02240
02241
02242
02243 static Node *
02244 transformCollateClause(ParseState *pstate, CollateClause *c)
02245 {
02246 CollateExpr *newc;
02247 Oid argtype;
02248
02249 newc = makeNode(CollateExpr);
02250 newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
02251
02252 argtype = exprType((Node *) newc->arg);
02253
02254
02255
02256
02257
02258 if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
02259 ereport(ERROR,
02260 (errcode(ERRCODE_DATATYPE_MISMATCH),
02261 errmsg("collations are not supported by type %s",
02262 format_type_be(argtype)),
02263 parser_errposition(pstate, c->location)));
02264
02265 newc->collOid = LookupCollation(pstate, c->collname, c->location);
02266 newc->location = c->location;
02267
02268 return (Node *) newc;
02269 }
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283 static Node *
02284 make_row_comparison_op(ParseState *pstate, List *opname,
02285 List *largs, List *rargs, int location)
02286 {
02287 RowCompareExpr *rcexpr;
02288 RowCompareType rctype;
02289 List *opexprs;
02290 List *opnos;
02291 List *opfamilies;
02292 ListCell *l,
02293 *r;
02294 List **opinfo_lists;
02295 Bitmapset *strats;
02296 int nopers;
02297 int i;
02298
02299 nopers = list_length(largs);
02300 if (nopers != list_length(rargs))
02301 ereport(ERROR,
02302 (errcode(ERRCODE_SYNTAX_ERROR),
02303 errmsg("unequal number of entries in row expressions"),
02304 parser_errposition(pstate, location)));
02305
02306
02307
02308
02309
02310 if (nopers == 0)
02311 ereport(ERROR,
02312 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02313 errmsg("cannot compare rows of zero length"),
02314 parser_errposition(pstate, location)));
02315
02316
02317
02318
02319
02320 opexprs = NIL;
02321 forboth(l, largs, r, rargs)
02322 {
02323 Node *larg = (Node *) lfirst(l);
02324 Node *rarg = (Node *) lfirst(r);
02325 OpExpr *cmp;
02326
02327 cmp = (OpExpr *) make_op(pstate, opname, larg, rarg, location);
02328 Assert(IsA(cmp, OpExpr));
02329
02330
02331
02332
02333
02334
02335 if (cmp->opresulttype != BOOLOID)
02336 ereport(ERROR,
02337 (errcode(ERRCODE_DATATYPE_MISMATCH),
02338 errmsg("row comparison operator must yield type boolean, "
02339 "not type %s",
02340 format_type_be(cmp->opresulttype)),
02341 parser_errposition(pstate, location)));
02342 if (expression_returns_set((Node *) cmp))
02343 ereport(ERROR,
02344 (errcode(ERRCODE_DATATYPE_MISMATCH),
02345 errmsg("row comparison operator must not return a set"),
02346 parser_errposition(pstate, location)));
02347 opexprs = lappend(opexprs, cmp);
02348 }
02349
02350
02351
02352
02353
02354
02355 if (nopers == 1)
02356 return (Node *) linitial(opexprs);
02357
02358
02359
02360
02361
02362
02363
02364 opinfo_lists = (List **) palloc(nopers * sizeof(List *));
02365 strats = NULL;
02366 i = 0;
02367 foreach(l, opexprs)
02368 {
02369 Oid opno = ((OpExpr *) lfirst(l))->opno;
02370 Bitmapset *this_strats;
02371 ListCell *j;
02372
02373 opinfo_lists[i] = get_op_btree_interpretation(opno);
02374
02375
02376
02377
02378
02379 this_strats = NULL;
02380 foreach(j, opinfo_lists[i])
02381 {
02382 OpBtreeInterpretation *opinfo = lfirst(j);
02383
02384 this_strats = bms_add_member(this_strats, opinfo->strategy);
02385 }
02386 if (i == 0)
02387 strats = this_strats;
02388 else
02389 strats = bms_int_members(strats, this_strats);
02390 i++;
02391 }
02392
02393
02394
02395
02396
02397
02398 i = bms_first_member(strats);
02399 if (i < 0)
02400 {
02401
02402 ereport(ERROR,
02403 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02404 errmsg("could not determine interpretation of row comparison operator %s",
02405 strVal(llast(opname))),
02406 errhint("Row comparison operators must be associated with btree operator families."),
02407 parser_errposition(pstate, location)));
02408 }
02409 rctype = (RowCompareType) i;
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419 if (rctype == ROWCOMPARE_EQ)
02420 return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
02421 if (rctype == ROWCOMPARE_NE)
02422 return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
02423
02424
02425
02426
02427
02428 opfamilies = NIL;
02429 for (i = 0; i < nopers; i++)
02430 {
02431 Oid opfamily = InvalidOid;
02432 ListCell *j;
02433
02434 foreach(j, opinfo_lists[i])
02435 {
02436 OpBtreeInterpretation *opinfo = lfirst(j);
02437
02438 if (opinfo->strategy == rctype)
02439 {
02440 opfamily = opinfo->opfamily_id;
02441 break;
02442 }
02443 }
02444 if (OidIsValid(opfamily))
02445 opfamilies = lappend_oid(opfamilies, opfamily);
02446 else
02447 ereport(ERROR,
02448 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02449 errmsg("could not determine interpretation of row comparison operator %s",
02450 strVal(llast(opname))),
02451 errdetail("There are multiple equally-plausible candidates."),
02452 parser_errposition(pstate, location)));
02453 }
02454
02455
02456
02457
02458
02459
02460
02461 opnos = NIL;
02462 largs = NIL;
02463 rargs = NIL;
02464 foreach(l, opexprs)
02465 {
02466 OpExpr *cmp = (OpExpr *) lfirst(l);
02467
02468 opnos = lappend_oid(opnos, cmp->opno);
02469 largs = lappend(largs, linitial(cmp->args));
02470 rargs = lappend(rargs, lsecond(cmp->args));
02471 }
02472
02473 rcexpr = makeNode(RowCompareExpr);
02474 rcexpr->rctype = rctype;
02475 rcexpr->opnos = opnos;
02476 rcexpr->opfamilies = opfamilies;
02477 rcexpr->inputcollids = NIL;
02478 rcexpr->largs = largs;
02479 rcexpr->rargs = rargs;
02480
02481 return (Node *) rcexpr;
02482 }
02483
02484
02485
02486
02487
02488
02489 static Node *
02490 make_row_distinct_op(ParseState *pstate, List *opname,
02491 RowExpr *lrow, RowExpr *rrow,
02492 int location)
02493 {
02494 Node *result = NULL;
02495 List *largs = lrow->args;
02496 List *rargs = rrow->args;
02497 ListCell *l,
02498 *r;
02499
02500 if (list_length(largs) != list_length(rargs))
02501 ereport(ERROR,
02502 (errcode(ERRCODE_SYNTAX_ERROR),
02503 errmsg("unequal number of entries in row expressions"),
02504 parser_errposition(pstate, location)));
02505
02506 forboth(l, largs, r, rargs)
02507 {
02508 Node *larg = (Node *) lfirst(l);
02509 Node *rarg = (Node *) lfirst(r);
02510 Node *cmp;
02511
02512 cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
02513 if (result == NULL)
02514 result = cmp;
02515 else
02516 result = (Node *) makeBoolExpr(OR_EXPR,
02517 list_make2(result, cmp),
02518 location);
02519 }
02520
02521 if (result == NULL)
02522 {
02523
02524 result = makeBoolConst(false, false);
02525 }
02526
02527 return result;
02528 }
02529
02530
02531
02532
02533 static Expr *
02534 make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
02535 int location)
02536 {
02537 Expr *result;
02538
02539 result = make_op(pstate, opname, ltree, rtree, location);
02540 if (((OpExpr *) result)->opresulttype != BOOLOID)
02541 ereport(ERROR,
02542 (errcode(ERRCODE_DATATYPE_MISMATCH),
02543 errmsg("IS DISTINCT FROM requires = operator to yield boolean"),
02544 parser_errposition(pstate, location)));
02545
02546
02547
02548
02549 NodeSetTag(result, T_DistinctExpr);
02550
02551 return result;
02552 }
02553
02554
02555
02556
02557
02558
02559
02560
02561 const char *
02562 ParseExprKindName(ParseExprKind exprKind)
02563 {
02564 switch (exprKind)
02565 {
02566 case EXPR_KIND_NONE:
02567 return "invalid expression context";
02568 case EXPR_KIND_OTHER:
02569 return "extension expression";
02570 case EXPR_KIND_JOIN_ON:
02571 return "JOIN/ON";
02572 case EXPR_KIND_JOIN_USING:
02573 return "JOIN/USING";
02574 case EXPR_KIND_FROM_SUBSELECT:
02575 return "sub-SELECT in FROM";
02576 case EXPR_KIND_FROM_FUNCTION:
02577 return "function in FROM";
02578 case EXPR_KIND_WHERE:
02579 return "WHERE";
02580 case EXPR_KIND_HAVING:
02581 return "HAVING";
02582 case EXPR_KIND_WINDOW_PARTITION:
02583 return "window PARTITION BY";
02584 case EXPR_KIND_WINDOW_ORDER:
02585 return "window ORDER BY";
02586 case EXPR_KIND_WINDOW_FRAME_RANGE:
02587 return "window RANGE";
02588 case EXPR_KIND_WINDOW_FRAME_ROWS:
02589 return "window ROWS";
02590 case EXPR_KIND_SELECT_TARGET:
02591 return "SELECT";
02592 case EXPR_KIND_INSERT_TARGET:
02593 return "INSERT";
02594 case EXPR_KIND_UPDATE_SOURCE:
02595 case EXPR_KIND_UPDATE_TARGET:
02596 return "UPDATE";
02597 case EXPR_KIND_GROUP_BY:
02598 return "GROUP BY";
02599 case EXPR_KIND_ORDER_BY:
02600 return "ORDER BY";
02601 case EXPR_KIND_DISTINCT_ON:
02602 return "DISTINCT ON";
02603 case EXPR_KIND_LIMIT:
02604 return "LIMIT";
02605 case EXPR_KIND_OFFSET:
02606 return "OFFSET";
02607 case EXPR_KIND_RETURNING:
02608 return "RETURNING";
02609 case EXPR_KIND_VALUES:
02610 return "VALUES";
02611 case EXPR_KIND_CHECK_CONSTRAINT:
02612 case EXPR_KIND_DOMAIN_CHECK:
02613 return "CHECK";
02614 case EXPR_KIND_COLUMN_DEFAULT:
02615 case EXPR_KIND_FUNCTION_DEFAULT:
02616 return "DEFAULT";
02617 case EXPR_KIND_INDEX_EXPRESSION:
02618 return "index expression";
02619 case EXPR_KIND_INDEX_PREDICATE:
02620 return "index predicate";
02621 case EXPR_KIND_ALTER_COL_TRANSFORM:
02622 return "USING";
02623 case EXPR_KIND_EXECUTE_PARAMETER:
02624 return "EXECUTE";
02625 case EXPR_KIND_TRIGGER_WHEN:
02626 return "WHEN";
02627
02628
02629
02630
02631
02632
02633
02634 }
02635 return "unrecognized expression kind";
02636 }