PostgreSQL Source Code  git master
parse_expr.c File Reference
#include "postgres.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "parser/analyze.h"
#include "parser/parse_agg.h"
#include "parser/parse_clause.h"
#include "parser/parse_coerce.h"
#include "parser/parse_collate.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/timestamp.h"
#include "utils/xml.h"
Include dependency graph for parse_expr.c:

Go to the source code of this file.

Functions

static NodetransformExprRecurse (ParseState *pstate, Node *expr)
 
static NodetransformParamRef (ParseState *pstate, ParamRef *pref)
 
static NodetransformAExprOp (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprOpAny (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprOpAll (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprDistinct (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprNullIf (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprIn (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprBetween (ParseState *pstate, A_Expr *a)
 
static NodetransformBoolExpr (ParseState *pstate, BoolExpr *a)
 
static NodetransformFuncCall (ParseState *pstate, FuncCall *fn)
 
static NodetransformMultiAssignRef (ParseState *pstate, MultiAssignRef *maref)
 
static NodetransformCaseExpr (ParseState *pstate, CaseExpr *c)
 
static NodetransformSubLink (ParseState *pstate, SubLink *sublink)
 
static NodetransformArrayExpr (ParseState *pstate, A_ArrayExpr *a, Oid array_type, Oid element_type, int32 typmod)
 
static NodetransformRowExpr (ParseState *pstate, RowExpr *r, bool allowDefault)
 
static NodetransformCoalesceExpr (ParseState *pstate, CoalesceExpr *c)
 
static NodetransformMinMaxExpr (ParseState *pstate, MinMaxExpr *m)
 
static NodetransformXmlExpr (ParseState *pstate, XmlExpr *x)
 
static NodetransformXmlSerialize (ParseState *pstate, XmlSerialize *xs)
 
static NodetransformBooleanTest (ParseState *pstate, BooleanTest *b)
 
static NodetransformCurrentOfExpr (ParseState *pstate, CurrentOfExpr *cexpr)
 
static NodetransformColumnRef (ParseState *pstate, ColumnRef *cref)
 
static NodetransformWholeRowRef (ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location)
 
static NodetransformIndirection (ParseState *pstate, A_Indirection *ind)
 
static NodetransformTypeCast (ParseState *pstate, TypeCast *tc)
 
static NodetransformCollateClause (ParseState *pstate, CollateClause *c)
 
static NodetransformJsonObjectConstructor (ParseState *pstate, JsonObjectConstructor *ctor)
 
static NodetransformJsonArrayConstructor (ParseState *pstate, JsonArrayConstructor *ctor)
 
static NodetransformJsonArrayQueryConstructor (ParseState *pstate, JsonArrayQueryConstructor *ctor)
 
static NodetransformJsonObjectAgg (ParseState *pstate, JsonObjectAgg *agg)
 
static NodetransformJsonArrayAgg (ParseState *pstate, JsonArrayAgg *agg)
 
static Nodemake_row_comparison_op (ParseState *pstate, List *opname, List *largs, List *rargs, int location)
 
static Nodemake_row_distinct_op (ParseState *pstate, List *opname, RowExpr *lrow, RowExpr *rrow, int location)
 
static Exprmake_distinct_op (ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
 
static Nodemake_nulltest_from_distinct (ParseState *pstate, A_Expr *distincta, Node *arg)
 
NodetransformExpr (ParseState *pstate, Node *expr, ParseExprKind exprKind)
 
static void unknown_attribute (ParseState *pstate, Node *relref, const char *attname, int location)
 
static bool exprIsNullConstant (Node *arg)
 
const char * ParseExprKindName (ParseExprKind exprKind)
 
static ConstgetJsonEncodingConst (JsonFormat *format)
 
static NodemakeJsonByteaToTextConversion (Node *expr, JsonFormat *format, int location)
 
static NodemakeCaseTestExpr (Node *expr)
 
static NodetransformJsonValueExpr (ParseState *pstate, JsonValueExpr *ve, JsonFormatType default_format)
 
static void checkJsonOutputFormat (ParseState *pstate, const JsonFormat *format, Oid targettype, bool allow_format_for_non_strings)
 
static JsonReturningtransformJsonOutput (ParseState *pstate, const JsonOutput *output, bool allow_format)
 
static JsonReturningtransformJsonConstructorOutput (ParseState *pstate, JsonOutput *output, List *args)
 
static NodecoerceJsonFuncExpr (ParseState *pstate, Node *expr, const JsonReturning *returning, bool report_error)
 
static NodemakeJsonConstructorExpr (ParseState *pstate, JsonConstructorType type, List *args, Expr *fexpr, JsonReturning *returning, bool unique, bool absent_on_null, int location)
 
static NodetransformJsonAggConstructor (ParseState *pstate, JsonAggConstructor *agg_ctor, JsonReturning *returning, List *args, const char *aggfn, Oid aggtype, JsonConstructorType ctor_type, bool unique, bool absent_on_null)
 

Variables

bool Transform_null_equals = false
 

Function Documentation

◆ checkJsonOutputFormat()

static void checkJsonOutputFormat ( ParseState pstate,
const JsonFormat format,
Oid  targettype,
bool  allow_format_for_non_strings 
)
static

Definition at line 3271 of file parse_expr.c.

3273 {
3274  if (!allow_format_for_non_strings &&
3275  format->format_type != JS_FORMAT_DEFAULT &&
3276  (targettype != BYTEAOID &&
3277  targettype != JSONOID &&
3278  targettype != JSONBOID))
3279  {
3280  char typcategory;
3281  bool typispreferred;
3282 
3283  get_type_category_preferred(targettype, &typcategory, &typispreferred);
3284 
3285  if (typcategory != TYPCATEGORY_STRING)
3286  ereport(ERROR,
3287  errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3288  parser_errposition(pstate, format->location),
3289  errmsg("cannot use JSON format with non-string output types"));
3290  }
3291 
3292  if (format->format_type == JS_FORMAT_JSON)
3293  {
3294  JsonEncoding enc = format->encoding != JS_ENC_DEFAULT ?
3295  format->encoding : JS_ENC_UTF8;
3296 
3297  if (targettype != BYTEAOID &&
3298  format->encoding != JS_ENC_DEFAULT)
3299  ereport(ERROR,
3300  errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3301  parser_errposition(pstate, format->location),
3302  errmsg("cannot set JSON encoding for non-bytea output types"));
3303 
3304  if (enc != JS_ENC_UTF8)
3305  ereport(ERROR,
3306  errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3307  errmsg("unsupported JSON encoding"),
3308  errhint("Only UTF8 JSON encoding is supported."),
3309  parser_errposition(pstate, format->location));
3310  }
3311 }
enc
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2668
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
static char format
@ JS_FORMAT_DEFAULT
Definition: primnodes.h:1519
@ JS_FORMAT_JSON
Definition: primnodes.h:1520
JsonEncoding
Definition: primnodes.h:1506
@ JS_ENC_DEFAULT
Definition: primnodes.h:1507
@ JS_ENC_UTF8
Definition: primnodes.h:1508

References enc, ereport, errcode(), errhint(), errmsg(), ERROR, format, get_type_category_preferred(), JS_ENC_DEFAULT, JS_ENC_UTF8, JS_FORMAT_DEFAULT, JS_FORMAT_JSON, and parser_errposition().

Referenced by transformJsonOutput().

◆ coerceJsonFuncExpr()

static Node* coerceJsonFuncExpr ( ParseState pstate,
Node expr,
const JsonReturning returning,
bool  report_error 
)
static

Definition at line 3406 of file parse_expr.c.

3408 {
3409  Node *res;
3410  int location;
3411  Oid exprtype = exprType(expr);
3412 
3413  /* if output type is not specified or equals to function type, return */
3414  if (!OidIsValid(returning->typid) || returning->typid == exprtype)
3415  return expr;
3416 
3417  location = exprLocation(expr);
3418 
3419  if (location < 0)
3420  location = returning->format->location;
3421 
3422  /* special case for RETURNING bytea FORMAT json */
3423  if (returning->format->format_type == JS_FORMAT_JSON &&
3424  returning->typid == BYTEAOID)
3425  {
3426  /* encode json text into bytea using pg_convert_to() */
3427  Node *texpr = coerce_to_specific_type(pstate, expr, TEXTOID,
3428  "JSON_FUNCTION");
3429  Const *enc = getJsonEncodingConst(returning->format);
3430  FuncExpr *fexpr = makeFuncExpr(F_CONVERT_TO, BYTEAOID,
3431  list_make2(texpr, enc),
3434 
3435  fexpr->location = location;
3436 
3437  return (Node *) fexpr;
3438  }
3439 
3440  /* try to coerce expression to the output type */
3441  res = coerce_to_target_type(pstate, expr, exprtype,
3442  returning->typid, returning->typmod,
3443  /* XXX throwing errors when casting to char(N) */
3446  location);
3447 
3448  if (!res && report_error)
3449  ereport(ERROR,
3450  errcode(ERRCODE_CANNOT_COERCE),
3451  errmsg("cannot cast type %s to %s",
3452  format_type_be(exprtype),
3453  format_type_be(returning->typid)),
3454  parser_coercion_errposition(pstate, location, expr));
3455 
3456  return res;
3457 }
#define OidIsValid(objectId)
Definition: c.h:759
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)
Definition: makefuncs.c:522
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:43
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1287
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:78
int parser_coercion_errposition(ParseState *pstate, int coerce_location, Node *input_expr)
Node * coerce_to_specific_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *constructName)
static Const * getJsonEncodingConst(JsonFormat *format)
Definition: parse_expr.c:3088
#define list_make2(x1, x2)
Definition: pg_list.h:214
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
@ COERCE_EXPLICIT_CAST
Definition: primnodes.h:662
@ COERCE_EXPLICIT_CALL
Definition: primnodes.h:661
@ COERCION_EXPLICIT
Definition: primnodes.h:644
int location
Definition: primnodes.h:697
int location
Definition: primnodes.h:1534
JsonFormatType format_type
Definition: primnodes.h:1532
JsonFormat * format
Definition: primnodes.h:1544
Definition: nodes.h:129

References COERCE_EXPLICIT_CALL, COERCE_EXPLICIT_CAST, coerce_to_specific_type(), coerce_to_target_type(), COERCION_EXPLICIT, enc, ereport, errcode(), errmsg(), ERROR, exprLocation(), exprType(), JsonReturning::format, JsonFormat::format_type, format_type_be(), getJsonEncodingConst(), InvalidOid, JS_FORMAT_JSON, list_make2, FuncExpr::location, JsonFormat::location, makeFuncExpr(), OidIsValid, parser_coercion_errposition(), res, JsonReturning::typid, and JsonReturning::typmod.

Referenced by makeJsonConstructorExpr().

◆ exprIsNullConstant()

static bool exprIsNullConstant ( Node arg)
static

Definition at line 862 of file parse_expr.c.

863 {
864  if (arg && IsA(arg, A_Const))
865  {
866  A_Const *con = (A_Const *) arg;
867 
868  if (con->isnull)
869  return true;
870  }
871  return false;
872 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:179
void * arg
bool isnull
Definition: parsenodes.h:361

References arg, IsA, and A_Const::isnull.

Referenced by transformAExprDistinct(), and transformAExprOp().

◆ getJsonEncodingConst()

static Const* getJsonEncodingConst ( JsonFormat format)
static

Definition at line 3088 of file parse_expr.c.

3089 {
3091  const char *enc;
3092  Name encname = palloc(sizeof(NameData));
3093 
3094  if (!format ||
3095  format->format_type == JS_FORMAT_DEFAULT ||
3096  format->encoding == JS_ENC_DEFAULT)
3098  else
3099  encoding = format->encoding;
3100 
3101  switch (encoding)
3102  {
3103  case JS_ENC_UTF16:
3104  enc = "UTF16";
3105  break;
3106  case JS_ENC_UTF32:
3107  enc = "UTF32";
3108  break;
3109  case JS_ENC_UTF8:
3110  enc = "UTF8";
3111  break;
3112  default:
3113  elog(ERROR, "invalid JSON encoding: %d", encoding);
3114  break;
3115  }
3116 
3117  namestrcpy(encname, enc);
3118 
3119  return makeConst(NAMEOID, -1, InvalidOid, NAMEDATALEN,
3120  NameGetDatum(encname), false, false);
3121 }
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:302
void * palloc(Size size)
Definition: mcxt.c:1210
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define NAMEDATALEN
int32 encoding
Definition: pg_database.h:41
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
@ JS_ENC_UTF32
Definition: primnodes.h:1510
@ JS_ENC_UTF16
Definition: primnodes.h:1509
Definition: c.h:725

References elog(), enc, encoding, ERROR, format, InvalidOid, JS_ENC_DEFAULT, JS_ENC_UTF16, JS_ENC_UTF32, JS_ENC_UTF8, JS_FORMAT_DEFAULT, makeConst(), NAMEDATALEN, NameGetDatum(), namestrcpy(), and palloc().

Referenced by coerceJsonFuncExpr(), and makeJsonByteaToTextConversion().

◆ make_distinct_op()

static Expr * make_distinct_op ( ParseState pstate,
List opname,
Node ltree,
Node rtree,
int  location 
)
static

Definition at line 2926 of file parse_expr.c.

2928 {
2929  Expr *result;
2930 
2931  result = make_op(pstate, opname, ltree, rtree,
2932  pstate->p_last_srf, location);
2933  if (((OpExpr *) result)->opresulttype != BOOLOID)
2934  ereport(ERROR,
2935  (errcode(ERRCODE_DATATYPE_MISMATCH),
2936  errmsg("IS DISTINCT FROM requires = operator to yield boolean"),
2937  parser_errposition(pstate, location)));
2938  if (((OpExpr *) result)->opretset)
2939  ereport(ERROR,
2940  (errcode(ERRCODE_DATATYPE_MISMATCH),
2941  /* translator: %s is name of a SQL construct, eg NULLIF */
2942  errmsg("%s must not return a set", "IS DISTINCT FROM"),
2943  parser_errposition(pstate, location)));
2944 
2945  /*
2946  * We rely on DistinctExpr and OpExpr being same struct
2947  */
2948  NodeSetTag(result, T_DistinctExpr);
2949 
2950  return result;
2951 }
#define NodeSetTag(nodeptr, t)
Definition: nodes.h:177
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, Node *last_srf, int location)
Definition: parse_oper.c:672
Node * p_last_srf
Definition: parse_node.h:228
Definition: ltree.h:43

References ereport, errcode(), errmsg(), ERROR, make_op(), NodeSetTag, ParseState::p_last_srf, and parser_errposition().

Referenced by make_row_distinct_op(), and transformAExprDistinct().

◆ make_nulltest_from_distinct()

static Node * make_nulltest_from_distinct ( ParseState pstate,
A_Expr distincta,
Node arg 
)
static

Definition at line 2959 of file parse_expr.c.

2960 {
2961  NullTest *nt = makeNode(NullTest);
2962 
2963  nt->arg = (Expr *) transformExprRecurse(pstate, arg);
2964  /* the argument can be any type, so don't coerce it */
2965  if (distincta->kind == AEXPR_NOT_DISTINCT)
2966  nt->nulltesttype = IS_NULL;
2967  else
2968  nt->nulltesttype = IS_NOT_NULL;
2969  /* argisrow = false is correct whether or not arg is composite */
2970  nt->argisrow = false;
2971  nt->location = distincta->location;
2972  return (Node *) nt;
2973 }
#define makeNode(_type_)
Definition: nodes.h:176
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:121
@ AEXPR_NOT_DISTINCT
Definition: parsenodes.h:315
@ IS_NULL
Definition: primnodes.h:1607
@ IS_NOT_NULL
Definition: primnodes.h:1607
int location
Definition: parsenodes.h:336
A_Expr_Kind kind
Definition: parsenodes.h:332
NullTestType nulltesttype
Definition: primnodes.h:1614
int location
Definition: primnodes.h:1617
Expr * arg
Definition: primnodes.h:1613

References AEXPR_NOT_DISTINCT, arg, NullTest::arg, IS_NOT_NULL, IS_NULL, A_Expr::kind, A_Expr::location, NullTest::location, makeNode, NullTest::nulltesttype, and transformExprRecurse().

Referenced by transformAExprDistinct().

◆ make_row_comparison_op()

static Node * make_row_comparison_op ( ParseState pstate,
List opname,
List largs,
List rargs,
int  location 
)
static

Definition at line 2680 of file parse_expr.c.

2682 {
2683  RowCompareExpr *rcexpr;
2684  RowCompareType rctype;
2685  List *opexprs;
2686  List *opnos;
2687  List *opfamilies;
2688  ListCell *l,
2689  *r;
2690  List **opinfo_lists;
2691  Bitmapset *strats;
2692  int nopers;
2693  int i;
2694 
2695  nopers = list_length(largs);
2696  if (nopers != list_length(rargs))
2697  ereport(ERROR,
2698  (errcode(ERRCODE_SYNTAX_ERROR),
2699  errmsg("unequal number of entries in row expressions"),
2700  parser_errposition(pstate, location)));
2701 
2702  /*
2703  * We can't compare zero-length rows because there is no principled basis
2704  * for figuring out what the operator is.
2705  */
2706  if (nopers == 0)
2707  ereport(ERROR,
2708  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2709  errmsg("cannot compare rows of zero length"),
2710  parser_errposition(pstate, location)));
2711 
2712  /*
2713  * Identify all the pairwise operators, using make_op so that behavior is
2714  * the same as in the simple scalar case.
2715  */
2716  opexprs = NIL;
2717  forboth(l, largs, r, rargs)
2718  {
2719  Node *larg = (Node *) lfirst(l);
2720  Node *rarg = (Node *) lfirst(r);
2721  OpExpr *cmp;
2722 
2723  cmp = castNode(OpExpr, make_op(pstate, opname, larg, rarg,
2724  pstate->p_last_srf, location));
2725 
2726  /*
2727  * We don't use coerce_to_boolean here because we insist on the
2728  * operator yielding boolean directly, not via coercion. If it
2729  * doesn't yield bool it won't be in any index opfamilies...
2730  */
2731  if (cmp->opresulttype != BOOLOID)
2732  ereport(ERROR,
2733  (errcode(ERRCODE_DATATYPE_MISMATCH),
2734  errmsg("row comparison operator must yield type boolean, "
2735  "not type %s",
2736  format_type_be(cmp->opresulttype)),
2737  parser_errposition(pstate, location)));
2738  if (expression_returns_set((Node *) cmp))
2739  ereport(ERROR,
2740  (errcode(ERRCODE_DATATYPE_MISMATCH),
2741  errmsg("row comparison operator must not return a set"),
2742  parser_errposition(pstate, location)));
2743  opexprs = lappend(opexprs, cmp);
2744  }
2745 
2746  /*
2747  * If rows are length 1, just return the single operator. In this case we
2748  * don't insist on identifying btree semantics for the operator (but we
2749  * still require it to return boolean).
2750  */
2751  if (nopers == 1)
2752  return (Node *) linitial(opexprs);
2753 
2754  /*
2755  * Now we must determine which row comparison semantics (= <> < <= > >=)
2756  * apply to this set of operators. We look for btree opfamilies
2757  * containing the operators, and see which interpretations (strategy
2758  * numbers) exist for each operator.
2759  */
2760  opinfo_lists = (List **) palloc(nopers * sizeof(List *));
2761  strats = NULL;
2762  i = 0;
2763  foreach(l, opexprs)
2764  {
2765  Oid opno = ((OpExpr *) lfirst(l))->opno;
2766  Bitmapset *this_strats;
2767  ListCell *j;
2768 
2769  opinfo_lists[i] = get_op_btree_interpretation(opno);
2770 
2771  /*
2772  * convert strategy numbers into a Bitmapset to make the intersection
2773  * calculation easy.
2774  */
2775  this_strats = NULL;
2776  foreach(j, opinfo_lists[i])
2777  {
2778  OpBtreeInterpretation *opinfo = lfirst(j);
2779 
2780  this_strats = bms_add_member(this_strats, opinfo->strategy);
2781  }
2782  if (i == 0)
2783  strats = this_strats;
2784  else
2785  strats = bms_int_members(strats, this_strats);
2786  i++;
2787  }
2788 
2789  /*
2790  * If there are multiple common interpretations, we may use any one of
2791  * them ... this coding arbitrarily picks the lowest btree strategy
2792  * number.
2793  */
2794  i = bms_next_member(strats, -1);
2795  if (i < 0)
2796  {
2797  /* No common interpretation, so fail */
2798  ereport(ERROR,
2799  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2800  errmsg("could not determine interpretation of row comparison operator %s",
2801  strVal(llast(opname))),
2802  errhint("Row comparison operators must be associated with btree operator families."),
2803  parser_errposition(pstate, location)));
2804  }
2805  rctype = (RowCompareType) i;
2806 
2807  /*
2808  * For = and <> cases, we just combine the pairwise operators with AND or
2809  * OR respectively.
2810  */
2811  if (rctype == ROWCOMPARE_EQ)
2812  return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
2813  if (rctype == ROWCOMPARE_NE)
2814  return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
2815 
2816  /*
2817  * Otherwise we need to choose exactly which opfamily to associate with
2818  * each operator.
2819  */
2820  opfamilies = NIL;
2821  for (i = 0; i < nopers; i++)
2822  {
2823  Oid opfamily = InvalidOid;
2824  ListCell *j;
2825 
2826  foreach(j, opinfo_lists[i])
2827  {
2828  OpBtreeInterpretation *opinfo = lfirst(j);
2829 
2830  if (opinfo->strategy == rctype)
2831  {
2832  opfamily = opinfo->opfamily_id;
2833  break;
2834  }
2835  }
2836  if (OidIsValid(opfamily))
2837  opfamilies = lappend_oid(opfamilies, opfamily);
2838  else /* should not happen */
2839  ereport(ERROR,
2840  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2841  errmsg("could not determine interpretation of row comparison operator %s",
2842  strVal(llast(opname))),
2843  errdetail("There are multiple equally-plausible candidates."),
2844  parser_errposition(pstate, location)));
2845  }
2846 
2847  /*
2848  * Now deconstruct the OpExprs and create a RowCompareExpr.
2849  *
2850  * Note: can't just reuse the passed largs/rargs lists, because of
2851  * possibility that make_op inserted coercion operations.
2852  */
2853  opnos = NIL;
2854  largs = NIL;
2855  rargs = NIL;
2856  foreach(l, opexprs)
2857  {
2858  OpExpr *cmp = (OpExpr *) lfirst(l);
2859 
2860  opnos = lappend_oid(opnos, cmp->opno);
2861  largs = lappend(largs, linitial(cmp->args));
2862  rargs = lappend(rargs, lsecond(cmp->args));
2863  }
2864 
2865  rcexpr = makeNode(RowCompareExpr);
2866  rcexpr->rctype = rctype;
2867  rcexpr->opnos = opnos;
2868  rcexpr->opfamilies = opfamilies;
2869  rcexpr->inputcollids = NIL; /* assign_expr_collations will fix this */
2870  rcexpr->largs = largs;
2871  rcexpr->rargs = rargs;
2872 
2873  return (Node *) rcexpr;
2874 }
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1039
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:755
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:928
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int j
Definition: isn.c:74
int i
Definition: isn.c:73
List * lappend(List *list, void *datum)
Definition: list.c:338
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
List * get_op_btree_interpretation(Oid opno)
Definition: lsyscache.c:600
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:372
bool expression_returns_set(Node *clause)
Definition: nodeFuncs.c:722
#define castNode(_type_, nodeptr)
Definition: nodes.h:197
#define lfirst(lc)
Definition: pg_list.h:172
#define llast(l)
Definition: pg_list.h:198
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:467
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
@ AND_EXPR
Definition: primnodes.h:858
@ OR_EXPR
Definition: primnodes.h:858
RowCompareType
Definition: primnodes.h:1378
@ ROWCOMPARE_NE
Definition: primnodes.h:1385
@ ROWCOMPARE_EQ
Definition: primnodes.h:1382
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747
Definition: pg_list.h:54
RowCompareType rctype
Definition: primnodes.h:1393
#define strVal(v)
Definition: value.h:82

References AND_EXPR, bms_add_member(), bms_int_members(), bms_next_member(), castNode, cmp(), ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, expression_returns_set(), forboth, format_type_be(), get_op_btree_interpretation(), i, InvalidOid, j, lappend(), lappend_oid(), RowCompareExpr::largs, lfirst, linitial, list_length(), llast, lsecond, make_op(), makeBoolExpr(), makeNode, NIL, OidIsValid, OpBtreeInterpretation::opfamily_id, OR_EXPR, ParseState::p_last_srf, palloc(), parser_errposition(), RowCompareExpr::rargs, RowCompareExpr::rctype, ROWCOMPARE_EQ, ROWCOMPARE_NE, OpBtreeInterpretation::strategy, and strVal.

Referenced by transformAExprIn(), transformAExprOp(), and transformSubLink().

◆ make_row_distinct_op()

static Node * make_row_distinct_op ( ParseState pstate,
List opname,
RowExpr lrow,
RowExpr rrow,
int  location 
)
static

Definition at line 2882 of file parse_expr.c.

2885 {
2886  Node *result = NULL;
2887  List *largs = lrow->args;
2888  List *rargs = rrow->args;
2889  ListCell *l,
2890  *r;
2891 
2892  if (list_length(largs) != list_length(rargs))
2893  ereport(ERROR,
2894  (errcode(ERRCODE_SYNTAX_ERROR),
2895  errmsg("unequal number of entries in row expressions"),
2896  parser_errposition(pstate, location)));
2897 
2898  forboth(l, largs, r, rargs)
2899  {
2900  Node *larg = (Node *) lfirst(l);
2901  Node *rarg = (Node *) lfirst(r);
2902  Node *cmp;
2903 
2904  cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
2905  if (result == NULL)
2906  result = cmp;
2907  else
2908  result = (Node *) makeBoolExpr(OR_EXPR,
2909  list_make2(result, cmp),
2910  location);
2911  }
2912 
2913  if (result == NULL)
2914  {
2915  /* zero-length rows? Generate constant FALSE */
2916  result = makeBoolConst(false, false);
2917  }
2918 
2919  return result;
2920 }
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:360
static Expr * make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_expr.c:2926
List * args
Definition: primnodes.h:1336

References RowExpr::args, cmp(), ereport, errcode(), errmsg(), ERROR, forboth, lfirst, list_length(), list_make2, make_distinct_op(), makeBoolConst(), makeBoolExpr(), OR_EXPR, and parser_errposition().

Referenced by transformAExprDistinct().

◆ makeCaseTestExpr()

static Node* makeCaseTestExpr ( Node expr)
static

Definition at line 3144 of file parse_expr.c.

3145 {
3146  CaseTestExpr *placeholder = makeNode(CaseTestExpr);
3147 
3148  placeholder->typeId = exprType(expr);
3149  placeholder->typeMod = exprTypmod(expr);
3150  placeholder->collation = exprCollation(expr);
3151 
3152  return (Node *) placeholder;
3153 }
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:278
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:780

References exprCollation(), exprType(), exprTypmod(), makeNode, and CaseTestExpr::typeId.

Referenced by makeJsonConstructorExpr(), and transformJsonValueExpr().

◆ makeJsonByteaToTextConversion()

static Node* makeJsonByteaToTextConversion ( Node expr,
JsonFormat format,
int  location 
)
static

Definition at line 3127 of file parse_expr.c.

3128 {
3130  FuncExpr *fexpr = makeFuncExpr(F_CONVERT_FROM, TEXTOID,
3131  list_make2(expr, encoding),
3134 
3135  fexpr->location = location;
3136 
3137  return (Node *) fexpr;
3138 }

References COERCE_EXPLICIT_CALL, encoding, format, getJsonEncodingConst(), InvalidOid, list_make2, FuncExpr::location, and makeFuncExpr().

Referenced by transformJsonValueExpr().

◆ makeJsonConstructorExpr()

static Node* makeJsonConstructorExpr ( ParseState pstate,
JsonConstructorType  type,
List args,
Expr fexpr,
JsonReturning returning,
bool  unique,
bool  absent_on_null,
int  location 
)
static

Definition at line 3460 of file parse_expr.c.

3463 {
3465  Node *placeholder;
3466  Node *coercion;
3467  Oid intermediate_typid =
3468  returning->format->format_type == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
3469 
3470  jsctor->args = args;
3471  jsctor->func = fexpr;
3472  jsctor->type = type;
3473  jsctor->returning = returning;
3474  jsctor->unique = unique;
3475  jsctor->absent_on_null = absent_on_null;
3476  jsctor->location = location;
3477 
3478  if (fexpr)
3479  placeholder = makeCaseTestExpr((Node *) fexpr);
3480  else
3481  {
3483 
3484  cte->typeId = intermediate_typid;
3485  cte->typeMod = -1;
3486  cte->collation = InvalidOid;
3487 
3488  placeholder = (Node *) cte;
3489  }
3490 
3491  coercion = coerceJsonFuncExpr(pstate, placeholder, returning, true);
3492 
3493  if (coercion != placeholder)
3494  jsctor->coercion = (Expr *) coercion;
3495 
3496  return (Node *) jsctor;
3497 }
static Node * makeCaseTestExpr(Node *expr)
Definition: parse_expr.c:3144
static Node * coerceJsonFuncExpr(ParseState *pstate, Node *expr, const JsonReturning *returning, bool report_error)
Definition: parse_expr.c:3406
@ JS_FORMAT_JSONB
Definition: primnodes.h:1521
JsonReturning * returning
Definition: primnodes.h:1580
JsonConstructorType type
Definition: primnodes.h:1576

References JsonConstructorExpr::absent_on_null, generate_unaccent_rules::args, JsonConstructorExpr::args, coerceJsonFuncExpr(), JsonConstructorExpr::coercion, JsonReturning::format, JsonFormat::format_type, JsonConstructorExpr::func, InvalidOid, JS_FORMAT_JSONB, JsonConstructorExpr::location, makeCaseTestExpr(), makeNode, JsonConstructorExpr::returning, generate_unaccent_rules::type, JsonConstructorExpr::type, CaseTestExpr::typeId, and JsonConstructorExpr::unique.

Referenced by transformJsonAggConstructor(), transformJsonArrayConstructor(), and transformJsonObjectConstructor().

◆ ParseExprKindName()

const char* ParseExprKindName ( ParseExprKind  exprKind)

Definition at line 2983 of file parse_expr.c.

2984 {
2985  switch (exprKind)
2986  {
2987  case EXPR_KIND_NONE:
2988  return "invalid expression context";
2989  case EXPR_KIND_OTHER:
2990  return "extension expression";
2991  case EXPR_KIND_JOIN_ON:
2992  return "JOIN/ON";
2993  case EXPR_KIND_JOIN_USING:
2994  return "JOIN/USING";
2996  return "sub-SELECT in FROM";
2998  return "function in FROM";
2999  case EXPR_KIND_WHERE:
3000  return "WHERE";
3001  case EXPR_KIND_POLICY:
3002  return "POLICY";
3003  case EXPR_KIND_HAVING:
3004  return "HAVING";
3005  case EXPR_KIND_FILTER:
3006  return "FILTER";
3008  return "window PARTITION BY";
3010  return "window ORDER BY";
3012  return "window RANGE";
3014  return "window ROWS";
3016  return "window GROUPS";
3018  return "SELECT";
3020  return "INSERT";
3023  return "UPDATE";
3024  case EXPR_KIND_MERGE_WHEN:
3025  return "MERGE WHEN";
3026  case EXPR_KIND_GROUP_BY:
3027  return "GROUP BY";
3028  case EXPR_KIND_ORDER_BY:
3029  return "ORDER BY";
3030  case EXPR_KIND_DISTINCT_ON:
3031  return "DISTINCT ON";
3032  case EXPR_KIND_LIMIT:
3033  return "LIMIT";
3034  case EXPR_KIND_OFFSET:
3035  return "OFFSET";
3036  case EXPR_KIND_RETURNING:
3037  return "RETURNING";
3038  case EXPR_KIND_VALUES:
3040  return "VALUES";
3043  return "CHECK";
3046  return "DEFAULT";
3048  return "index expression";
3050  return "index predicate";
3052  return "statistics expression";
3054  return "USING";
3056  return "EXECUTE";
3058  return "WHEN";
3060  return "partition bound";
3062  return "PARTITION BY";
3064  return "CALL";
3065  case EXPR_KIND_COPY_WHERE:
3066  return "WHERE";
3068  return "GENERATED AS";
3069  case EXPR_KIND_CYCLE_MARK:
3070  return "CYCLE";
3071 
3072  /*
3073  * There is intentionally no default: case here, so that the
3074  * compiler will warn if we add a new ParseExprKind without
3075  * extending this switch. If we do see an unrecognized value at
3076  * runtime, we'll fall through to the "unrecognized" return.
3077  */
3078  }
3079  return "unrecognized expression kind";
3080 }
@ EXPR_KIND_EXECUTE_PARAMETER
Definition: parse_node.h:75
@ EXPR_KIND_DOMAIN_CHECK
Definition: parse_node.h:68
@ EXPR_KIND_COPY_WHERE
Definition: parse_node.h:81
@ EXPR_KIND_COLUMN_DEFAULT
Definition: parse_node.h:69
@ EXPR_KIND_DISTINCT_ON
Definition: parse_node.h:61
@ EXPR_KIND_MERGE_WHEN
Definition: parse_node.h:58
@ EXPR_KIND_STATS_EXPRESSION
Definition: parse_node.h:73
@ EXPR_KIND_INDEX_EXPRESSION
Definition: parse_node.h:71
@ EXPR_KIND_PARTITION_BOUND
Definition: parse_node.h:78
@ EXPR_KIND_FUNCTION_DEFAULT
Definition: parse_node.h:70
@ EXPR_KIND_WINDOW_FRAME_RANGE
Definition: parse_node.h:51
@ EXPR_KIND_VALUES
Definition: parse_node.h:65
@ EXPR_KIND_FROM_SUBSELECT
Definition: parse_node.h:44
@ EXPR_KIND_POLICY
Definition: parse_node.h:77
@ EXPR_KIND_WINDOW_FRAME_GROUPS
Definition: parse_node.h:53
@ EXPR_KIND_PARTITION_EXPRESSION
Definition: parse_node.h:79
@ EXPR_KIND_JOIN_USING
Definition: parse_node.h:43
@ EXPR_KIND_INDEX_PREDICATE
Definition: parse_node.h:72
@ EXPR_KIND_ORDER_BY
Definition: parse_node.h:60
@ EXPR_KIND_OFFSET
Definition: parse_node.h:63
@ EXPR_KIND_JOIN_ON
Definition: parse_node.h:42
@ EXPR_KIND_HAVING
Definition: parse_node.h:47
@ EXPR_KIND_INSERT_TARGET
Definition: parse_node.h:55
@ EXPR_KIND_ALTER_COL_TRANSFORM
Definition: parse_node.h:74
@ EXPR_KIND_LIMIT
Definition: parse_node.h:62
@ EXPR_KIND_WHERE
Definition: parse_node.h:46
@ EXPR_KIND_UPDATE_TARGET
Definition: parse_node.h:57
@ EXPR_KIND_SELECT_TARGET
Definition: parse_node.h:54
@ EXPR_KIND_RETURNING
Definition: parse_node.h:64
@ EXPR_KIND_GENERATED_COLUMN
Definition: parse_node.h:82
@ EXPR_KIND_NONE
Definition: parse_node.h:40
@ EXPR_KIND_CALL_ARGUMENT
Definition: parse_node.h:80
@ EXPR_KIND_GROUP_BY
Definition: parse_node.h:59
@ EXPR_KIND_OTHER
Definition: parse_node.h:41
@ EXPR_KIND_FROM_FUNCTION
Definition: parse_node.h:45
@ EXPR_KIND_TRIGGER_WHEN
Definition: parse_node.h:76
@ EXPR_KIND_FILTER
Definition: parse_node.h:48
@ EXPR_KIND_UPDATE_SOURCE
Definition: parse_node.h:56
@ EXPR_KIND_CHECK_CONSTRAINT
Definition: parse_node.h:67
@ EXPR_KIND_WINDOW_PARTITION
Definition: parse_node.h:49
@ EXPR_KIND_CYCLE_MARK
Definition: parse_node.h:83
@ EXPR_KIND_WINDOW_FRAME_ROWS
Definition: parse_node.h:52
@ EXPR_KIND_WINDOW_ORDER
Definition: parse_node.h:50
@ EXPR_KIND_VALUES_SINGLE
Definition: parse_node.h:66

References EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CALL_ARGUMENT, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, EXPR_KIND_COPY_WHERE, EXPR_KIND_CYCLE_MARK, EXPR_KIND_DISTINCT_ON, EXPR_KIND_DOMAIN_CHECK, EXPR_KIND_EXECUTE_PARAMETER, EXPR_KIND_FILTER, EXPR_KIND_FROM_FUNCTION, EXPR_KIND_FROM_SUBSELECT, EXPR_KIND_FUNCTION_DEFAULT, EXPR_KIND_GENERATED_COLUMN, EXPR_KIND_GROUP_BY, EXPR_KIND_HAVING, EXPR_KIND_INDEX_EXPRESSION, EXPR_KIND_INDEX_PREDICATE, EXPR_KIND_INSERT_TARGET, EXPR_KIND_JOIN_ON, EXPR_KIND_JOIN_USING, EXPR_KIND_LIMIT, EXPR_KIND_MERGE_WHEN, EXPR_KIND_NONE, EXPR_KIND_OFFSET, EXPR_KIND_ORDER_BY, EXPR_KIND_OTHER, EXPR_KIND_PARTITION_BOUND, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_POLICY, EXPR_KIND_RETURNING, EXPR_KIND_SELECT_TARGET, EXPR_KIND_STATS_EXPRESSION, EXPR_KIND_TRIGGER_WHEN, EXPR_KIND_UPDATE_SOURCE, EXPR_KIND_UPDATE_TARGET, EXPR_KIND_VALUES, EXPR_KIND_VALUES_SINGLE, EXPR_KIND_WHERE, EXPR_KIND_WINDOW_FRAME_GROUPS, EXPR_KIND_WINDOW_FRAME_RANGE, EXPR_KIND_WINDOW_FRAME_ROWS, EXPR_KIND_WINDOW_ORDER, and EXPR_KIND_WINDOW_PARTITION.

Referenced by check_agglevels_and_constraints(), check_srf_call_placement(), checkTargetlistEntrySQL92(), findTargetlistEntrySQL92(), and transformWindowFuncCall().

◆ transformAExprBetween()

static Node * transformAExprBetween ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1235 of file parse_expr.c.

1236 {
1237  Node *aexpr;
1238  Node *bexpr;
1239  Node *cexpr;
1240  Node *result;
1241  Node *sub1;
1242  Node *sub2;
1243  List *args;
1244 
1245  /* Deconstruct A_Expr into three subexprs */
1246  aexpr = a->lexpr;
1247  args = castNode(List, a->rexpr);
1248  Assert(list_length(args) == 2);
1249  bexpr = (Node *) linitial(args);
1250  cexpr = (Node *) lsecond(args);
1251 
1252  /*
1253  * Build the equivalent comparison expression. Make copies of
1254  * multiply-referenced subexpressions for safety. (XXX this is really
1255  * wrong since it results in multiple runtime evaluations of what may be
1256  * volatile expressions ...)
1257  *
1258  * Ideally we would not use hard-wired operators here but instead use
1259  * opclasses. However, mixed data types and other issues make this
1260  * difficult:
1261  * http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
1262  */
1263  switch (a->kind)
1264  {
1265  case AEXPR_BETWEEN:
1267  aexpr, bexpr,
1268  a->location),
1269  makeSimpleA_Expr(AEXPR_OP, "<=",
1270  copyObject(aexpr), cexpr,
1271  a->location));
1272  result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1273  break;
1274  case AEXPR_NOT_BETWEEN:
1276  aexpr, bexpr,
1277  a->location),
1279  copyObject(aexpr), cexpr,
1280  a->location));
1281  result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1282  break;
1283  case AEXPR_BETWEEN_SYM:
1285  aexpr, bexpr,
1286  a->location),
1287  makeSimpleA_Expr(AEXPR_OP, "<=",
1288  copyObject(aexpr), cexpr,
1289  a->location));
1290  sub1 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1292  copyObject(aexpr), copyObject(cexpr),
1293  a->location),
1294  makeSimpleA_Expr(AEXPR_OP, "<=",
1295  copyObject(aexpr), copyObject(bexpr),
1296  a->location));
1297  sub2 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1298  args = list_make2(sub1, sub2);
1299  result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1300  break;
1301  case AEXPR_NOT_BETWEEN_SYM:
1303  aexpr, bexpr,
1304  a->location),
1306  copyObject(aexpr), cexpr,
1307  a->location));
1308  sub1 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1310  copyObject(aexpr), copyObject(cexpr),
1311  a->location),
1313  copyObject(aexpr), copyObject(bexpr),
1314  a->location));
1315  sub2 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1316  args = list_make2(sub1, sub2);
1317  result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1318  break;
1319  default:
1320  elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
1321  result = NULL; /* keep compiler quiet */
1322  break;
1323  }
1324 
1325  return transformExprRecurse(pstate, result);
1326 }
int a
Definition: isn.c:69
Assert(fmt[strlen(fmt) - 1] !='\n')
A_Expr * makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location)
Definition: makefuncs.c:49
#define copyObject(obj)
Definition: nodes.h:244
@ AEXPR_BETWEEN
Definition: parsenodes.h:321
@ AEXPR_BETWEEN_SYM
Definition: parsenodes.h:323
@ AEXPR_NOT_BETWEEN_SYM
Definition: parsenodes.h:324
@ AEXPR_NOT_BETWEEN
Definition: parsenodes.h:322
@ AEXPR_OP
Definition: parsenodes.h:311

