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 NodetransformSQLValueFunction (ParseState *pstate, SQLValueFunction *svf)
 
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 NodetransformJsonIsPredicate (ParseState *pstate, JsonIsPredicate *p)
 
static NodetransformJsonFuncExpr (ParseState *pstate, JsonFuncExpr *p)
 
static NodetransformJsonValueExpr (ParseState *pstate, JsonValueExpr *jve)
 
static NodetransformJsonParseExpr (ParseState *pstate, JsonParseExpr *expr)
 
static NodetransformJsonScalarExpr (ParseState *pstate, JsonScalarExpr *expr)
 
static NodetransformJsonSerializeExpr (ParseState *pstate, JsonSerializeExpr *expr)
 
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 NodetransformJsonValueExprExt (ParseState *pstate, JsonValueExpr *ve, JsonFormatType default_format, bool isarg, Oid targettype)
 
static NodetransformJsonValueExprDefault (ParseState *pstate, JsonValueExpr *jve)
 
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)
 
static NodetransformJsonParseArg (ParseState *pstate, Node *jsexpr, JsonFormat *format, Oid *exprtype)
 
static void transformJsonPassingArgs (ParseState *pstate, JsonFormatType format, List *args, List **passing_values, List **passing_names)
 
static JsonBehaviortransformJsonBehavior (ParseState *pstate, JsonBehavior *behavior, JsonBehaviorType default_behavior)
 
static JsonExprtransformJsonExprCommon (ParseState *pstate, JsonFuncExpr *func)
 
static void assignDefaultJsonReturningType (Node *context_item, JsonFormat *context_format, JsonReturning *ret)
 
static JsonCoercioncoerceJsonExpr (ParseState *pstate, Node *expr, const JsonReturning *returning)
 
static void transformJsonFuncExprOutput (ParseState *pstate, JsonFuncExpr *func, JsonExpr *jsexpr)
 
static NodecoerceDefaultJsonExpr (ParseState *pstate, JsonExpr *jsexpr, Node *defexpr)
 
static JsonCoercioninitJsonItemCoercion (ParseState *pstate, Oid typid, const JsonReturning *returning)
 
static void initJsonItemCoercions (ParseState *pstate, JsonItemCoercions *coercions, const JsonReturning *returning, Oid contextItemTypeId)
 
static JsonReturningtransformJsonConstructorRet (ParseState *pstate, JsonOutput *output, const char *fname)
 

Variables

bool Transform_null_equals = false
 

Function Documentation

◆ assignDefaultJsonReturningType()

static void assignDefaultJsonReturningType ( Node context_item,
JsonFormat context_format,
JsonReturning ret 
)
static

Definition at line 4157 of file parse_expr.c.

4159 {
4160  bool is_jsonb;
4161 
4162  ret->format = copyObject(context_format);
4163 
4164  if (ret->format->format_type == JS_FORMAT_DEFAULT)
4165  is_jsonb = exprType(context_item) == JSONBOID;
4166  else
4167  is_jsonb = ret->format->format_type == JS_FORMAT_JSONB;
4168 
4169  ret->typid = is_jsonb ? JSONBOID : JSONOID;
4170  ret->typmod = -1;
4171 }
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
#define copyObject(obj)
Definition: nodes.h:689
@ JS_FORMAT_JSONB
Definition: primnodes.h:1277
@ JS_FORMAT_DEFAULT
Definition: primnodes.h:1275
JsonFormatType format_type
Definition: primnodes.h:1319
JsonFormat * format
Definition: primnodes.h:1331

References copyObject, exprType(), JsonReturning::format, JsonFormat::format_type, JS_FORMAT_DEFAULT, JS_FORMAT_JSONB, JsonReturning::typid, and JsonReturning::typmod.

Referenced by transformJsonFuncExprOutput().

◆ checkJsonOutputFormat()

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

Definition at line 3423 of file parse_expr.c.

3425 {
3426  if (!allow_format_for_non_strings &&
3427  format->format_type != JS_FORMAT_DEFAULT &&
3428  (targettype != BYTEAOID &&
3429  targettype != JSONOID &&
3430  targettype != JSONBOID))
3431  {
3432  char typcategory;
3433  bool typispreferred;
3434 
3435  get_type_category_preferred(targettype, &typcategory, &typispreferred);
3436 
3437  if (typcategory != TYPCATEGORY_STRING)
3438  ereport(ERROR,
3439  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3440  parser_errposition(pstate, format->location),
3441  errmsg("cannot use JSON format with non-string output types")));
3442  }
3443 
3444  if (format->format_type == JS_FORMAT_JSON)
3445  {
3446  JsonEncoding enc = format->encoding != JS_ENC_DEFAULT ?
3447  format->encoding : JS_ENC_UTF8;
3448 
3449  if (targettype != BYTEAOID &&
3450  format->encoding != JS_ENC_DEFAULT)
3451  ereport(ERROR,
3452  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3453  parser_errposition(pstate, format->location),
3454  errmsg("cannot set JSON encoding for non-bytea output types")));
3455 
3456  if (enc != JS_ENC_UTF8)
3457  ereport(ERROR,
3458  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3459  errmsg("unsupported JSON encoding"),
3460  errhint("only UTF8 JSON encoding is supported"),
3461  parser_errposition(pstate, format->location)));
3462  }
3463 }
int errhint(const char *fmt,...)
Definition: elog.c:1151
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
struct pg_encoding enc
Definition: encode.c:562
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2667
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
static char format
@ JS_FORMAT_JSON
Definition: primnodes.h:1276
JsonEncoding
Definition: primnodes.h:1262
@ JS_ENC_DEFAULT
Definition: primnodes.h:1263
@ JS_ENC_UTF8
Definition: primnodes.h:1264

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().

◆ coerceDefaultJsonExpr()

static Node* coerceDefaultJsonExpr ( ParseState pstate,
JsonExpr jsexpr,
Node defexpr 
)
static

Definition at line 4263 of file parse_expr.c.

4264 {
4265  int location;
4266  Oid exprtype;
4267 
4268  if (!defexpr)
4269  return NULL;
4270 
4271  exprtype = exprType(defexpr);
4272  location = exprLocation(defexpr);
4273 
4274  if (location < 0)
4275  location = jsexpr->location;
4276 
4277  defexpr = coerce_to_target_type(pstate,
4278  defexpr,
4279  exprtype,
4280  jsexpr->returning->typid,
4281  jsexpr->returning->typmod,
4284  location);
4285 
4286  if (!defexpr)
4287  ereport(ERROR,
4288  (errcode(ERRCODE_CANNOT_COERCE),
4289  errmsg("cannot cast DEFAULT expression type %s to %s",
4290  format_type_be(exprtype),
4291  format_type_be(jsexpr->returning->typid)),
4292  parser_errposition(pstate, location)));
4293 
4294  return defexpr;
4295 }
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1343
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
unsigned int Oid
Definition: postgres_ext.h:31
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:494
@ COERCION_EXPLICIT
Definition: primnodes.h:475
int location
Definition: primnodes.h:1466
JsonReturning * returning
Definition: primnodes.h:1460

References COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_EXPLICIT, ereport, errcode(), errmsg(), ERROR, exprLocation(), exprType(), format_type_be(), JsonExpr::location, parser_errposition(), JsonExpr::returning, JsonReturning::typid, and JsonReturning::typmod.

Referenced by transformJsonFuncExpr().

◆ coerceJsonExpr()

static JsonCoercion* coerceJsonExpr ( ParseState pstate,
Node expr,
const JsonReturning returning 
)
static

Definition at line 4179 of file parse_expr.c.

4180 {
4181  char typtype;
4182  JsonCoercion *coercion = makeNode(JsonCoercion);
4183 
4184  coercion->expr = coerceJsonFuncExpr(pstate, expr, returning, false);
4185 
4186  if (coercion->expr)
4187  {
4188  if (coercion->expr == expr)
4189  coercion->expr = NULL;
4190 
4191  return coercion;
4192  }
4193 
4194  typtype = get_typtype(returning->typid);
4195 
4196  if (returning->typid == RECORDOID ||
4197  typtype == TYPTYPE_COMPOSITE ||
4198  typtype == TYPTYPE_DOMAIN ||
4199  type_is_array(returning->typid))
4200  coercion->via_populate = true;
4201  else
4202  coercion->via_io = true;
4203 
4204  return coercion;
4205 }
char get_typtype(Oid typid)
Definition: lsyscache.c:2586
#define type_is_array(typid)
Definition: lsyscache.h:202
#define makeNode(_type_)
Definition: nodes.h:621
static Node * coerceJsonFuncExpr(ParseState *pstate, Node *expr, const JsonReturning *returning, bool report_error)
Definition: parse_expr.c:3558
Node * expr
Definition: primnodes.h:1420
bool via_populate
Definition: primnodes.h:1421

References coerceJsonFuncExpr(), JsonCoercion::expr, get_typtype(), makeNode, type_is_array, JsonReturning::typid, JsonCoercion::via_io, and JsonCoercion::via_populate.

Referenced by initJsonItemCoercion(), and transformJsonFuncExprOutput().

◆ coerceJsonFuncExpr()

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

Definition at line 3558 of file parse_expr.c.

3560 {
3561  Node *res;
3562  int location;
3563  Oid exprtype = exprType(expr);
3564 
3565  /* if output type is not specified or equals to function type, return */
3566  if (!OidIsValid(returning->typid) || returning->typid == exprtype)
3567  return expr;
3568 
3569  location = exprLocation(expr);
3570 
3571  if (location < 0)
3572  location = returning->format->location;
3573 
3574  /* special case for RETURNING bytea FORMAT json */
3575  if (returning->format->format_type == JS_FORMAT_JSON &&
3576  returning->typid == BYTEAOID)
3577  {
3578  /* encode json text into bytea using pg_convert_to() */
3579  Node *texpr = coerce_to_specific_type(pstate, expr, TEXTOID,
3580  "JSON_FUNCTION");
3581  Const *enc = getJsonEncodingConst(returning->format);
3582  FuncExpr *fexpr = makeFuncExpr(F_CONVERT_TO, BYTEAOID,
3583  list_make2(texpr, enc),
3586 
3587  fexpr->location = location;
3588 
3589  return (Node *) fexpr;
3590  }
3591 
3592  /* try to coerce expression to the output type */
3593  res = coerce_to_target_type(pstate, expr, exprtype,
3594  returning->typid, returning->typmod,
3595  /* XXX throwing errors when casting to char(N) */
3598  location);
3599 
3600  if (!res && report_error)
3601  ereport(ERROR,
3602  (errcode(ERRCODE_CANNOT_COERCE),
3603  errmsg("cannot cast type %s to %s",
3604  format_type_be(exprtype),
3605  format_type_be(returning->typid)),
3606  parser_coercion_errposition(pstate, location, expr)));
3607 
3608  return res;
3609 }
#define OidIsValid(objectId)
Definition: c.h:710
FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)
Definition: makefuncs.c:520
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:3175
#define list_make2(x1, x2)
Definition: pg_list.h:208
#define InvalidOid
Definition: postgres_ext.h:36
@ COERCE_EXPLICIT_CAST
Definition: primnodes.h:493
@ COERCE_EXPLICIT_CALL
Definition: primnodes.h:492
int location
Definition: primnodes.h:513
int location
Definition: primnodes.h:1321
Definition: nodes.h:574

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 coerceJsonExpr(), and makeJsonConstructorExpr().

◆ exprIsNullConstant()

static bool exprIsNullConstant ( Node arg)
static

Definition at line 910 of file parse_expr.c.