References a, AEXPR_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_NOT_BETWEEN, AEXPR_NOT_BETWEEN_SYM, AEXPR_OP, AND_EXPR, generate_unaccent_rules::args, Assert(), castNode, copyObject, elog(), ERROR, linitial, list_length(), list_make2, lsecond, makeBoolExpr(), makeSimpleA_Expr(), OR_EXPR, and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformAExprDistinct()

static Node * transformAExprDistinct ( ParseState pstate,
A_Expr a 
)
static

Definition at line 984 of file parse_expr.c.

985 {
986  Node *lexpr = a->lexpr;
987  Node *rexpr = a->rexpr;
988  Node *result;
989 
990  /*
991  * If either input is an undecorated NULL literal, transform to a NullTest
992  * on the other input. That's simpler to process than a full DistinctExpr,
993  * and it avoids needing to require that the datatype have an = operator.
994  */
995  if (exprIsNullConstant(rexpr))
996  return make_nulltest_from_distinct(pstate, a, lexpr);
997  if (exprIsNullConstant(lexpr))
998  return make_nulltest_from_distinct(pstate, a, rexpr);
999 
1000  lexpr = transformExprRecurse(pstate, lexpr);
1001  rexpr = transformExprRecurse(pstate, rexpr);
1002 
1003  if (lexpr && IsA(lexpr, RowExpr) &&
1004  rexpr && IsA(rexpr, RowExpr))
1005  {
1006  /* ROW() op ROW() is handled specially */
1007  result = make_row_distinct_op(pstate, a->name,
1008  (RowExpr *) lexpr,
1009  (RowExpr *) rexpr,
1010  a->location);
1011  }
1012  else
1013  {
1014  /* Ordinary scalar operator */
1015  result = (Node *) make_distinct_op(pstate,
1016  a->name,
1017  lexpr,
1018  rexpr,
1019  a->location);
1020  }
1021 
1022  /*
1023  * If it's NOT DISTINCT, we first build a DistinctExpr and then stick a
1024  * NOT on top.
1025  */
1026  if (a->kind == AEXPR_NOT_DISTINCT)
1027  result = (Node *) makeBoolExpr(NOT_EXPR,
1028  list_make1(result),
1029  a->location);
1030 
1031  return result;
1032 }
static Node * make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg)
Definition: parse_expr.c:2959
static bool exprIsNullConstant(Node *arg)
Definition: parse_expr.c:862
static Node * make_row_distinct_op(ParseState *pstate, List *opname, RowExpr *lrow, RowExpr *rrow, int location)
Definition: parse_expr.c:2882
#define list_make1(x1)
Definition: pg_list.h:212
@ NOT_EXPR
Definition: primnodes.h:858