911 {
912  if (arg && IsA(arg, A_Const))
913  {
914  A_Const *con = (A_Const *) arg;
915 
916  if (con->isnull)
917  return true;
918  }
919  return false;
920 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:624
void * arg
bool isnull
Definition: parsenodes.h:317

References arg, IsA, and A_Const::isnull.

Referenced by transformAExprDistinct(), and transformAExprOp().

◆ getJsonEncodingConst()

static Const* getJsonEncodingConst ( JsonFormat format)
static

Definition at line 3175 of file parse_expr.c.

3176 {
3178  const char *enc;
3179  Name encname = palloc(sizeof(NameData));
3180 
3181  if (!format ||
3182  format->format_type == JS_FORMAT_DEFAULT ||
3183  format->encoding == JS_ENC_DEFAULT)
3185  else
3186  encoding = format->encoding;
3187 
3188  switch (encoding)
3189  {
3190  case JS_ENC_UTF16:
3191  enc = "UTF16";
3192  break;
3193  case JS_ENC_UTF32:
3194  enc = "UTF32";
3195  break;
3196  case JS_ENC_UTF8:
3197  enc = "UTF8";
3198  break;
3199  default:
3200  elog(ERROR, "invalid JSON encoding: %d", encoding);
3201  break;
3202  }
3203 
3204  namestrcpy(encname, enc);
3205 
3206  return makeConst(NAMEOID, -1, InvalidOid, NAMEDATALEN,
3207  NameGetDatum(encname), false, false);
3208 }
#define elog(elevel,...)
Definition: elog.h:218
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:300
void * palloc(Size size)
Definition: mcxt.c:1068
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define NAMEDATALEN
int32 encoding
Definition: pg_database.h:41
#define NameGetDatum(X)
Definition: postgres.h:639
@ JS_ENC_UTF32
Definition: primnodes.h:1266
@ JS_ENC_UTF16
Definition: primnodes.h:1265
Definition: c.h:676

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().

◆ initJsonItemCoercion()

static JsonCoercion* initJsonItemCoercion ( ParseState pstate,
Oid  typid,
const JsonReturning returning 
)
static

Definition at line 4302 of file parse_expr.c.

4304 {
4305  Node *expr;
4306 
4307  if (typid == UNKNOWNOID)
4308  {
4309  expr = (Node *) makeNullConst(UNKNOWNOID, -1, InvalidOid);
4310  }
4311  else
4312  {
4313  CaseTestExpr *placeholder = makeNode(CaseTestExpr);
4314 
4315  placeholder->typeId = typid;
4316  placeholder->typeMod = -1;
4317  placeholder->collation = InvalidOid;
4318 
4319  expr = (Node *) placeholder;
4320  }
4321 
4322  return coerceJsonExpr(pstate, expr, returning);
4323 }
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition: makefuncs.c:338
static JsonCoercion * coerceJsonExpr(ParseState *pstate, Node *expr, const JsonReturning *returning)
Definition: parse_expr.c:4179
int32 typeMod
Definition: primnodes.h:1028

References coerceJsonExpr(), CaseTestExpr::collation, InvalidOid, makeNode, makeNullConst(), CaseTestExpr::typeId, and CaseTestExpr::typeMod.

Referenced by initJsonItemCoercions().

◆ initJsonItemCoercions()

static void initJsonItemCoercions ( ParseState pstate,
JsonItemCoercions coercions,
const JsonReturning returning,
Oid  contextItemTypeId 
)
static

Definition at line 4326 of file parse_expr.c.

4328 {
4329  struct
4330  {
4331  JsonCoercion **coercion;
4332  Oid typid;
4333  } *p,
4334  coercionTypids[] =
4335  {
4336  {&coercions->null, UNKNOWNOID},
4337  {&coercions->string, TEXTOID},
4338  {&coercions->numeric, NUMERICOID},
4339  {&coercions->boolean, BOOLOID},
4340  {&coercions->date, DATEOID},
4341  {&coercions->time, TIMEOID},
4342  {&coercions->timetz, TIMETZOID},
4343  {&coercions->timestamp, TIMESTAMPOID},
4344  {&coercions->timestamptz, TIMESTAMPTZOID},
4345  {&coercions->composite, contextItemTypeId},
4346  {NULL, InvalidOid}
4347  };
4348 
4349  for (p = coercionTypids; p->coercion; p++)
4350  *p->coercion = initJsonItemCoercion(pstate, p->typid, returning);
4351 }
static JsonCoercion * initJsonItemCoercion(ParseState *pstate, Oid typid, const JsonReturning *returning)
Definition: parse_expr.c:4302
JsonCoercion * string
Definition: primnodes.h:1435
JsonCoercion * timetz
Definition: primnodes.h:1440
JsonCoercion * numeric
Definition: primnodes.h:1436
JsonCoercion * date
Definition: primnodes.h:1438
JsonCoercion * composite
Definition: primnodes.h:1443
JsonCoercion * null
Definition: primnodes.h:1434
JsonCoercion * time
Definition: primnodes.h:1439
JsonCoercion * timestamptz
Definition: primnodes.h:1442
JsonCoercion * boolean
Definition: primnodes.h:1437
JsonCoercion * timestamp
Definition: primnodes.h:1441

References JsonItemCoercions::boolean, JsonItemCoercions::composite, JsonItemCoercions::date, initJsonItemCoercion(), InvalidOid, JsonItemCoercions::null, JsonItemCoercions::numeric, JsonItemCoercions::string, JsonItemCoercions::time, JsonItemCoercions::timestamp, JsonItemCoercions::timestamptz, and JsonItemCoercions::timetz.

Referenced by transformJsonFuncExpr().

◆ make_distinct_op()

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

Definition at line 3013 of file parse_expr.c.

3015 {
3016  Expr *result;
3017 
3018  result = make_op(pstate, opname, ltree, rtree,
3019  pstate->p_last_srf, location);
3020  if (((OpExpr *) result)->opresulttype != BOOLOID)
3021  ereport(ERROR,
3022  (errcode(ERRCODE_DATATYPE_MISMATCH),
3023  errmsg("IS DISTINCT FROM requires = operator to yield boolean"),
3024  parser_errposition(pstate, location)));
3025  if (((OpExpr *) result)->opretset)
3026  ereport(ERROR,
3027  (errcode(ERRCODE_DATATYPE_MISMATCH),
3028  /* translator: %s is name of a SQL construct, eg NULLIF */
3029  errmsg("%s must not return a set", "IS DISTINCT FROM"),
3030  parser_errposition(pstate, location)));
3031 
3032  /*
3033  * We rely on DistinctExpr and OpExpr being same struct
3034  */
3035  NodeSetTag(result, T_DistinctExpr);
3036 
3037  return result;
3038 }
@ T_DistinctExpr
Definition: nodes.h:167
#define NodeSetTag(nodeptr, t)
Definition: nodes.h:622
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:215
Definition: ltree.h:43

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

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 3046 of file parse_expr.c.

3047 {
3048  NullTest *nt = makeNode(NullTest);
3049 
3050  nt->arg = (Expr *) transformExprRecurse(pstate, arg);
3051  /* the argument can be any type, so don't coerce it */
3052  if (distincta->kind == AEXPR_NOT_DISTINCT)
3053  nt->nulltesttype = IS_NULL;
3054  else
3055  nt->nulltesttype = IS_NOT_NULL;
3056  /* argisrow = false is correct whether or not arg is composite */
3057  nt->argisrow = false;
3058  nt->location = distincta->location;
3059  return (Node *) nt;
3060 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:130
@ AEXPR_NOT_DISTINCT
Definition: parsenodes.h:275
@ IS_NULL
Definition: primnodes.h:1520
@ IS_NOT_NULL
Definition: primnodes.h:1520
int location
Definition: parsenodes.h:294
A_Expr_Kind kind
Definition: parsenodes.h:290
NullTestType nulltesttype
Definition: primnodes.h:1527
int location
Definition: primnodes.h:1529
bool argisrow
Definition: primnodes.h:1528
Expr * arg
Definition: primnodes.h:1526

References AEXPR_NOT_DISTINCT, arg, NullTest::arg, NullTest::argisrow, 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 2767 of file parse_expr.c.

2769 {
2770  RowCompareExpr *rcexpr;
2771  RowCompareType rctype;
2772  List *opexprs;
2773  List *opnos;
2774  List *opfamilies;
2775  ListCell *l,
2776  *r;
2777  List **opinfo_lists;
2778  Bitmapset *strats;
2779  int nopers;
2780  int i;
2781 
2782  nopers = list_length(largs);
2783  if (nopers != list_length(rargs))
2784  ereport(ERROR,
2785  (errcode(ERRCODE_SYNTAX_ERROR),
2786  errmsg("unequal number of entries in row expressions"),
2787  parser_errposition(pstate, location)));
2788 
2789  /*
2790  * We can't compare zero-length rows because there is no principled basis
2791  * for figuring out what the operator is.
2792  */
2793  if (nopers == 0)
2794  ereport(ERROR,
2795  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2796  errmsg("cannot compare rows of zero length"),
2797  parser_errposition(pstate, location)));
2798 
2799  /*
2800  * Identify all the pairwise operators, using make_op so that behavior is
2801  * the same as in the simple scalar case.
2802  */
2803  opexprs = NIL;
2804  forboth(l, largs, r, rargs)
2805  {
2806  Node *larg = (Node *) lfirst(l);
2807  Node *rarg = (Node *) lfirst(r);
2808  OpExpr *cmp;
2809 
2810  cmp = castNode(OpExpr, make_op(pstate, opname, larg, rarg,
2811  pstate->p_last_srf, location));
2812 
2813  /*
2814  * We don't use coerce_to_boolean here because we insist on the
2815  * operator yielding boolean directly, not via coercion. If it
2816  * doesn't yield bool it won't be in any index opfamilies...
2817  */
2818  if (cmp->opresulttype != BOOLOID)
2819  ereport(ERROR,
2820  (errcode(ERRCODE_DATATYPE_MISMATCH),
2821  errmsg("row comparison operator must yield type boolean, "
2822  "not type %s",
2823  format_type_be(cmp->opresulttype)),
2824  parser_errposition(pstate, location)));
2825  if (expression_returns_set((Node *) cmp))
2826  ereport(ERROR,
2827  (errcode(ERRCODE_DATATYPE_MISMATCH),
2828  errmsg("row comparison operator must not return a set"),
2829  parser_errposition(pstate, location)));
2830  opexprs = lappend(opexprs, cmp);
2831  }
2832 
2833  /*
2834  * If rows are length 1, just return the single operator. In this case we
2835  * don't insist on identifying btree semantics for the operator (but we
2836  * still require it to return boolean).
2837  */
2838  if (nopers == 1)
2839  return (Node *) linitial(opexprs);
2840 
2841  /*
2842  * Now we must determine which row comparison semantics (= <> < <= > >=)
2843  * apply to this set of operators. We look for btree opfamilies
2844  * containing the operators, and see which interpretations (strategy
2845  * numbers) exist for each operator.
2846  */
2847  opinfo_lists = (List **) palloc(nopers * sizeof(List *));
2848  strats = NULL;
2849  i = 0;
2850  foreach(l, opexprs)
2851  {
2852  Oid opno = ((OpExpr *) lfirst(l))->opno;
2853  Bitmapset *this_strats;
2854  ListCell *j;
2855 
2856  opinfo_lists[i] = get_op_btree_interpretation(opno);
2857 
2858  /*
2859  * convert strategy numbers into a Bitmapset to make the intersection
2860  * calculation easy.
2861  */
2862  this_strats = NULL;
2863  foreach(j, opinfo_lists[i])
2864  {
2865  OpBtreeInterpretation *opinfo = lfirst(j);
2866 
2867  this_strats = bms_add_member(this_strats, opinfo->strategy);
2868  }
2869  if (i == 0)
2870  strats = this_strats;
2871  else
2872  strats = bms_int_members(strats, this_strats);
2873  i++;
2874  }
2875 
2876  /*
2877  * If there are multiple common interpretations, we may use any one of
2878  * them ... this coding arbitrarily picks the lowest btree strategy
2879  * number.
2880  */
2881  i = bms_first_member(strats);
2882  if (i < 0)
2883  {
2884  /* No common interpretation, so fail */
2885  ereport(ERROR,
2886  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2887  errmsg("could not determine interpretation of row comparison operator %s",
2888  strVal(llast(opname))),
2889  errhint("Row comparison operators must be associated with btree operator families."),
2890  parser_errposition(pstate, location)));
2891  }
2892  rctype = (RowCompareType) i;
2893 
2894  /*
2895  * For = and <> cases, we just combine the pairwise operators with AND or
2896  * OR respectively.
2897  */
2898  if (rctype == ROWCOMPARE_EQ)
2899  return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
2900  if (rctype == ROWCOMPARE_NE)
2901  return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
2902 
2903  /*
2904  * Otherwise we need to choose exactly which opfamily to associate with
2905  * each operator.
2906  */
2907  opfamilies = NIL;
2908  for (i = 0; i < nopers; i++)
2909  {
2910  Oid opfamily = InvalidOid;
2911  ListCell *j;
2912 
2913  foreach(j, opinfo_lists[i])
2914  {
2915  OpBtreeInterpretation *opinfo = lfirst(j);
2916 
2917  if (opinfo->strategy == rctype)
2918  {
2919  opfamily = opinfo->opfamily_id;
2920  break;
2921  }
2922  }
2923  if (OidIsValid(opfamily))
2924  opfamilies = lappend_oid(opfamilies, opfamily);
2925  else /* should not happen */
2926  ereport(ERROR,
2927  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2928  errmsg("could not determine interpretation of row comparison operator %s",
2929  strVal(llast(opname))),
2930  errdetail("There are multiple equally-plausible candidates."),
2931  parser_errposition(pstate, location)));
2932  }
2933 
2934  /*
2935  * Now deconstruct the OpExprs and create a RowCompareExpr.
2936  *
2937  * Note: can't just reuse the passed largs/rargs lists, because of
2938  * possibility that make_op inserted coercion operations.
2939  */
2940  opnos = NIL;
2941  largs = NIL;
2942  rargs = NIL;
2943  foreach(l, opexprs)
2944  {
2945  OpExpr *cmp = (OpExpr *) lfirst(l);
2946 
2947  opnos = lappend_oid(opnos, cmp->opno);
2948  largs = lappend(largs, linitial(cmp->args));
2949  rargs = lappend(rargs, lsecond(cmp->args));
2950  }
2951 
2952  rcexpr = makeNode(RowCompareExpr);
2953  rcexpr->rctype = rctype;
2954  rcexpr->opnos = opnos;
2955  rcexpr->opfamilies = opfamilies;
2956  rcexpr->inputcollids = NIL; /* assign_expr_collations will fix this */
2957  rcexpr->largs = largs;
2958  rcexpr->rargs = rargs;
2959 
2960  return (Node *) rcexpr;
2961 }
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:738
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:904
int bms_first_member(Bitmapset *a)
Definition: bitmapset.c:998
int errdetail(const char *fmt,...)
Definition: elog.c:1037
int j
Definition: isn.c:74
int i
Definition: isn.c:73
List * lappend(List *list, void *datum)
Definition: list.c:336
List * lappend_oid(List *list, Oid datum)
Definition: list.c:372
List * get_op_btree_interpretation(Oid opno)
Definition: lsyscache.c:599
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:370
bool expression_returns_set(Node *clause)
Definition: nodeFuncs.c:736
#define castNode(_type_, nodeptr)
Definition: nodes.h:642
#define lfirst(lc)
Definition: pg_list.h:169
#define llast(l)
Definition: pg_list.h:194
static int list_length(const List *l)
Definition: pg_list.h:149
#define NIL
Definition: pg_list.h:65
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:446
#define linitial(l)
Definition: pg_list.h:174
#define lsecond(l)
Definition: pg_list.h:179
@ AND_EXPR
Definition: primnodes.h:628
@ OR_EXPR
Definition: primnodes.h:628
RowCompareType
Definition: primnodes.h:1110
@ ROWCOMPARE_NE
Definition: primnodes.h:1117
@ ROWCOMPARE_EQ
Definition: primnodes.h:1114
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747
Definition: pg_list.h:51
RowCompareType rctype
Definition: primnodes.h:1123
List * opfamilies
Definition: primnodes.h:1125
List * inputcollids
Definition: primnodes.h:1126
#define strVal(v)
Definition: value.h:72

References AND_EXPR, bms_add_member(), bms_first_member(), bms_int_members(), castNode, cmp(), ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, expression_returns_set(), forboth, format_type_be(), get_op_btree_interpretation(), i, RowCompareExpr::inputcollids, InvalidOid, j, lappend(), lappend_oid(), RowCompareExpr::largs, lfirst, linitial, list_length(), llast, lsecond, make_op(), makeBoolExpr(), makeNode, NIL, OidIsValid, RowCompareExpr::opfamilies, OpBtreeInterpretation::opfamily_id, RowCompareExpr::opnos, 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 2969 of file parse_expr.c.

2972 {
2973  Node *result = NULL;
2974  List *largs = lrow->args;
2975  List *rargs = rrow->args;
2976  ListCell *l,
2977  *r;
2978 
2979  if (list_length(largs) != list_length(rargs))
2980  ereport(ERROR,
2981  (errcode(ERRCODE_SYNTAX_ERROR),
2982  errmsg("unequal number of entries in row expressions"),
2983  parser_errposition(pstate, location)));
2984 
2985  forboth(l, largs, r, rargs)
2986  {
2987  Node *larg = (Node *) lfirst(l);
2988  Node *rarg = (Node *) lfirst(r);
2989  Node *cmp;
2990 
2991  cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
2992  if (result == NULL)
2993  result = cmp;
2994  else
2995  result = (Node *) makeBoolExpr(OR_EXPR,
2996  list_make2(result, cmp),
2997  location);
2998  }
2999 
3000  if (result == NULL)
3001  {
3002  /* zero-length rows? Generate constant FALSE */
3003  result = makeBoolConst(false, false);
3004  }
3005 
3006  return result;
3007 }
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:358
static Expr * make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_expr.c:3013
List * args
Definition: primnodes.h:1075

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 3231 of file parse_expr.c.

3232 {
3233  CaseTestExpr *placeholder = makeNode(CaseTestExpr);
3234 
3235  placeholder->typeId = exprType(expr);
3236  placeholder->typeMod = exprTypmod(expr);
3237  placeholder->collation = exprCollation(expr);
3238 
3239  return (Node *) placeholder;
3240 }
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:286
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:788

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

Referenced by makeJsonConstructorExpr(), transformJsonFuncExprOutput(), transformJsonParseArg(), and transformJsonValueExprExt().

◆ makeJsonByteaToTextConversion()

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

Definition at line 3214 of file parse_expr.c.

3215 {
3217  FuncExpr *fexpr = makeFuncExpr(F_CONVERT_FROM, TEXTOID,
3218  list_make2(expr, encoding),
3221 
3222  fexpr->location = location;
3223 
3224  return (Node *) fexpr;
3225 }

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

Referenced by transformJsonParseArg(), and transformJsonValueExprExt().

◆ 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 3612 of file parse_expr.c.

3615 {
3617  Node *placeholder;
3618  Node *coercion;
3619  Oid intermediate_typid =
3620  returning->format->format_type == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
3621 
3622  jsctor->args = args;
3623  jsctor->func = fexpr;
3624  jsctor->type = type;
3625  jsctor->returning = returning;
3626  jsctor->unique = unique;
3627  jsctor->absent_on_null = absent_on_null;
3628  jsctor->location = location;
3629 
3630  if (fexpr)
3631  placeholder = makeCaseTestExpr((Node *) fexpr);
3632  else
3633  {
3635 
3636  cte->typeId = intermediate_typid;
3637  cte->typeMod = -1;
3638  cte->collation = InvalidOid;
3639 
3640  placeholder = (Node *) cte;
3641  }
3642 
3643  coercion = coerceJsonFuncExpr(pstate, placeholder, returning, true);
3644 
3645  if (coercion != placeholder)
3646  jsctor->coercion = (Expr *) coercion;
3647 
3648  return (Node *) jsctor;
3649 }
static Node * makeCaseTestExpr(Node *expr)
Definition: parse_expr.c:3231
JsonReturning * returning
Definition: primnodes.h:1370
JsonConstructorType type
Definition: primnodes.h:1366

References JsonConstructorExpr::absent_on_null, generate_unaccent_rules::args, JsonConstructorExpr::args, coerceJsonFuncExpr(), JsonConstructorExpr::coercion, CaseTestExpr::collation, 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, CaseTestExpr::typeMod, and JsonConstructorExpr::unique.

Referenced by transformJsonAggConstructor(), transformJsonArrayConstructor(), transformJsonObjectConstructor(), transformJsonParseExpr(), transformJsonScalarExpr(), and transformJsonSerializeExpr().

◆ ParseExprKindName()

const char* ParseExprKindName ( ParseExprKind  exprKind)

Definition at line 3070 of file parse_expr.c.

3071 {
3072  switch (exprKind)
3073  {
3074  case EXPR_KIND_NONE:
3075  return "invalid expression context";
3076  case EXPR_KIND_OTHER:
3077  return "extension expression";
3078  case EXPR_KIND_JOIN_ON:
3079  return "JOIN/ON";
3080  case EXPR_KIND_JOIN_USING:
3081  return "JOIN/USING";
3083  return "sub-SELECT in FROM";
3085  return "function in FROM";
3086  case EXPR_KIND_WHERE:
3087  return "WHERE";
3088  case EXPR_KIND_POLICY:
3089  return "POLICY";
3090  case EXPR_KIND_HAVING:
3091  return "HAVING";
3092  case EXPR_KIND_FILTER:
3093  return "FILTER";
3095  return "window PARTITION BY";
3097  return "window ORDER BY";
3099  return "window RANGE";
3101  return "window ROWS";
3103  return "window GROUPS";
3105  return "SELECT";
3107  return "INSERT";
3110  return "UPDATE";
3111  case EXPR_KIND_MERGE_WHEN:
3112  return "MERGE WHEN";
3113  case EXPR_KIND_GROUP_BY:
3114  return "GROUP BY";
3115  case EXPR_KIND_ORDER_BY:
3116  return "ORDER BY";
3117  case EXPR_KIND_DISTINCT_ON:
3118  return "DISTINCT ON";
3119  case EXPR_KIND_LIMIT:
3120  return "LIMIT";
3121  case EXPR_KIND_OFFSET:
3122  return "OFFSET";
3123  case EXPR_KIND_RETURNING:
3124  return "RETURNING";
3125  case EXPR_KIND_VALUES:
3127  return "VALUES";
3130  return "CHECK";
3133  return "DEFAULT";
3135  return "index expression";
3137  return "index predicate";
3139  return "statistics expression";
3141  return "USING";
3143  return "EXECUTE";
3145  return "WHEN";
3147  return "partition bound";
3149  return "PARTITION BY";
3151  return "CALL";
3152  case EXPR_KIND_COPY_WHERE:
3153  return "WHERE";
3155  return "GENERATED AS";
3156  case EXPR_KIND_CYCLE_MARK:
3157  return "CYCLE";
3158 
3159  /*
3160  * There is intentionally no default: case here, so that the
3161  * compiler will warn if we add a new ParseExprKind without
3162  * extending this switch. If we do see an unrecognized value at
3163  * runtime, we'll fall through to the "unrecognized" return.
3164  */
3165  }
3166  return "unrecognized expression kind";
3167 }
@ 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 1283 of file parse_expr.c.

1284 {
1285  Node *aexpr;
1286  Node *bexpr;
1287  Node *cexpr;
1288  Node *result;
1289  Node *sub1;
1290  Node *sub2;
1291  List *args;
1292 
1293  /* Deconstruct A_Expr into three subexprs */
1294  aexpr = a->lexpr;
1295  args = castNode(List, a->rexpr);
1296  Assert(list_length(args) == 2);
1297  bexpr = (Node *) linitial(args);
1298  cexpr = (Node *) lsecond(args);
1299 
1300  /*
1301  * Build the equivalent comparison expression. Make copies of
1302  * multiply-referenced subexpressions for safety. (XXX this is really
1303  * wrong since it results in multiple runtime evaluations of what may be
1304  * volatile expressions ...)
1305  *
1306  * Ideally we would not use hard-wired operators here but instead use
1307  * opclasses. However, mixed data types and other issues make this
1308  * difficult:
1309  * http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
1310  */
1311  switch (a->kind)
1312  {
1313  case AEXPR_BETWEEN:
1315  aexpr, bexpr,
1316  a->location),
1317  makeSimpleA_Expr(AEXPR_OP, "<=",
1318  copyObject(aexpr), cexpr,
1319  a->location));
1320  result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1321  break;
1322  case AEXPR_NOT_BETWEEN:
1324  aexpr, bexpr,
1325  a->location),
1327  copyObject(aexpr), cexpr,
1328  a->location));
1329  result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1330  break;
1331  case AEXPR_BETWEEN_SYM:
1333  aexpr, bexpr,
1334  a->location),
1335  makeSimpleA_Expr(AEXPR_OP, "<=",
1336  copyObject(aexpr), cexpr,
1337  a->location));
1338  sub1 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1340  copyObject(aexpr), copyObject(cexpr),
1341  a->location),
1342  makeSimpleA_Expr(AEXPR_OP, "<=",
1343  copyObject(aexpr), copyObject(bexpr),
1344  a->location));
1345  sub2 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1346  args = list_make2(sub1, sub2);
1347  result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1348  break;
1349  case AEXPR_NOT_BETWEEN_SYM:
1351  aexpr, bexpr,
1352  a->location),
1354  copyObject(aexpr), cexpr,
1355  a->location));
1356  sub1 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1358  copyObject(aexpr), copyObject(cexpr),
1359  a->location),
1361  copyObject(aexpr), copyObject(bexpr),
1362  a->location));
1363  sub2 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1364  args = list_make2(sub1, sub2);
1365  result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1366  break;
1367  default:
1368  elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
1369  result = NULL; /* keep compiler quiet */
1370  break;
1371  }
1372 
1373  return transformExprRecurse(pstate, result);
1374 }
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
@ AEXPR_BETWEEN
Definition: parsenodes.h:281
@ AEXPR_BETWEEN_SYM
Definition: parsenodes.h:283
@ AEXPR_NOT_BETWEEN_SYM
Definition: parsenodes.h:284
@ AEXPR_NOT_BETWEEN
Definition: parsenodes.h:282
@ AEXPR_OP
Definition: parsenodes.h:271

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 1032 of file parse_expr.c.

1033 {
1034  Node *lexpr = a->lexpr;
1035  Node *rexpr = a->rexpr;
1036  Node *result;
1037 
1038  /*
1039  * If either input is an undecorated NULL literal, transform to a NullTest
1040  * on the other input. That's simpler to process than a full DistinctExpr,
1041  * and it avoids needing to require that the datatype have an = operator.
1042  */
1043  if (exprIsNullConstant(rexpr))
1044  return make_nulltest_from_distinct(pstate, a, lexpr);
1045  if (exprIsNullConstant(lexpr))
1046  return make_nulltest_from_distinct(pstate, a, rexpr);
1047 
1048  lexpr = transformExprRecurse(pstate, lexpr);
1049  rexpr = transformExprRecurse(pstate, rexpr);
1050 
1051  if (lexpr && IsA(lexpr, RowExpr) &&
1052  rexpr && IsA(rexpr, RowExpr))
1053  {
1054  /* ROW() op ROW() is handled specially */
1055  result = make_row_distinct_op(pstate, a->name,
1056  (RowExpr *) lexpr,
1057  (RowExpr *) rexpr,
1058  a->location);
1059  }
1060  else
1061  {
1062  /* Ordinary scalar operator */
1063  result = (Node *) make_distinct_op(pstate,
1064  a->name,
1065  lexpr,
1066  rexpr,
1067  a->location);
1068  }
1069 
1070  /*
1071  * If it's NOT DISTINCT, we first build a DistinctExpr and then stick a
1072  * NOT on top.
1073  */
1074  if (a->kind == AEXPR_NOT_DISTINCT)
1075  result = (Node *) makeBoolExpr(NOT_EXPR,
1076  list_make1(result),
1077  a->location);
1078 
1079  return result;
1080 }
static Node * make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg)
Definition: parse_expr.c:3046
static bool exprIsNullConstant(Node *arg)
Definition: parse_expr.c:910
static Node * make_row_distinct_op(ParseState *pstate, List *opname, RowExpr *lrow, RowExpr *rrow, int location)
Definition: parse_expr.c:2969
#define list_make1(x1)
Definition: pg_list.h:206
@ NOT_EXPR
Definition: primnodes.h:628

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 1125 of file parse_expr.c.

1126 {
1127  Node *result = NULL;
1128  Node *lexpr;
1129  List *rexprs;
1130  List *rvars;
1131  List *rnonvars;
1132  bool useOr;
1133  ListCell *l;
1134 
1135  /*
1136  * If the operator is <>, combine with AND not OR.
1137  */
1138  if (strcmp(strVal(linitial(a->name)), "<>") == 0)
1139  useOr = false;
1140  else
1141  useOr = true;
1142 
1143  /*
1144  * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
1145  * possible if there is a suitable array type available. If not, we fall
1146  * back to a boolean condition tree with multiple copies of the lefthand
1147  * expression. Also, any IN-list items that contain Vars are handled as
1148  * separate boolean conditions, because that gives the planner more scope
1149  * for optimization on such clauses.
1150  *
1151  * First step: transform all the inputs, and detect whether any contain
1152  * Vars.
1153  */
1154  lexpr = transformExprRecurse(pstate, a->lexpr);
1155  rexprs = rvars = rnonvars = NIL;
1156  foreach(l, (List *) a->rexpr)
1157  {
1158  Node *rexpr = transformExprRecurse(pstate, lfirst(l));
1159 
1160  rexprs = lappend(rexprs, rexpr);
1161  if (contain_vars_of_level(rexpr, 0))
1162  rvars = lappend(rvars, rexpr);
1163  else
1164  rnonvars = lappend(rnonvars, rexpr);
1165  }
1166 
1167  /*
1168  * ScalarArrayOpExpr is only going to be useful if there's more than one
1169  * non-Var righthand item.
1170  */
1171  if (list_length(rnonvars) > 1)
1172  {
1173  List *allexprs;
1174  Oid scalar_type;
1175  Oid array_type;
1176 
1177  /*
1178  * Try to select a common type for the array elements. Note that
1179  * since the LHS' type is first in the list, it will be preferred when
1180  * there is doubt (eg, when all the RHS items are unknown literals).
1181  *
1182  * Note: use list_concat here not lcons, to avoid damaging rnonvars.
1183  */
1184  allexprs = list_concat(list_make1(lexpr), rnonvars);
1185  scalar_type = select_common_type(pstate, allexprs, NULL, NULL);
1186 
1187  /* We have to verify that the selected type actually works */
1188  if (OidIsValid(scalar_type) &&
1189  !verify_common_type(scalar_type, allexprs))
1190  scalar_type = InvalidOid;
1191 
1192  /*
1193  * Do we have an array type to use? Aside from the case where there
1194  * isn't one, we don't risk using ScalarArrayOpExpr when the common
1195  * type is RECORD, because the RowExpr comparison logic below can cope
1196  * with some cases of non-identical row types.
1197  */
1198  if (OidIsValid(scalar_type) && scalar_type != RECORDOID)
1199  array_type = get_array_type(scalar_type);
1200  else
1201  array_type = InvalidOid;
1202  if (array_type != InvalidOid)
1203  {
1204  /*
1205  * OK: coerce all the right-hand non-Var inputs to the common type
1206  * and build an ArrayExpr for them.
1207  */
1208  List *aexprs;
1209  ArrayExpr *newa;
1210 
1211  aexprs = NIL;
1212  foreach(l, rnonvars)
1213  {
1214  Node *rexpr = (Node *) lfirst(l);
1215 
1216  rexpr = coerce_to_common_type(pstate, rexpr,
1217  scalar_type,
1218  "IN");
1219  aexprs = lappend(aexprs, rexpr);
1220  }
1221  newa = makeNode(ArrayExpr);
1222  newa->array_typeid = array_type;
1223  /* array_collid will be set by parse_collate.c */
1224  newa->element_typeid = scalar_type;
1225  newa->elements = aexprs;
1226  newa->multidims = false;
1227  newa->location = -1;
1228 
1229  result = (Node *) make_scalar_array_op(pstate,
1230  a->name,
1231  useOr,
1232  lexpr,
1233  (Node *) newa,
1234  a->location);
1235 
1236  /* Consider only the Vars (if any) in the loop below */
1237  rexprs = rvars;
1238  }
1239  }
1240 
1241  /*
1242  * Must do it the hard way, ie, with a boolean expression tree.
1243  */
1244  foreach(l, rexprs)
1245  {
1246  Node *rexpr = (Node *) lfirst(l);
1247  Node *cmp;
1248 
1249  if (IsA(lexpr, RowExpr) &&
1250  IsA(rexpr, RowExpr))
1251  {
1252  /* ROW() op ROW() is handled specially */
1253  cmp = make_row_comparison_op(pstate,
1254  a->name,
1255  copyObject(((RowExpr *) lexpr)->args),
1256  ((RowExpr *) rexpr)->args,
1257  a->location);
1258  }
1259  else
1260  {
1261  /* Ordinary scalar operator */
1262  cmp = (Node *) make_op(pstate,
1263  a->name,
1264  copyObject(lexpr),
1265  rexpr,
1266  pstate->p_last_srf,
1267  a->location);
1268  }
1269 
1270  cmp = coerce_to_boolean(pstate, cmp, "IN");
1271  if (result == NULL)
1272  result = cmp;
1273  else
1274  result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
1275  list_make2(result, cmp),
1276  a->location);
1277  }
1278 
1279  return result;
1280 }
List * list_concat(List *list1, const List *list2)
Definition: list.c:540
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2744
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:2767
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:1048
bool multidims
Definition: primnodes.h:1047
Oid array_typeid
Definition: primnodes.h:1043
List * elements
Definition: primnodes.h:1046
Oid element_typeid
Definition: primnodes.h:1045
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:438

References a, AND_EXPR, generate_unaccent_rules::args, ArrayExpr::array_typeid, cmp(), coerce_to_boolean(), coerce_to_common_type(), contain_vars_of_level(), copyObject, ArrayExpr::element_typeid, 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, ArrayExpr::multidims, 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 1083 of file parse_expr.c.

1084 {
1085  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
1086  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
1087  OpExpr *result;
1088 
1089  result = (OpExpr *) make_op(pstate,
1090  a->name,
1091  lexpr,
1092  rexpr,
1093  pstate->p_last_srf,
1094  a->location);
1095 
1096  /*
1097  * The comparison operator itself should yield boolean ...
1098  */
1099  if (result->opresulttype != BOOLOID)
1100  ereport(ERROR,
1101  (errcode(ERRCODE_DATATYPE_MISMATCH),
1102  errmsg("NULLIF requires = operator to yield boolean"),
1103  parser_errposition(pstate, a->location)));
1104  if (result->opretset)
1105  ereport(ERROR,
1106  (errcode(ERRCODE_DATATYPE_MISMATCH),
1107  /* translator: %s is name of a SQL construct, eg NULLIF */
1108  errmsg("%s must not return a set", "NULLIF"),
1109  parser_errposition(pstate, a->location)));
1110 
1111  /*
1112  * ... but the NullIfExpr will yield the first operand's type.
1113  */
1114  result->opresulttype = exprType((Node *) linitial(result->args));
1115 
1116  /*
1117  * We rely on NullIfExpr and OpExpr being the same struct
1118  */
1119  NodeSetTag(result, T_NullIfExpr);
1120 
1121  return (Node *) result;
1122 }
@ T_NullIfExpr
Definition: nodes.h:168
bool opretset
Definition: primnodes.h:554
List * args
Definition: primnodes.h:557
Oid opresulttype
Definition: primnodes.h:553

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

Referenced by transformExprRecurse().

◆ transformAExprOp()

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

Definition at line 923 of file parse_expr.c.

924 {
925  Node *lexpr = a->lexpr;
926  Node *rexpr = a->rexpr;
927  Node *result;
928 
929  /*
930  * Special-case "foo = NULL" and "NULL = foo" for compatibility with
931  * standards-broken products (like Microsoft's). Turn these into IS NULL
932  * exprs. (If either side is a CaseTestExpr, then the expression was
933  * generated internally from a CASE-WHEN expression, and
934  * transform_null_equals does not apply.)
935  */
936  if (Transform_null_equals &&
937  list_length(a->name) == 1 &&
938  strcmp(strVal(linitial(a->name)), "=") == 0 &&
939  (exprIsNullConstant(lexpr) || exprIsNullConstant(rexpr)) &&
940  (!IsA(lexpr, CaseTestExpr) && !IsA(rexpr, CaseTestExpr)))
941  {
942  NullTest *n = makeNode(NullTest);
943 
944  n->nulltesttype = IS_NULL;
945  n->location = a->location;
946 
947  if (exprIsNullConstant(lexpr))
948  n->arg = (Expr *) rexpr;
949  else
950  n->arg = (Expr *) lexpr;
951 
952  result = transformExprRecurse(pstate, (Node *) n);
953  }
954  else if (lexpr && IsA(lexpr, RowExpr) &&
955  rexpr && IsA(rexpr, SubLink) &&
956  ((SubLink *) rexpr)->subLinkType == EXPR_SUBLINK)
957  {
958  /*
959  * Convert "row op subselect" into a ROWCOMPARE sublink. Formerly the
960  * grammar did this, but now that a row construct is allowed anywhere
961  * in expressions, it's easier to do it here.
962  */
963  SubLink *s = (SubLink *) rexpr;
964 
966  s->testexpr = lexpr;
967  s->operName = a->name;
968  s->location = a->location;
969  result = transformExprRecurse(pstate, (Node *) s);
970  }
971  else if (lexpr && IsA(lexpr, RowExpr) &&
972  rexpr && IsA(rexpr, RowExpr))
973  {
974  /* ROW() op ROW() is handled specially */
975  lexpr = transformExprRecurse(pstate, lexpr);
976  rexpr = transformExprRecurse(pstate, rexpr);
977 
978  result = make_row_comparison_op(pstate,
979  a->name,
980  castNode(RowExpr, lexpr)->args,
981  castNode(RowExpr, rexpr)->args,
982  a->location);
983  }
984  else
985  {
986  /* Ordinary scalar operator */
987  Node *last_srf = pstate->p_last_srf;
988 
989  lexpr = transformExprRecurse(pstate, lexpr);
990  rexpr = transformExprRecurse(pstate, rexpr);
991 
992  result = (Node *) make_op(pstate,
993  a->name,
994  lexpr,
995  rexpr,
996  last_srf,
997  a->location);
998  }
999 
1000  return result;
1001 }
bool Transform_null_equals
Definition: parse_expr.c:45
@ EXPR_SUBLINK
Definition: primnodes.h:696
@ ROWCOMPARE_SUBLINK
Definition: primnodes.h:695

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, SubLink::operName, 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 1018 of file parse_expr.c.

1019 {
1020  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
1021  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
1022 
1023  return (Node *) make_scalar_array_op(pstate,
1024  a->name,
1025  false,
1026  lexpr,
1027  rexpr,
1028  a->location);
1029 }

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

Referenced by transformExprRecurse().

◆ transformAExprOpAny()

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

Definition at line 1004 of file parse_expr.c.

1005 {
1006  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
1007  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
1008 
1009  return (Node *) make_scalar_array_op(pstate,
1010  a->name,
1011  true,
1012  lexpr,
1013  rexpr,
1014  a->location);
1015 }

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 1988 of file parse_expr.c.