References a, AEXPR_NOT_DISTINCT, exprIsNullConstant(), IsA, list_make1, make_distinct_op(), make_nulltest_from_distinct(), make_row_distinct_op(), makeBoolExpr(), NOT_EXPR, and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformAExprIn()

static Node * transformAExprIn ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1077 of file parse_expr.c.

1078 {
1079  Node *result = NULL;
1080  Node *lexpr;
1081  List *rexprs;
1082  List *rvars;
1083  List *rnonvars;
1084  bool useOr;
1085  ListCell *l;
1086 
1087  /*
1088  * If the operator is <>, combine with AND not OR.
1089  */
1090  if (strcmp(strVal(linitial(a->name)), "<>") == 0)
1091  useOr = false;
1092  else
1093  useOr = true;
1094 
1095  /*
1096  * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
1097  * possible if there is a suitable array type available. If not, we fall
1098  * back to a boolean condition tree with multiple copies of the lefthand
1099  * expression. Also, any IN-list items that contain Vars are handled as
1100  * separate boolean conditions, because that gives the planner more scope
1101  * for optimization on such clauses.
1102  *
1103  * First step: transform all the inputs, and detect whether any contain
1104  * Vars.
1105  */
1106  lexpr = transformExprRecurse(pstate, a->lexpr);
1107  rexprs = rvars = rnonvars = NIL;
1108  foreach(l, (List *) a->rexpr)
1109  {
1110  Node *rexpr = transformExprRecurse(pstate, lfirst(l));
1111 
1112  rexprs = lappend(rexprs, rexpr);
1113  if (contain_vars_of_level(rexpr, 0))
1114  rvars = lappend(rvars, rexpr);
1115  else
1116  rnonvars = lappend(rnonvars, rexpr);
1117  }
1118 
1119  /*
1120  * ScalarArrayOpExpr is only going to be useful if there's more than one
1121  * non-Var righthand item.
1122  */
1123  if (list_length(rnonvars) > 1)
1124  {
1125  List *allexprs;
1126  Oid scalar_type;
1127  Oid array_type;
1128 
1129  /*
1130  * Try to select a common type for the array elements. Note that
1131  * since the LHS' type is first in the list, it will be preferred when
1132  * there is doubt (eg, when all the RHS items are unknown literals).
1133  *
1134  * Note: use list_concat here not lcons, to avoid damaging rnonvars.
1135  */
1136  allexprs = list_concat(list_make1(lexpr), rnonvars);
1137  scalar_type = select_common_type(pstate, allexprs, NULL, NULL);
1138 
1139  /* We have to verify that the selected type actually works */
1140  if (OidIsValid(scalar_type) &&
1141  !verify_common_type(scalar_type, allexprs))
1142  scalar_type = InvalidOid;
1143 
1144  /*
1145  * Do we have an array type to use? Aside from the case where there
1146  * isn't one, we don't risk using ScalarArrayOpExpr when the common
1147  * type is RECORD, because the RowExpr comparison logic below can cope
1148  * with some cases of non-identical row types.
1149  */
1150  if (OidIsValid(scalar_type) && scalar_type != RECORDOID)
1151  array_type = get_array_type(scalar_type);
1152  else
1153  array_type = InvalidOid;
1154  if (array_type != InvalidOid)
1155  {
1156  /*
1157  * OK: coerce all the right-hand non-Var inputs to the common type
1158  * and build an ArrayExpr for them.
1159  */
1160  List *aexprs;
1161  ArrayExpr *newa;
1162 
1163  aexprs = NIL;
1164  foreach(l, rnonvars)
1165  {
1166  Node *rexpr = (Node *) lfirst(l);
1167 
1168  rexpr = coerce_to_common_type(pstate, rexpr,
1169  scalar_type,
1170  "IN");
1171  aexprs = lappend(aexprs, rexpr);
1172  }
1173  newa = makeNode(ArrayExpr);
1174  newa->array_typeid = array_type;
1175  /* array_collid will be set by parse_collate.c */
1176  newa->element_typeid = scalar_type;
1177  newa->elements = aexprs;
1178  newa->multidims = false;
1179  newa->location = -1;
1180 
1181  result = (Node *) make_scalar_array_op(pstate,
1182  a->name,
1183  useOr,
1184  lexpr,
1185  (Node *) newa,
1186  a->location);
1187 
1188  /* Consider only the Vars (if any) in the loop below */
1189  rexprs = rvars;
1190  }
1191  }
1192 
1193  /*
1194  * Must do it the hard way, ie, with a boolean expression tree.
1195  */
1196  foreach(l, rexprs)
1197  {
1198  Node *rexpr = (Node *) lfirst(l);
1199  Node *cmp;
1200 
1201  if (IsA(lexpr, RowExpr) &&
1202  IsA(rexpr, RowExpr))
1203  {
1204  /* ROW() op ROW() is handled specially */
1205  cmp = make_row_comparison_op(pstate,
1206  a->name,
1207  copyObject(((RowExpr *) lexpr)->args),
1208  ((RowExpr *) rexpr)->args,
1209  a->location);
1210  }
1211  else
1212  {
1213  /* Ordinary scalar operator */
1214  cmp = (Node *) make_op(pstate,
1215  a->name,
1216  copyObject(lexpr),
1217  rexpr,
1218  pstate->p_last_srf,
1219  a->location);
1220  }
1221 
1222  cmp = coerce_to_boolean(pstate, cmp, "IN");
1223  if (result == NULL)
1224  result = cmp;
1225  else
1226  result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
1227  list_make2(result, cmp),
1228  a->location);
1229  }
1230 
1231  return result;
1232 }
List * list_concat(List *list1, const List *list2)
Definition: list.c:560
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2745
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
bool verify_common_type(Oid common_type, List *exprs)
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
static Node * make_row_comparison_op(ParseState *pstate, List *opname, List *largs, List *rargs, int location)
Definition: parse_expr.c:2680
Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:783
int location
Definition: primnodes.h:1309
List * elements
Definition: primnodes.h:1305
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:441

References a, AND_EXPR, generate_unaccent_rules::args, cmp(), coerce_to_boolean(), coerce_to_common_type(), contain_vars_of_level(), copyObject, ArrayExpr::elements, get_array_type(), InvalidOid, IsA, lappend(), lfirst, linitial, list_concat(), list_length(), list_make1, list_make2, ArrayExpr::location, make_op(), make_row_comparison_op(), make_scalar_array_op(), makeBoolExpr(), makeNode, NIL, OidIsValid, OR_EXPR, ParseState::p_last_srf, select_common_type(), strVal, transformExprRecurse(), and verify_common_type().

Referenced by transformExprRecurse().

◆ transformAExprNullIf()

static Node * transformAExprNullIf ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1035 of file parse_expr.c.

1036 {
1037  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
1038  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
1039  OpExpr *result;
1040 
1041  result = (OpExpr *) make_op(pstate,
1042  a->name,
1043  lexpr,
1044  rexpr,
1045  pstate->p_last_srf,
1046  a->location);
1047 
1048  /*
1049  * The comparison operator itself should yield boolean ...
1050  */
1051  if (result->opresulttype != BOOLOID)
1052  ereport(ERROR,
1053  (errcode(ERRCODE_DATATYPE_MISMATCH),
1054  errmsg("NULLIF requires = operator to yield boolean"),
1055  parser_errposition(pstate, a->location)));
1056  if (result->opretset)
1057  ereport(ERROR,
1058  (errcode(ERRCODE_DATATYPE_MISMATCH),
1059  /* translator: %s is name of a SQL construct, eg NULLIF */
1060  errmsg("%s must not return a set", "NULLIF"),
1061  parser_errposition(pstate, a->location)));
1062 
1063  /*
1064  * ... but the NullIfExpr will yield the first operand's type.
1065  */
1066  result->opresulttype = exprType((Node *) linitial(result->args));
1067 
1068  /*
1069  * We rely on NullIfExpr and OpExpr being the same struct
1070  */
1071  NodeSetTag(result, T_NullIfExpr);
1072 
1073  return (Node *) result;
1074 }
List * args
Definition: primnodes.h:763

References a, OpExpr::args, ereport, errcode(), errmsg(), ERROR, exprType(), linitial, make_op(), NodeSetTag, ParseState::p_last_srf, parser_errposition(), and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformAExprOp()

static Node * transformAExprOp ( ParseState pstate,
A_Expr a 
)
static

Definition at line 875 of file parse_expr.c.

876 {
877  Node *lexpr = a->lexpr;
878  Node *rexpr = a->rexpr;
879  Node *result;
880 
881  /*
882  * Special-case "foo = NULL" and "NULL = foo" for compatibility with
883  * standards-broken products (like Microsoft's). Turn these into IS NULL
884  * exprs. (If either side is a CaseTestExpr, then the expression was
885  * generated internally from a CASE-WHEN expression, and
886  * transform_null_equals does not apply.)
887  */
888  if (Transform_null_equals &&
889  list_length(a->name) == 1 &&
890  strcmp(strVal(linitial(a->name)), "=") == 0 &&
891  (exprIsNullConstant(lexpr) || exprIsNullConstant(rexpr)) &&
892  (!IsA(lexpr, CaseTestExpr) && !IsA(rexpr, CaseTestExpr)))
893  {
894  NullTest *n = makeNode(NullTest);
895 
896  n->nulltesttype = IS_NULL;
897  n->location = a->location;
898 
899  if (exprIsNullConstant(lexpr))
900  n->arg = (Expr *) rexpr;
901  else
902  n->arg = (Expr *) lexpr;
903 
904  result = transformExprRecurse(pstate, (Node *) n);
905  }
906  else if (lexpr && IsA(lexpr, RowExpr) &&
907  rexpr && IsA(rexpr, SubLink) &&
908  ((SubLink *) rexpr)->subLinkType == EXPR_SUBLINK)
909  {
910  /*
911  * Convert "row op subselect" into a ROWCOMPARE sublink. Formerly the
912  * grammar did this, but now that a row construct is allowed anywhere
913  * in expressions, it's easier to do it here.
914  */
915  SubLink *s = (SubLink *) rexpr;
916 
918  s->testexpr = lexpr;
919  s->operName = a->name;
920  s->location = a->location;
921  result = transformExprRecurse(pstate, (Node *) s);
922  }
923  else if (lexpr && IsA(lexpr, RowExpr) &&
924  rexpr && IsA(rexpr, RowExpr))
925  {
926  /* ROW() op ROW() is handled specially */
927  lexpr = transformExprRecurse(pstate, lexpr);
928  rexpr = transformExprRecurse(pstate, rexpr);
929 
930  result = make_row_comparison_op(pstate,
931  a->name,
932  castNode(RowExpr, lexpr)->args,
933  castNode(RowExpr, rexpr)->args,
934  a->location);
935  }
936  else
937  {
938  /* Ordinary scalar operator */
939  Node *last_srf = pstate->p_last_srf;
940 
941  lexpr = transformExprRecurse(pstate, lexpr);
942  rexpr = transformExprRecurse(pstate, rexpr);
943 
944  result = (Node *) make_op(pstate,
945  a->name,
946  lexpr,
947  rexpr,
948  last_srf,
949  a->location);
950  }
951 
952  return result;
953 }
bool Transform_null_equals
Definition: parse_expr.c:45
@ EXPR_SUBLINK
Definition: primnodes.h:928
@ ROWCOMPARE_SUBLINK
Definition: primnodes.h:927

References a, NullTest::arg, generate_unaccent_rules::args, castNode, EXPR_SUBLINK, exprIsNullConstant(), IS_NULL, IsA, linitial, list_length(), SubLink::location, NullTest::location, make_op(), make_row_comparison_op(), makeNode, NullTest::nulltesttype, ParseState::p_last_srf, ROWCOMPARE_SUBLINK, strVal, SubLink::subLinkType, SubLink::testexpr, Transform_null_equals, and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformAExprOpAll()

static Node * transformAExprOpAll ( ParseState pstate,
A_Expr a 
)
static

Definition at line 970 of file parse_expr.c.

971 {
972  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
973  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
974 
975  return (Node *) make_scalar_array_op(pstate,
976  a->name,
977  false,
978  lexpr,
979  rexpr,
980  a->location);
981 }

References a, make_scalar_array_op(), and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformAExprOpAny()

static Node * transformAExprOpAny ( ParseState pstate,
A_Expr a 
)
static

Definition at line 956 of file parse_expr.c.

957 {
958  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
959  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
960 
961  return (Node *) make_scalar_array_op(pstate,
962  a->name,
963  true,
964  lexpr,
965  rexpr,
966  a->location);
967 }

References a, make_scalar_array_op(), and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformArrayExpr()

static Node * transformArrayExpr ( ParseState pstate,
A_ArrayExpr a,
Oid  array_type,
Oid  element_type,
int32  typmod 
)
static

Definition at line 1940 of file parse_expr.c.

1942 {
1943  ArrayExpr *newa = makeNode(ArrayExpr);
1944  List *newelems = NIL;
1945  List *newcoercedelems = NIL;
1946  ListCell *element;
1947  Oid coerce_type;
1948  bool coerce_hard;
1949 
1950  /*
1951  * Transform the element expressions
1952  *
1953  * Assume that the array is one-dimensional unless we find an array-type
1954  * element expression.
1955  */
1956  newa->multidims = false;
1957  foreach(element, a->elements)
1958  {
1959  Node *e = (Node *) lfirst(element);
1960  Node *newe;
1961 
1962  /*
1963  * If an element is itself an A_ArrayExpr, recurse directly so that we
1964  * can pass down any target type we were given.
1965  */
1966  if (IsA(e, A_ArrayExpr))
1967  {
1968  newe = transformArrayExpr(pstate,
1969  (A_ArrayExpr *) e,
1970  array_type,
1971  element_type,
1972  typmod);
1973  /* we certainly have an array here */
1974  Assert(array_type == InvalidOid || array_type == exprType(newe));
1975  newa->multidims = true;
1976  }
1977  else
1978  {
1979  newe = transformExprRecurse(pstate, e);
1980 
1981  /*
1982  * Check for sub-array expressions, if we haven't already found
1983  * one.
1984  */
1985  if (!newa->multidims && type_is_array(exprType(newe)))
1986  newa->multidims = true;
1987  }
1988 
1989  newelems = lappend(newelems, newe);
1990  }
1991 
1992  /*
1993  * Select a target type for the elements.
1994  *
1995  * If we haven't been given a target array type, we must try to deduce a
1996  * common type based on the types of the individual elements present.
1997  */
1998  if (OidIsValid(array_type))
1999  {
2000  /* Caller must ensure array_type matches element_type */
2001  Assert(OidIsValid(element_type));
2002  coerce_type = (newa->multidims ? array_type : element_type);
2003  coerce_hard = true;
2004  }
2005  else
2006  {
2007  /* Can't handle an empty array without a target type */
2008  if (newelems == NIL)
2009  ereport(ERROR,
2010  (errcode(ERRCODE_INDETERMINATE_DATATYPE),
2011  errmsg("cannot determine type of empty array"),
2012  errhint("Explicitly cast to the desired type, "
2013  "for example ARRAY[]::integer[]."),
2014  parser_errposition(pstate, a->location)));
2015 
2016  /* Select a common type for the elements */
2017  coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
2018 
2019  if (newa->multidims)
2020  {
2021  array_type = coerce_type;
2022  element_type = get_element_type(array_type);
2023  if (!OidIsValid(element_type))
2024  ereport(ERROR,
2025  (errcode(ERRCODE_UNDEFINED_OBJECT),
2026  errmsg("could not find element type for data type %s",
2027  format_type_be(array_type)),
2028  parser_errposition(pstate, a->location)));
2029  }
2030  else
2031  {
2032  element_type = coerce_type;
2033  array_type = get_array_type(element_type);
2034  if (!OidIsValid(array_type))
2035  ereport(ERROR,
2036  (errcode(ERRCODE_UNDEFINED_OBJECT),
2037  errmsg("could not find array type for data type %s",
2038  format_type_be(element_type)),
2039  parser_errposition(pstate, a->location)));
2040  }
2041  coerce_hard = false;
2042  }
2043 
2044  /*
2045  * Coerce elements to target type
2046  *
2047  * If the array has been explicitly cast, then the elements are in turn
2048  * explicitly coerced.
2049  *
2050  * If the array's type was merely derived from the common type of its
2051  * elements, then the elements are implicitly coerced to the common type.
2052  * This is consistent with other uses of select_common_type().
2053  */
2054  foreach(element, newelems)
2055  {
2056  Node *e = (Node *) lfirst(element);
2057  Node *newe;
2058 
2059  if (coerce_hard)
2060  {
2061  newe = coerce_to_target_type(pstate, e,
2062  exprType(e),
2063  coerce_type,
2064  typmod,
2067  -1);
2068  if (newe == NULL)
2069  ereport(ERROR,
2070  (errcode(ERRCODE_CANNOT_COERCE),
2071  errmsg("cannot cast type %s to %s",
2074  parser_errposition(pstate, exprLocation(e))));
2075  }
2076  else
2077  newe = coerce_to_common_type(pstate, e,
2078  coerce_type,
2079  "ARRAY");
2080  newcoercedelems = lappend(newcoercedelems, newe);
2081  }
2082 
2083  newa->array_typeid = array_type;
2084  /* array_collid will be set by parse_collate.c */
2085  newa->element_typeid = element_type;
2086  newa->elements = newcoercedelems;
2087  newa->location = a->location;
2088 
2089  return (Node *) newa;
2090 }
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2717
#define type_is_array(typid)
Definition: lsyscache.h:206
Node * coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:157
static Node * transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, Oid array_type, Oid element_type, int32 typmod)
Definition: parse_expr.c:1940
e
Definition: preproc-init.c:82
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:376

References a, Assert(), COERCE_EXPLICIT_CAST, coerce_to_common_type(), coerce_to_target_type(), coerce_type(), COERCION_EXPLICIT, element(), ArrayExpr::elements, ereport, errcode(), errhint(), errmsg(), ERROR, exprLocation(), exprType(), format_type_be(), get_array_type(), get_element_type(), InvalidOid, IsA, lappend(), lfirst, ArrayExpr::location, makeNode, NIL, OidIsValid, parser_errposition(), select_common_type(), transformExprRecurse(), and type_is_array.

Referenced by transformExprRecurse(), and transformTypeCast().

◆ transformBooleanTest()

static Node * transformBooleanTest ( ParseState pstate,
BooleanTest b 
)
static

Definition at line 2392 of file parse_expr.c.

2393 {
2394  const char *clausename;
2395 
2396  switch (b->booltesttype)
2397  {
2398  case IS_TRUE:
2399  clausename = "IS TRUE";
2400  break;
2401  case IS_NOT_TRUE:
2402  clausename = "IS NOT TRUE";
2403  break;
2404  case IS_FALSE:
2405  clausename = "IS FALSE";
2406  break;
2407  case IS_NOT_FALSE:
2408  clausename = "IS NOT FALSE";
2409  break;
2410  case IS_UNKNOWN:
2411  clausename = "IS UNKNOWN";
2412  break;
2413  case IS_NOT_UNKNOWN:
2414  clausename = "IS NOT UNKNOWN";
2415  break;
2416  default:
2417  elog(ERROR, "unrecognized booltesttype: %d",
2418  (int) b->booltesttype);
2419  clausename = NULL; /* keep compiler quiet */
2420  }
2421 
2422  b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
2423 
2424  b->arg = (Expr *) coerce_to_boolean(pstate,
2425  (Node *) b->arg,
2426  clausename);
2427 
2428  return (Node *) b;
2429 }
int b
Definition: isn.c:70
@ IS_NOT_TRUE
Definition: primnodes.h:1631
@ IS_NOT_FALSE
Definition: primnodes.h:1631
@ IS_NOT_UNKNOWN
Definition: primnodes.h:1631
@ IS_TRUE
Definition: primnodes.h:1631
@ IS_UNKNOWN
Definition: primnodes.h:1631
@ IS_FALSE
Definition: primnodes.h:1631