1990 {
1991  ArrayExpr *newa = makeNode(ArrayExpr);
1992  List *newelems = NIL;
1993  List *newcoercedelems = NIL;
1994  ListCell *element;
1995  Oid coerce_type;
1996  bool coerce_hard;
1997 
1998  /*
1999  * Transform the element expressions
2000  *
2001  * Assume that the array is one-dimensional unless we find an array-type
2002  * element expression.
2003  */
2004  newa->multidims = false;
2005  foreach(element, a->elements)
2006  {
2007  Node *e = (Node *) lfirst(element);
2008  Node *newe;
2009 
2010  /*
2011  * If an element is itself an A_ArrayExpr, recurse directly so that we
2012  * can pass down any target type we were given.
2013  */
2014  if (IsA(e, A_ArrayExpr))
2015  {
2016  newe = transformArrayExpr(pstate,
2017  (A_ArrayExpr *) e,
2018  array_type,
2019  element_type,
2020  typmod);
2021  /* we certainly have an array here */
2022  Assert(array_type == InvalidOid || array_type == exprType(newe));
2023  newa->multidims = true;
2024  }
2025  else
2026  {
2027  newe = transformExprRecurse(pstate, e);
2028 
2029  /*
2030  * Check for sub-array expressions, if we haven't already found
2031  * one.
2032  */
2033  if (!newa->multidims && type_is_array(exprType(newe)))
2034  newa->multidims = true;
2035  }
2036 
2037  newelems = lappend(newelems, newe);
2038  }
2039 
2040  /*
2041  * Select a target type for the elements.
2042  *
2043  * If we haven't been given a target array type, we must try to deduce a
2044  * common type based on the types of the individual elements present.
2045  */
2046  if (OidIsValid(array_type))
2047  {
2048  /* Caller must ensure array_type matches element_type */
2049  Assert(OidIsValid(element_type));
2050  coerce_type = (newa->multidims ? array_type : element_type);
2051  coerce_hard = true;
2052  }
2053  else
2054  {
2055  /* Can't handle an empty array without a target type */
2056  if (newelems == NIL)
2057  ereport(ERROR,
2058  (errcode(ERRCODE_INDETERMINATE_DATATYPE),
2059  errmsg("cannot determine type of empty array"),
2060  errhint("Explicitly cast to the desired type, "
2061  "for example ARRAY[]::integer[]."),
2062  parser_errposition(pstate, a->location)));
2063 
2064  /* Select a common type for the elements */
2065  coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
2066 
2067  if (newa->multidims)
2068  {
2069  array_type = coerce_type;
2070  element_type = get_element_type(array_type);
2071  if (!OidIsValid(element_type))
2072  ereport(ERROR,
2073  (errcode(ERRCODE_UNDEFINED_OBJECT),
2074  errmsg("could not find element type for data type %s",
2075  format_type_be(array_type)),
2076  parser_errposition(pstate, a->location)));
2077  }
2078  else
2079  {
2080  element_type = coerce_type;
2081  array_type = get_array_type(element_type);
2082  if (!OidIsValid(array_type))
2083  ereport(ERROR,
2084  (errcode(ERRCODE_UNDEFINED_OBJECT),
2085  errmsg("could not find array type for data type %s",
2086  format_type_be(element_type)),
2087  parser_errposition(pstate, a->location)));
2088  }
2089  coerce_hard = false;
2090  }
2091 
2092  /*
2093  * Coerce elements to target type
2094  *
2095  * If the array has been explicitly cast, then the elements are in turn
2096  * explicitly coerced.
2097  *
2098  * If the array's type was merely derived from the common type of its
2099  * elements, then the elements are implicitly coerced to the common type.
2100  * This is consistent with other uses of select_common_type().
2101  */
2102  foreach(element, newelems)
2103  {
2104  Node *e = (Node *) lfirst(element);
2105  Node *newe;
2106 
2107  if (coerce_hard)
2108  {
2109  newe = coerce_to_target_type(pstate, e,
2110  exprType(e),
2111  coerce_type,
2112  typmod,
2115  -1);
2116  if (newe == NULL)
2117  ereport(ERROR,
2118  (errcode(ERRCODE_CANNOT_COERCE),
2119  errmsg("cannot cast type %s to %s",
2122  parser_errposition(pstate, exprLocation(e))));
2123  }
2124  else
2125  newe = coerce_to_common_type(pstate, e,
2126  coerce_type,
2127  "ARRAY");
2128  newcoercedelems = lappend(newcoercedelems, newe);
2129  }
2130 
2131  newa->array_typeid = array_type;
2132  /* array_collid will be set by parse_collate.c */
2133  newa->element_typeid = element_type;
2134  newa->elements = newcoercedelems;
2135  newa->location = a->location;
2136 
2137  return (Node *) newa;
2138 }
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2716
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:1988
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, ArrayExpr::array_typeid, Assert(), COERCE_EXPLICIT_CAST, coerce_to_common_type(), coerce_to_target_type(), coerce_type(), COERCION_EXPLICIT, element(), ArrayExpr::element_typeid, 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, ArrayExpr::multidims, 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 2484 of file parse_expr.c.

2485 {
2486  const char *clausename;
2487 
2488  switch (b->booltesttype)
2489  {
2490  case IS_TRUE:
2491  clausename = "IS TRUE";
2492  break;
2493  case IS_NOT_TRUE:
2494  clausename = "IS NOT TRUE";
2495  break;
2496  case IS_FALSE:
2497  clausename = "IS FALSE";
2498  break;
2499  case IS_NOT_FALSE:
2500  clausename = "IS NOT FALSE";
2501  break;
2502  case IS_UNKNOWN:
2503  clausename = "IS UNKNOWN";
2504  break;
2505  case IS_NOT_UNKNOWN:
2506  clausename = "IS NOT UNKNOWN";
2507  break;
2508  default:
2509  elog(ERROR, "unrecognized booltesttype: %d",
2510  (int) b->booltesttype);
2511  clausename = NULL; /* keep compiler quiet */
2512  }
2513 
2514  b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
2515 
2516  b->arg = (Expr *) coerce_to_boolean(pstate,
2517  (Node *) b->arg,
2518  clausename);
2519 
2520  return (Node *) b;
2521 }
int b
Definition: isn.c:70
@ IS_NOT_TRUE
Definition: primnodes.h:1543
@ IS_NOT_FALSE
Definition: primnodes.h:1543
@ IS_NOT_UNKNOWN
Definition: primnodes.h:1543
@ IS_TRUE
Definition: primnodes.h:1543
@ IS_UNKNOWN
Definition: primnodes.h:1543
@ IS_FALSE
Definition: primnodes.h:1543

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 1377 of file parse_expr.c.

1378 {
1379  List *args = NIL;
1380  const char *opname;
1381  ListCell *lc;
1382 
1383  switch (a->boolop)
1384  {
1385  case AND_EXPR:
1386  opname = "AND";
1387  break;
1388  case OR_EXPR:
1389  opname = "OR";
1390  break;
1391  case NOT_EXPR:
1392  opname = "NOT";
1393  break;
1394  default:
1395  elog(ERROR, "unrecognized boolop: %d", (int) a->boolop);
1396  opname = NULL; /* keep compiler quiet */
1397  break;
1398  }
1399 
1400  foreach(lc, a->args)
1401  {
1402  Node *arg = (Node *) lfirst(lc);
1403 
1404  arg = transformExprRecurse(pstate, arg);
1405  arg = coerce_to_boolean(pstate, arg, opname);
1406  args = lappend(args, arg);
1407  }
1408 
1409  return (Node *) makeBoolExpr(a->boolop, args, a->location);
1410 }

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 1606 of file parse_expr.c.

1607 {
1608  CaseExpr *newc = makeNode(CaseExpr);
1609  Node *last_srf = pstate->p_last_srf;
1610  Node *arg;
1611  CaseTestExpr *placeholder;
1612  List *newargs;
1613  List *resultexprs;
1614  ListCell *l;
1615  Node *defresult;
1616  Oid ptype;
1617 
1618  /* transform the test expression, if any */
1619  arg = transformExprRecurse(pstate, (Node *) c->arg);
1620 
1621  /* generate placeholder for test expression */
1622  if (arg)
1623  {
1624  /*
1625  * If test expression is an untyped literal, force it to text. We have
1626  * to do something now because we won't be able to do this coercion on
1627  * the placeholder. This is not as flexible as what was done in 7.4
1628  * and before, but it's good enough to handle the sort of silly coding
1629  * commonly seen.
1630  */
1631  if (exprType(arg) == UNKNOWNOID)
1632  arg = coerce_to_common_type(pstate, arg, TEXTOID, "CASE");
1633 
1634  /*
1635  * Run collation assignment on the test expression so that we know
1636  * what collation to mark the placeholder with. In principle we could
1637  * leave it to parse_collate.c to do that later, but propagating the
1638  * result to the CaseTestExpr would be unnecessarily complicated.
1639  */
1640  assign_expr_collations(pstate, arg);
1641 
1642  placeholder = makeNode(CaseTestExpr);
1643  placeholder->typeId = exprType(arg);
1644  placeholder->typeMod = exprTypmod(arg);
1645  placeholder->collation = exprCollation(arg);
1646  }
1647  else
1648  placeholder = NULL;
1649 
1650  newc->arg = (Expr *) arg;
1651 
1652  /* transform the list of arguments */
1653  newargs = NIL;
1654  resultexprs = NIL;
1655  foreach(l, c->args)
1656  {
1657  CaseWhen *w = lfirst_node(CaseWhen, l);
1658  CaseWhen *neww = makeNode(CaseWhen);
1659  Node *warg;
1660 
1661  warg = (Node *) w->expr;
1662  if (placeholder)
1663  {
1664  /* shorthand form was specified, so expand... */
1665  warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
1666  (Node *) placeholder,
1667  warg,
1668  w->location);
1669  }
1670  neww->expr = (Expr *) transformExprRecurse(pstate, warg);
1671 
1672  neww->expr = (Expr *) coerce_to_boolean(pstate,
1673  (Node *) neww->expr,
1674  "CASE/WHEN");
1675 
1676  warg = (Node *) w->result;
1677  neww->result = (Expr *) transformExprRecurse(pstate, warg);
1678  neww->location = w->location;
1679 
1680  newargs = lappend(newargs, neww);
1681  resultexprs = lappend(resultexprs, neww->result);
1682  }
1683 
1684  newc->args = newargs;
1685 
1686  /* transform the default clause */
1687  defresult = (Node *) c->defresult;
1688  if (defresult == NULL)
1689  {
1690  A_Const *n = makeNode(A_Const);
1691 
1692  n->isnull = true;
1693  n->location = -1;
1694  defresult = (Node *) n;
1695  }
1696  newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
1697 
1698  /*
1699  * Note: default result is considered the most significant type in
1700  * determining preferred type. This is how the code worked before, but it
1701  * seems a little bogus to me --- tgl
1702  */
1703  resultexprs = lcons(newc->defresult, resultexprs);
1704 
1705  ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
1706  Assert(OidIsValid(ptype));
1707  newc->casetype = ptype;
1708  /* casecollid will be set by parse_collate.c */
1709 
1710  /* Convert default result clause, if necessary */
1711  newc->defresult = (Expr *)
1712  coerce_to_common_type(pstate,
1713  (Node *) newc->defresult,
1714  ptype,
1715  "CASE/ELSE");
1716 
1717  /* Convert when-clause results, if necessary */
1718  foreach(l, newc->args)
1719  {
1720  CaseWhen *w = (CaseWhen *) lfirst(l);
1721 
1722  w->result = (Expr *)
1723  coerce_to_common_type(pstate,
1724  (Node *) w->result,
1725  ptype,
1726  "CASE/WHEN");
1727  }
1728 
1729  /* if any subexpression contained a SRF, complain */
1730  if (pstate->p_last_srf != last_srf)
1731  ereport(ERROR,
1732  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1733  /* translator: %s is name of a SQL construct, eg GROUP BY */
1734  errmsg("set-returning functions are not allowed in %s",
1735  "CASE"),
1736  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
1737  parser_errposition(pstate,
1738  exprLocation(pstate->p_last_srf))));
1739 
1740  newc->location = c->location;
1741 
1742  return (Node *) newc;
1743 }
List * lcons(void *datum, List *list)
Definition: list.c:474
void assign_expr_collations(ParseState *pstate, Node *expr)
#define lfirst_node(type, lc)
Definition: pg_list.h:172
char * c
int location
Definition: parsenodes.h:318
Expr * arg
Definition: primnodes.h:987
int location
Definition: primnodes.h:990
Oid casetype
Definition: primnodes.h:985
Expr * defresult
Definition: primnodes.h:989
List * args
Definition: primnodes.h:988
Expr * result
Definition: primnodes.h:1000
Expr * expr
Definition: primnodes.h:999
int location
Definition: primnodes.h:1001

References AEXPR_OP, arg, CaseExpr::arg, CaseExpr::args, Assert(), assign_expr_collations(), CaseExpr::casetype, coerce_to_boolean(), coerce_to_common_type(), CaseTestExpr::collation, 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(), CaseTestExpr::typeId, and CaseTestExpr::typeMod.

Referenced by transformExprRecurse().

◆ transformCoalesceExpr()

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

Definition at line 2171 of file parse_expr.c.

2172 {
2174  Node *last_srf = pstate->p_last_srf;
2175  List *newargs = NIL;
2176  List *newcoercedargs = NIL;
2177  ListCell *args;
2178 
2179  foreach(args, c->args)
2180  {
2181  Node *e = (Node *) lfirst(args);
2182  Node *newe;
2183 
2184  newe = transformExprRecurse(pstate, e);
2185  newargs = lappend(newargs, newe);
2186  }
2187 
2188  newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
2189  /* coalescecollid will be set by parse_collate.c */
2190 
2191  /* Convert arguments if necessary */
2192  foreach(args, newargs)
2193  {
2194  Node *e = (Node *) lfirst(args);
2195  Node *newe;
2196 
2197  newe = coerce_to_common_type(pstate, e,
2198  newc->coalescetype,
2199  "COALESCE");
2200  newcoercedargs = lappend(newcoercedargs, newe);
2201  }
2202 
2203  /* if any subexpression contained a SRF, complain */
2204  if (pstate->p_last_srf != last_srf)
2205  ereport(ERROR,
2206  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2207  /* translator: %s is name of a SQL construct, eg GROUP BY */
2208  errmsg("set-returning functions are not allowed in %s",
2209  "COALESCE"),
2210  errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
2211  parser_errposition(pstate,
2212  exprLocation(pstate->p_last_srf))));
2213 
2214  newc->args = newcoercedargs;
2215  newc->location = c->location;
2216  return (Node *) newc;
2217 }
List * args
Definition: primnodes.h:1139
Oid coalescetype
Definition: primnodes.h:1137

References generate_unaccent_rules::args, CoalesceExpr::args, CoalesceExpr::coalescetype, 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 2727 of file parse_expr.c.

2728 {
2729  CollateExpr *newc;
2730  Oid argtype;
2731 
2732  newc = makeNode(CollateExpr);
2733  newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
2734 
2735  argtype = exprType((Node *) newc->arg);
2736 
2737  /*
2738  * The unknown type is not collatable, but coerce_type() takes care of it
2739  * separately, so we'll let it go here.
2740  */
2741  if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
2742  ereport(ERROR,
2743  (errcode(ERRCODE_DATATYPE_MISMATCH),
2744  errmsg("collations are not supported by type %s",
2745  format_type_be(argtype)),
2746  parser_errposition(pstate, c->location)));
2747 
2748  newc->collOid = LookupCollation(pstate, c->collname, c->location);
2749  newc->location = c->location;
2750 
2751  return (Node *) newc;
2752 }
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:3038
Oid LookupCollation(ParseState *pstate, List *collnames, int location)
Definition: parse_type.c:517
Expr * arg
Definition: primnodes.h:955
int location
Definition: primnodes.h:957

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 501 of file parse_expr.c.