References b, coerce_to_boolean(), elog(), ERROR, IS_FALSE, IS_NOT_FALSE, IS_NOT_TRUE, IS_NOT_UNKNOWN, IS_TRUE, IS_UNKNOWN, and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformBoolExpr()

static Node * transformBoolExpr ( ParseState pstate,
BoolExpr a 
)
static

Definition at line 1329 of file parse_expr.c.

1330 {
1331  List *args = NIL;
1332  const char *opname;
1333  ListCell *lc;
1334 
1335  switch (a->boolop)
1336  {
1337  case AND_EXPR:
1338  opname = "AND";
1339  break;
1340  case OR_EXPR:
1341  opname = "OR";
1342  break;
1343  case NOT_EXPR:
1344  opname = "NOT";
1345  break;
1346  default:
1347  elog(ERROR, "unrecognized boolop: %d", (int) a->boolop);
1348  opname = NULL; /* keep compiler quiet */
1349  break;
1350  }
1351 
1352  foreach(lc, a->args)
1353  {
1354  Node *arg = (Node *) lfirst(lc);
1355 
1356  arg = transformExprRecurse(pstate, arg);
1357  arg = coerce_to_boolean(pstate, arg, opname);
1358  args = lappend(args, arg);
1359  }
1360 
1361  return (Node *) makeBoolExpr(a->boolop, args, a->location);
1362 }

References a, AND_EXPR, arg, generate_unaccent_rules::args, coerce_to_boolean(), elog(), ERROR, lappend(), lfirst, makeBoolExpr(), NIL, NOT_EXPR, OR_EXPR, and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformCaseExpr()

static Node * transformCaseExpr ( ParseState pstate,
CaseExpr c 
)
static

Definition at line 1558 of file parse_expr.c.

1559 {
1560  CaseExpr *newc = makeNode(CaseExpr);
1561  Node *last_srf = pstate->p_last_srf;
1562  Node *arg;
1563  CaseTestExpr *placeholder;
1564  List *newargs;
1565  List *resultexprs;
1566  ListCell *l;
1567  Node *defresult;
1568  Oid ptype;
1569 
1570  /* transform the test expression, if any */
1571  arg = transformExprRecurse(pstate, (Node *) c->arg);
1572 
1573  /* generate placeholder for test expression */
1574  if (arg)
1575  {
1576  /*
1577  * If test expression is an untyped literal, force it to text. We have
1578  * to do something now because we won't be able to do this coercion on
1579  * the placeholder. This is not as flexible as what was done in 7.4
1580  * and before, but it's good enough to handle the sort of silly coding
1581  * commonly seen.
1582  */
1583  if (exprType(arg) == UNKNOWNOID)
1584  arg = coerce_to_common_type(pstate, arg, TEXTOID, "CASE");
1585 
1586  /*
1587  * Run collation assignment on the test expression so that we know
1588  * what collation to mark the placeholder with. In principle we could
1589  * leave it to parse_collate.c to do that later, but propagating the
1590  * result to the CaseTestExpr would be unnecessarily complicated.
1591  */
1592  assign_expr_collations(pstate, arg);
1593 
1594  placeholder = makeNode(CaseTestExpr);
1595  placeholder->typeId = exprType(arg);
1596  placeholder->typeMod = exprTypmod(arg);
1597  placeholder->collation = exprCollation(arg);
1598  }
1599  else
1600  placeholder = NULL;
1601 
1602  newc->arg = (Expr *) arg;
1603 
1604  /* transform the list of arguments */
1605  newargs = NIL;
1606  resultexprs = NIL;
1607  foreach(l, c->args)
1608  {
1609  CaseWhen *w = lfirst_node(CaseWhen, l);
1610  CaseWhen *neww = makeNode(CaseWhen);
1611  Node *warg;
1612 
1613  warg = (Node *) w->expr;
1614  if (placeholder)
1615  {
1616  /* shorthand form was specified, so expand... */
1617  warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
1618  (Node *) placeholder,
1619  warg,
1620  w->location);
1621  }
1622  neww->expr = (Expr *) transformExprRecurse(pstate, warg);
1623 
1624  neww->expr = (Expr *) coerce_to_boolean(pstate,
1625  (Node *) neww->expr,
1626  "CASE/WHEN");
1627 
1628  warg = (Node *) w->result;
1629  neww->result = (Expr *) transformExprRecurse(pstate, warg);
1630  neww->location = w->location;
1631 
1632  newargs = lappend(newargs, neww);
1633  resultexprs = lappend(resultexprs, neww->result);
1634  }
1635 
1636  newc->args = newargs;
1637 
1638  /* transform the default clause */
1639  defresult = (Node *) c->defresult;
1640  if (defresult == NULL)
1641  {
1642  A_Const *n = makeNode(A_Const);
1643 
1644  n->isnull = true;
1645  n->location = -1;
1646  defresult = (Node *) n;
1647  }
1648  newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
1649 
1650  /*
1651  * Note: default result is considered the most significant type in
1652  * determining preferred type. This is how the code worked before, but it
1653  * seems a little bogus to me --- tgl
1654  */
1655  resultexprs = lcons(newc->defresult, resultexprs);
1656 
1657  ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
1658  Assert(OidIsValid(ptype));
1659  newc->casetype = ptype;
1660  /* casecollid will be set by parse_collate.c */
1661 
1662  /* Convert default result clause, if necessary */
1663  newc->defresult = (Expr *)
1664  coerce_to_common_type(pstate,
1665  (Node *) newc->defresult,
1666  ptype,
1667  "CASE/ELSE");
1668 
1669  /* Convert when-clause results, if necessary */
1670  foreach(l, newc->args)
1671  {
1672  CaseWhen *w = (CaseWhen *) lfirst(l);
1673 
1674  w->result = (Expr *)
1675  coerce_to_common_type(pstate,
1676  (Node *) w->result,
1677  ptype,
1678  "CASE/WHEN");
1679  }
1680 
1681  /* if any subexpression contained a SRF, complain */
1682  if (pstate->p_last_srf != last_srf)
1683  ereport(ERROR,
1684  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1685  /* translator: %s is name of a SQL construct, eg GROUP BY */
1686  errmsg("set-returning functions are not allowed in %s",
1687  "CASE"),
1688  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
1689  parser_errposition(pstate,
1690  exprLocation(pstate->p_last_srf))));
1691 
1692  newc->location = c->location;
1693 
1694  return (Node *) newc;
1695 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
List * lcons(void *datum, List *list)
Definition: list.c:494
void assign_expr_collations(ParseState *pstate, Node *expr)
#define lfirst_node(type, lc)
Definition: pg_list.h:176
char * c
int location
Definition: parsenodes.h:362
Expr * arg
Definition: primnodes.h:1240
int location
Definition: primnodes.h:1243
Expr * defresult
Definition: primnodes.h:1242
List * args
Definition: primnodes.h:1241
Expr * result
Definition: primnodes.h:1253
Expr * expr
Definition: primnodes.h:1252
int location
Definition: primnodes.h:1254

References AEXPR_OP, arg, CaseExpr::arg, CaseExpr::args, Assert(), assign_expr_collations(), coerce_to_boolean(), coerce_to_common_type(), CaseExpr::defresult, ereport, errcode(), errhint(), errmsg(), ERROR, CaseWhen::expr, exprCollation(), exprLocation(), exprType(), exprTypmod(), if(), A_Const::isnull, lappend(), lcons(), lfirst, lfirst_node, A_Const::location, CaseExpr::location, CaseWhen::location, makeNode, makeSimpleA_Expr(), NIL, OidIsValid, ParseState::p_last_srf, parser_errposition(), CaseWhen::result, select_common_type(), transformExprRecurse(), and CaseTestExpr::typeId.

Referenced by transformExprRecurse().

◆ transformCoalesceExpr()

static Node * transformCoalesceExpr ( ParseState pstate,
CoalesceExpr c 
)
static

Definition at line 2131 of file parse_expr.c.

2132 {
2134  Node *last_srf = pstate->p_last_srf;
2135  List *newargs = NIL;
2136  List *newcoercedargs = NIL;
2137  ListCell *args;
2138 
2139  foreach(args, c->args)
2140  {
2141  Node *e = (Node *) lfirst(args);
2142  Node *newe;
2143 
2144  newe = transformExprRecurse(pstate, e);
2145  newargs = lappend(newargs, newe);
2146  }
2147 
2148  newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
2149  /* coalescecollid will be set by parse_collate.c */
2150 
2151  /* Convert arguments if necessary */
2152  foreach(args, newargs)
2153  {
2154  Node *e = (Node *) lfirst(args);
2155  Node *newe;
2156 
2157  newe = coerce_to_common_type(pstate, e,
2158  newc->coalescetype,
2159  "COALESCE");
2160  newcoercedargs = lappend(newcoercedargs, newe);
2161  }
2162 
2163  /* if any subexpression contained a SRF, complain */
2164  if (pstate->p_last_srf != last_srf)
2165  ereport(ERROR,
2166  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2167  /* translator: %s is name of a SQL construct, eg GROUP BY */
2168  errmsg("set-returning functions are not allowed in %s",
2169  "COALESCE"),
2170  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
2171  parser_errposition(pstate,
2172  exprLocation(pstate->p_last_srf))));
2173 
2174  newc->args = newcoercedargs;
2175  newc->location = c->location;
2176  return (Node *) newc;
2177 }
List * args
Definition: primnodes.h:1417

References generate_unaccent_rules::args, CoalesceExpr::args, coerce_to_common_type(), ereport, errcode(), errhint(), errmsg(), ERROR, exprLocation(), lappend(), lfirst, CoalesceExpr::location, makeNode, NIL, ParseState::p_last_srf, parser_errposition(), select_common_type(), and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformCollateClause()

static Node * transformCollateClause ( ParseState pstate,
CollateClause c 
)
static

Definition at line 2640 of file parse_expr.c.

2641 {
2642  CollateExpr *newc;
2643  Oid argtype;
2644 
2645  newc = makeNode(CollateExpr);
2646  newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
2647 
2648  argtype = exprType((Node *) newc->arg);
2649 
2650  /*
2651  * The unknown type is not collatable, but coerce_type() takes care of it
2652  * separately, so we'll let it go here.
2653  */
2654  if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
2655  ereport(ERROR,
2656  (errcode(ERRCODE_DATATYPE_MISMATCH),
2657  errmsg("collations are not supported by type %s",
2658  format_type_be(argtype)),
2659  parser_errposition(pstate, c->location)));
2660 
2661  newc->collOid = LookupCollation(pstate, c->collname, c->location);
2662  newc->location = c->location;
2663 
2664  return (Node *) newc;
2665 }
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:3039
Oid LookupCollation(ParseState *pstate, List *collnames, int location)
Definition: parse_type.c:515
Expr * arg
Definition: primnodes.h:1206

References CollateExpr::arg, CollateExpr::collOid, ereport, errcode(), errmsg(), ERROR, exprType(), format_type_be(), CollateExpr::location, LookupCollation(), makeNode, parser_errposition(), transformExprRecurse(), and type_is_collatable().

Referenced by transformExprRecurse().

◆ transformColumnRef()

static Node * transformColumnRef ( ParseState pstate,
ColumnRef cref 
)
static

Definition at line 463 of file parse_expr.c.