502 {
503  Node *node = NULL;
504  char *nspname = NULL;
505  char *relname = NULL;
506  char *colname = NULL;
507  ParseNamespaceItem *nsitem;
508  int levels_up;
509  enum
510  {
511  CRERR_NO_COLUMN,
512  CRERR_NO_RTE,
513  CRERR_WRONG_DB,
514  CRERR_TOO_MANY
515  } crerr = CRERR_NO_COLUMN;
516  const char *err;
517 
518  /*
519  * Check to see if the column reference is in an invalid place within the
520  * query. We allow column references in most places, except in default
521  * expressions and partition bound expressions.
522  */
523  err = NULL;
524  switch (pstate->p_expr_kind)
525  {
526  case EXPR_KIND_NONE:
527  Assert(false); /* can't happen */
528  break;
529  case EXPR_KIND_OTHER:
530  case EXPR_KIND_JOIN_ON:
534  case EXPR_KIND_WHERE:
535  case EXPR_KIND_POLICY:
536  case EXPR_KIND_HAVING:
537  case EXPR_KIND_FILTER:
548  case EXPR_KIND_GROUP_BY:
549  case EXPR_KIND_ORDER_BY:
551  case EXPR_KIND_LIMIT:
552  case EXPR_KIND_OFFSET:
553  case EXPR_KIND_RETURNING:
554  case EXPR_KIND_VALUES:
570  /* okay */
571  break;
572 
574  err = _("cannot use column reference in DEFAULT expression");
575  break;
577  err = _("cannot use column reference in partition bound expression");
578  break;
579 
580  /*
581  * There is intentionally no default: case here, so that the
582  * compiler will warn if we add a new ParseExprKind without
583  * extending this switch. If we do see an unrecognized value at
584  * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
585  * which is sane anyway.
586  */
587  }
588  if (err)
589  ereport(ERROR,
590  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
591  errmsg_internal("%s", err),
592  parser_errposition(pstate, cref->location)));
593 
594  /*
595  * Give the PreParseColumnRefHook, if any, first shot. If it returns
596  * non-null then that's all, folks.
597  */
598  if (pstate->p_pre_columnref_hook != NULL)
599  {
600  node = pstate->p_pre_columnref_hook(pstate, cref);
601  if (node != NULL)
602  return node;
603  }
604 
605  /*----------
606  * The allowed syntaxes are:
607  *
608  * A First try to resolve as unqualified column name;
609  * if no luck, try to resolve as unqualified table name (A.*).
610  * A.B A is an unqualified table name; B is either a
611  * column or function name (trying column name first).
612  * A.B.C schema A, table B, col or func name C.
613  * A.B.C.D catalog A, schema B, table C, col or func D.
614  * A.* A is an unqualified table name; means whole-row value.
615  * A.B.* whole-row value of table B in schema A.
616  * A.B.C.* whole-row value of table C in schema B in catalog A.
617  *
618  * We do not need to cope with bare "*"; that will only be accepted by
619  * the grammar at the top level of a SELECT list, and transformTargetList
620  * will take care of it before it ever gets here. Also, "A.*" etc will
621  * be expanded by transformTargetList if they appear at SELECT top level,
622  * so here we are only going to see them as function or operator inputs.
623  *
624  * Currently, if a catalog name is given then it must equal the current
625  * database name; we check it here and then discard it.
626  *----------
627  */
628  switch (list_length(cref->fields))
629  {
630  case 1:
631  {
632  Node *field1 = (Node *) linitial(cref->fields);
633 
634  Assert(IsA(field1, String));
635  colname = strVal(field1);
636 
637  /* Try to identify as an unqualified column */
638  node = colNameToVar(pstate, colname, false, cref->location);
639 
640  if (node == NULL)
641  {
642  /*
643  * Not known as a column of any range-table entry.
644  *
645  * Try to find the name as a relation. Note that only
646  * relations already entered into the rangetable will be
647  * recognized.
648  *
649  * This is a hack for backwards compatibility with
650  * PostQUEL-inspired syntax. The preferred form now is
651  * "rel.*".
652  */
653  nsitem = refnameNamespaceItem(pstate, NULL, colname,
654  cref->location,
655  &levels_up);
656  if (nsitem)
657  node = transformWholeRowRef(pstate, nsitem, levels_up,
658  cref->location);
659  }
660  break;
661  }
662  case 2:
663  {
664  Node *field1 = (Node *) linitial(cref->fields);
665  Node *field2 = (Node *) lsecond(cref->fields);
666 
667  Assert(IsA(field1, String));
668  relname = strVal(field1);
669 
670  /* Locate the referenced nsitem */
671  nsitem = refnameNamespaceItem(pstate, nspname, relname,
672  cref->location,
673  &levels_up);
674  if (nsitem == NULL)
675  {
676  crerr = CRERR_NO_RTE;
677  break;
678  }
679 
680  /* Whole-row reference? */
681  if (IsA(field2, A_Star))
682  {
683  node = transformWholeRowRef(pstate, nsitem, levels_up,
684  cref->location);
685  break;
686  }
687 
688  Assert(IsA(field2, String));
689  colname = strVal(field2);
690 
691  /* Try to identify as a column of the nsitem */
692  node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
693  cref->location);
694  if (node == NULL)
695  {
696  /* Try it as a function call on the whole row */
697  node = transformWholeRowRef(pstate, nsitem, levels_up,
698  cref->location);
699  node = ParseFuncOrColumn(pstate,
700  list_make1(makeString(colname)),
701  list_make1(node),
702  pstate->p_last_srf,
703  NULL,
704  false,
705  cref->location);
706  }
707  break;
708  }
709  case 3:
710  {
711  Node *field1 = (Node *) linitial(cref->fields);
712  Node *field2 = (Node *) lsecond(cref->fields);
713  Node *field3 = (Node *) lthird(cref->fields);
714 
715  Assert(IsA(field1, String));
716  nspname = strVal(field1);
717  Assert(IsA(field2, String));
718  relname = strVal(field2);
719 
720  /* Locate the referenced nsitem */
721  nsitem = refnameNamespaceItem(pstate, nspname, relname,
722  cref->location,
723  &levels_up);
724  if (nsitem == NULL)
725  {
726  crerr = CRERR_NO_RTE;
727  break;
728  }
729 
730  /* Whole-row reference? */
731  if (IsA(field3, A_Star))
732  {
733  node = transformWholeRowRef(pstate, nsitem, levels_up,
734  cref->location);
735  break;
736  }
737 
738  Assert(IsA(field3, String));
739  colname = strVal(field3);
740 
741  /* Try to identify as a column of the nsitem */
742  node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
743  cref->location);
744  if (node == NULL)
745  {
746  /* Try it as a function call on the whole row */
747  node = transformWholeRowRef(pstate, nsitem, levels_up,
748  cref->location);
749  node = ParseFuncOrColumn(pstate,
750  list_make1(makeString(colname)),
751  list_make1(node),
752  pstate->p_last_srf,
753  NULL,
754  false,
755  cref->location);
756  }
757  break;
758  }
759  case 4:
760  {
761  Node *field1 = (Node *) linitial(cref->fields);
762  Node *field2 = (Node *) lsecond(cref->fields);
763  Node *field3 = (Node *) lthird(cref->fields);
764  Node *field4 = (Node *) lfourth(cref->fields);
765  char *catname;
766 
767  Assert(IsA(field1, String));
768  catname = strVal(field1);
769  Assert(IsA(field2, String));
770  nspname = strVal(field2);
771  Assert(IsA(field3, String));
772  relname = strVal(field3);
773 
774  /*
775  * We check the catalog name and then ignore it.
776  */
777  if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
778  {
779  crerr = CRERR_WRONG_DB;
780  break;
781  }
782 
783  /* Locate the referenced nsitem */
784  nsitem = refnameNamespaceItem(pstate, nspname, relname,
785  cref->location,
786  &levels_up);
787  if (nsitem == NULL)
788  {
789  crerr = CRERR_NO_RTE;
790  break;
791  }
792 
793  /* Whole-row reference? */
794  if (IsA(field4, A_Star))
795  {
796  node = transformWholeRowRef(pstate, nsitem, levels_up,
797  cref->location);
798  break;
799  }
800 
801  Assert(IsA(field4, String));
802  colname = strVal(field4);
803 
804  /* Try to identify as a column of the nsitem */
805  node = scanNSItemForColumn(pstate, nsitem, levels_up, colname,
806  cref->location);
807  if (node == NULL)
808  {
809  /* Try it as a function call on the whole row */
810  node = transformWholeRowRef(pstate, nsitem, levels_up,
811  cref->location);
812  node = ParseFuncOrColumn(pstate,
813  list_make1(makeString(colname)),
814  list_make1(node),
815  pstate->p_last_srf,
816  NULL,
817  false,
818  cref->location);
819  }
820  break;
821  }
822  default:
823  crerr = CRERR_TOO_MANY; /* too many dotted names */
824  break;
825  }
826 
827  /*
828  * Now give the PostParseColumnRefHook, if any, a chance. We pass the
829  * translation-so-far so that it can throw an error if it wishes in the
830  * case that it has a conflicting interpretation of the ColumnRef. (If it
831  * just translates anyway, we'll throw an error, because we can't undo
832  * whatever effects the preceding steps may have had on the pstate.) If it
833  * returns NULL, use the standard translation, or throw a suitable error
834  * if there is none.
835  */
836  if (pstate->p_post_columnref_hook != NULL)
837  {
838  Node *hookresult;
839 
840  hookresult = pstate->p_post_columnref_hook(pstate, cref, node);
841  if (node == NULL)
842  node = hookresult;
843  else if (hookresult != NULL)
844  ereport(ERROR,
845  (errcode(ERRCODE_AMBIGUOUS_COLUMN),
846  errmsg("column reference \"%s\" is ambiguous",
847  NameListToString(cref->fields)),
848  parser_errposition(pstate, cref->location)));
849  }
850 
851  /*
852  * Throw error if no translation found.
853  */
854  if (node == NULL)
855  {
856  switch (crerr)
857  {
858  case CRERR_NO_COLUMN:
859  errorMissingColumn(pstate, relname, colname, cref->location);
860  break;
861  case CRERR_NO_RTE:
862  errorMissingRTE(pstate, makeRangeVar(nspname, relname,
863  cref->location));
864  break;
865  case CRERR_WRONG_DB:
866  ereport(ERROR,
867  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
868  errmsg("cross-database references are not implemented: %s",
869  NameListToString(cref->fields)),
870  parser_errposition(pstate, cref->location)));
871  break;
872  case CRERR_TOO_MANY:
873  ereport(ERROR,
874  (errcode(ERRCODE_SYNTAX_ERROR),
875  errmsg("improper qualified name (too many dotted names): %s",
876  NameListToString(cref->fields)),
877  parser_errposition(pstate, cref->location)));
878  break;
879  }
880  }
881 
882  return node;
883 }
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2994
int errmsg_internal(const char *fmt,...)
Definition: elog.c:991
#define _(x)
Definition: elog.c:89
Oid MyDatabaseId
Definition: globals.c:89
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:423
char * NameListToString(List *names)
Definition: namespace.c:3148
static Node * transformWholeRowRef(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location)
Definition: parse_expr.c:2576
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:184
#define lfourth(l)
Definition: pg_list.h:189
int location
Definition: parsenodes.h:253
List * fields
Definition: parsenodes.h:252
ParseExprKind p_expr_kind
Definition: parse_node.h:197
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:221
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:222
Definition: value.h:58
String * makeString(char *str)
Definition: value.c:63

References _, Assert(), colNameToVar(), ereport, 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 2524 of file parse_expr.c.

2525 {
2526  /* CURRENT OF can only appear at top level of UPDATE/DELETE */
2527  Assert(pstate->p_target_nsitem != NULL);
2528  cexpr->cvarno = pstate->p_target_nsitem->p_rtindex;
2529 
2530  /*
2531  * Check to see if the cursor name matches a parameter of type REFCURSOR.
2532  * If so, replace the raw name reference with a parameter reference. (This
2533  * is a hack for the convenience of plpgsql.)
2534  */
2535  if (cexpr->cursor_name != NULL) /* in case already transformed */
2536  {
2537  ColumnRef *cref = makeNode(ColumnRef);
2538  Node *node = NULL;
2539 
2540  /* Build an unqualified ColumnRef with the given name */
2541  cref->fields = list_make1(makeString(cexpr->cursor_name));
2542  cref->location = -1;
2543 
2544  /* See if there is a translation available from a parser hook */
2545  if (pstate->p_pre_columnref_hook != NULL)
2546  node = pstate->p_pre_columnref_hook(pstate, cref);
2547  if (node == NULL && pstate->p_post_columnref_hook != NULL)
2548  node = pstate->p_post_columnref_hook(pstate, cref, NULL);
2549 
2550  /*
2551  * XXX Should we throw an error if we get a translation that isn't a
2552  * refcursor Param? For now it seems best to silently ignore false
2553  * matches.
2554  */
2555  if (node != NULL && IsA(node, Param))
2556  {
2557  Param *p = (Param *) node;
2558 
2559  if (p->paramkind == PARAM_EXTERN &&
2560  p->paramtype == REFCURSOROID)
2561  {
2562  /* Matches, so convert CURRENT OF to a param reference */
2563  cexpr->cursor_name = NULL;
2564  cexpr->cursor_param = p->paramid;
2565  }
2566  }
2567  }
2568 
2569  return (Node *) cexpr;
2570 }
@ PARAM_EXTERN
Definition: primnodes.h:267
char * cursor_name
Definition: primnodes.h:1625
int paramid
Definition: primnodes.h:277
Oid paramtype
Definition: primnodes.h:278
ParamKind paramkind
Definition: primnodes.h:276
ParseNamespaceItem * p_target_nsitem
Definition: parse_node.h:194

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 130 of file parse_expr.c.