464 {
465  Node *node = NULL;
466  char *nspname = NULL;
467  char *relname = NULL;
468  char *colname = NULL;
469  ParseNamespaceItem *nsitem;
470  int levels_up;
471  enum
472  {
473  CRERR_NO_COLUMN,
474  CRERR_NO_RTE,
475  CRERR_WRONG_DB,
476  CRERR_TOO_MANY
477  } crerr = CRERR_NO_COLUMN;
478  const char *err;
479 
480  /*
481  * Check to see if the column reference is in an invalid place within the
482  * query. We allow column references in most places, except in default
483  * expressions and partition bound expressions.
484  */
485  err = NULL;
486  switch (pstate->p_expr_kind)
487  {
488  case EXPR_KIND_NONE:
489  Assert(false); /* can't happen */
490  break;
491  case EXPR_KIND_OTHER:
492  case EXPR_KIND_JOIN_ON:
496  case EXPR_KIND_WHERE:
497  case EXPR_KIND_POLICY:
498  case EXPR_KIND_HAVING:
499  case EXPR_KIND_FILTER:
510  case EXPR_KIND_GROUP_BY:
511  case EXPR_KIND_ORDER_BY:
513  case EXPR_KIND_LIMIT:
514  case EXPR_KIND_OFFSET:
515  case EXPR_KIND_RETURNING:
516  case EXPR_KIND_VALUES:
532  /* okay */
533  break;
534 
536  err = _("cannot use column reference in DEFAULT expression");
537  break;
539  err = _("cannot use column reference in partition bound expression");
540  break;
541 
542  /*
543  * There is intentionally no default: case here, so that the
544  * compiler will warn if we add a new ParseExprKind without
545  * extending this switch. If we do see an unrecognized value at
546  * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
547  * which is sane anyway.
548  */
549  }
550  if (err)
551  ereport(ERROR,
552  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
553  errmsg_internal("%s", err),
554  parser_errposition(pstate, cref->location)));
555 
556  /*
557  * Give the PreParseColumnRefHook, if any, first shot. If it returns
558  * non-null then that's all, folks.
559  */
560  if (pstate->p_pre_columnref_hook != NULL)
561  {
562  node = pstate->p_pre_columnref_hook(pstate, cref);
563  if (node != NULL)
564  return node;
565  }
566 
567  /*----------
568  * The allowed syntaxes are:
569  *
570  * A First try to resolve as unqualified column name;
571  * if no luck, try to resolve as unqualified table name (A.*).
572  * A.B A is an unqualified table name; B is either a
573  * column or function name (trying column name first).
574  * A.B.C schema A, table B, col or func name C.
575  * A.B.C.D catalog A, schema B, table C, col or func D.
576  * A.* A is an unqualified table name; means whole-row value.
577  * A.B.* whole-row value of table B in schema A.
578  * A.B.C.* whole-row value of table C in schema B in catalog A.
579  *
580  * We do not need to cope with bare "*"; that will only be accepted by
581  * the grammar at the top level of a SELECT list, and transformTargetList
582  * will take care of it before it ever gets here. Also, "A.*" etc will
583  * be expanded by transformTargetList if they appear at SELECT top level,
584  * so here we are only going to see them as function or operator inputs.
585  *
586  * Currently, if a catalog name is given then it must equal the current
587  * database name; we check it here and then discard it.
588  *----------
589  */
590  switch (list_length(cref->fields))
591  {
592  case 1:
593  {
594  Node *field1 = (Node *) linitial(cref->fields);
595 
596  colname = strVal(field1);
597 
598  /* Try to identify as an unqualified column */
599  node = colNameToVar(pstate, colname, false, cref->location);
600 
601  if (node == NULL)
602  {
603  /*
604  * Not known as a column of any range-table entry.
605  *
606  * Try to find the name as a relation. Note that only
607  * relations already entered into the rangetable will be
608  * recognized.
609  *
610  * This is a hack for backwards compatibility with
611  * PostQUEL-inspired syntax. The preferred form now is
612  * "rel.*".
613  */
614  nsitem = refnameNamespaceItem(pstate, NULL, colname,
615  cref->location,
616  &levels_up);
617  if (nsitem)
618  node = transformWholeRowRef(pstate, nsitem, levels_up,
619  cref->location);
620  }
621  break;
622  }
623  case 2:
624  {
625  Node *field1 = (Node *) linitial(cref->fields);
626  Node *field2 = (Node *) lsecond(cref->fields);
627 
628  relname = strVal(field1);
629 
630  /* Locate the referenced nsitem */
631  nsitem = refnameNamespaceItem(pstate, nspname, relname,
632  cref->location,
633  &levels_up);
634  if (nsitem == NULL)
635  {
636  crerr = CRERR_NO_RTE;
637  break;
638  }
639 
640  /* Whole-row reference? */
641  if (IsA(field2, A_Star))
642  {
643  node = transformWholeRowRef(pstate, nsitem, levels_up,
644  cref->location);
645  break;
646  }
647 
648  colname = strVal(field2);
649 
650  /* Try to identify as a column of the nsitem */
651  node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
652  cref->location);
653  if (node == NULL)
654  {
655  /* Try it as a function call on the whole row */
656  node = transformWholeRowRef(pstate, nsitem, levels_up,
657  cref->location);
658  node = ParseFuncOrColumn(pstate,
659  list_make1(makeString(colname)),
660  list_make1(node),
661  pstate->p_last_srf,
662  NULL,
663  false,
664  cref->location);
665  }
666  break;
667  }
668  case 3:
669  {
670  Node *field1 = (Node *) linitial(cref->fields);
671  Node *field2 = (Node *) lsecond(cref->fields);
672  Node *field3 = (Node *) lthird(cref->fields);
673 
674  nspname = strVal(field1);
675  relname = strVal(field2);
676 
677  /* Locate the referenced nsitem */
678  nsitem = refnameNamespaceItem(pstate, nspname, relname,
679  cref->location,
680  &levels_up);
681  if (nsitem == NULL)
682  {
683  crerr = CRERR_NO_RTE;
684  break;
685  }
686 
687  /* Whole-row reference? */
688  if (IsA(field3, A_Star))
689  {
690  node = transformWholeRowRef(pstate, nsitem, levels_up,
691  cref->location);
692  break;
693  }
694 
695  colname = strVal(field3);
696 
697  /* Try to identify as a column of the nsitem */
698  node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
699  cref->location);
700  if (node == NULL)
701  {
702  /* Try it as a function call on the whole row */
703  node = transformWholeRowRef(pstate, nsitem, levels_up,
704  cref->location);
705  node = ParseFuncOrColumn(pstate,
706  list_make1(makeString(colname)),
707  list_make1(node),
708  pstate->p_last_srf,
709  NULL,
710  false,
711  cref->location);
712  }
713  break;
714  }
715  case 4:
716  {
717  Node *field1 = (Node *) linitial(cref->fields);
718  Node *field2 = (Node *) lsecond(cref->fields);
719  Node *field3 = (Node *) lthird(cref->fields);
720  Node *field4 = (Node *) lfourth(cref->fields);
721  char *catname;
722 
723  catname = strVal(field1);
724  nspname = strVal(field2);
725  relname = strVal(field3);
726 
727  /*
728  * We check the catalog name and then ignore it.
729  */
730  if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
731  {
732  crerr = CRERR_WRONG_DB;
733  break;
734  }
735 
736  /* Locate the referenced nsitem */
737  nsitem = refnameNamespaceItem(pstate, nspname, relname,
738  cref->location,
739  &levels_up);
740  if (nsitem == NULL)
741  {
742  crerr = CRERR_NO_RTE;
743  break;
744  }
745 
746  /* Whole-row reference? */
747  if (IsA(field4, A_Star))
748  {
749  node = transformWholeRowRef(pstate, nsitem, levels_up,
750  cref->location);
751  break;
752  }
753 
754  colname = strVal(field4);
755 
756  /* Try to identify as a column of the nsitem */
757  node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
758  cref->location);
759  if (node == NULL)
760  {
761  /* Try it as a function call on the whole row */
762  node = transformWholeRowRef(pstate, nsitem, levels_up,
763  cref->location);
764  node = ParseFuncOrColumn(pstate,
765  list_make1(makeString(colname)),
766  list_make1(node),
767  pstate->p_last_srf,
768  NULL,
769  false,
770  cref->location);
771  }
772  break;
773  }
774  default:
775  crerr = CRERR_TOO_MANY; /* too many dotted names */
776  break;
777  }
778 
779  /*
780  * Now give the PostParseColumnRefHook, if any, a chance. We pass the
781  * translation-so-far so that it can throw an error if it wishes in the
782  * case that it has a conflicting interpretation of the ColumnRef. (If it
783  * just translates anyway, we'll throw an error, because we can't undo
784  * whatever effects the preceding steps may have had on the pstate.) If it
785  * returns NULL, use the standard translation, or throw a suitable error
786  * if there is none.
787  */
788  if (pstate->p_post_columnref_hook != NULL)
789  {
790  Node *hookresult;
791 
792  hookresult = pstate->p_post_columnref_hook(pstate, cref, node);
793  if (node == NULL)
794  node = hookresult;
795  else if (hookresult != NULL)
796  ereport(ERROR,
797  (errcode(ERRCODE_AMBIGUOUS_COLUMN),
798  errmsg("column reference \"%s\" is ambiguous",
799  NameListToString(cref->fields)),
800  parser_errposition(pstate, cref->location)));
801  }
802 
803  /*
804  * Throw error if no translation found.
805  */
806  if (node == NULL)
807  {
808  switch (crerr)
809  {
810  case CRERR_NO_COLUMN:
811  errorMissingColumn(pstate, relname, colname, cref->location);
812  break;
813  case CRERR_NO_RTE:
814  errorMissingRTE(pstate, makeRangeVar(nspname, relname,
815  cref->location));
816  break;
817  case CRERR_WRONG_DB:
818  ereport(ERROR,
819  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
820  errmsg("cross-database references are not implemented: %s",
821  NameListToString(cref->fields)),
822  parser_errposition(pstate, cref->location)));
823  break;
824  case CRERR_TOO_MANY:
825  ereport(ERROR,
826  (errcode(ERRCODE_SYNTAX_ERROR),
827  errmsg("improper qualified name (too many dotted names): %s",
828  NameListToString(cref->fields)),
829  parser_errposition(pstate, cref->location)));
830  break;
831  }
832  }
833 
834  return node;
835 }
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3023
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
#define _(x)
Definition: elog.c:91
void err(int eval, const char *fmt,...)
Definition: err.c:43
Oid MyDatabaseId
Definition: globals.c:89
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:425
char * NameListToString(List *names)
Definition: namespace.c:3145
static Node * transformWholeRowRef(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location)
Definition: parse_expr.c:2484
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, Node *last_srf, FuncCall *fn, bool proc_call, int location)
Definition: parse_func.c:90
void errorMissingColumn(ParseState *pstate, const char *relname, const char *colname, int location)
void errorMissingRTE(ParseState *pstate, RangeVar *relation)
Node * scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, const char *colname, int location)
ParseNamespaceItem * refnameNamespaceItem(ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
Node * colNameToVar(ParseState *pstate, const char *colname, bool localonly, int location)
NameData relname
Definition: pg_class.h:38
#define lthird(l)
Definition: pg_list.h:188
#define lfourth(l)
Definition: pg_list.h:193
int location
Definition: parsenodes.h:293
List * fields
Definition: parsenodes.h:292
ParseExprKind p_expr_kind
Definition: parse_node.h:210
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:234
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:235
String * makeString(char *str)
Definition: value.c:63

References _, Assert(), colNameToVar(), ereport, err(), errcode(), errmsg(), errmsg_internal(), ERROR, errorMissingColumn(), errorMissingRTE(), EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CALL_ARGUMENT, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, EXPR_KIND_COPY_WHERE, EXPR_KIND_CYCLE_MARK, EXPR_KIND_DISTINCT_ON, EXPR_KIND_DOMAIN_CHECK, EXPR_KIND_EXECUTE_PARAMETER, EXPR_KIND_FILTER, EXPR_KIND_FROM_FUNCTION, EXPR_KIND_FROM_SUBSELECT, EXPR_KIND_FUNCTION_DEFAULT, EXPR_KIND_GENERATED_COLUMN, EXPR_KIND_GROUP_BY, EXPR_KIND_HAVING, EXPR_KIND_INDEX_EXPRESSION, EXPR_KIND_INDEX_PREDICATE, EXPR_KIND_INSERT_TARGET, EXPR_KIND_JOIN_ON, EXPR_KIND_JOIN_USING, EXPR_KIND_LIMIT, EXPR_KIND_MERGE_WHEN, EXPR_KIND_NONE, EXPR_KIND_OFFSET, EXPR_KIND_ORDER_BY, EXPR_KIND_OTHER, EXPR_KIND_PARTITION_BOUND, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_POLICY, EXPR_KIND_RETURNING, EXPR_KIND_SELECT_TARGET, EXPR_KIND_STATS_EXPRESSION, EXPR_KIND_TRIGGER_WHEN, EXPR_KIND_UPDATE_SOURCE, EXPR_KIND_UPDATE_TARGET, EXPR_KIND_VALUES, EXPR_KIND_VALUES_SINGLE, EXPR_KIND_WHERE, EXPR_KIND_WINDOW_FRAME_GROUPS, EXPR_KIND_WINDOW_FRAME_RANGE, EXPR_KIND_WINDOW_FRAME_ROWS, EXPR_KIND_WINDOW_ORDER, EXPR_KIND_WINDOW_PARTITION, ColumnRef::fields, get_database_name(), IsA, lfourth, linitial, list_length(), list_make1, ColumnRef::location, lsecond, lthird, makeRangeVar(), makeString(), MyDatabaseId, NameListToString(), ParseState::p_expr_kind, ParseState::p_last_srf, ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseFuncOrColumn(), parser_errposition(), refnameNamespaceItem(), relname, scanNSItemForColumn(), strVal, and transformWholeRowRef().

Referenced by transformExprRecurse().

◆ transformCurrentOfExpr()

static Node * transformCurrentOfExpr ( ParseState pstate,
CurrentOfExpr cexpr 
)
static

Definition at line 2432 of file parse_expr.c.

2433 {
2434  /* CURRENT OF can only appear at top level of UPDATE/DELETE */
2435  Assert(pstate->p_target_nsitem != NULL);
2436  cexpr->cvarno = pstate->p_target_nsitem->p_rtindex;
2437 
2438  /*
2439  * Check to see if the cursor name matches a parameter of type REFCURSOR.
2440  * If so, replace the raw name reference with a parameter reference. (This
2441  * is a hack for the convenience of plpgsql.)
2442  */
2443  if (cexpr->cursor_name != NULL) /* in case already transformed */
2444  {
2445  ColumnRef *cref = makeNode(ColumnRef);
2446  Node *node = NULL;
2447 
2448  /* Build an unqualified ColumnRef with the given name */
2449  cref->fields = list_make1(makeString(cexpr->cursor_name));
2450  cref->location = -1;
2451 
2452  /* See if there is a translation available from a parser hook */
2453  if (pstate->p_pre_columnref_hook != NULL)
2454  node = pstate->p_pre_columnref_hook(pstate, cref);
2455  if (node == NULL && pstate->p_post_columnref_hook != NULL)
2456  node = pstate->p_post_columnref_hook(pstate, cref, NULL);
2457 
2458  /*
2459  * XXX Should we throw an error if we get a translation that isn't a
2460  * refcursor Param? For now it seems best to silently ignore false
2461  * matches.
2462  */
2463  if (node != NULL && IsA(node, Param))
2464  {
2465  Param *p = (Param *) node;
2466 
2467  if (p->paramkind == PARAM_EXTERN &&
2468  p->paramtype == REFCURSOROID)
2469  {
2470  /* Matches, so convert CURRENT OF to a param reference */
2471  cexpr->cursor_name = NULL;
2472  cexpr->cursor_param = p->paramid;
2473  }
2474  }
2475  }
2476 
2477  return (Node *) cexpr;
2478 }
@ PARAM_EXTERN
Definition: primnodes.h:345
char * cursor_name
Definition: primnodes.h:1724
int paramid
Definition: primnodes.h:355
Oid paramtype
Definition: primnodes.h:356
ParamKind paramkind
Definition: primnodes.h:354
ParseNamespaceItem * p_target_nsitem
Definition: parse_node.h:207

References Assert(), CurrentOfExpr::cursor_name, CurrentOfExpr::cursor_param, CurrentOfExpr::cvarno, ColumnRef::fields, IsA, list_make1, ColumnRef::location, makeNode, makeString(), ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseNamespaceItem::p_rtindex, ParseState::p_target_nsitem, PARAM_EXTERN, Param::paramid, Param::paramkind, and Param::paramtype.

Referenced by transformExprRecurse().

◆ transformExpr()

Node* transformExpr ( ParseState pstate,
Node expr,
ParseExprKind  exprKind 
)

◆ transformExprRecurse()

static Node * transformExprRecurse ( ParseState pstate,
Node expr 
)
static

Definition at line 121 of file parse_expr.c.

122 {
123  Node *result;
124 
125  if (expr == NULL)
126  return NULL;
127 
128  /* Guard against stack overflow due to overly complex expressions */
130 
131  switch (nodeTag(expr))
132  {
133  case T_ColumnRef:
134  result = transformColumnRef(pstate, (ColumnRef *) expr);
135  break;
136 
137  case T_ParamRef:
138  result = transformParamRef(pstate, (ParamRef *) expr);
139  break;
140 
141  case T_A_Const:
142  result = (Node *) make_const(pstate, (A_Const *) expr);
143  break;
144 
145  case T_A_Indirection:
146  result = transformIndirection(pstate, (A_Indirection *) expr);
147  break;
148 
149  case T_A_ArrayExpr:
150  result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
151  InvalidOid, InvalidOid, -1);
152  break;
153 
154  case T_TypeCast:
155  result = transformTypeCast(pstate, (TypeCast *) expr);
156  break;
157 
158  case T_CollateClause:
159  result = transformCollateClause(pstate, (CollateClause *) expr);
160  break;
161 
162  case T_A_Expr:
163  {
164  A_Expr *a = (A_Expr *) expr;
165 
166  switch (a->kind)
167  {
168  case AEXPR_OP:
169  result = transformAExprOp(pstate, a);
170  break;
171  case AEXPR_OP_ANY:
172  result = transformAExprOpAny(pstate, a);
173  break;
174  case AEXPR_OP_ALL:
175  result = transformAExprOpAll(pstate, a);
176  break;
177  case AEXPR_DISTINCT:
178  case AEXPR_NOT_DISTINCT:
179  result = transformAExprDistinct(pstate, a);
180  break;
181  case AEXPR_NULLIF:
182  result = transformAExprNullIf(pstate, a);
183  break;
184  case AEXPR_IN:
185  result = transformAExprIn(pstate, a);
186  break;
187  case AEXPR_LIKE:
188  case AEXPR_ILIKE:
189  case AEXPR_SIMILAR:
190  /* we can transform these just like AEXPR_OP */
191  result = transformAExprOp(pstate, a);
192  break;
193  case AEXPR_BETWEEN:
194  case AEXPR_NOT_BETWEEN:
195  case AEXPR_BETWEEN_SYM:
197  result = transformAExprBetween(pstate, a);
198  break;
199  default:
200  elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
201  result = NULL; /* keep compiler quiet */
202  break;
203  }
204  break;
205  }
206 
207  case T_BoolExpr:
208  result = transformBoolExpr(pstate, (BoolExpr *) expr);
209  break;
210 
211  case T_FuncCall:
212  result = transformFuncCall(pstate, (FuncCall *) expr);
213  break;
214 
215  case T_MultiAssignRef:
216  result = transformMultiAssignRef(pstate, (MultiAssignRef *) expr);
217  break;
218 
219  case T_GroupingFunc:
220  result = transformGroupingFunc(pstate, (GroupingFunc *) expr);
221  break;
222 
223  case T_NamedArgExpr:
224  {
225  NamedArgExpr *na = (NamedArgExpr *) expr;
226 
227  na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
228  result = expr;
229  break;
230  }
231 
232  case T_SubLink:
233  result = transformSubLink(pstate, (SubLink *) expr);
234  break;
235 
236  case T_CaseExpr:
237  result = transformCaseExpr(pstate, (CaseExpr *) expr);
238  break;
239 
240  case T_RowExpr:
241  result = transformRowExpr(pstate, (RowExpr *) expr, false);
242  break;
243 
244  case T_CoalesceExpr:
245  result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
246  break;
247 
248  case T_MinMaxExpr:
249  result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
250  break;
251 
252  case T_XmlExpr:
253  result = transformXmlExpr(pstate, (XmlExpr *) expr);
254  break;
255 
256  case T_XmlSerialize:
257  result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
258  break;
259 
260  case T_NullTest:
261  {
262  NullTest *n = (NullTest *) expr;
263 
264  n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
265  /* the argument can be any type, so don't coerce it */
266  n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
267  result = expr;
268  break;
269  }
270 
271  case T_BooleanTest:
272  result = transformBooleanTest(pstate, (BooleanTest *) expr);
273  break;
274 
275  case T_CurrentOfExpr:
276  result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
277  break;
278 
279  /*
280  * In all places where DEFAULT is legal, the caller should have
281  * processed it rather than passing it to transformExpr().
282  */
283  case T_SetToDefault:
284  ereport(ERROR,
285  (errcode(ERRCODE_SYNTAX_ERROR),
286  errmsg("DEFAULT is not allowed in this context"),
287  parser_errposition(pstate,
288  ((SetToDefault *) expr)->location)));
289  break;
290 
291  /*
292  * CaseTestExpr doesn't require any processing; it is only
293  * injected into parse trees in a fully-formed state.
294  *
295  * Ordinarily we should not see a Var here, but it is convenient
296  * for transformJoinUsingClause() to create untransformed operator
297  * trees containing already-transformed Vars. The best
298  * alternative would be to deconstruct and reconstruct column
299  * references, which seems expensively pointless. So allow it.
300  */
301  case T_CaseTestExpr:
302  case T_Var:
303  {
304  result = (Node *) expr;
305  break;
306  }
307 
308  case T_JsonObjectConstructor:
309  result = transformJsonObjectConstructor(pstate, (JsonObjectConstructor *) expr);
310  break;
311 
312  case T_JsonArrayConstructor:
313  result = transformJsonArrayConstructor(pstate, (JsonArrayConstructor *) expr);
314  break;
315 
316  case T_JsonArrayQueryConstructor:
318  break;
319 
320  case T_JsonObjectAgg:
321  result = transformJsonObjectAgg(pstate, (JsonObjectAgg *) expr);
322  break;
323 
324  case T_JsonArrayAgg:
325  result = transformJsonArrayAgg(pstate, (JsonArrayAgg *) expr);
326  break;
327 
328  default:
329  /* should not reach here */
330  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
331  result = NULL; /* keep compiler quiet */
332  break;
333  }
334 
335  return result;
336 }
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2613
#define nodeTag(nodeptr)
Definition: nodes.h:133
Node * transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
Definition: parse_agg.c:248
static Node * transformJsonArrayConstructor(ParseState *pstate, JsonArrayConstructor *ctor)
Definition: parse_expr.c:3793
static Node * transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
Definition: parse_expr.c:2432
static Node * transformAExprOpAll(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:970
static Node * transformAExprIn(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1077
static Node * transformAExprOpAny(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:956
static Node * transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
Definition: parse_expr.c:2348
static Node * transformAExprNullIf(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1035
static Node * transformJsonArrayQueryConstructor(ParseState *pstate, JsonArrayQueryConstructor *ctor)
Definition: parse_expr.c:3544
static Node * transformColumnRef(ParseState *pstate, ColumnRef *cref)
Definition: parse_expr.c:463
static Node * transformCollateClause(ParseState *pstate, CollateClause *c)
Definition: parse_expr.c:2640
static Node * transformBoolExpr(ParseState *pstate, BoolExpr *a)
Definition: parse_expr.c:1329
static Node * transformFuncCall(ParseState *pstate, FuncCall *fn)
Definition: parse_expr.c:1365
static Node * transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
Definition: parse_expr.c:2180
static Node * transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
Definition: parse_expr.c:2131
static Node * transformSubLink(ParseState *pstate, SubLink *sublink)
Definition: parse_expr.c:1698
static Node * transformJsonObjectConstructor(ParseState *pstate, JsonObjectConstructor *ctor)
Definition: parse_expr.c:3509
static Node * transformAExprOp(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:875
static Node * transformJsonArrayAgg(ParseState *pstate, JsonArrayAgg *agg)
Definition: parse_expr.c:3752
static Node * transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
Definition: parse_expr.c:1410
static Node * transformBooleanTest(ParseState *pstate, BooleanTest *b)
Definition: parse_expr.c:2392
static Node * transformTypeCast(ParseState *pstate, TypeCast *tc)
Definition: parse_expr.c:2556
static Node * transformParamRef(ParseState *pstate, ParamRef *pref)
Definition: parse_expr.c:838
static Node * transformCaseExpr(ParseState *pstate, CaseExpr *c)
Definition: parse_expr.c:1558
static Node * transformIndirection(ParseState *pstate, A_Indirection *ind)
Definition: parse_expr.c:391
static Node * transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
Definition: parse_expr.c:2093
static Node * transformXmlExpr(ParseState *pstate, XmlExpr *x)
Definition: parse_expr.c:2219
static Node * transformAExprBetween(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1235
static Node * transformJsonObjectAgg(ParseState *pstate, JsonObjectAgg *agg)
Definition: parse_expr.c:3693
static Node * transformAExprDistinct(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:984
Const * make_const(ParseState *pstate, A_Const *aconst)
Definition: parse_node.c:352
@ AEXPR_NULLIF
Definition: parsenodes.h:316
@ AEXPR_ILIKE
Definition: parsenodes.h:319
@ AEXPR_IN
Definition: parsenodes.h:317
@ AEXPR_DISTINCT
Definition: parsenodes.h:314
@ AEXPR_SIMILAR
Definition: parsenodes.h:320
@ AEXPR_LIKE
Definition: parsenodes.h:318
@ AEXPR_OP_ANY
Definition: parsenodes.h:312
@ AEXPR_OP_ALL
Definition: parsenodes.h:313
void check_stack_depth(void)
Definition: postgres.c:3461
Expr * arg
Definition: primnodes.h:718

References a, AEXPR_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_DISTINCT, AEXPR_ILIKE, AEXPR_IN, AEXPR_LIKE, AEXPR_NOT_BETWEEN, AEXPR_NOT_BETWEEN_SYM, AEXPR_NOT_DISTINCT, AEXPR_NULLIF, AEXPR_OP, AEXPR_OP_ALL, AEXPR_OP_ANY, AEXPR_SIMILAR, NamedArgExpr::arg, NullTest::arg, check_stack_depth(), elog(), ereport, errcode(), errmsg(), ERROR, exprType(), InvalidOid, make_const(), nodeTag, parser_errposition(), transformAExprBetween(), transformAExprDistinct(), transformAExprIn(), transformAExprNullIf(), transformAExprOp(), transformAExprOpAll(), transformAExprOpAny(), transformArrayExpr(), transformBooleanTest(), transformBoolExpr(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformColumnRef(), transformCurrentOfExpr(), transformFuncCall(), transformGroupingFunc(), transformIndirection(), transformJsonArrayAgg(), transformJsonArrayConstructor(), transformJsonArrayQueryConstructor(), transformJsonObjectAgg(), transformJsonObjectConstructor(), transformMinMaxExpr(), transformMultiAssignRef(), transformParamRef(), transformRowExpr(), transformSubLink(), transformTypeCast(), transformXmlExpr(), transformXmlSerialize(), and type_is_rowtype().

Referenced by make_nulltest_from_distinct(), transformAExprBetween(), transformAExprDistinct(), transformAExprIn(), transformAExprNullIf(), transformAExprOp(), transformAExprOpAll(), transformAExprOpAny(), transformArrayExpr(), transformBooleanTest(), transformBoolExpr(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformExpr(), transformFuncCall(), transformIndirection(), transformJsonArrayQueryConstructor(), transformJsonObjectAgg(), transformJsonObjectConstructor(), transformJsonValueExpr(), transformMinMaxExpr(), transformMultiAssignRef(), transformSubLink(), transformTypeCast(), transformXmlExpr(), and transformXmlSerialize().

◆ transformFuncCall()

static Node * transformFuncCall ( ParseState pstate,
FuncCall fn 
)
static

Definition at line 1365 of file parse_expr.c.

1366 {
1367  Node *last_srf = pstate->p_last_srf;
1368  List *targs;
1369  ListCell *args;
1370 
1371  /* Transform the list of arguments ... */
1372  targs = NIL;
1373  foreach(args, fn->args)
1374  {
1375  targs = lappend(targs, transformExprRecurse(pstate,
1376  (Node *) lfirst(args)));
1377  }
1378 
1379  /*
1380  * When WITHIN GROUP is used, we treat its ORDER BY expressions as
1381  * additional arguments to the function, for purposes of function lookup
1382  * and argument type coercion. So, transform each such expression and add
1383  * them to the targs list. We don't explicitly mark where each argument
1384  * came from, but ParseFuncOrColumn can tell what's what by reference to
1385  * list_length(fn->agg_order).
1386  */
1387  if (fn->agg_within_group)
1388  {
1389  Assert(fn->agg_order != NIL);
1390  foreach(args, fn->agg_order)
1391  {
1392  SortBy *arg = (SortBy *) lfirst(args);
1393 
1394  targs = lappend(targs, transformExpr(pstate, arg->node,
1396  }
1397  }
1398 
1399  /* ... and hand off to ParseFuncOrColumn */
1400  return ParseFuncOrColumn(pstate,
1401  fn->funcname,
1402  targs,
1403  last_srf,
1404  fn,
1405  false,
1406  fn->location);
1407 }
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:103
static void * fn(void *arg)

References arg, generate_unaccent_rules::args, Assert(), EXPR_KIND_ORDER_BY, fn(), lappend(), lfirst, NIL, ParseState::p_last_srf, ParseFuncOrColumn(), transformExpr(), and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformIndirection()

static Node * transformIndirection ( ParseState pstate,
A_Indirection ind 
)
static

Definition at line 391 of file parse_expr.c.

392 {
393  Node *last_srf = pstate->p_last_srf;
394  Node *result = transformExprRecurse(pstate, ind->arg);
395  List *subscripts = NIL;
396  int location = exprLocation(result);
397  ListCell *i;
398 
399  /*
400  * We have to split any field-selection operations apart from
401  * subscripting. Adjacent A_Indices nodes have to be treated as a single
402  * multidimensional subscript operation.
403  */
404  foreach(i, ind->indirection)
405  {
406  Node *n = lfirst(i);
407 
408  if (IsA(n, A_Indices))
409  subscripts = lappend(subscripts, n);
410  else if (IsA(n, A_Star))
411  {
412  ereport(ERROR,
413  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
414  errmsg("row expansion via \"*\" is not supported here"),
415  parser_errposition(pstate, location)));
416  }
417  else
418  {
419  Node *newresult;
420 
421  Assert(IsA(n, String));
422 
423  /* process subscripts before this field selection */
424  if (subscripts)
425  result = (Node *) transformContainerSubscripts(pstate,
426  result,
427  exprType(result),
428  exprTypmod(result),
429  subscripts,
430  false);
431  subscripts = NIL;
432 
433  newresult = ParseFuncOrColumn(pstate,
434  list_make1(n),
435  list_make1(result),
436  last_srf,
437  NULL,
438  false,
439  location);
440  if (newresult == NULL)
441  unknown_attribute(pstate, result, strVal(n), location);
442  result = newresult;
443  }
444  }
445  /* process trailing subscripts, if any */
446  if (subscripts)
447  result = (Node *) transformContainerSubscripts(pstate,
448  result,
449  exprType(result),
450  exprTypmod(result),
451  subscripts,
452  false);
453 
454  return result;
455 }
static void unknown_attribute(ParseState *pstate, Node *relref, const char *attname, int location)
Definition: parse_expr.c:345
SubscriptingRef * transformContainerSubscripts(ParseState *pstate, Node *containerBase, Oid containerType, int32 containerTypMod, List *indirection, bool isAssignment)
Definition: parse_node.c:248
Definition: value.h:64

References Assert(), ereport, errcode(), errmsg(), ERROR, exprLocation(), exprType(), exprTypmod(), i, IsA, lappend(), lfirst, list_make1, NIL, ParseState::p_last_srf, ParseFuncOrColumn(), parser_errposition(), strVal, transformContainerSubscripts(), transformExprRecurse(), and unknown_attribute().

Referenced by transformExprRecurse().

◆ transformJsonAggConstructor()

static Node* transformJsonAggConstructor ( ParseState pstate,
JsonAggConstructor agg_ctor,
JsonReturning returning,
List args,
const char *  aggfn,
Oid  aggtype,
JsonConstructorType  ctor_type,
bool  unique,
bool  absent_on_null 
)
static

Definition at line 3610 of file parse_expr.c.

3615 {
3616  Oid aggfnoid;
3617  Node *node;
3618  Expr *aggfilter = agg_ctor->agg_filter ? (Expr *)
3619  transformWhereClause(pstate, agg_ctor->agg_filter,
3620  EXPR_KIND_FILTER, "FILTER") : NULL;
3621 
3623  CStringGetDatum(aggfn)));
3624 
3625  if (agg_ctor->over)
3626  {
3627  /* window function */
3628  WindowFunc *wfunc = makeNode(WindowFunc);
3629 
3630  wfunc->winfnoid = aggfnoid;
3631  wfunc->wintype = aggtype;
3632  /* wincollid and inputcollid will be set by parse_collate.c */
3633  wfunc->args = args;
3634  /* winref will be set by transformWindowFuncCall */
3635  wfunc->winstar = false;
3636  wfunc->winagg = true;
3637  wfunc->aggfilter = aggfilter;
3638  wfunc->location = agg_ctor->location;
3639 
3640  /*
3641  * ordered aggs not allowed in windows yet
3642  */
3643  if (agg_ctor->agg_order != NIL)
3644  ereport(ERROR,
3645  errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3646  errmsg("aggregate ORDER BY is not implemented for window functions"),
3647  parser_errposition(pstate, agg_ctor->location));
3648 
3649  /* parse_agg.c does additional window-func-specific processing */
3650  transformWindowFuncCall(pstate, wfunc, agg_ctor->over);
3651 
3652  node = (Node *) wfunc;
3653  }
3654  else
3655  {
3656  Aggref *aggref = makeNode(Aggref);
3657 
3658  aggref->aggfnoid = aggfnoid;
3659  aggref->aggtype = aggtype;
3660 
3661  /* aggcollid and inputcollid will be set by parse_collate.c */
3662  aggref->aggtranstype = InvalidOid; /* will be set by planner */
3663  /* aggargtypes will be set by transformAggregateCall */
3664  /* aggdirectargs and args will be set by transformAggregateCall */
3665  /* aggorder and aggdistinct will be set by transformAggregateCall */
3666  aggref->aggfilter = aggfilter;
3667  aggref->aggstar = false;
3668  aggref->aggvariadic = false;
3669  aggref->aggkind = AGGKIND_NORMAL;
3670  /* agglevelsup will be set by transformAggregateCall */
3671  aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
3672  aggref->location = agg_ctor->location;
3673 
3674  transformAggregateCall(pstate, aggref, args, agg_ctor->agg_order, false);
3675 
3676  node = (Node *) aggref;
3677  }
3678 
3679  return makeJsonConstructorExpr(pstate, ctor_type, NIL, (Expr *) node,
3680  returning, unique, absent_on_null,
3681  agg_ctor->location);
3682 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
@ AGGSPLIT_SIMPLE
Definition: nodes.h:385
void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, WindowDef *windef)
Definition: parse_agg.c:809
void transformAggregateCall(ParseState *pstate, Aggref *agg, List *args, List *aggorder, bool agg_distinct)
Definition: parse_agg.c:103
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
static Node * makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type, List *args, Expr *fexpr, JsonReturning *returning, bool unique, bool absent_on_null, int location)
Definition: parse_expr.c:3460
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
Datum regprocin(PG_FUNCTION_ARGS)
Definition: regproc.c:66
Oid aggfnoid
Definition: primnodes.h:422
Expr * aggfilter
Definition: primnodes.h:455
int location
Definition: primnodes.h:485
struct WindowDef * over
Definition: parsenodes.h:1793
List * args
Definition: primnodes.h:553
Expr * aggfilter
Definition: primnodes.h:555
int location
Definition: primnodes.h:563
Oid winfnoid
Definition: primnodes.h:545

References JsonAggConstructor::agg_filter, JsonAggConstructor::agg_order, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggfnoid, AGGSPLIT_SIMPLE, generate_unaccent_rules::args, WindowFunc::args, CStringGetDatum(), DatumGetInt32(), DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, EXPR_KIND_FILTER, InvalidOid, JsonAggConstructor::location, Aggref::location, WindowFunc::location, makeJsonConstructorExpr(), makeNode, NIL, JsonAggConstructor::over, parser_errposition(), regprocin(), transformAggregateCall(), transformWhereClause(), transformWindowFuncCall(), and WindowFunc::winfnoid.

Referenced by transformJsonArrayAgg(), and transformJsonObjectAgg().

◆ transformJsonArrayAgg()

static Node * transformJsonArrayAgg ( ParseState pstate,
JsonArrayAgg agg 
)
static

Definition at line 3752 of file parse_expr.c.

3753 {
3754  JsonReturning *returning;
3755  Node *arg;
3756  const char *aggfnname;
3757  Oid aggtype;
3758 
3760 
3761  returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
3762  list_make1(arg));
3763 
3764  if (returning->format->format_type == JS_FORMAT_JSONB)
3765  {
3766  aggfnname = agg->absent_on_null ?
3767  "pg_catalog.jsonb_agg_strict" : "pg_catalog.jsonb_agg";
3768  aggtype = JSONBOID;
3769  }
3770  else
3771  {
3772  aggfnname = agg->absent_on_null ?
3773  "pg_catalog.json_agg_strict" : "pg_catalog.json_agg";
3774  aggtype = JSONOID;
3775  }
3776 
3777  return transformJsonAggConstructor(pstate, agg->constructor, returning,
3778  list_make1(arg), aggfnname, aggtype,
3780  false, agg->absent_on_null);
3781 }
static JsonReturning * transformJsonConstructorOutput(ParseState *pstate, JsonOutput *output, List *args)
Definition: parse_expr.c:3363
static Node * transformJsonValueExpr(ParseState *pstate, JsonValueExpr *ve, JsonFormatType default_format)
Definition: parse_expr.c:3160
static Node * transformJsonAggConstructor(ParseState *pstate, JsonAggConstructor *agg_ctor, JsonReturning *returning, List *args, const char *aggfn, Oid aggtype, JsonConstructorType ctor_type, bool unique, bool absent_on_null)
Definition: parse_expr.c:3610
@ JSCTOR_JSON_ARRAYAGG
Definition: primnodes.h:1566
JsonOutput * output
Definition: parsenodes.h:1790
bool absent_on_null
Definition: parsenodes.h:1819
JsonValueExpr * arg
Definition: parsenodes.h:1818
JsonAggConstructor * constructor
Definition: parsenodes.h:1817

References JsonArrayAgg::absent_on_null, arg, JsonArrayAgg::arg, JsonArrayAgg::constructor, JsonReturning::format, JsonFormat::format_type, JS_FORMAT_DEFAULT, JS_FORMAT_JSONB, JSCTOR_JSON_ARRAYAGG, list_make1, JsonAggConstructor::output, transformJsonAggConstructor(), transformJsonConstructorOutput(), and transformJsonValueExpr().

Referenced by transformExprRecurse().

◆ transformJsonArrayConstructor()

static Node * transformJsonArrayConstructor ( ParseState pstate,
JsonArrayConstructor ctor 
)
static

Definition at line 3793 of file parse_expr.c.

3794 {
3795  JsonReturning *returning;
3796  List *args = NIL;
3797 
3798  /* transform element expressions, if any */
3799  if (ctor->exprs)
3800  {
3801  ListCell *lc;
3802 
3803  /* transform and append element arguments */
3804  foreach(lc, ctor->exprs)
3805  {
3806  JsonValueExpr *jsval = castNode(JsonValueExpr, lfirst(lc));
3807  Node *val = transformJsonValueExpr(pstate, jsval,
3809 
3810  args = lappend(args, val);
3811  }
3812  }
3813 
3814  returning = transformJsonConstructorOutput(pstate, ctor->output, args);
3815 
3816  return makeJsonConstructorExpr(pstate, JSCTOR_JSON_ARRAY, args, NULL,
3817  returning, false, ctor->absent_on_null,
3818  ctor->location);
3819 }
long val
Definition: informix.c:664
@ JSCTOR_JSON_ARRAY
Definition: primnodes.h:1564
JsonOutput * output
Definition: parsenodes.h:1763

References JsonArrayConstructor::absent_on_null, generate_unaccent_rules::args, castNode, JsonArrayConstructor::exprs, JS_FORMAT_DEFAULT, JSCTOR_JSON_ARRAY, lappend(), lfirst, JsonArrayConstructor::location, makeJsonConstructorExpr(), NIL, JsonArrayConstructor::output, transformJsonConstructorOutput(), transformJsonValueExpr(), and val.

Referenced by transformExprRecurse().

◆ transformJsonArrayQueryConstructor()

static Node * transformJsonArrayQueryConstructor ( ParseState pstate,
JsonArrayQueryConstructor ctor 
)
static

Definition at line 3544 of file parse_expr.c.

3546 {
3547  SubLink *sublink = makeNode(SubLink);
3550  Alias *alias = makeNode(Alias);
3551  ResTarget *target = makeNode(ResTarget);
3553  ColumnRef *colref = makeNode(ColumnRef);
3554  Query *query;
3555  ParseState *qpstate;
3556 
3557  /* Transform query only for counting target list entries. */
3558  qpstate = make_parsestate(pstate);
3559 
3560  query = transformStmt(qpstate, ctor->query);
3561 
3562  if (count_nonjunk_tlist_entries(query->targetList) != 1)
3563  ereport(ERROR,
3564  errcode(ERRCODE_SYNTAX_ERROR),
3565  errmsg("subquery must return only one column"),
3566  parser_errposition(pstate, ctor->location));
3567 
3568  free_parsestate(qpstate);
3569 
3570  colref->fields = list_make2(makeString(pstrdup("q")),
3571  makeString(pstrdup("a")));
3572  colref->location = ctor->location;
3573 
3574  agg->arg = makeJsonValueExpr((Expr *) colref, ctor->format);
3575  agg->absent_on_null = ctor->absent_on_null;
3577  agg->constructor->agg_order = NIL;
3578  agg->constructor->output = ctor->output;
3579  agg->constructor->location = ctor->location;
3580 
3581  target->name = NULL;
3582  target->indirection = NIL;
3583  target->val = (Node *) agg;
3584  target->location = ctor->location;
3585 
3586  alias->aliasname = pstrdup("q");
3587  alias->colnames = list_make1(makeString(pstrdup("a")));
3588 
3589  range->lateral = false;
3590  range->subquery = ctor->query;
3591  range->alias = alias;
3592 
3593  select->targetList = list_make1(target);
3594  select->fromClause = list_make1(range);
3595 
3596  sublink->subLinkType = EXPR_SUBLINK;
3597  sublink->subLinkId = 0;
3598  sublink->testexpr = NULL;
3599  sublink->operName = NIL;
3600  sublink->subselect = (Node *) select;
3601  sublink->location = ctor->location;
3602 
3603  return transformExprRecurse(pstate, (Node *) sublink);
3604 }
JsonValueExpr * makeJsonValueExpr(Expr *expr, JsonFormat *format)
Definition: makefuncs.c:851
char * pstrdup(const char *in)
Definition: mcxt.c:1624
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
Query * transformStmt(ParseState *pstate, Node *parseTree)
Definition: analyze.c:314
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
char * aliasname
Definition: primnodes.h:42
List * colnames
Definition: primnodes.h:43
List * targetList
Definition: parsenodes.h:189
int location
Definition: parsenodes.h:518
Node * val
Definition: parsenodes.h:517
List * indirection
Definition: parsenodes.h:516
char * name
Definition: parsenodes.h:515
int count_nonjunk_tlist_entries(List *tlist)
Definition: tlist.c:186
#define select(n, r, w, e, timeout)
Definition: win32_port.h:499

References JsonArrayQueryConstructor::absent_on_null, JsonArrayAgg::absent_on_null, JsonAggConstructor::agg_order, Alias::aliasname, JsonArrayAgg::arg, Alias::colnames, JsonArrayAgg::constructor, count_nonjunk_tlist_entries(), ereport, errcode(), errmsg(), ERROR, EXPR_SUBLINK, ColumnRef::fields, JsonArrayQueryConstructor::format, free_parsestate(), ResTarget::indirection, list_make1, list_make2, ColumnRef::location, ResTarget::location, JsonArrayQueryConstructor::location, JsonAggConstructor::location, SubLink::location, make_parsestate(), makeJsonValueExpr(), makeNode, makeString(), ResTarget::name, NIL, JsonArrayQueryConstructor::output, JsonAggConstructor::output, parser_errposition(), pstrdup(), JsonArrayQueryConstructor::query, range(), select, SubLink::subLinkId, SubLink::subLinkType, SubLink::subselect, Query::targetList, SubLink::testexpr, transformExprRecurse(), transformStmt(), and ResTarget::val.

Referenced by transformExprRecurse().

◆ transformJsonConstructorOutput()

static JsonReturning* transformJsonConstructorOutput ( ParseState pstate,
JsonOutput output,
List args 
)
static

Definition at line 3363 of file parse_expr.c.

3365 {
3366  JsonReturning *returning = transformJsonOutput(pstate, output, true);
3367 
3368  if (!OidIsValid(returning->typid))
3369  {
3370  ListCell *lc;
3371  bool have_jsonb = false;
3372 
3373  foreach(lc, args)
3374  {
3375  Node *expr = lfirst(lc);
3376  Oid typid = exprType(expr);
3377 
3378  have_jsonb |= typid == JSONBOID;
3379 
3380  if (have_jsonb)
3381  break;
3382  }
3383 
3384  if (have_jsonb)
3385  {
3386  returning->typid = JSONBOID;
3387  returning->format->format_type = JS_FORMAT_JSONB;
3388  }
3389  else
3390  {
3391  /* XXX TEXT is default by the standard, but we return JSON */
3392  returning->typid = JSONOID;
3393  returning->format->format_type = JS_FORMAT_JSON;
3394  }
3395 
3396  returning->typmod = -1;
3397  }
3398 
3399  return returning;
3400 }
FILE * output
static JsonReturning * transformJsonOutput(ParseState *pstate, const JsonOutput *output, bool allow_format)
Definition: parse_expr.c:3321

References generate_unaccent_rules::args, exprType(), JsonReturning::format, JsonFormat::format_type, JS_FORMAT_JSON, JS_FORMAT_JSONB, lfirst, OidIsValid, output, transformJsonOutput(), JsonReturning::typid, and JsonReturning::typmod.

Referenced by transformJsonArrayAgg(), transformJsonArrayConstructor(), transformJsonObjectAgg(), and transformJsonObjectConstructor().

◆ transformJsonObjectAgg()

static Node * transformJsonObjectAgg ( ParseState pstate,
JsonObjectAgg agg 
)
static

Definition at line 3693 of file parse_expr.c.

3694 {
3695  JsonReturning *returning;
3696  Node *key;
3697  Node *val;
3698  List *args;
3699  const char *aggfnname;
3700  Oid aggtype;
3701 
3702  key = transformExprRecurse(pstate, (Node *) agg->arg->key);
3704  args = list_make2(key, val);
3705 
3706  returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
3707  args);
3708 
3709  if (returning->format->format_type == JS_FORMAT_JSONB)
3710  {
3711  if (agg->absent_on_null)
3712  if (agg->unique)
3713  aggfnname = "pg_catalog.jsonb_object_agg_unique_strict";
3714  else
3715  aggfnname = "pg_catalog.jsonb_object_agg_strict";
3716  else if (agg->unique)
3717  aggfnname = "pg_catalog.jsonb_object_agg_unique";
3718  else
3719  aggfnname = "pg_catalog.jsonb_object_agg";
3720 
3721  aggtype = JSONBOID;
3722  }
3723  else
3724  {
3725  if (agg->absent_on_null)
3726  if (agg->unique)
3727  aggfnname = "pg_catalog.json_object_agg_unique_strict";
3728  else
3729  aggfnname = "pg_catalog.json_object_agg_strict";
3730  else if (agg->unique)
3731  aggfnname = "pg_catalog.json_object_agg_unique";
3732  else
3733  aggfnname = "pg_catalog.json_object_agg";
3734 
3735  aggtype = JSONOID;
3736  }
3737 
3738  return transformJsonAggConstructor(pstate, agg->constructor, returning,
3739  args, aggfnname, aggtype,
3741  agg->unique, agg->absent_on_null);
3742 }
@ JSCTOR_JSON_OBJECTAGG
Definition: primnodes.h:1565
JsonValueExpr * value
Definition: parsenodes.h:1738
JsonAggConstructor * constructor
Definition: parsenodes.h:1804
JsonKeyValue * arg
Definition: parsenodes.h:1805
bool absent_on_null
Definition: parsenodes.h:1806

References JsonObjectAgg::absent_on_null, JsonObjectAgg::arg, generate_unaccent_rules::args, JsonObjectAgg::constructor, JsonReturning::format, JsonFormat::format_type, JS_FORMAT_DEFAULT, JS_FORMAT_JSONB, JSCTOR_JSON_OBJECTAGG, JsonKeyValue::key, sort-test::key, list_make2, JsonAggConstructor::output, transformExprRecurse(), transformJsonAggConstructor(), transformJsonConstructorOutput(), transformJsonValueExpr(), JsonObjectAgg::unique, val, and JsonKeyValue::value.

Referenced by transformExprRecurse().

◆ transformJsonObjectConstructor()

static Node * transformJsonObjectConstructor ( ParseState pstate,
JsonObjectConstructor ctor 
)
static

Definition at line 3509 of file parse_expr.c.

3510 {
3511  JsonReturning *returning;
3512  List *args = NIL;
3513 
3514  /* transform key-value pairs, if any */
3515  if (ctor->exprs)
3516  {
3517  ListCell *lc;
3518 
3519  /* transform and append key-value arguments */
3520  foreach(lc, ctor->exprs)
3521  {
3523  Node *key = transformExprRecurse(pstate, (Node *) kv->key);
3524  Node *val = transformJsonValueExpr(pstate, kv->value,
3526 
3527  args = lappend(args, key);
3528  args = lappend(args, val);
3529  }
3530  }
3531 
3532  returning = transformJsonConstructorOutput(pstate, ctor->output, args);
3533 
3534  return makeJsonConstructorExpr(pstate, JSCTOR_JSON_OBJECT, args, NULL,
3535  returning, ctor->unique,
3536  ctor->absent_on_null, ctor->location);
3537 }
@ JSCTOR_JSON_OBJECT
Definition: primnodes.h:1563
JsonOutput * output
Definition: parsenodes.h:1749

References JsonObjectConstructor::absent_on_null, generate_unaccent_rules::args, castNode, JsonObjectConstructor::exprs, JS_FORMAT_DEFAULT, JSCTOR_JSON_OBJECT, JsonKeyValue::key, sort-test::key, lappend(), lfirst, JsonObjectConstructor::location, makeJsonConstructorExpr(), NIL, JsonObjectConstructor::output, transformExprRecurse(), transformJsonConstructorOutput(), transformJsonValueExpr(), JsonObjectConstructor::unique, val, and JsonKeyValue::value.

Referenced by transformExprRecurse().

◆ transformJsonOutput()

static JsonReturning* transformJsonOutput ( ParseState pstate,
const JsonOutput output,
bool  allow_format 
)
static

Definition at line 3321 of file parse_expr.c.

3323 {
3324  JsonReturning *ret;
3325 
3326  /* if output clause is not specified, make default clause value */
3327  if (!output)
3328  {
3329  ret = makeNode(JsonReturning);
3330 
3332  ret->typid = InvalidOid;
3333  ret->typmod = -1;
3334 
3335  return ret;
3336  }
3337 
3338  ret = copyObject(output->returning);
3339 
3340  typenameTypeIdAndMod(pstate, output->typeName, &ret->typid, &ret->typmod);
3341 
3342  if (output->typeName->setof)
3343  ereport(ERROR,
3344  errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3345  errmsg("returning SETOF types is not supported in SQL/JSON functions"));
3346 
3347  if (ret->format->format_type == JS_FORMAT_DEFAULT)
3348  /* assign JSONB format when returning jsonb, or JSON format otherwise */
3349  ret->format->format_type =
3350  ret->typid == JSONBOID ? JS_FORMAT_JSONB : JS_FORMAT_JSON;
3351  else
3352  checkJsonOutputFormat(pstate, ret->format, ret->typid, allow_format);
3353 
3354  return ret;
3355 }
JsonFormat * makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
Definition: makefuncs.c:835
static void checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format, Oid targettype, bool allow_format_for_non_strings)
Definition: parse_expr.c:3271
void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p)
Definition: parse_type.c:310

References checkJsonOutputFormat(), copyObject, ereport, errcode(), errmsg(), ERROR, JsonReturning::format, JsonFormat::format_type, InvalidOid, JS_ENC_DEFAULT, JS_FORMAT_DEFAULT, JS_FORMAT_JSON, JS_FORMAT_JSONB, makeJsonFormat(), makeNode, output, typenameTypeIdAndMod(), JsonReturning::typid, and JsonReturning::typmod.

Referenced by transformJsonConstructorOutput().

◆ transformJsonValueExpr()

static Node* transformJsonValueExpr ( ParseState pstate,
JsonValueExpr ve,
JsonFormatType  default_format 
)
static

Definition at line 3160 of file parse_expr.c.

3162 {
3163  Node *expr = transformExprRecurse(pstate, (Node *) ve->raw_expr);
3164  Node *rawexpr;
3166  Oid exprtype;
3167  int location;
3168  char typcategory;
3169  bool typispreferred;
3170 
3171  /*
3172  * Using JSON_VALUE here is slightly bogus: perhaps we need to be passed a
3173  * JsonConstructorType so that we can use one of JSON_OBJECTAGG, etc.
3174  */
3175  if (exprType(expr) == UNKNOWNOID)
3176  expr = coerce_to_specific_type(pstate, expr, TEXTOID, "JSON_VALUE");
3177 
3178  rawexpr = expr;
3179  exprtype = exprType(expr);
3180  location = exprLocation(expr);
3181 
3182  get_type_category_preferred(exprtype, &typcategory, &typispreferred);
3183 
3184  if (ve->format->format_type != JS_FORMAT_DEFAULT)
3185  {
3186  if (ve->format->encoding != JS_ENC_DEFAULT && exprtype != BYTEAOID)
3187  ereport(ERROR,
3188  errcode(ERRCODE_DATATYPE_MISMATCH),
3189  errmsg("JSON ENCODING clause is only allowed for bytea input type"),
3190  parser_errposition(pstate, ve->format->location));
3191 
3192  if (exprtype == JSONOID || exprtype == JSONBOID)
3193  {
3194  format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
3195  ereport(WARNING,
3196  errmsg("FORMAT JSON has no effect for json and jsonb types"),
3197  parser_errposition(pstate, ve->format->location));
3198  }
3199  else
3200  format = ve->format->format_type;
3201  }
3202  else if (exprtype == JSONOID || exprtype == JSONBOID)
3203  format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
3204  else
3205  format = default_format;
3206 
3207  if (format != JS_FORMAT_DEFAULT)
3208  {
3209  Oid targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
3210  Node *orig = makeCaseTestExpr(expr);
3211  Node *coerced;
3212 
3213  expr = orig;
3214 
3215  if (exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING)
3216  ereport(ERROR,
3217  errcode(ERRCODE_DATATYPE_MISMATCH),
3219  "cannot use non-string types with implicit FORMAT JSON clause" :
3220  "cannot use non-string types with explicit FORMAT JSON clause"),
3221  parser_errposition(pstate, ve->format->location >= 0 ?
3222  ve->format->location : location));
3223 
3224  /* Convert encoded JSON text from bytea. */
3225  if (format == JS_FORMAT_JSON && exprtype == BYTEAOID)
3226  {
3227  expr = makeJsonByteaToTextConversion(expr, ve->format, location);
3228  exprtype = TEXTOID;
3229  }
3230 
3231  /* Try to coerce to the target type. */
3232  coerced = coerce_to_target_type(pstate, expr, exprtype,
3233  targettype, -1,
3236  location);
3237 
3238  if (!coerced)
3239  {
3240  /* If coercion failed, use to_json()/to_jsonb() functions. */
3241  Oid fnoid = targettype == JSONOID ? F_TO_JSON : F_TO_JSONB;
3242  FuncExpr *fexpr = makeFuncExpr(fnoid, targettype,
3243  list_make1(expr),
3246 
3247  fexpr->location = location;
3248 
3249  coerced = (Node *) fexpr;
3250  }
3251 
3252  if (coerced == orig)
3253  expr = rawexpr;
3254  else
3255  {
3256  ve = copyObject(ve);
3257  ve->raw_expr = (Expr *) rawexpr;
3258  ve->formatted_expr = (Expr *) coerced;
3259 
3260  expr = (Node *) ve;
3261  }
3262  }
3263 
3264  return expr;
3265 }
#define WARNING
Definition: elog.h:36
static Node * makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
Definition: parse_expr.c:3127
JsonFormatType
Definition: primnodes.h:1518
JsonEncoding encoding
Definition: primnodes.h:1533
Expr * formatted_expr
Definition: primnodes.h:1557
JsonFormat * format
Definition: primnodes.h:1558
Expr * raw_expr
Definition: primnodes.h:1556

References COERCE_EXPLICIT_CALL, COERCE_EXPLICIT_CAST, coerce_to_specific_type(), coerce_to_target_type(), COERCION_EXPLICIT, copyObject, JsonFormat::encoding, ereport, errcode(), errmsg(), ERROR, exprLocation(), exprType(), format, JsonValueExpr::format, JsonFormat::format_type, JsonValueExpr::formatted_expr, get_type_category_preferred(), InvalidOid, JS_ENC_DEFAULT, JS_FORMAT_DEFAULT, JS_FORMAT_JSON, JS_FORMAT_JSONB, list_make1, FuncExpr::location, JsonFormat::location, makeCaseTestExpr(), makeFuncExpr(), makeJsonByteaToTextConversion(), parser_errposition(), JsonValueExpr::raw_expr, transformExprRecurse(), and WARNING.

Referenced by transformJsonArrayAgg(), transformJsonArrayConstructor(), transformJsonObjectAgg(), and transformJsonObjectConstructor().

◆ transformMinMaxExpr()

static Node * transformMinMaxExpr ( ParseState pstate,
MinMaxExpr m 
)
static

Definition at line 2180 of file parse_expr.c.

2181 {
2182  MinMaxExpr *newm = makeNode(MinMaxExpr);
2183  List *newargs = NIL;
2184  List *newcoercedargs = NIL;
2185  const char *funcname = (m->op == IS_GREATEST) ? "GREATEST" : "LEAST";
2186  ListCell *args;
2187 
2188  newm->op = m->op;
2189  foreach(args, m->args)
2190  {
2191  Node *e = (Node *) lfirst(args);
2192  Node *newe;
2193 
2194  newe = transformExprRecurse(pstate, e);
2195  newargs = lappend(newargs, newe);
2196  }
2197 
2198  newm->minmaxtype = select_common_type(pstate, newargs, funcname, NULL);
2199  /* minmaxcollid and inputcollid will be set by parse_collate.c */
2200 
2201  /* Convert arguments if necessary */
2202  foreach(args, newargs)
2203  {
2204  Node *e = (Node *) lfirst(args);
2205  Node *newe;
2206 
2207  newe = coerce_to_common_type(pstate, e,
2208  newm->minmaxtype,
2209  funcname);
2210  newcoercedargs = lappend(newcoercedargs, newe);
2211  }
2212 
2213  newm->args = newcoercedargs;
2214  newm->location = m->location;
2215  return (Node *) newm;
2216 }
#define funcname
Definition: indent_codes.h:69
@ IS_GREATEST
Definition: primnodes.h:1427
List * args
Definition: primnodes.h:1443
int location
Definition: primnodes.h:1445
MinMaxOp op
Definition: primnodes.h:1441

References generate_unaccent_rules::args, MinMaxExpr::args, coerce_to_common_type(), funcname, IS_GREATEST, lappend(), lfirst, MinMaxExpr::location, makeNode, NIL, MinMaxExpr::op, select_common_type(), and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformMultiAssignRef()

static Node * transformMultiAssignRef ( ParseState pstate,
MultiAssignRef maref 
)
static

Definition at line 1410 of file parse_expr.c.

1411 {
1412  SubLink *sublink;
1413  RowExpr *rexpr;
1414  Query *qtree;
1415  TargetEntry *tle;
1416 
1417  /* We should only see this in first-stage processing of UPDATE tlists */
1419 
1420  /* We only need to transform the source if this is the first column */
1421  if (maref->colno == 1)
1422  {
1423  /*
1424  * For now, we only allow EXPR SubLinks and RowExprs as the source of
1425  * an UPDATE multiassignment. This is sufficient to cover interesting
1426  * cases; at worst, someone would have to write (SELECT * FROM expr)
1427  * to expand a composite-returning expression of another form.
1428  */
1429  if (IsA(maref->source, SubLink) &&
1430  ((SubLink *) maref->source)->subLinkType == EXPR_SUBLINK)
1431  {
1432  /* Relabel it as a MULTIEXPR_SUBLINK */
1433  sublink = (SubLink *) maref->source;
1434  sublink->subLinkType = MULTIEXPR_SUBLINK;
1435  /* And transform it */
1436  sublink = (SubLink *) transformExprRecurse(pstate,
1437  (Node *) sublink);
1438 
1439  qtree = castNode(Query, sublink->subselect);
1440 
1441  /* Check subquery returns required number of columns */
1442  if (count_nonjunk_tlist_entries(qtree->targetList) != maref->ncolumns)
1443  ereport(ERROR,
1444  (errcode(ERRCODE_SYNTAX_ERROR),
1445  errmsg("number of columns does not match number of values"),
1446  parser_errposition(pstate, sublink->location)));
1447 
1448  /*
1449  * Build a resjunk tlist item containing the MULTIEXPR SubLink,
1450  * and add it to pstate->p_multiassign_exprs, whence it will later
1451  * get appended to the completed targetlist. We needn't worry
1452  * about selecting a resno for it; transformUpdateStmt will do
1453  * that.
1454  */
1455  tle = makeTargetEntry((Expr *) sublink, 0, NULL, true);
1457  tle);
1458 
1459  /*
1460  * Assign a unique-within-this-targetlist ID to the MULTIEXPR
1461  * SubLink. We can just use its position in the
1462  * p_multiassign_exprs list.
1463  */
1464  sublink->subLinkId = list_length(pstate->p_multiassign_exprs);
1465  }
1466  else if (IsA(maref->source, RowExpr))
1467  {
1468  /* Transform the RowExpr, allowing SetToDefault items */
1469  rexpr = (RowExpr *) transformRowExpr(pstate,
1470  (RowExpr *) maref->source,
1471  true);
1472 
1473  /* Check it returns required number of columns */
1474  if (list_length(rexpr->args) != maref->ncolumns)
1475  ereport(ERROR,
1476  (errcode(ERRCODE_SYNTAX_ERROR),
1477  errmsg("number of columns does not match number of values"),
1478  parser_errposition(pstate, rexpr->location)));
1479 
1480  /*
1481  * Temporarily append it to p_multiassign_exprs, so we can get it
1482  * back when we come back here for additional columns.
1483  */
1484  tle = makeTargetEntry((Expr *) rexpr, 0, NULL, true);
1486  tle);
1487  }
1488  else
1489  ereport(ERROR,
1490  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1491  errmsg("source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression"),
1492  parser_errposition(pstate, exprLocation(maref->source))));
1493  }
1494  else
1495  {
1496  /*
1497  * Second or later column in a multiassignment. Re-fetch the
1498  * transformed SubLink or RowExpr, which we assume is still the last
1499  * entry in p_multiassign_exprs.
1500  */
1501  Assert(pstate->p_multiassign_exprs != NIL);
1502  tle = (TargetEntry *) llast(pstate->p_multiassign_exprs);
1503  }
1504 
1505  /*
1506  * Emit the appropriate output expression for the current column
1507  */
1508  if (IsA(tle->expr, SubLink))
1509  {
1510  Param *param;
1511 
1512  sublink = (SubLink *) tle->expr;
1513  Assert(sublink->subLinkType == MULTIEXPR_SUBLINK);
1514  qtree = castNode(Query, sublink->subselect);
1515 
1516  /* Build a Param representing the current subquery output column */
1517  tle = (TargetEntry *) list_nth(qtree->targetList, maref->colno - 1);
1518  Assert(!tle->resjunk);
1519 
1520  param = makeNode(Param);
1521  param->paramkind = PARAM_MULTIEXPR;
1522  param->paramid = (sublink->subLinkId << 16) | maref->colno;
1523  param->paramtype = exprType((Node *) tle->expr);
1524  param->paramtypmod = exprTypmod((Node *) tle->expr);
1525  param->paramcollid = exprCollation((Node *) tle->expr);
1526  param->location = exprLocation((Node *) tle->expr);
1527 
1528  return (Node *) param;
1529  }
1530 
1531  if (IsA(tle->expr, RowExpr))
1532  {
1533  Node *result;
1534 
1535  rexpr = (RowExpr *) tle->expr;
1536 
1537  /* Just extract and return the next element of the RowExpr */
1538  result = (Node *) list_nth(rexpr->args, maref->colno - 1);
1539 
1540  /*
1541  * If we're at the last column, delete the RowExpr from
1542  * p_multiassign_exprs; we don't need it anymore, and don't want it in
1543  * the finished UPDATE tlist. We assume this is still the last entry
1544  * in p_multiassign_exprs.
1545  */
1546  if (maref->colno == maref->ncolumns)
1547  pstate->p_multiassign_exprs =
1549 
1550  return result;
1551  }
1552 
1553  elog(ERROR, "unexpected expr type in multiassign list");
1554  return NULL; /* keep compiler quiet */
1555 }
List * list_delete_last(List *list)
Definition: list.c:956
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:241
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
@ MULTIEXPR_SUBLINK
Definition: primnodes.h:929
@ PARAM_MULTIEXPR
Definition: primnodes.h:348
int location
Definition: primnodes.h:362
List * p_multiassign_exprs
Definition: parse_node.h:212
int location
Definition: primnodes.h:1360
Expr * expr
Definition: primnodes.h:1816

References RowExpr::args, Assert(), castNode, MultiAssignRef::colno, count_nonjunk_tlist_entries(), elog(), ereport, errcode(), errmsg(), ERROR, TargetEntry::expr, EXPR_KIND_UPDATE_SOURCE, EXPR_SUBLINK, exprCollation(), exprLocation(), exprType(), exprTypmod(), IsA, lappend(), list_delete_last(), list_length(), list_nth(), llast, Param::location, RowExpr::location, makeNode, makeTargetEntry(), MULTIEXPR_SUBLINK, MultiAssignRef::ncolumns, NIL, ParseState::p_expr_kind, ParseState::p_multiassign_exprs, PARAM_MULTIEXPR, Param::paramid, Param::paramkind, Param::paramtype, parser_errposition(), MultiAssignRef::source, SubLink::subLinkId, SubLink::subLinkType, SubLink::subselect, Query::targetList, transformExprRecurse(), and transformRowExpr().

Referenced by transformExprRecurse().

◆ transformParamRef()

static Node * transformParamRef ( ParseState pstate,
ParamRef pref 
)
static

Definition at line 838 of file parse_expr.c.

839 {
840  Node *result;
841 
842  /*
843  * The core parser knows nothing about Params. If a hook is supplied,
844  * call it. If not, or if the hook returns NULL, throw a generic error.
845  */
846  if (pstate->p_paramref_hook != NULL)
847  result = pstate->p_paramref_hook(pstate, pref);
848  else
849  result = NULL;
850 
851  if (result == NULL)
852  ereport(ERROR,
853  (errcode(ERRCODE_UNDEFINED_PARAMETER),
854  errmsg("there is no parameter $%d", pref->number),
855  parser_errposition(pstate, pref->location)));
856 
857  return result;
858 }
int location
Definition: parsenodes.h:303
int number
Definition: parsenodes.h:302
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:236

References ereport, errcode(), errmsg(), ERROR, ParamRef::location, ParamRef::number, ParseState::p_paramref_hook, and parser_errposition().

Referenced by transformExprRecurse().

◆ transformRowExpr()

static Node * transformRowExpr ( ParseState pstate,
RowExpr r,
bool  allowDefault 
)
static

Definition at line 2093 of file parse_expr.c.

2094 {
2095  RowExpr *newr;
2096  char fname[16];
2097  int fnum;
2098 
2099  newr = makeNode(RowExpr);
2100 
2101  /* Transform the field expressions */
2102  newr->args = transformExpressionList(pstate, r->args,
2103  pstate->p_expr_kind, allowDefault);
2104 
2105  /* Disallow more columns than will fit in a tuple */
2107  ereport(ERROR,
2108  (errcode(ERRCODE_TOO_MANY_COLUMNS),
2109  errmsg("ROW expressions can have at most %d entries",
2111  parser_errposition(pstate, r->location)));
2112 
2113  /* Barring later casting, we consider the type RECORD */
2114  newr->row_typeid = RECORDOID;
2115  newr->row_format = COERCE_IMPLICIT_CAST;
2116 
2117  /* ROW() has anonymous columns, so invent some field names */
2118  newr->colnames = NIL;
2119  for (fnum = 1; fnum <= list_length(newr->args); fnum++)
2120  {
2121  snprintf(fname, sizeof(fname), "f%d", fnum);
2122  newr->colnames = lappend(newr->colnames, makeString(pstrdup(fname)));
2123  }
2124 
2125  newr->location = r->location;
2126 
2127  return (Node *) newr;
2128 }
#define MaxTupleAttributeNumber
Definition: htup_details.h:34
List * transformExpressionList(ParseState *pstate, List *exprlist, ParseExprKind exprKind, bool allowDefault)
Definition: parse_target.c:221
#define snprintf
Definition: port.h:238
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:663

References RowExpr::args, COERCE_IMPLICIT_CAST, ereport, errcode(), errmsg(), ERROR, lappend(), list_length(), RowExpr::location, makeNode, makeString(), MaxTupleAttributeNumber, NIL, ParseState::p_expr_kind, parser_errposition(), pstrdup(), snprintf, and transformExpressionList().

Referenced by transformExprRecurse(), and transformMultiAssignRef().

◆ transformSubLink()

static Node * transformSubLink ( ParseState pstate,
SubLink sublink 
)
static

Definition at line 1698 of file parse_expr.c.

1699 {
1700  Node *result = (Node *) sublink;
1701  Query *qtree;
1702  const char *err;
1703 
1704  /*
1705  * Check to see if the sublink is in an invalid place within the query. We
1706  * allow sublinks everywhere in SELECT/INSERT/UPDATE/DELETE/MERGE, but
1707  * generally not in utility statements.
1708  */
1709  err = NULL;
1710  switch (pstate->p_expr_kind)
1711  {
1712  case EXPR_KIND_NONE:
1713  Assert(false); /* can't happen */
1714  break;
1715  case EXPR_KIND_OTHER:
1716  /* Accept sublink here; caller must throw error if wanted */
1717  break;
1718  case EXPR_KIND_JOIN_ON:
1719  case EXPR_KIND_JOIN_USING:
1722  case EXPR_KIND_WHERE:
1723  case EXPR_KIND_POLICY:
1724  case EXPR_KIND_HAVING:
1725  case EXPR_KIND_FILTER:
1735  case EXPR_KIND_MERGE_WHEN:
1736  case EXPR_KIND_GROUP_BY:
1737  case EXPR_KIND_ORDER_BY:
1738  case EXPR_KIND_DISTINCT_ON:
1739  case EXPR_KIND_LIMIT:
1740  case EXPR_KIND_OFFSET:
1741  case EXPR_KIND_RETURNING:
1742  case EXPR_KIND_VALUES:
1744  case EXPR_KIND_CYCLE_MARK:
1745  /* okay */
1746  break;
1749  err = _("cannot use subquery in check constraint");
1750  break;
1753  err = _("cannot use subquery in DEFAULT expression");
1754  break;
1756  err = _("cannot use subquery in index expression");
1757  break;
1759  err = _("cannot use subquery in index predicate");
1760  break;
1762  err = _("cannot use subquery in statistics expression");
1763  break;
1765  err = _("cannot use subquery in transform expression");
1766  break;
1768  err = _("cannot use subquery in EXECUTE parameter");
1769  break;
1771  err = _("cannot use subquery in trigger WHEN condition");
1772  break;
1774  err = _("cannot use subquery in partition bound");
1775  break;
1777  err = _("cannot use subquery in partition key expression");
1778  break;
1780  err = _("cannot use subquery in CALL argument");
1781  break;
1782  case EXPR_KIND_COPY_WHERE:
1783  err = _("cannot use subquery in COPY FROM WHERE condition");
1784  break;
1786  err = _("cannot use subquery in column generation expression");
1787  break;
1788 
1789  /*
1790  * There is intentionally no default: case here, so that the
1791  * compiler will warn if we add a new ParseExprKind without
1792  * extending this switch. If we do see an unrecognized value at
1793  * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
1794  * which is sane anyway.
1795  */
1796  }
1797  if (err)
1798  ereport(ERROR,
1799  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1800  errmsg_internal("%s", err),
1801  parser_errposition(pstate, sublink->location)));
1802 
1803  pstate->p_hasSubLinks = true;
1804 
1805  /*
1806  * OK, let's transform the sub-SELECT.
1807  */
1808  qtree = parse_sub_analyze(sublink->subselect, pstate, NULL, false, true);
1809 
1810  /*
1811  * Check that we got a SELECT. Anything else should be impossible given
1812  * restrictions of the grammar, but check anyway.
1813  */
1814  if (!IsA(qtree, Query) ||
1815  qtree->commandType != CMD_SELECT)
1816  elog(ERROR, "unexpected non-SELECT command in SubLink");
1817 
1818  sublink->subselect = (Node *) qtree;
1819 
1820  if (sublink->subLinkType == EXISTS_SUBLINK)
1821  {
1822  /*
1823  * EXISTS needs no test expression or combining operator. These fields
1824  * should be null already, but make sure.
1825  */
1826  sublink->testexpr = NULL;
1827  sublink->operName = NIL;
1828  }
1829  else if (sublink->subLinkType == EXPR_SUBLINK ||
1830  sublink->subLinkType == ARRAY_SUBLINK)
1831  {
1832  /*
1833  * Make sure the subselect delivers a single column (ignoring resjunk
1834  * targets).
1835  */
1836  if (count_nonjunk_tlist_entries(qtree->targetList) != 1)
1837  ereport(ERROR,
1838  (errcode(ERRCODE_SYNTAX_ERROR),
1839  errmsg("subquery must return only one column"),
1840  parser_errposition(pstate, sublink->location)));
1841 
1842  /*
1843  * EXPR and ARRAY need no test expression or combining operator. These
1844  * fields should be null already, but make sure.
1845  */
1846  sublink->testexpr = NULL;
1847  sublink->operName = NIL;
1848  }
1849  else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
1850  {
1851  /* Same as EXPR case, except no restriction on number of columns */
1852  sublink->testexpr = NULL;
1853  sublink->operName = NIL;
1854  }
1855  else
1856  {
1857  /* ALL, ANY, or ROWCOMPARE: generate row-comparing expression */
1858  Node *lefthand;
1859  List *left_list;
1860  List *right_list;
1861  ListCell *l;
1862 
1863  /*
1864  * If the source was "x IN (select)", convert to "x = ANY (select)".
1865  */
1866  if (sublink->operName == NIL)
1867  sublink->operName = list_make1(makeString("="));
1868 
1869  /*
1870  * Transform lefthand expression, and convert to a list
1871  */
1872  lefthand = transformExprRecurse(pstate, sublink->testexpr);
1873  if (lefthand && IsA(lefthand, RowExpr))
1874  left_list = ((RowExpr *) lefthand)->args;
1875  else
1876  left_list = list_make1(lefthand);
1877 
1878  /*
1879  * Build a list of PARAM_SUBLINK nodes representing the output columns
1880  * of the subquery.
1881  */
1882  right_list = NIL;
1883  foreach(l, qtree->targetList)
1884  {
1885  TargetEntry *tent = (TargetEntry *) lfirst(l);
1886  Param *param;
1887 
1888  if (tent->resjunk)
1889  continue;
1890 
1891  param = makeNode(Param);
1892  param->paramkind = PARAM_SUBLINK;
1893  param->paramid = tent->resno;
1894  param->paramtype = exprType((Node *) tent->expr);
1895  param->paramtypmod = exprTypmod((Node *) tent->expr);
1896  param->paramcollid = exprCollation((Node *) tent->expr);
1897  param->location = -1;
1898 
1899  right_list = lappend(right_list, param);
1900  }
1901 
1902  /*
1903  * We could rely on make_row_comparison_op to complain if the list
1904  * lengths differ, but we prefer to generate a more specific error
1905  * message.
1906  */
1907  if (list_length(left_list) < list_length(right_list))
1908  ereport(ERROR,
1909  (errcode(ERRCODE_SYNTAX_ERROR),
1910  errmsg("subquery has too many columns"),
1911  parser_errposition(pstate, sublink->location)));
1912  if (list_length(left_list) > list_length(right_list))
1913  ereport(ERROR,
1914  (errcode(ERRCODE_SYNTAX_ERROR),
1915  errmsg("subquery has too few columns"),
1916  parser_errposition(pstate, sublink->location)));
1917 
1918  /*
1919  * Identify the combining operator(s) and generate a suitable
1920  * row-comparison expression.
1921  */
1922  sublink->testexpr = make_row_comparison_op(pstate,
1923  sublink->operName,
1924  left_list,
1925  right_list,
1926  sublink->location);
1927  }
1928 
1929  return result;
1930 }
@ CMD_SELECT
Definition: nodes.h:276
Query * parse_sub_analyze(Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent, bool resolve_unknowns)
Definition: analyze.c:224
@ ARRAY_SUBLINK
Definition: primnodes.h:930
@ EXISTS_SUBLINK
Definition: primnodes.h:924
@ PARAM_SUBLINK
Definition: primnodes.h:347
bool p_hasSubLinks
Definition: parse_node.h:225
CmdType commandType
Definition: parsenodes.h:128
AttrNumber resno
Definition: primnodes.h:1818

References _, ARRAY_SUBLINK, Assert(), CMD_SELECT, Query::commandType, count_nonjunk_tlist_entries(), elog(), ereport, err(), errcode(), errmsg(), errmsg_internal(), ERROR, EXISTS_SUBLINK, TargetEntry::expr, EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CALL_ARGUMENT, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, EXPR_KIND_COPY_WHERE, EXPR_KIND_CYCLE_MARK, EXPR_KIND_DISTINCT_ON, EXPR_KIND_DOMAIN_CHECK, EXPR_KIND_EXECUTE_PARAMETER, EXPR_KIND_FILTER, EXPR_KIND_FROM_FUNCTION, EXPR_KIND_FROM_SUBSELECT, EXPR_KIND_FUNCTION_DEFAULT, EXPR_KIND_GENERATED_COLUMN, EXPR_KIND_GROUP_BY, EXPR_KIND_HAVING, EXPR_KIND_INDEX_EXPRESSION, EXPR_KIND_INDEX_PREDICATE, EXPR_KIND_INSERT_TARGET, EXPR_KIND_JOIN_ON, EXPR_KIND_JOIN_USING, EXPR_KIND_LIMIT, EXPR_KIND_MERGE_WHEN, EXPR_KIND_NONE, EXPR_KIND_OFFSET, EXPR_KIND_ORDER_BY, EXPR_KIND_OTHER, EXPR_KIND_PARTITION_BOUND, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_POLICY, EXPR_KIND_RETURNING, EXPR_KIND_SELECT_TARGET, EXPR_KIND_STATS_EXPRESSION, EXPR_KIND_TRIGGER_WHEN, EXPR_KIND_UPDATE_SOURCE, EXPR_KIND_UPDATE_TARGET, EXPR_KIND_VALUES, EXPR_KIND_VALUES_SINGLE, EXPR_KIND_WHERE, EXPR_KIND_WINDOW_FRAME_GROUPS, EXPR_KIND_WINDOW_FRAME_RANGE, EXPR_KIND_WINDOW_FRAME_ROWS, EXPR_KIND_WINDOW_ORDER, EXPR_KIND_WINDOW_PARTITION, EXPR_SUBLINK, exprCollation(), exprType(), exprTypmod(), IsA, lappend(), lfirst, list_length(), list_make1, Param::location, SubLink::location, make_row_comparison_op(), makeNode, makeString(), MULTIEXPR_SUBLINK, NIL, ParseState::p_expr_kind, ParseState::p_hasSubLinks, PARAM_SUBLINK, Param::paramid, Param::paramkind, Param::paramtype, parse_sub_analyze(), parser_errposition(), TargetEntry::resno, SubLink::subLinkType, SubLink::subselect, Query::targetList, SubLink::testexpr, and transformExprRecurse().

Referenced by transformExprRecurse().

◆ transformTypeCast()

static Node * transformTypeCast ( ParseState pstate,
TypeCast tc 
)
static

Definition at line 2556 of file parse_expr.c.

2557 {
2558  Node *result;
2559  Node *arg = tc->arg;
2560  Node *expr;
2561  Oid inputType;
2562  Oid targetType;
2563  int32 targetTypmod;
2564  int location;
2565 
2566  /* Look up the type name first */
2567  typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
2568 
2569  /*
2570  * If the subject of the typecast is an ARRAY[] construct and the target
2571  * type is an array type, we invoke transformArrayExpr() directly so that
2572  * we can pass down the type information. This avoids some cases where
2573  * transformArrayExpr() might not infer the correct type. Otherwise, just
2574  * transform the argument normally.
2575  */
2576  if (IsA(arg, A_ArrayExpr))
2577  {
2578  Oid targetBaseType;
2579  int32 targetBaseTypmod;
2580  Oid elementType;
2581 
2582  /*
2583  * If target is a domain over array, work with the base array type
2584  * here. Below, we'll cast the array type to the domain. In the
2585  * usual case that the target is not a domain, the remaining steps
2586  * will be a no-op.
2587  */
2588  targetBaseTypmod = targetTypmod;
2589  targetBaseType = getBaseTypeAndTypmod(targetType, &targetBaseTypmod);
2590  elementType = get_element_type(targetBaseType);
2591  if (OidIsValid(elementType))
2592  {
2593  expr = transformArrayExpr(pstate,
2594  (A_ArrayExpr *) arg,
2595  targetBaseType,
2596  elementType,
2597  targetBaseTypmod);
2598  }
2599  else
2600  expr = transformExprRecurse(pstate, arg);
2601  }
2602  else
2603  expr = transformExprRecurse(pstate, arg);
2604 
2605  inputType = exprType(expr);
2606  if (inputType == InvalidOid)
2607  return expr; /* do nothing if NULL input */
2608 
2609  /*
2610  * Location of the coercion is preferentially the location of the :: or
2611  * CAST symbol, but if there is none then use the location of the type
2612  * name (this can happen in TypeName 'string' syntax, for instance).
2613  */
2614  location = tc->location;
2615  if (location < 0)
2616  location = tc->typeName->location;
2617 
2618  result = coerce_to_target_type(pstate, expr, inputType,
2619  targetType, targetTypmod,
2622  location);
2623  if (result == NULL)
2624  ereport(ERROR,
2625  (errcode(ERRCODE_CANNOT_COERCE),
2626  errmsg("cannot cast type %s to %s",
2627  format_type_be(inputType),
2628  format_type_be(targetType)),
2629  parser_coercion_errposition(pstate, location, expr)));
2630 
2631  return result;
2632 }
signed int int32
Definition: c.h:478
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2496
TypeName * typeName
Definition: parsenodes.h:372
int location
Definition: parsenodes.h:373
Node * arg
Definition: parsenodes.h:371
int location
Definition: parsenodes.h:273

References arg, TypeCast::arg, COERCE_EXPLICIT_CAST, coerce_to_target_type(), COERCION_EXPLICIT, ereport, errcode(), errmsg(), ERROR, exprType(), format_type_be(), get_element_type(), getBaseTypeAndTypmod(), InvalidOid, IsA, TypeName::location, TypeCast::location, OidIsValid, parser_coercion_errposition(), transformArrayExpr(), transformExprRecurse(), TypeCast::typeName, and typenameTypeIdAndMod().

Referenced by transformExprRecurse().

◆ transformWholeRowRef()

static Node * transformWholeRowRef ( ParseState pstate,
ParseNamespaceItem nsitem,
int  sublevels_up,
int  location 
)
static

Definition at line 2484 of file parse_expr.c.

2486 {
2487  /*
2488  * Build the appropriate referencing node. Normally this can be a
2489  * whole-row Var, but if the nsitem is a JOIN USING alias then it contains
2490  * only a subset of the columns of the underlying join RTE, so that will
2491  * not work. Instead we immediately expand the reference into a RowExpr.
2492  * Since the JOIN USING's common columns are fully determined at this
2493  * point, there seems no harm in expanding it now rather than during
2494  * planning.
2495  *
2496  * Note that if the RTE is a function returning scalar, we create just a
2497  * plain reference to the function value, not a composite containing a
2498  * single column. This is pretty inconsistent at first sight, but it's
2499  * what we've done historically. One argument for it is that "rel" and
2500  * "rel.*" mean the same thing for composite relations, so why not for
2501  * scalar functions...
2502  */
2503  if (nsitem->p_names == nsitem->p_rte->eref)
2504  {
2505  Var *result;
2506 
2507  result = makeWholeRowVar(nsitem->p_rte, nsitem->p_rtindex,
2508  sublevels_up, true);
2509 
2510  /* location is not filled in by makeWholeRowVar */
2511  result->location = location;
2512 
2513  /* mark Var if it's nulled by any outer joins */
2514  markNullableIfNeeded(pstate, result);
2515 
2516  /* mark relation as requiring whole-row SELECT access */
2517  markVarForSelectPriv(pstate, result);
2518 
2519  return (Node *) result;
2520  }
2521  else
2522  {
2523  RowExpr *rowexpr;
2524  List *fields;
2525 
2526  /*
2527  * We want only as many columns as are listed in p_names->colnames,
2528  * and we should use those names not whatever possibly-aliased names
2529  * are in the RTE. We needn't worry about marking the RTE for SELECT
2530  * access, as the common columns are surely so marked already.
2531  */
2532  expandRTE(nsitem->p_rte, nsitem->p_rtindex,
2533  sublevels_up, location, false,
2534  NULL, &fields);
2535  rowexpr = makeNode(RowExpr);
2536  rowexpr->args = list_truncate(fields,
2537  list_length(nsitem->p_names->colnames));
2538  rowexpr->row_typeid = RECORDOID;
2539  rowexpr->row_format = COERCE_IMPLICIT_CAST;
2540  rowexpr->colnames = copyObject(nsitem->p_names->colnames);
2541  rowexpr->location = location;
2542 
2543  /* XXX we ought to mark the row as possibly nullable */
2544 
2545  return (Node *) rowexpr;
2546  }
2547 }
List * list_truncate(List *list, int new_size)
Definition: list.c:630
Var * makeWholeRowVar(RangeTblEntry *rte, int varno, Index varlevelsup, bool allowScalar)
Definition: makefuncs.c:136
void markNullableIfNeeded(ParseState *pstate, Var *var)
void markVarForSelectPriv(ParseState *pstate, Var *var)
void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, int location, bool include_dropped, List **colnames, List **colvars)
RangeTblEntry * p_rte
Definition: parse_node.h:286
Alias * eref
Definition: parsenodes.h:1200
Definition: primnodes.h:226
int location
Definition: primnodes.h:271

References RowExpr::args, COERCE_IMPLICIT_CAST, Alias::colnames, copyObject, RangeTblEntry::eref, expandRTE(), list_length(), list_truncate(), Var::location, RowExpr::location, makeNode, makeWholeRowVar(), markNullableIfNeeded(), markVarForSelectPriv(), ParseNamespaceItem::p_names, ParseNamespaceItem::p_rte, and ParseNamespaceItem::p_rtindex.

Referenced by transformColumnRef().

◆ transformXmlExpr()

static Node * transformXmlExpr ( ParseState pstate,
XmlExpr x 
)
static

Definition at line 2219 of file parse_expr.c.

2220 {
2221  XmlExpr *newx;
2222  ListCell *lc;
2223  int i;
2224 
2225  newx = makeNode(XmlExpr);
2226  newx->op = x->op;
2227  if (x->name)
2228  newx->name = map_sql_identifier_to_xml_name(x->name, false, false);
2229  else
2230  newx->name = NULL;
2231  newx->xmloption = x->xmloption;
2232  newx->type = XMLOID; /* this just marks the node as transformed */
2233  newx->typmod = -1;
2234  newx->location = x->location;
2235 
2236  /*
2237  * gram.y built the named args as a list of ResTarget. Transform each,
2238  * and break the names out as a separate list.
2239  */
2240  newx->named_args = NIL;
2241  newx->arg_names = NIL;
2242 
2243  foreach(lc, x->named_args)
2244  {
2245  ResTarget *r = lfirst_node(ResTarget, lc);
2246  Node *expr;
2247  char *argname;
2248 
2249  expr = transformExprRecurse(pstate, r->val);
2250 
2251  if (r->name)
2252  argname = map_sql_identifier_to_xml_name(r->name, false, false);
2253  else if (IsA(r->val, ColumnRef))
2255  true, false);
2256  else
2257  {
2258  ereport(ERROR,
2259  (errcode(ERRCODE_SYNTAX_ERROR),
2260  x->op == IS_XMLELEMENT
2261  ? errmsg("unnamed XML attribute value must be a column reference")
2262  : errmsg("unnamed XML element value must be a column reference"),
2263  parser_errposition(pstate, r->location)));
2264  argname = NULL; /* keep compiler quiet */
2265  }
2266 
2267  /* reject duplicate argnames in XMLELEMENT only */
2268  if (x->op == IS_XMLELEMENT)
2269  {
2270  ListCell *lc2;
2271 
2272  foreach(lc2, newx->arg_names)
2273  {
2274  if (strcmp(argname, strVal(lfirst(lc2))) == 0)
2275  ereport(ERROR,
2276  (errcode(ERRCODE_SYNTAX_ERROR),
2277  errmsg("XML attribute name \"%s\" appears more than once",
2278  argname),
2279  parser_errposition(pstate, r->location)));
2280  }
2281  }
2282 
2283  newx->named_args = lappend(newx->named_args, expr);
2284  newx->arg_names = lappend(newx->arg_names, makeString(argname));
2285  }
2286 
2287  /* The other arguments are of varying types depending on the function */
2288  newx->args = NIL;
2289  i = 0;
2290  foreach(lc, x->args)
2291  {
2292  Node *e = (Node *) lfirst(lc);
2293  Node *newe;
2294 
2295  newe = transformExprRecurse(pstate, e);
2296  switch (x->op)
2297  {
2298  case IS_XMLCONCAT:
2299  newe = coerce_to_specific_type(pstate, newe, XMLOID,
2300  "XMLCONCAT");
2301  break;
2302  case IS_XMLELEMENT:
2303  /* no coercion necessary */
2304  break;
2305  case IS_XMLFOREST:
2306  newe = coerce_to_specific_type(pstate, newe, XMLOID,
2307  "XMLFOREST");
2308  break;
2309  case IS_XMLPARSE:
2310  if (i == 0)
2311  newe = coerce_to_specific_type(pstate, newe, TEXTOID,
2312  "XMLPARSE");
2313  else
2314  newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
2315  break;
2316  case IS_XMLPI:
2317  newe = coerce_to_specific_type(pstate, newe, TEXTOID,
2318  "XMLPI");
2319  break;
2320  case IS_XMLROOT:
2321  if (i == 0)
2322  newe = coerce_to_specific_type(pstate, newe, XMLOID,
2323  "XMLROOT");
2324  else if (i == 1)
2325  newe = coerce_to_specific_type(pstate, newe, TEXTOID,
2326  "XMLROOT");
2327  else
2328  newe = coerce_to_specific_type(pstate, newe, INT4OID,
2329  "XMLROOT");
2330  break;
2331  case IS_XMLSERIALIZE:
2332  /* not handled here */
2333  Assert(false);
2334  break;
2335  case IS_DOCUMENT:
2336  newe = coerce_to_specific_type(pstate, newe, XMLOID,
2337  "IS DOCUMENT");
2338  break;
2339  }
2340  newx->args = lappend(newx->args, newe);
2341  i++;
2342  }
2343 
2344  return (Node *) newx;
2345 }
int x
Definition: isn.c:71
char * FigureColname(Node *node)
@ IS_DOCUMENT
Definition: primnodes.h:1468
@ IS_XMLFOREST
Definition: primnodes.h:1463
@ IS_XMLCONCAT
Definition: primnodes.h:1461
@ IS_XMLPI
Definition: primnodes.h:1465
@ IS_XMLPARSE
Definition: primnodes.h:1464
@ IS_XMLSERIALIZE
Definition: primnodes.h:1467
@ IS_XMLROOT
Definition: primnodes.h:1466
@ IS_XMLELEMENT
Definition: primnodes.h:1462
List * args
Definition: primnodes.h:1489
int location
Definition: primnodes.h:1498
List * named_args
Definition: primnodes.h:1485
XmlExprOp op
Definition: primnodes.h:1481
char * map_sql_identifier_to_xml_name(const char *ident, bool fully_escaped, bool escape_period)
Definition: xml.c:2286

References XmlExpr::args, Assert(), coerce_to_boolean(), coerce_to_specific_type(), ereport, errcode(), errmsg(), ERROR, FigureColname(), i, IS_DOCUMENT, IS_XMLCONCAT, IS_XMLELEMENT,