131 {
132  Node *result;
133 
134  if (expr == NULL)
135  return NULL;
136 
137  /* Guard against stack overflow due to overly complex expressions */
139 
140  switch (nodeTag(expr))
141  {
142  case T_ColumnRef:
143  result = transformColumnRef(pstate, (ColumnRef *) expr);
144  break;
145 
146  case T_ParamRef:
147  result = transformParamRef(pstate, (ParamRef *) expr);
148  break;
149 
150  case T_A_Const:
151  result = (Node *) make_const(pstate, (A_Const *) expr);
152  break;
153 
154  case T_A_Indirection:
155  result = transformIndirection(pstate, (A_Indirection *) expr);
156  break;
157 
158  case T_A_ArrayExpr:
159  result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
160  InvalidOid, InvalidOid, -1);
161  break;
162 
163  case T_TypeCast:
164  result = transformTypeCast(pstate, (TypeCast *) expr);
165  break;
166 
167  case T_CollateClause:
168  result = transformCollateClause(pstate, (CollateClause *) expr);
169  break;
170 
171  case T_A_Expr:
172  {
173  A_Expr *a = (A_Expr *) expr;
174 
175  switch (a->kind)
176  {
177  case AEXPR_OP:
178  result = transformAExprOp(pstate, a);
179  break;
180  case AEXPR_OP_ANY:
181  result = transformAExprOpAny(pstate, a);
182  break;
183  case AEXPR_OP_ALL:
184  result = transformAExprOpAll(pstate, a);
185  break;
186  case AEXPR_DISTINCT:
187  case AEXPR_NOT_DISTINCT:
188  result = transformAExprDistinct(pstate, a);
189  break;
190  case AEXPR_NULLIF:
191  result = transformAExprNullIf(pstate, a);
192  break;
193  case AEXPR_IN:
194  result = transformAExprIn(pstate, a);
195  break;
196  case AEXPR_LIKE:
197  case AEXPR_ILIKE:
198  case AEXPR_SIMILAR:
199  /* we can transform these just like AEXPR_OP */
200  result = transformAExprOp(pstate, a);
201  break;
202  case AEXPR_BETWEEN:
203  case AEXPR_NOT_BETWEEN:
204  case AEXPR_BETWEEN_SYM:
206  result = transformAExprBetween(pstate, a);
207  break;
208  default:
209  elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
210  result = NULL; /* keep compiler quiet */
211  break;
212  }
213  break;
214  }
215 
216  case T_BoolExpr:
217  result = transformBoolExpr(pstate, (BoolExpr *) expr);
218  break;
219 
220  case T_FuncCall:
221  result = transformFuncCall(pstate, (FuncCall *) expr);
222  break;
223 
224  case T_MultiAssignRef:
225  result = transformMultiAssignRef(pstate, (MultiAssignRef *) expr);
226  break;
227 
228  case T_GroupingFunc:
229  result = transformGroupingFunc(pstate, (GroupingFunc *) expr);
230  break;
231 
232  case T_NamedArgExpr:
233  {
234  NamedArgExpr *na = (NamedArgExpr *) expr;
235 
236  na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
237  result = expr;
238  break;
239  }
240 
241  case T_SubLink:
242  result = transformSubLink(pstate, (SubLink *) expr);
243  break;
244 
245  case T_CaseExpr:
246  result = transformCaseExpr(pstate, (CaseExpr *) expr);
247  break;
248 
249  case T_RowExpr:
250  result = transformRowExpr(pstate, (RowExpr *) expr, false);
251  break;
252 
253  case T_CoalesceExpr:
254  result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
255  break;
256 
257  case T_MinMaxExpr:
258  result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
259  break;
260 
261  case T_SQLValueFunction:
262  result = transformSQLValueFunction(pstate,
263  (SQLValueFunction *) expr);
264  break;
265 
266  case T_XmlExpr:
267  result = transformXmlExpr(pstate, (XmlExpr *) expr);
268  break;
269 
270  case T_XmlSerialize:
271  result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
272  break;
273 
274  case T_NullTest:
275  {
276  NullTest *n = (NullTest *) expr;
277 
278  n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
279  /* the argument can be any type, so don't coerce it */
280  n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
281  result = expr;
282  break;
283  }
284 
285  case T_BooleanTest:
286  result = transformBooleanTest(pstate, (BooleanTest *) expr);
287  break;
288 
289  case T_CurrentOfExpr:
290  result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
291  break;
292 
293  /*
294  * In all places where DEFAULT is legal, the caller should have
295  * processed it rather than passing it to transformExpr().
296  */
297  case T_SetToDefault:
298  ereport(ERROR,
299  (errcode(ERRCODE_SYNTAX_ERROR),
300  errmsg("DEFAULT is not allowed in this context"),
301  parser_errposition(pstate,
302  ((SetToDefault *) expr)->location)));
303  break;
304 
305  /*
306  * CaseTestExpr doesn't require any processing; it is only
307  * injected into parse trees in a fully-formed state.
308  *
309  * Ordinarily we should not see a Var here, but it is convenient
310  * for transformJoinUsingClause() to create untransformed operator
311  * trees containing already-transformed Vars. The best
312  * alternative would be to deconstruct and reconstruct column
313  * references, which seems expensively pointless. So allow it.
314  */
315  case T_CaseTestExpr:
316  case T_Var:
317  {
318  result = (Node *) expr;
319  break;
320  }
321 
323  result = transformJsonObjectConstructor(pstate, (JsonObjectConstructor *) expr);
324  break;
325 
327  result = transformJsonArrayConstructor(pstate, (JsonArrayConstructor *) expr);
328  break;
329 
332  break;
333 
334  case T_JsonObjectAgg:
335  result = transformJsonObjectAgg(pstate, (JsonObjectAgg *) expr);
336  break;
337 
338  case T_JsonArrayAgg:
339  result = transformJsonArrayAgg(pstate, (JsonArrayAgg *) expr);
340  break;
341 
342  case T_JsonIsPredicate:
343  result = transformJsonIsPredicate(pstate, (JsonIsPredicate *) expr);
344  break;
345 
346  case T_JsonFuncExpr:
347  result = transformJsonFuncExpr(pstate, (JsonFuncExpr *) expr);
348  break;
349 
350  case T_JsonValueExpr:
351  result = transformJsonValueExpr(pstate, (JsonValueExpr *) expr);
352  break;
353 
354  case T_JsonParseExpr:
355  result = transformJsonParseExpr(pstate, (JsonParseExpr *) expr);
356  break;
357 
358  case T_JsonScalarExpr:
359  result = transformJsonScalarExpr(pstate, (JsonScalarExpr *) expr);
360  break;
361 
362  case T_JsonSerializeExpr:
363  result = transformJsonSerializeExpr(pstate, (JsonSerializeExpr *) expr);
364  break;
365 
366  default:
367  /* should not reach here */
368  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
369  result = NULL; /* keep compiler quiet */
370  break;
371  }
372 
373  return result;
374 }
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2612
#define nodeTag(nodeptr)
Definition: nodes.h:578
@ T_CoalesceExpr
Definition: nodes.h:187
@ T_JsonParseExpr
Definition: nodes.h:208
@ T_JsonSerializeExpr
Definition: nodes.h:210
@ T_XmlSerialize
Definition: nodes.h:493
@ T_SubLink
Definition: nodes.h:171
@ T_JsonArrayConstructor
Definition: nodes.h:512
@ T_BoolExpr
Definition: nodes.h:170
@ T_CaseExpr
Definition: nodes.h:181
@ T_XmlExpr
Definition: nodes.h:190
@ T_JsonFuncExpr
Definition: nodes.h:517
@ T_JsonObjectConstructor
Definition: nodes.h:511
@ T_MultiAssignRef
Definition: nodes.h:463
@ T_JsonScalarExpr
Definition: nodes.h:209
@ T_A_ArrayExpr
Definition: nodes.h:461
@ T_RowExpr
Definition: nodes.h:185
@ T_FuncCall
Definition: nodes.h:457
@ T_A_Const
Definition: nodes.h:456
@ T_MinMaxExpr
Definition: nodes.h:188
@ T_A_Expr
Definition: nodes.h:453
@ T_A_Indirection
Definition: nodes.h:460
@ T_CurrentOfExpr
Definition: nodes.h:196
@ T_BooleanTest
Definition: nodes.h:192
@ T_ParamRef
Definition: nodes.h:455
@ T_JsonArrayQueryConstructor
Definition: nodes.h:513
@ T_JsonIsPredicate
Definition: nodes.h:518
@ T_JsonValueExpr
Definition: nodes.h:207
@ T_SQLValueFunction
Definition: nodes.h:189
@ T_NamedArgExpr
Definition: nodes.h:165
@ T_JsonArrayAgg
Definition: nodes.h:516
@ T_JsonObjectAgg
Definition: nodes.h:515
@ T_GroupingFunc
Definition: nodes.h:161
@ T_CollateClause
Definition: nodes.h:465
@ T_ColumnRef
Definition: nodes.h:454
@ T_Var
Definition: nodes.h:157
@ T_CaseTestExpr
Definition: nodes.h:183
@ T_NullTest
Definition: nodes.h:191
@ T_SetToDefault
Definition: nodes.h:195
@ T_TypeCast
Definition: nodes.h:464
Node * transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
Definition: parse_agg.c:247
static Node * transformJsonArrayConstructor(ParseState *pstate, JsonArrayConstructor *ctor)
Definition: parse_expr.c:3944
static Node * transformJsonScalarExpr(ParseState *pstate, JsonScalarExpr *expr)
Definition: parse_expr.c:4554
static Node * transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
Definition: parse_expr.c:2524
static Node * transformAExprOpAll(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1018
static Node * transformAExprIn(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1125
static Node * transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *p)
Definition: parse_expr.c:4024
static Node * transformAExprOpAny(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1004
static Node * transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
Definition: parse_expr.c:2441
static Node * transformAExprNullIf(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1083
static Node * transformJsonArrayQueryConstructor(ParseState *pstate, JsonArrayQueryConstructor *ctor)
Definition: parse_expr.c:3695
static Node * transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf)
Definition: parse_expr.c:2259
static Node * transformColumnRef(ParseState *pstate, ColumnRef *cref)
Definition: parse_expr.c:501
static Node * transformCollateClause(ParseState *pstate, CollateClause *c)
Definition: parse_expr.c:2727
static Node * transformBoolExpr(ParseState *pstate, BoolExpr *a)
Definition: parse_expr.c:1377
static Node * transformFuncCall(ParseState *pstate, FuncCall *fn)
Definition: parse_expr.c:1413
static Node * transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
Definition: parse_expr.c:2220
static Node * transformJsonValueExpr(ParseState *pstate, JsonValueExpr *jve)
Definition: parse_expr.c:3403
static Node * transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
Definition: parse_expr.c:2171
static Node * transformSubLink(ParseState *pstate, SubLink *sublink)
Definition: parse_expr.c:1746
static Node * transformJsonObjectConstructor(ParseState *pstate, JsonObjectConstructor *ctor)
Definition: parse_expr.c:3661
static Node * transformAExprOp(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:923
static Node * transformJsonArrayAgg(ParseState *pstate, JsonArrayAgg *agg)
Definition: parse_expr.c:3903
static Node * transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
Definition: parse_expr.c:1458
static Node * transformBooleanTest(ParseState *pstate, BooleanTest *b)
Definition: parse_expr.c:2484
static Node * transformTypeCast(ParseState *pstate, TypeCast *tc)
Definition: parse_expr.c:2643
static Node * transformParamRef(ParseState *pstate, ParamRef *pref)
Definition: parse_expr.c:886
static Node * transformCaseExpr(ParseState *pstate, CaseExpr *c)
Definition: parse_expr.c:1606
static Node * transformJsonParseExpr(ParseState *pstate, JsonParseExpr *expr)
Definition: parse_expr.c:4511
static Node * transformIndirection(ParseState *pstate, A_Indirection *ind)
Definition: parse_expr.c:429
static Node * transformJsonSerializeExpr(ParseState *pstate, JsonSerializeExpr *expr)
Definition: parse_expr.c:4571
static Node * transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
Definition: parse_expr.c:2141
static Node * transformXmlExpr(ParseState *pstate, XmlExpr *x)
Definition: parse_expr.c:2312
static Node * transformAExprBetween(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1283
static Node * transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *p)
Definition: parse_expr.c:4357
static Node * transformJsonObjectAgg(ParseState *pstate, JsonObjectAgg *agg)
Definition: parse_expr.c:3844
static Node * transformAExprDistinct(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1032
Const * make_const(ParseState *pstate, A_Const *aconst)
Definition: parse_node.c:351
@ AEXPR_NULLIF
Definition: parsenodes.h:276
@ AEXPR_ILIKE
Definition: parsenodes.h:279
@ AEXPR_IN
Definition: parsenodes.h:277
@ AEXPR_DISTINCT
Definition: parsenodes.h:274
@ AEXPR_SIMILAR
Definition: parsenodes.h:280
@ AEXPR_LIKE
Definition: parsenodes.h:278
@ AEXPR_OP_ANY
Definition: parsenodes.h:272
@ AEXPR_OP_ALL
Definition: parsenodes.h:273
void check_stack_depth(void)
Definition: postgres.c:3500
Expr * arg
Definition: primnodes.h:533

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, NullTest::argisrow, check_stack_depth(), elog, ereport, errcode(), errmsg(), ERROR, exprType(), InvalidOid, make_const(), nodeTag, parser_errposition(), T_A_ArrayExpr, T_A_Const, T_A_Expr, T_A_Indirection, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CollateClause, T_ColumnRef, T_CurrentOfExpr, T_FuncCall, T_GroupingFunc, T_JsonArrayAgg, T_JsonArrayConstructor, T_JsonArrayQueryConstructor, T_JsonFuncExpr, T_JsonIsPredicate, T_JsonObjectAgg, T_JsonObjectConstructor, T_JsonParseExpr, T_JsonScalarExpr, T_JsonSerializeExpr, T_JsonValueExpr, T_MinMaxExpr, T_MultiAssignRef, T_NamedArgExpr, T_NullTest, T_ParamRef, T_RowExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_TypeCast, T_Var, T_XmlExpr, T_XmlSerialize, transformAExprBetween(), transformAExprDistinct(), transformAExprIn(), transformAExprNullIf(), transformAExprOp(), transformAExprOpAll(), transformAExprOpAny(), transformArrayExpr(), transformBooleanTest(), transformBoolExpr(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformColumnRef(), transformCurrentOfExpr(), transformFuncCall(), transformGroupingFunc(), transformIndirection(), transformJsonArrayAgg(), transformJsonArrayConstructor(), transformJsonArrayQueryConstructor(), transformJsonFuncExpr(), transformJsonIsPredicate(), transformJsonObjectAgg(), transformJsonObjectConstructor(), transformJsonParseExpr(), transformJsonScalarExpr(), transformJsonSerializeExpr(), transformJsonValueExpr(), transformMinMaxExpr(), transformMultiAssignRef(), transformParamRef(), transformRowExpr(), transformSQLValueFunction(), 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(), transformJsonBehavior(), transformJsonExprCommon(), transformJsonObjectAgg(), transformJsonObjectConstructor(), transformJsonParseArg(), transformJsonScalarExpr(), transformJsonValueExprExt(), transformMinMaxExpr(), transformMultiAssignRef(), transformSubLink(), transformTypeCast(), transformXmlExpr(), and transformXmlSerialize().

◆ transformFuncCall()

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

Definition at line 1413 of file parse_expr.c.

1414 {
1415  Node *last_srf = pstate->p_last_srf;
1416  List *targs;
1417  ListCell *args;
1418 
1419  /* Transform the list of arguments ... */
1420  targs = NIL;
1421  foreach(args, fn->args)
1422  {
1423  targs = lappend(targs, transformExprRecurse(pstate,
1424  (Node *) lfirst(args)));
1425  }
1426 
1427  /*
1428  * When WITHIN GROUP is used, we treat its ORDER BY expressions as
1429  * additional arguments to the function, for purposes of function lookup
1430  * and argument type coercion. So, transform each such expression and add
1431  * them to the targs list. We don't explicitly mark where each argument
1432  * came from, but ParseFuncOrColumn can tell what's what by reference to
1433  * list_length(fn->agg_order).
1434  */
1435  if (fn->agg_within_group)
1436  {
1437  Assert(fn->agg_order != NIL);
1438  foreach(args, fn->agg_order)
1439  {
1440  SortBy *arg = (SortBy *) lfirst(args);
1441 
1442  targs = lappend(targs, transformExpr(pstate, arg->node,
1444  }
1445  }
1446 
1447  /* ... and hand off to ParseFuncOrColumn */
1448  return ParseFuncOrColumn(pstate,
1449  fn->funcname,
1450  targs,
1451  last_srf,
1452  fn,
1453  false,
1454  fn->location);
1455 }
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:112
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 429 of file parse_expr.c.

430 {
431  Node *last_srf = pstate->p_last_srf;
432  Node *result = transformExprRecurse(pstate, ind->arg);
433  List *subscripts = NIL;
434  int location = exprLocation(result);
435  ListCell *i;
436 
437  /*
438  * We have to split any field-selection operations apart from
439  * subscripting. Adjacent A_Indices nodes have to be treated as a single
440  * multidimensional subscript operation.
441  */
442  foreach(i, ind->indirection)
443  {
444  Node *n = lfirst(i);
445 
446  if (IsA(n, A_Indices))
447  subscripts = lappend(subscripts, n);
448  else if (IsA(n, A_Star))
449  {
450  ereport(ERROR,
451  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
452  errmsg("row expansion via \"*\" is not supported here"),
453  parser_errposition(pstate, location)));
454  }
455  else
456  {
457  Node *newresult;
458 
459  Assert(IsA(n, String));
460 
461  /* process subscripts before this field selection */
462  if (subscripts)
463  result = (Node *) transformContainerSubscripts(pstate,
464  result,
465  exprType(result),
466  exprTypmod(result),
467  subscripts,
468  false);
469  subscripts = NIL;
470 
471  newresult = ParseFuncOrColumn(pstate,
472  list_make1(n),
473  list_make1(result),
474  last_srf,
475  NULL,
476  false,
477  location);
478  if (newresult == NULL)
479  unknown_attribute(pstate, result, strVal(n), location);
480  result = newresult;
481  }
482  }
483  /* process trailing subscripts, if any */
484  if (subscripts)
485  result = (Node *) transformContainerSubscripts(pstate,
486  result,
487  exprType(result),
488  exprTypmod(result),
489  subscripts,
490  false);
491 
492  return result;
493 }
static void unknown_attribute(ParseState *pstate, Node *relref, const char *attname, int location)
Definition: parse_expr.c:383
SubscriptingRef * transformContainerSubscripts(ParseState *pstate, Node *containerBase, Oid containerType, int32 containerTypMod, List *indirection, bool isAssignment)
Definition: parse_node.c:247

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 3761 of file parse_expr.c.

3766 {
3767  Oid aggfnoid;
3768  Node *node;
3769  Expr *aggfilter = agg_ctor->agg_filter ? (Expr *)
3770  transformWhereClause(pstate, agg_ctor->agg_filter,
3771  EXPR_KIND_FILTER, "FILTER") : NULL;
3772 
3774  CStringGetDatum(aggfn)));
3775 
3776  if (agg_ctor->over)
3777  {
3778  /* window function */
3779  WindowFunc *wfunc = makeNode(WindowFunc);
3780 
3781  wfunc->winfnoid = aggfnoid;
3782  wfunc->wintype = aggtype;
3783  /* wincollid and inputcollid will be set by parse_collate.c */
3784  wfunc->args = args;
3785  /* winref will be set by transformWindowFuncCall */
3786  wfunc->winstar = false;
3787  wfunc->winagg = true;
3788  wfunc->aggfilter = aggfilter;
3789  wfunc->location = agg_ctor->location;
3790 
3791  /*
3792  * ordered aggs not allowed in windows yet
3793  */
3794  if (agg_ctor->agg_order != NIL)
3795  ereport(ERROR,
3796  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3797  errmsg("aggregate ORDER BY is not implemented for window functions"),
3798  parser_errposition(pstate, agg_ctor->location)));
3799 
3800  /* parse_agg.c does additional window-func-specific processing */
3801  transformWindowFuncCall(pstate, wfunc, agg_ctor->over);
3802 
3803  node = (Node *) wfunc;
3804  }
3805  else
3806  {
3807  Aggref *aggref = makeNode(Aggref);
3808 
3809  aggref->aggfnoid = aggfnoid;
3810  aggref->aggtype = aggtype;
3811 
3812  /* aggcollid and inputcollid will be set by parse_collate.c */
3813  aggref->aggtranstype = InvalidOid; /* will be set by planner */
3814  /* aggargtypes will be set by transformAggregateCall */
3815  /* aggdirectargs and args will be set by transformAggregateCall */
3816  /* aggorder and aggdistinct will be set by transformAggregateCall */
3817  aggref->aggfilter = aggfilter;
3818  aggref->aggstar = false;
3819  aggref->aggvariadic = false;
3820  aggref->aggkind = AGGKIND_NORMAL;
3821  /* agglevelsup will be set by transformAggregateCall */
3822  aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
3823  aggref->location = agg_ctor->location;
3824 
3825  transformAggregateCall(pstate, aggref, args, agg_ctor->agg_order, false);
3826 
3827  node = (Node *) aggref;
3828  }
3829 
3830  return makeJsonConstructorExpr(pstate, ctor_type, NIL, (Expr *) node,
3831  returning, unique, absent_on_null,
3832  agg_ctor->location);
3833 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:631
@ AGGSPLIT_SIMPLE
Definition: nodes.h:830
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:102
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:3612
#define CStringGetDatum(X)
Definition: postgres.h:622
#define DatumGetInt32(X)
Definition: postgres.h:516
Datum regprocin(PG_FUNCTION_ARGS)
Definition: regproc.c:61
bool aggstar
Definition: primnodes.h:343
Oid aggfnoid
Definition: primnodes.h:332
bool aggvariadic
Definition: primnodes.h:344
char aggkind
Definition: primnodes.h:346
Oid aggtranstype
Definition: primnodes.h:336
Expr * aggfilter
Definition: primnodes.h:342
Oid aggtype
Definition: primnodes.h:333
int location
Definition: primnodes.h:351
AggSplit aggsplit
Definition: primnodes.h:348
struct WindowDef * over
Definition: parsenodes.h:1854
bool winagg
Definition: primnodes.h:403
List * args
Definition: primnodes.h:399
Expr * aggfilter
Definition: primnodes.h:400
int location
Definition: primnodes.h:404
Oid winfnoid
Definition: primnodes.h:395
bool winstar
Definition: primnodes.h:402
Oid wintype
Definition: primnodes.h:396

References JsonAggConstructor::agg_filter, JsonAggConstructor::agg_order, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggfnoid, Aggref::aggkind, Aggref::aggsplit, AGGSPLIT_SIMPLE, Aggref::aggstar, Aggref::aggtranstype, Aggref::aggtype, Aggref::aggvariadic, 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(), WindowFunc::winagg, WindowFunc::winfnoid, WindowFunc::winstar, and WindowFunc::wintype.

Referenced by transformJsonArrayAgg(), and transformJsonObjectAgg().

◆ transformJsonArrayAgg()

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

Definition at line 3903 of file parse_expr.c.

3904 {
3905  JsonReturning *returning;
3906  Node *arg;
3907  const char *aggfnname;
3908  Oid aggtype;
3909 
3910  arg = transformJsonValueExprDefault(pstate, agg->arg);
3911 
3912  returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
3913  list_make1(arg));
3914 
3915  if (returning->format->format_type == JS_FORMAT_JSONB)
3916  {
3917  aggfnname = agg->absent_on_null ?
3918  "pg_catalog.jsonb_agg_strict" : "pg_catalog.jsonb_agg";
3919  aggtype = JSONBOID;
3920  }
3921  else
3922  {
3923  aggfnname = agg->absent_on_null ?
3924  "pg_catalog.json_agg_strict" : "pg_catalog.json_agg";
3925  aggtype = JSONOID;
3926  }
3927 
3928  return transformJsonAggConstructor(pstate, agg->constructor, returning,
3929  list_make1(arg), aggfnname, aggtype,
3931  false, agg->absent_on_null);
3932 }
static JsonReturning * transformJsonConstructorOutput(ParseState *pstate, JsonOutput *output, List *args)
Definition: parse_expr.c:3515
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:3761
static Node * transformJsonValueExprDefault(ParseState *pstate, JsonValueExpr *jve)
Definition: parse_expr.c:3413
@ JSCTOR_JSON_ARRAYAGG
Definition: primnodes.h:1353
JsonOutput * output
Definition: parsenodes.h:1851
bool absent_on_null
Definition: parsenodes.h:1880
JsonValueExpr * arg
Definition: parsenodes.h:1879
JsonAggConstructor * constructor
Definition: parsenodes.h:1878

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

Referenced by transformExprRecurse().

◆ transformJsonArrayConstructor()

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

Definition at line 3944 of file parse_expr.c.

3945 {
3946  JsonReturning *returning;
3947  List *args = NIL;
3948 
3949  /* transform element expressions, if any */
3950  if (ctor->exprs)
3951  {
3952  ListCell *lc;
3953 
3954  /* transform and append element arguments */
3955  foreach(lc, ctor->exprs)
3956  {
3957  JsonValueExpr *jsval = castNode(JsonValueExpr, lfirst(lc));
3958  Node *val = transformJsonValueExprDefault(pstate, jsval);
3959 
3960  args = lappend(args, val);
3961  }
3962  }
3963 
3964  returning = transformJsonConstructorOutput(pstate, ctor->output, args);
3965 
3966  return makeJsonConstructorExpr(pstate, JSCTOR_JSON_ARRAY, args, NULL,
3967  returning, false, ctor->absent_on_null,
3968  ctor->location);
3969 }
long val
Definition: informix.c:664
@ JSCTOR_JSON_ARRAY
Definition: primnodes.h:1351
JsonOutput * output
Definition: parsenodes.h:1824

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

Referenced by transformExprRecurse().

◆ transformJsonArrayQueryConstructor()

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

Definition at line 3695 of file parse_expr.c.

3697 {
3698  SubLink *sublink = makeNode(SubLink);
3701  Alias *alias = makeNode(Alias);
3702  ResTarget *target = makeNode(ResTarget);
3704  ColumnRef *colref = makeNode(ColumnRef);
3705  Query *query;
3706  ParseState *qpstate;
3707 
3708  /* Transform query only for counting target list entries. */
3709  qpstate = make_parsestate(pstate);
3710 
3711  query = transformStmt(qpstate, ctor->query);
3712 
3713  if (count_nonjunk_tlist_entries(query->targetList) != 1)
3714  ereport(ERROR,
3715  (errcode(ERRCODE_SYNTAX_ERROR),
3716  errmsg("subquery must return only one column"),
3717  parser_errposition(pstate, ctor->location)));
3718 
3719  free_parsestate(qpstate);
3720 
3721  colref->fields = list_make2(makeString(pstrdup("q")),
3722  makeString(pstrdup("a")));
3723  colref->location = ctor->location;
3724 
3725  agg->arg = makeJsonValueExpr((Expr *) colref, ctor->format);
3726  agg->absent_on_null = ctor->absent_on_null;
3728  agg->constructor->agg_order = NIL;
3729  agg->constructor->output = ctor->output;
3730  agg->constructor->location = ctor->location;
3731 
3732  target->name = NULL;
3733  target->indirection = NIL;
3734  target->val = (Node *) agg;
3735  target->location = ctor->location;
3736 
3737  alias->aliasname = pstrdup("q");
3738  alias->colnames = list_make1(makeString(pstrdup("a")));
3739 
3740  range->lateral = false;
3741  range->subquery = ctor->query;
3742  range->alias = alias;
3743 
3744  select->targetList = list_make1(target);
3745  select->fromClause = list_make1(range);
3746 
3747  sublink->subLinkType = EXPR_SUBLINK;
3748  sublink->subLinkId = 0;
3749  sublink->testexpr = NULL;
3750  sublink->operName = NIL;
3751  sublink->subselect = (Node *) select;
3752  sublink->location = ctor->location;
3753 
3754  return transformExprRecurse(pstate, (Node *) sublink);
3755 }
JsonValueExpr * makeJsonValueExpr(Expr *expr, JsonFormat *format)
Definition: makefuncs.c:844
char * pstrdup(const char *in)
Definition: mcxt.c:1305
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:76
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:43
Query * transformStmt(ParseState *pstate, Node *parseTree)
Definition: analyze.c:313
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:155
int location
Definition: parsenodes.h:474
Node * val
Definition: parsenodes.h:473
List * indirection
Definition: parsenodes.h:472
char * name
Definition: parsenodes.h:471
int count_nonjunk_tlist_entries(List *tlist)
Definition: tlist.c:175
#define select(n, r, w, e, timeout)
Definition: win32_port.h:474

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, SubLink::operName, 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().

◆ transformJsonBehavior()

static JsonBehavior* transformJsonBehavior ( ParseState pstate,
JsonBehavior behavior,
JsonBehaviorType  default_behavior 
)
static

Definition at line 4071 of file parse_expr.c.

4073 {
4074  JsonBehaviorType behavior_type = default_behavior;
4075  Node *default_expr = NULL;
4076 
4077  if (behavior)
4078  {
4079  behavior_type = behavior->btype;
4080  if (behavior_type == JSON_BEHAVIOR_DEFAULT)
4081  default_expr = transformExprRecurse(pstate, behavior->default_expr);
4082  }
4083  return makeJsonBehavior(behavior_type, default_expr);
4084 }
JsonBehavior * makeJsonBehavior(JsonBehaviorType type, Node *default_expr)
Definition: makefuncs.c:860
JsonBehaviorType
Definition: primnodes.h:1289
@ JSON_BEHAVIOR_DEFAULT
Definition: primnodes.h:1298
JsonBehaviorType btype
Definition: primnodes.h:1409
Node * default_expr
Definition: primnodes.h:1410

References JsonBehavior::btype, JsonBehavior::default_expr, JSON_BEHAVIOR_DEFAULT, makeJsonBehavior(), and transformExprRecurse().

Referenced by transformJsonExprCommon().

◆ transformJsonConstructorOutput()

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

Definition at line 3515 of file parse_expr.c.

3517 {
3518  JsonReturning *returning = transformJsonOutput(pstate, output, true);
3519 
3520  if (!OidIsValid(returning->typid))
3521  {
3522  ListCell *lc;
3523  bool have_jsonb = false;
3524 
3525  foreach(lc, args)
3526  {
3527  Node *expr = lfirst(lc);
3528  Oid typid = exprType(expr);
3529 
3530  have_jsonb |= typid == JSONBOID;
3531 
3532  if (have_jsonb)
3533  break;
3534  }
3535 
3536  if (have_jsonb)
3537  {
3538  returning->typid = JSONBOID;
3539  returning->format->format_type = JS_FORMAT_JSONB;
3540  }
3541  else
3542  {
3543  /* XXX TEXT is default by the standard, but we return JSON */
3544  returning->typid = JSONOID;
3545  returning->format->format_type = JS_FORMAT_JSON;
3546  }
3547 
3548  returning->typmod = -1;
3549  }
3550 
3551  return returning;
3552 }
static JsonReturning * transformJsonOutput(ParseState *pstate, const JsonOutput *output, bool allow_format)
Definition: parse_expr.c:3473
static void output(uint64 loop_count)

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().

◆ transformJsonConstructorRet()

static JsonReturning* transformJsonConstructorRet ( ParseState pstate,
JsonOutput output,
const char *  fname 
)
static

Definition at line 4476 of file parse_expr.c.

4477 {
4478  JsonReturning *returning;
4479 
4480  if (output)
4481  {
4482  returning = transformJsonOutput(pstate, output, false);
4483 
4484  Assert(OidIsValid(returning->typid));
4485 
4486  if (returning->typid != JSONOID && returning->typid != JSONBOID)
4487  ereport(ERROR,
4488  (errcode(ERRCODE_DATATYPE_MISMATCH),
4489  errmsg("cannot use RETURNING type %s in %s",
4490  format_type_be(returning->typid), fname),
4491  parser_errposition(pstate, output->typeName->location)));
4492  }
4493  else
4494  {
4495  Oid targettype = JSONOID;
4497 
4498  returning = makeNode(JsonReturning);
4499  returning->format = makeJsonFormat(format, JS_ENC_DEFAULT, -1);
4500  returning->typid = targettype;
4501  returning->typmod = -1;
4502  }
4503 
4504  return returning;
4505 }
JsonFormat * makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
Definition: makefuncs.c:828
JsonFormatType
Definition: primnodes.h:1274

References Assert(), ereport, errcode(), errmsg(), ERROR, format, JsonReturning::format, format_type_be(), JS_ENC_DEFAULT, JS_FORMAT_JSON, makeJsonFormat(), makeNode, OidIsValid, output(), parser_errposition(), transformJsonOutput(), JsonReturning::typid, and JsonReturning::typmod.

Referenced by transformJsonParseExpr(), and transformJsonScalarExpr().

◆ transformJsonExprCommon()

static JsonExpr* transformJsonExprCommon ( ParseState pstate,
JsonFuncExpr func 
)
static

Definition at line 4091 of file parse_expr.c.

4092 {
4093  JsonExpr *jsexpr = makeNode(JsonExpr);
4094  Node *pathspec;
4096 
4097  if (func->common->pathname && func->op != JSON_TABLE_OP)
4098  ereport(ERROR,
4099  (errcode(ERRCODE_SYNTAX_ERROR),
4100  errmsg("JSON_TABLE path name is not allowed here"),
4101  parser_errposition(pstate, func->location)));
4102 
4103  jsexpr->location = func->location;
4104  jsexpr->op = func->op;
4105  jsexpr->formatted_expr = transformJsonValueExpr(pstate, func->common->expr);
4106 
4107  assign_expr_collations(pstate, jsexpr->formatted_expr);
4108 
4109  /* format is determined by context item type */
4110  format = exprType(jsexpr->formatted_expr) == JSONBOID ? JS_FORMAT_JSONB : JS_FORMAT_JSON;
4111 
4112  jsexpr->result_coercion = NULL;
4113  jsexpr->omit_quotes = false;
4114 
4115  jsexpr->format = func->common->expr->format;
4116 
4117  pathspec = transformExprRecurse(pstate, func->common->pathspec);
4118 
4119  jsexpr->path_spec =
4120  coerce_to_target_type(pstate, pathspec, exprType(pathspec),
4121  JSONPATHOID, -1,
4123  exprLocation(pathspec));
4124  if (!jsexpr->path_spec)
4125  ereport(ERROR,
4126  (errcode(ERRCODE_DATATYPE_MISMATCH),
4127  errmsg("JSON path expression must be type %s, not type %s",
4128  "jsonpath", format_type_be(exprType(pathspec))),
4129  parser_errposition(pstate, exprLocation(pathspec))));
4130 
4131  /* transform and coerce to json[b] passing arguments */
4133  &jsexpr->passing_values, &jsexpr->passing_names);
4134 
4135  if (func->op != JSON_EXISTS_OP && func->op != JSON_TABLE_OP)
4136  jsexpr->on_empty = transformJsonBehavior(pstate, func->on_empty,
4138 
4139  if (func->op == JSON_EXISTS_OP)
4140  jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4142  else if (func->op == JSON_TABLE_OP)
4143  jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4145  else
4146  jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4148 
4149  return jsexpr;
4150 }
static JsonBehavior * transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior, JsonBehaviorType default_behavior)
Definition: parse_expr.c:4071
static void transformJsonPassingArgs(ParseState *pstate, JsonFormatType format, List *args, List **passing_values, List **passing_names)
Definition: parse_expr.c:4046
@ JSON_BEHAVIOR_EMPTY
Definition: primnodes.h:1292
@ JSON_BEHAVIOR_FALSE
Definition: primnodes.h:1294
@ JSON_BEHAVIOR_NULL
Definition: primnodes.h:1290
@ JSON_TABLE_OP
Definition: primnodes.h:1254
@ JSON_EXISTS_OP
Definition: primnodes.h:1253
char * pathname
Definition: parsenodes.h:1654
JsonValueExpr * expr
Definition: parsenodes.h:1652
List * passing
Definition: parsenodes.h:1655
Node * pathspec
Definition: parsenodes.h:1653
Node * formatted_expr
Definition: primnodes.h:1454
List * passing_values
Definition: primnodes.h:1459
JsonBehavior * on_empty
Definition: primnodes.h:1461
JsonFormat * format
Definition: primnodes.h:1456
List * passing_names
Definition: primnodes.h:1458
Node * path_spec
Definition: primnodes.h:1457
JsonCoercion * result_coercion
Definition: primnodes.h:1455
JsonExprOp op
Definition: primnodes.h:1453
JsonBehavior * on_error
Definition: primnodes.h:1462
bool omit_quotes
Definition: primnodes.h:1465
JsonExprOp op
Definition: parsenodes.h:1666
JsonBehavior * on_empty
Definition: parsenodes.h:1669
JsonBehavior * on_error
Definition: parsenodes.h:1670
JsonCommon * common
Definition: parsenodes.h:1667
JsonFormat * format
Definition: primnodes.h:1345

References assign_expr_collations(), COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_EXPLICIT, JsonFuncExpr::common, ereport, errcode(), errmsg(), ERROR, JsonCommon::expr, exprLocation(), exprType(), format, JsonValueExpr::format, JsonExpr::format, format_type_be(), JsonExpr::formatted_expr, JS_FORMAT_JSON, JS_FORMAT_JSONB, JSON_BEHAVIOR_EMPTY, JSON_BEHAVIOR_FALSE, JSON_BEHAVIOR_NULL, JSON_EXISTS_OP, JSON_TABLE_OP, JsonFuncExpr::location, JsonExpr::location, makeNode, JsonExpr::omit_quotes, JsonFuncExpr::on_empty, JsonExpr::on_empty, JsonFuncExpr::on_error, JsonExpr::on_error, JsonFuncExpr::op, JsonExpr::op, parser_errposition(), JsonCommon::passing, JsonExpr::passing_names, JsonExpr::passing_values, JsonExpr::path_spec, JsonCommon::pathname, JsonCommon::pathspec, JsonExpr::result_coercion, transformExprRecurse(), transformJsonBehavior(), transformJsonPassingArgs(), and transformJsonValueExpr().

Referenced by transformJsonFuncExpr().

◆ transformJsonFuncExpr()

static Node * transformJsonFuncExpr ( ParseState pstate,
JsonFuncExpr p 
)
static

Definition at line 4357 of file parse_expr.c.

4358 {
4359  JsonExpr *jsexpr = transformJsonExprCommon(pstate, func);
4360  const char *func_name = NULL;
4361  Node *contextItemExpr = jsexpr->formatted_expr;
4362 
4363  switch (func->op)
4364  {
4365  case JSON_VALUE_OP:
4366  func_name = "JSON_VALUE";
4367 
4368  transformJsonFuncExprOutput(pstate, func, jsexpr);
4369 
4372 
4373  jsexpr->on_empty->default_expr =
4374  coerceDefaultJsonExpr(pstate, jsexpr,
4375  jsexpr->on_empty->default_expr);
4376 
4377  jsexpr->on_error->default_expr =
4378  coerceDefaultJsonExpr(pstate, jsexpr,
4379  jsexpr->on_error->default_expr);
4380 
4382  initJsonItemCoercions(pstate, jsexpr->coercions, jsexpr->returning,
4383  exprType(contextItemExpr));
4384 
4385  break;
4386 
4387  case JSON_QUERY_OP:
4388  func_name = "JSON_QUERY";
4389 
4390  transformJsonFuncExprOutput(pstate, func, jsexpr);
4391 
4392  jsexpr->on_empty->default_expr =
4393  coerceDefaultJsonExpr(pstate, jsexpr,
4394  jsexpr->on_empty->default_expr);
4395 
4396  jsexpr->on_error->default_expr =
4397  coerceDefaultJsonExpr(pstate, jsexpr,
4398  jsexpr->on_error->default_expr);
4399 
4400  jsexpr->wrapper = func->wrapper;
4401  jsexpr->omit_quotes = func->omit_quotes;
4402 
4403  break;
4404 
4405  case JSON_EXISTS_OP:
4406  func_name = "JSON_EXISTS";
4407 
4408  jsexpr->returning = transformJsonOutput(pstate, func->output, false);
4409 
4412 
4413  if (!OidIsValid(jsexpr->returning->typid))
4414  {
4415  jsexpr->returning->typid = BOOLOID;
4416  jsexpr->returning->typmod = -1;
4417  }
4418  else if (jsexpr->returning->typid != BOOLOID)
4419  {
4420  CaseTestExpr *placeholder = makeNode(CaseTestExpr);
4421  int location = exprLocation((Node *) jsexpr);
4422 
4423  placeholder->typeId = BOOLOID;
4424  placeholder->typeMod = -1;
4425  placeholder->collation = InvalidOid;
4426 
4428  jsexpr->result_coercion->expr =
4429  coerce_to_target_type(pstate, (Node *) placeholder, BOOLOID,
4430  jsexpr->returning->typid,
4431  jsexpr->returning->typmod,
4434  location);
4435 
4436  if (!jsexpr->result_coercion->expr)
4437  ereport(ERROR,
4438  (errcode(ERRCODE_CANNOT_COERCE),
4439  errmsg("cannot cast type %s to %s",
4440  format_type_be(BOOLOID),
4441  format_type_be(jsexpr->returning->typid)),
4442  parser_coercion_errposition(pstate, location, (Node *) jsexpr)));
4443 
4444  if (jsexpr->result_coercion->expr == (Node *) placeholder)
4445  jsexpr->result_coercion->expr = NULL;
4446  }
4447  break;
4448 
4449  case JSON_TABLE_OP:
4450  jsexpr->returning = makeNode(JsonReturning);
4452  jsexpr->returning->typid = exprType(contextItemExpr);
4453  jsexpr->returning->typmod = -1;
4454 
4455  if (jsexpr->returning->typid != JSONBOID)
4456  ereport(ERROR,
4457  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4458  errmsg("JSON_TABLE() is not yet implemented for the json type"),
4459  errhint("Try casting the argument to jsonb"),
4460  parser_errposition(pstate, func->location)));
4461 
4462  break;
4463  }
4464 
4465  if (exprType(contextItemExpr) != JSONBOID)
4466  ereport(ERROR,
4467  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4468  errmsg("%s() is not yet implemented for the json type", func_name),
4469  errhint("Try casting the argument to jsonb"),
4470  parser_errposition(pstate, func->location)));
4471 
4472  return (Node *) jsexpr;
4473 }
static Node * coerceDefaultJsonExpr(ParseState *pstate, JsonExpr *jsexpr, Node *defexpr)
Definition: parse_expr.c:4263
static void initJsonItemCoercions(ParseState *pstate, JsonItemCoercions *coercions, const JsonReturning *returning, Oid contextItemTypeId)
Definition: parse_expr.c:4326
static void transformJsonFuncExprOutput(ParseState *pstate, JsonFuncExpr *func, JsonExpr *jsexpr)
Definition: parse_expr.c:4211
static JsonExpr * transformJsonExprCommon(ParseState *pstate, JsonFuncExpr *func)
Definition: parse_expr.c:4091
@ JSON_QUERY_OP
Definition: primnodes.h:1252
@ JSON_VALUE_OP
Definition: primnodes.h:1251
JsonItemCoercions * coercions
Definition: primnodes.h:1463
JsonWrapper wrapper
Definition: primnodes.h:1464
JsonEncoding encoding
Definition: primnodes.h:1320

References COERCE_IMPLICIT_CAST, coerce_to_target_type(), coerceDefaultJsonExpr(), COERCION_EXPLICIT, JsonExpr::coercions, CaseTestExpr::collation, JsonBehavior::default_expr, JsonFormat::encoding, ereport, errcode(), errhint(), errmsg(), ERROR, exprLocation(), exprType(), JsonReturning::format, JsonFormat::format_type, format_type_be(), JsonExpr::formatted_expr, initJsonItemCoercions(), InvalidOid, JS_ENC_DEFAULT, JS_FORMAT_DEFAULT, JSON_EXISTS_OP, JSON_QUERY_OP, JSON_TABLE_OP, JSON_VALUE_OP, JsonFuncExpr::location, makeJsonFormat(), makeNode, OidIsValid, JsonFuncExpr::omit_quotes, JsonExpr::omit_quotes, JsonExpr::on_empty, JsonExpr::on_error, JsonFuncExpr::op, JsonFuncExpr::output, parser_coercion_errposition(), parser_errposition(), JsonExpr::returning, transformJsonExprCommon(), transformJsonFuncExprOutput(), transformJsonOutput(), CaseTestExpr::typeId, CaseTestExpr::typeMod, JsonReturning::typid, JsonReturning::typmod, JsonFuncExpr::wrapper, and JsonExpr::wrapper.

Referenced by transformExprRecurse().

◆ transformJsonFuncExprOutput()

static void transformJsonFuncExprOutput ( ParseState pstate,
JsonFuncExpr func,
JsonExpr jsexpr 
)
static

Definition at line 4211 of file parse_expr.c.

4213 {
4214  Node *expr = jsexpr->formatted_expr;
4215 
4216  jsexpr->returning = transformJsonOutput(pstate, func->output, false);
4217 
4218  /* JSON_VALUE returns text by default */
4219  if (func->op == JSON_VALUE_OP && !OidIsValid(jsexpr->returning->typid))
4220  {
4221  jsexpr->returning->typid = TEXTOID;
4222  jsexpr->returning->typmod = -1;
4223  }
4224 
4225  if (OidIsValid(jsexpr->returning->typid))
4226  {
4227  JsonReturning ret;
4228 
4229  if (func->op == JSON_VALUE_OP &&
4230  jsexpr->returning->typid != JSONOID &&
4231  jsexpr->returning->typid != JSONBOID)
4232  {
4233  /* Forced coercion via I/O for JSON_VALUE for non-JSON types */
4235  jsexpr->result_coercion->expr = NULL;
4236  jsexpr->result_coercion->via_io = true;
4237  return;
4238  }
4239 
4240  assignDefaultJsonReturningType(jsexpr->formatted_expr, jsexpr->format, &ret);
4241 
4242  if (ret.typid != jsexpr->returning->typid ||
4243  ret.typmod != jsexpr->returning->typmod)
4244  {
4245  Node *placeholder = makeCaseTestExpr(expr);
4246 
4247  Assert(((CaseTestExpr *) placeholder)->typeId == ret.typid);
4248  Assert(((CaseTestExpr *) placeholder)->typeMod == ret.typmod);
4249 
4250  jsexpr->result_coercion = coerceJsonExpr(pstate, placeholder,
4251  jsexpr->returning);
4252  }
4253  }
4254  else
4256  jsexpr->returning);
4257 }
static void assignDefaultJsonReturningType(Node *context_item, JsonFormat *context_format, JsonReturning *ret)
Definition: parse_expr.c:4157
JsonOutput * output
Definition: parsenodes.h:1668

References Assert(), assignDefaultJsonReturningType(), coerceJsonExpr(), JsonCoercion::expr, JsonExpr::format, JsonExpr::formatted_expr, JSON_VALUE_OP, makeCaseTestExpr(), makeNode, OidIsValid, JsonFuncExpr::op, JsonFuncExpr::output, JsonExpr::result_coercion, JsonExpr::returning, transformJsonOutput(), JsonReturning::typid, JsonReturning::typmod, and JsonCoercion::via_io.

Referenced by transformJsonFuncExpr().

◆ transformJsonIsPredicate()

static Node * transformJsonIsPredicate ( ParseState pstate,
JsonIsPredicate p 
)
static

Definition at line 4024 of file parse_expr.c.

4025 {
4026  Oid exprtype;
4027  Node *expr = transformJsonParseArg(pstate, pred->expr, pred->format,
4028  &exprtype);
4029 
4030  /* make resulting expression */
4031  if (exprtype != TEXTOID && exprtype != JSONOID && exprtype != JSONBOID)
4032  ereport(ERROR,
4033  (errcode(ERRCODE_DATATYPE_MISMATCH),
4034  errmsg("cannot use type %s in IS JSON predicate",
4035  format_type_be(exprtype))));
4036 
4037  /* This intentionally(?) drops the format clause. */
4038  return makeJsonIsPredicate(expr, NULL, pred->item_type,
4039  pred->unique_keys, pred->location);
4040 }
Node * makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type, bool unique_keys, int location)
Definition: makefuncs.c:930
static Node * transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format, Oid *exprtype)
Definition: parse_expr.c:3972

References ereport, errcode(), errmsg(), ERROR, JsonIsPredicate::expr, JsonIsPredicate::format, format_type_be(), JsonIsPredicate::item_type, JsonIsPredicate::location, makeJsonIsPredicate(), transformJsonParseArg(), and JsonIsPredicate::unique_keys.

Referenced by transformExprRecurse().

◆ transformJsonObjectAgg()

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

Definition at line 3844 of file parse_expr.c.

3845 {
3846  JsonReturning *returning;
3847  Node *key;
3848  Node *val;
3849  List *args;
3850  const char *aggfnname;
3851  Oid aggtype;
3852 
3853  key = transformExprRecurse(pstate, (Node *) agg->arg->key);
3854  val = transformJsonValueExprDefault(pstate, agg->arg->value);
3855  args = list_make2(key, val);
3856 
3857  returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
3858  args);
3859 
3860  if (returning->format->format_type == JS_FORMAT_JSONB)
3861  {
3862  if (agg->absent_on_null)
3863  if (agg->unique)
3864  aggfnname = "pg_catalog.jsonb_object_agg_unique_strict"; /* F_JSONB_OBJECT_AGG_UNIQUE_STRICT */
3865  else
3866  aggfnname = "pg_catalog.jsonb_object_agg_strict"; /* F_JSONB_OBJECT_AGG_STRICT */
3867  else if (agg->unique)
3868  aggfnname = "pg_catalog.jsonb_object_agg_unique"; /* F_JSONB_OBJECT_AGG_UNIQUE */
3869  else
3870  aggfnname = "pg_catalog.jsonb_object_agg"; /* F_JSONB_OBJECT_AGG */
3871 
3872  aggtype = JSONBOID;
3873  }
3874  else
3875  {
3876  if (agg->absent_on_null)
3877  if (agg->unique)
3878  aggfnname = "pg_catalog.json_object_agg_unique_strict"; /* F_JSON_OBJECT_AGG_UNIQUE_STRICT */
3879  else
3880  aggfnname = "pg_catalog.json_object_agg_strict"; /* F_JSON_OBJECT_AGG_STRICT */
3881  else if (agg->unique)
3882  aggfnname = "pg_catalog.json_object_agg_unique"; /* F_JSON_OBJECT_AGG_UNIQUE */
3883  else
3884  aggfnname = "pg_catalog.json_object_agg"; /* F_JSON_OBJECT_AGG */
3885 
3886  aggtype = JSONOID;
3887  }
3888 
3889  return transformJsonAggConstructor(pstate, agg->constructor, returning,
3890  args, aggfnname, aggtype,
3892  agg->unique, agg->absent_on_null);
3893 }
@ JSCTOR_JSON_OBJECTAGG
Definition: primnodes.h:1352
JsonValueExpr * value
Definition: parsenodes.h:1762
JsonAggConstructor * constructor
Definition: parsenodes.h:1865
JsonKeyValue * arg
Definition: parsenodes.h:1866
bool absent_on_null
Definition: parsenodes.h:1867

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

Referenced by transformExprRecurse().

◆ transformJsonObjectConstructor()

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

Definition at line 3661 of file parse_expr.c.

3662 {
3663  JsonReturning *returning;
3664  List *args = NIL;
3665 
3666  /* transform key-value pairs, if any */
3667  if (ctor->exprs)
3668  {
3669  ListCell *lc;
3670 
3671  /* transform and append key-value arguments */
3672  foreach(lc, ctor->exprs)
3673  {
3675  Node *key = transformExprRecurse(pstate, (Node *) kv->key);
3676  Node *val = transformJsonValueExprDefault(pstate, kv->value);
3677 
3678  args = lappend(args, key);
3679  args = lappend(args, val);
3680  }
3681  }
3682 
3683  returning = transformJsonConstructorOutput(pstate, ctor->output, args);
3684 
3685  return makeJsonConstructorExpr(pstate, JSCTOR_JSON_OBJECT, args, NULL,
3686  returning, ctor->unique,
3687  ctor->absent_on_null, ctor->location);
3688 }
@ JSCTOR_JSON_OBJECT
Definition: primnodes.h:1350
JsonOutput * output
Definition: parsenodes.h:1810

References JsonObjectConstructor::absent_on_null, generate_unaccent_rules::args, castNode, JsonObjectConstructor::exprs, JSCTOR_JSON_OBJECT, JsonKeyValue::key, sort-test::key, lappend(), lfirst, JsonObjectConstructor::location, makeJsonConstructorExpr(), NIL, JsonObjectConstructor::output, transformExprRecurse(), transformJsonConstructorOutput(), transformJsonValueExprDefault(), 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 3473 of file parse_expr.c.

3475 {
3476  JsonReturning *ret;
3477 
3478  /* if output clause is not specified, make default clause value */
3479  if (!output)
3480  {
3481  ret = makeNode(JsonReturning);
3482 
3484  ret->typid = InvalidOid;
3485  ret->typmod = -1;
3486 
3487  return ret;
3488  }
3489 
3490  ret = copyObject(output->returning);
3491 
3492  typenameTypeIdAndMod(pstate, output->typeName, &ret->typid, &ret->typmod);
3493 
3494  if (output->typeName->setof)
3495  ereport(ERROR,
3496  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3497  errmsg("returning SETOF types is not supported in SQL/JSON functions")));
3498 
3499  if (ret->format->format_type == JS_FORMAT_DEFAULT)
3500  /* assign JSONB format when returning jsonb, or JSON format otherwise */
3501  ret->format->format_type =
3502  ret->typid == JSONBOID ? JS_FORMAT_JSONB : JS_FORMAT_JSON;
3503  else
3504  checkJsonOutputFormat(pstate, ret->format, ret->typid, allow_format);
3505 
3506  return ret;
3507 }
static void checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format, Oid targettype, bool allow_format_for_non_strings)
Definition: parse_expr.c:3423
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(), transformJsonConstructorRet(), transformJsonFuncExpr(), transformJsonFuncExprOutput(), and transformJsonSerializeExpr().

◆ transformJsonParseArg()

static Node* transformJsonParseArg ( ParseState pstate,
Node jsexpr,
JsonFormat format,
Oid exprtype 
)
static

Definition at line 3972 of file parse_expr.c.

3974 {
3975  Node *raw_expr = transformExprRecurse(pstate, jsexpr);
3976  Node *expr = raw_expr;
3977 
3978  *exprtype = exprType(expr);
3979 
3980  /* prepare input document */
3981  if (*exprtype == BYTEAOID)
3982  {
3983  JsonValueExpr *jve;
3984 
3985  expr = makeCaseTestExpr(raw_expr);
3986  expr = makeJsonByteaToTextConversion(expr, format, exprLocation(expr));
3987  *exprtype = TEXTOID;
3988 
3989  jve = makeJsonValueExpr((Expr *) raw_expr, format);
3990 
3991  jve->formatted_expr = (Expr *) expr;
3992  expr = (Node *) jve;
3993  }
3994  else
3995  {
3996  char typcategory;
3997  bool typispreferred;
3998 
3999  get_type_category_preferred(*exprtype, &typcategory, &typispreferred);
4000 
4001  if (*exprtype == UNKNOWNOID || typcategory == TYPCATEGORY_STRING)
4002  {
4003  expr = coerce_to_target_type(pstate, (Node *) expr, *exprtype,
4004  TEXTOID, -1,
4006  COERCE_IMPLICIT_CAST, -1);
4007  *exprtype = TEXTOID;
4008  }
4009 
4010  if (format->encoding != JS_ENC_DEFAULT)
4011  ereport(ERROR,
4012  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4013  parser_errposition(pstate, format->location),
4014  errmsg("cannot use JSON FORMAT ENCODING clause for non-bytea input types")));
4015  }
4016 
4017  return expr;
4018 }
static Node * makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
Definition: parse_expr.c:3214
@ COERCION_IMPLICIT
Definition: primnodes.h:472
Expr * formatted_expr
Definition: primnodes.h:1344

References COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_IMPLICIT, ereport, errcode(), errmsg(), ERROR, exprLocation(), exprType(), format, JsonValueExpr::formatted_expr, get_type_category_preferred(), JS_ENC_DEFAULT, makeCaseTestExpr(), makeJsonByteaToTextConversion(), makeJsonValueExpr(), parser_errposition(), and transformExprRecurse().

Referenced by transformJsonIsPredicate(), and transformJsonParseExpr().

◆ transformJsonParseExpr()

static Node * transformJsonParseExpr ( ParseState pstate,
JsonParseExpr expr 
)
static

Definition at line 4511 of file parse_expr.c.

4512 {
4513  JsonReturning *returning = transformJsonConstructorRet(pstate, jsexpr->output,
4514  "JSON()");
4515  Node *arg;
4516 
4517  if (jsexpr->unique_keys)
4518  {
4519  /*
4520  * Coerce string argument to text and then to json[b] in the executor
4521  * node with key uniqueness check.
4522  */
4523  JsonValueExpr *jve = jsexpr->expr;
4524  Oid arg_type;
4525 
4526  arg = transformJsonParseArg(pstate, (Node *) jve->raw_expr, jve->format,
4527  &arg_type);
4528 
4529  if (arg_type != TEXTOID)
4530  ereport(ERROR,
4531  (errcode(ERRCODE_DATATYPE_MISMATCH),
4532  errmsg("cannot use non-string types with WITH UNIQUE KEYS clause"),
4533  parser_errposition(pstate, jsexpr->location)));
4534  }
4535  else
4536  {
4537  /*
4538  * Coerce argument to target type using CAST for compatibility with PG
4539  * function-like CASTs.
4540  */
4541  arg = transformJsonValueExprExt(pstate, jsexpr->expr, JS_FORMAT_JSON,
4542  false, returning->typid);
4543  }
4544 
4546  returning, jsexpr->unique_keys, false,
4547  jsexpr->location);
4548 }