PostgreSQL Source Code git master
parse_expr.c File Reference
#include "postgres.h"
#include "catalog/pg_aggregate.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 NodetransformMergeSupportFunc (ParseState *pstate, MergeSupportFunc *f)
 
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 *pred)
 
static NodetransformJsonParseExpr (ParseState *pstate, JsonParseExpr *jsexpr)
 
static NodetransformJsonScalarExpr (ParseState *pstate, JsonScalarExpr *jsexpr)
 
static NodetransformJsonSerializeExpr (ParseState *pstate, JsonSerializeExpr *expr)
 
static NodetransformJsonFuncExpr (ParseState *pstate, JsonFuncExpr *func)
 
static void transformJsonPassingArgs (ParseState *pstate, const char *constructName, JsonFormatType format, List *args, List **passing_values, List **passing_names)
 
static JsonBehaviortransformJsonBehavior (ParseState *pstate, JsonBehavior *behavior, JsonBehaviorType default_behavior, JsonReturning *returning)
 
static NodeGetJsonBehaviorConst (JsonBehaviorType btype, int location)
 
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 NodetransformJsonValueExpr (ParseState *pstate, const char *constructName, JsonValueExpr *ve, JsonFormatType default_format, Oid targettype, bool isarg)
 
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, Oid aggfnoid, Oid aggtype, JsonConstructorType ctor_type, bool unique, bool absent_on_null)
 
static NodetransformJsonParseArg (ParseState *pstate, Node *jsexpr, JsonFormat *format, Oid *exprtype)
 
static JsonReturningtransformJsonReturning (ParseState *pstate, JsonOutput *output, const char *fname)
 
static bool ValidJsonBehaviorDefaultExpr (Node *expr, void *context)
 

Variables

bool Transform_null_equals = false
 

Function Documentation

◆ checkJsonOutputFormat()

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

Definition at line 3440 of file parse_expr.c.

3442{
3443 if (!allow_format_for_non_strings &&
3444 format->format_type != JS_FORMAT_DEFAULT &&
3445 (targettype != BYTEAOID &&
3446 targettype != JSONOID &&
3447 targettype != JSONBOID))
3448 {
3449 char typcategory;
3450 bool typispreferred;
3451
3452 get_type_category_preferred(targettype, &typcategory, &typispreferred);
3453
3454 if (typcategory != TYPCATEGORY_STRING)
3455 ereport(ERROR,
3456 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3457 parser_errposition(pstate, format->location),
3458 errmsg("cannot use JSON format with non-string output types"));
3459 }
3460
3461 if (format->format_type == JS_FORMAT_JSON)
3462 {
3463 JsonEncoding enc = format->encoding != JS_ENC_DEFAULT ?
3464 format->encoding : JS_ENC_UTF8;
3465
3466 if (targettype != BYTEAOID &&
3467 format->encoding != JS_ENC_DEFAULT)
3468 ereport(ERROR,
3469 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3470 parser_errposition(pstate, format->location),
3471 errmsg("cannot set JSON encoding for non-bytea output types"));
3472
3473 if (enc != JS_ENC_UTF8)
3474 ereport(ERROR,
3475 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3476 errmsg("unsupported JSON encoding"),
3477 errhint("Only UTF8 JSON encoding is supported."),
3478 parser_errposition(pstate, format->location));
3479 }
3480}
enc
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2710
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
static char format
@ JS_FORMAT_DEFAULT
Definition: primnodes.h:1638
@ JS_FORMAT_JSON
Definition: primnodes.h:1639
JsonEncoding
Definition: primnodes.h:1625
@ JS_ENC_DEFAULT
Definition: primnodes.h:1626
@ JS_ENC_UTF8
Definition: primnodes.h:1627

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

Referenced by transformJsonOutput().

◆ coerceJsonFuncExpr()

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

Definition at line 3580 of file parse_expr.c.

3582{
3583 Node *res;
3584 int location;
3585 Oid exprtype = exprType(expr);
3586
3587 /* if output type is not specified or equals to function type, return */
3588 if (!OidIsValid(returning->typid) || returning->typid == exprtype)
3589 return expr;
3590
3591 location = exprLocation(expr);
3592
3593 if (location < 0)
3594 location = returning->format->location;
3595
3596 /* special case for RETURNING bytea FORMAT json */
3597 if (returning->format->format_type == JS_FORMAT_JSON &&
3598 returning->typid == BYTEAOID)
3599 {
3600 /* encode json text into bytea using pg_convert_to() */
3601 Node *texpr = coerce_to_specific_type(pstate, expr, TEXTOID,
3602 "JSON_FUNCTION");
3603 Const *enc = getJsonEncodingConst(returning->format);
3604 FuncExpr *fexpr = makeFuncExpr(F_CONVERT_TO, BYTEAOID,
3605 list_make2(texpr, enc),
3608
3609 fexpr->location = location;
3610
3611 return (Node *) fexpr;
3612 }
3613
3614 /*
3615 * For other cases, try to coerce expression to the output type using
3616 * assignment-level casts, erroring out if none available. This basically
3617 * allows coercing the jsonb value to any string type (typcategory = 'S').
3618 *
3619 * Requesting assignment-level here means that typmod / length coercion
3620 * assumes implicit coercion which is the behavior we want; see
3621 * build_coercion_expression().
3622 */
3623 res = coerce_to_target_type(pstate, expr, exprtype,
3624 returning->typid, returning->typmod,
3627 location);
3628
3629 if (!res && report_error)
3630 ereport(ERROR,
3631 errcode(ERRCODE_CANNOT_COERCE),
3632 errmsg("cannot cast type %s to %s",
3633 format_type_be(exprtype),
3634 format_type_be(returning->typid)),
3635 parser_coercion_errposition(pstate, location, expr));
3636
3637 return res;
3638}
#define OidIsValid(objectId)
Definition: c.h:729
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)
Definition: makefuncs.c:545
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1380
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)
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
static Const * getJsonEncodingConst(JsonFormat *format)
Definition: parse_expr.c:3217
#define list_make2(x1, x2)
Definition: pg_list.h:214
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:736
@ COERCE_EXPLICIT_CALL
Definition: primnodes.h:734
@ COERCION_ASSIGNMENT
Definition: primnodes.h:715
ParseLoc location
Definition: primnodes.h:770
ParseLoc location
Definition: primnodes.h:1653
JsonFormatType format_type
Definition: primnodes.h:1651
JsonFormat * format
Definition: primnodes.h:1663
Definition: nodes.h:129

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

Referenced by makeJsonConstructorExpr().

◆ exprIsNullConstant()

static bool exprIsNullConstant ( Node arg)
static

Definition at line 908 of file parse_expr.c.

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

References arg, IsA, and A_Const::isnull.

Referenced by transformAExprDistinct(), and transformAExprOp().

◆ GetJsonBehaviorConst()

static Node * GetJsonBehaviorConst ( JsonBehaviorType  btype,
int  location 
)
static

Definition at line 4825 of file parse_expr.c.

4826{
4827 Datum val = (Datum) 0;
4828 Oid typid = JSONBOID;
4829 int len = -1;
4830 bool isbyval = false;
4831 bool isnull = false;
4832 Const *con;
4833
4834 switch (btype)
4835 {
4838 break;
4839
4842 break;
4843
4844 case JSON_BEHAVIOR_TRUE:
4845 val = BoolGetDatum(true);
4846 typid = BOOLOID;
4847 len = sizeof(bool);
4848 isbyval = true;
4849 break;
4850
4852 val = BoolGetDatum(false);
4853 typid = BOOLOID;
4854 len = sizeof(bool);
4855 isbyval = true;
4856 break;
4857
4858 case JSON_BEHAVIOR_NULL:
4861 val = (Datum) 0;
4862 isnull = true;
4863 typid = INT4OID;
4864 len = sizeof(int32);
4865 isbyval = true;
4866 break;
4867
4868 /* These two behavior types are handled by the caller. */
4871 Assert(false);
4872 break;
4873
4874 default:
4875 elog(ERROR, "unrecognized SQL/JSON behavior %d", btype);
4876 break;
4877 }
4878
4879 con = makeConst(typid, -1, InvalidOid, len, val, isnull, isbyval);
4880 con->location = location;
4881
4882 return (Node *) con;
4883}
#define Assert(condition)
Definition: c.h:812
int32_t int32
Definition: c.h:481
#define elog(elevel,...)
Definition: elog.h:225
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
long val
Definition: informix.c:689
Datum jsonb_in(PG_FUNCTION_ARGS)
Definition: jsonb.c:73
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:301
const void size_t len
uintptr_t Datum
Definition: postgres.h:64
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
@ JSON_BEHAVIOR_ERROR
Definition: primnodes.h:1766
@ JSON_BEHAVIOR_TRUE
Definition: primnodes.h:1768
@ JSON_BEHAVIOR_DEFAULT
Definition: primnodes.h:1773
@ JSON_BEHAVIOR_EMPTY
Definition: primnodes.h:1767
@ JSON_BEHAVIOR_FALSE
Definition: primnodes.h:1769
@ JSON_BEHAVIOR_NULL
Definition: primnodes.h:1765
@ JSON_BEHAVIOR_EMPTY_OBJECT
Definition: primnodes.h:1772
@ JSON_BEHAVIOR_UNKNOWN
Definition: primnodes.h:1770
@ JSON_BEHAVIOR_EMPTY_ARRAY
Definition: primnodes.h:1771

References Assert, BoolGetDatum(), CStringGetDatum(), DirectFunctionCall1, elog, ERROR, InvalidOid, JSON_BEHAVIOR_DEFAULT, JSON_BEHAVIOR_EMPTY, JSON_BEHAVIOR_EMPTY_ARRAY, JSON_BEHAVIOR_EMPTY_OBJECT, JSON_BEHAVIOR_ERROR, JSON_BEHAVIOR_FALSE, JSON_BEHAVIOR_NULL, JSON_BEHAVIOR_TRUE, JSON_BEHAVIOR_UNKNOWN, jsonb_in(), len, makeConst(), and val.

Referenced by transformJsonBehavior().

◆ getJsonEncodingConst()

static Const * getJsonEncodingConst ( JsonFormat format)
static

Definition at line 3217 of file parse_expr.c.

3218{
3220 const char *enc;
3221 Name encname = palloc(sizeof(NameData));
3222
3223 if (!format ||
3224 format->format_type == JS_FORMAT_DEFAULT ||
3225 format->encoding == JS_ENC_DEFAULT)
3227 else
3228 encoding = format->encoding;
3229
3230 switch (encoding)
3231 {
3232 case JS_ENC_UTF16:
3233 enc = "UTF16";
3234 break;
3235 case JS_ENC_UTF32:
3236 enc = "UTF32";
3237 break;
3238 case JS_ENC_UTF8:
3239 enc = "UTF8";
3240 break;
3241 default:
3242 elog(ERROR, "invalid JSON encoding: %d", encoding);
3243 break;
3244 }
3245
3246 namestrcpy(encname, enc);
3247
3248 return makeConst(NAMEOID, -1, InvalidOid, NAMEDATALEN,
3249 NameGetDatum(encname), false, false);
3250}
void * palloc(Size size)
Definition: mcxt.c:1317
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define NAMEDATALEN
int32 encoding
Definition: pg_database.h:41
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
@ JS_ENC_UTF32
Definition: primnodes.h:1629
@ JS_ENC_UTF16
Definition: primnodes.h:1628
Definition: c.h:695

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

Referenced by coerceJsonFuncExpr(), and makeJsonByteaToTextConversion().

◆ make_distinct_op()

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

Definition at line 3052 of file parse_expr.c.

3054{
3055 Expr *result;
3056
3057 result = make_op(pstate, opname, ltree, rtree,
3058 pstate->p_last_srf, location);
3059 if (((OpExpr *) result)->opresulttype != BOOLOID)
3060 ereport(ERROR,
3061 (errcode(ERRCODE_DATATYPE_MISMATCH),
3062 /* translator: %s is name of a SQL construct, eg NULLIF */
3063 errmsg("%s requires = operator to yield boolean",
3064 "IS DISTINCT FROM"),
3065 parser_errposition(pstate, location)));
3066 if (((OpExpr *) result)->opretset)
3067 ereport(ERROR,
3068 (errcode(ERRCODE_DATATYPE_MISMATCH),
3069 /* translator: %s is name of a SQL construct, eg NULLIF */
3070 errmsg("%s must not return a set", "IS DISTINCT FROM"),
3071 parser_errposition(pstate, location)));
3072
3073 /*
3074 * We rely on DistinctExpr and OpExpr being same struct
3075 */
3076 NodeSetTag(result, T_DistinctExpr);
3077
3078 return result;
3079}
#define NodeSetTag(nodeptr, t)
Definition: nodes.h:156
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, Node *last_srf, int location)
Definition: parse_oper.c:660
Node * p_last_srf
Definition: parse_node.h:248
Definition: ltree.h:43

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

Referenced by make_row_distinct_op(), and transformAExprDistinct().

◆ make_nulltest_from_distinct()

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

Definition at line 3087 of file parse_expr.c.

3088{
3089 NullTest *nt = makeNode(NullTest);
3090
3091 nt->arg = (Expr *) transformExprRecurse(pstate, arg);
3092 /* the argument can be any type, so don't coerce it */
3093 if (distincta->kind == AEXPR_NOT_DISTINCT)
3094 nt->nulltesttype = IS_NULL;
3095 else
3097 /* argisrow = false is correct whether or not arg is composite */
3098 nt->argisrow = false;
3099 nt->location = distincta->location;
3100 return (Node *) nt;
3101}
#define makeNode(_type_)
Definition: nodes.h:155
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:136
@ AEXPR_NOT_DISTINCT
Definition: parsenodes.h:319
@ IS_NULL
Definition: primnodes.h:1952
@ IS_NOT_NULL
Definition: primnodes.h:1952
ParseLoc location
Definition: parsenodes.h:340
A_Expr_Kind kind
Definition: parsenodes.h:336
NullTestType nulltesttype
Definition: primnodes.h:1959
ParseLoc location
Definition: primnodes.h:1962
Expr * arg
Definition: primnodes.h:1958

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

Referenced by transformAExprDistinct().

◆ make_row_comparison_op()

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

Definition at line 2806 of file parse_expr.c.

2808{
2809 RowCompareExpr *rcexpr;
2810 RowCompareType rctype;
2811 List *opexprs;
2812 List *opnos;
2813 List *opfamilies;
2814 ListCell *l,
2815 *r;
2816 List **opinfo_lists;
2817 Bitmapset *strats;
2818 int nopers;
2819 int i;
2820
2821 nopers = list_length(largs);
2822 if (nopers != list_length(rargs))
2823 ereport(ERROR,
2824 (errcode(ERRCODE_SYNTAX_ERROR),
2825 errmsg("unequal number of entries in row expressions"),
2826 parser_errposition(pstate, location)));
2827
2828 /*
2829 * We can't compare zero-length rows because there is no principled basis
2830 * for figuring out what the operator is.
2831 */
2832 if (nopers == 0)
2833 ereport(ERROR,
2834 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2835 errmsg("cannot compare rows of zero length"),
2836 parser_errposition(pstate, location)));
2837
2838 /*
2839 * Identify all the pairwise operators, using make_op so that behavior is
2840 * the same as in the simple scalar case.
2841 */
2842 opexprs = NIL;
2843 forboth(l, largs, r, rargs)
2844 {
2845 Node *larg = (Node *) lfirst(l);
2846 Node *rarg = (Node *) lfirst(r);
2847 OpExpr *cmp;
2848
2849 cmp = castNode(OpExpr, make_op(pstate, opname, larg, rarg,
2850 pstate->p_last_srf, location));
2851
2852 /*
2853 * We don't use coerce_to_boolean here because we insist on the
2854 * operator yielding boolean directly, not via coercion. If it
2855 * doesn't yield bool it won't be in any index opfamilies...
2856 */
2857 if (cmp->opresulttype != BOOLOID)
2858 ereport(ERROR,
2859 (errcode(ERRCODE_DATATYPE_MISMATCH),
2860 errmsg("row comparison operator must yield type boolean, "
2861 "not type %s",
2862 format_type_be(cmp->opresulttype)),
2863 parser_errposition(pstate, location)));
2865 ereport(ERROR,
2866 (errcode(ERRCODE_DATATYPE_MISMATCH),
2867 errmsg("row comparison operator must not return a set"),
2868 parser_errposition(pstate, location)));
2869 opexprs = lappend(opexprs, cmp);
2870 }
2871
2872 /*
2873 * If rows are length 1, just return the single operator. In this case we
2874 * don't insist on identifying btree semantics for the operator (but we
2875 * still require it to return boolean).
2876 */
2877 if (nopers == 1)
2878 return (Node *) linitial(opexprs);
2879
2880 /*
2881 * Now we must determine which row comparison semantics (= <> < <= > >=)
2882 * apply to this set of operators. We look for btree opfamilies
2883 * containing the operators, and see which interpretations (strategy
2884 * numbers) exist for each operator.
2885 */
2886 opinfo_lists = (List **) palloc(nopers * sizeof(List *));
2887 strats = NULL;
2888 i = 0;
2889 foreach(l, opexprs)
2890 {
2891 Oid opno = ((OpExpr *) lfirst(l))->opno;
2892 Bitmapset *this_strats;
2893 ListCell *j;
2894
2895 opinfo_lists[i] = get_op_btree_interpretation(opno);
2896
2897 /*
2898 * convert strategy numbers into a Bitmapset to make the intersection
2899 * calculation easy.
2900 */
2901 this_strats = NULL;
2902 foreach(j, opinfo_lists[i])
2903 {
2904 OpBtreeInterpretation *opinfo = lfirst(j);
2905
2906 this_strats = bms_add_member(this_strats, opinfo->strategy);
2907 }
2908 if (i == 0)
2909 strats = this_strats;
2910 else
2911 strats = bms_int_members(strats, this_strats);
2912 i++;
2913 }
2914
2915 /*
2916 * If there are multiple common interpretations, we may use any one of
2917 * them ... this coding arbitrarily picks the lowest btree strategy
2918 * number.
2919 */
2920 i = bms_next_member(strats, -1);
2921 if (i < 0)
2922 {
2923 /* No common interpretation, so fail */
2924 ereport(ERROR,
2925 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2926 errmsg("could not determine interpretation of row comparison operator %s",
2927 strVal(llast(opname))),
2928 errhint("Row comparison operators must be associated with btree operator families."),
2929 parser_errposition(pstate, location)));
2930 }
2931 rctype = (RowCompareType) i;
2932
2933 /*
2934 * For = and <> cases, we just combine the pairwise operators with AND or
2935 * OR respectively.
2936 */
2937 if (rctype == ROWCOMPARE_EQ)
2938 return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
2939 if (rctype == ROWCOMPARE_NE)
2940 return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
2941
2942 /*
2943 * Otherwise we need to choose exactly which opfamily to associate with
2944 * each operator.
2945 */
2946 opfamilies = NIL;
2947 for (i = 0; i < nopers; i++)
2948 {
2949 Oid opfamily = InvalidOid;
2950 ListCell *j;
2951
2952 foreach(j, opinfo_lists[i])
2953 {
2954 OpBtreeInterpretation *opinfo = lfirst(j);
2955
2956 if (opinfo->strategy == rctype)
2957 {
2958 opfamily = opinfo->opfamily_id;
2959 break;
2960 }
2961 }
2962 if (OidIsValid(opfamily))
2963 opfamilies = lappend_oid(opfamilies, opfamily);
2964 else /* should not happen */
2965 ereport(ERROR,
2966 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2967 errmsg("could not determine interpretation of row comparison operator %s",
2968 strVal(llast(opname))),
2969 errdetail("There are multiple equally-plausible candidates."),
2970 parser_errposition(pstate, location)));
2971 }
2972
2973 /*
2974 * Now deconstruct the OpExprs and create a RowCompareExpr.
2975 *
2976 * Note: can't just reuse the passed largs/rargs lists, because of
2977 * possibility that make_op inserted coercion operations.
2978 */
2979 opnos = NIL;
2980 largs = NIL;
2981 rargs = NIL;
2982 foreach(l, opexprs)
2983 {
2984 OpExpr *cmp = (OpExpr *) lfirst(l);
2985
2986 opnos = lappend_oid(opnos, cmp->opno);
2987 largs = lappend(largs, linitial(cmp->args));
2988 rargs = lappend(rargs, lsecond(cmp->args));
2989 }
2990
2991 rcexpr = makeNode(RowCompareExpr);
2992 rcexpr->rctype = rctype;
2993 rcexpr->opnos = opnos;
2994 rcexpr->opfamilies = opfamilies;
2995 rcexpr->inputcollids = NIL; /* assign_expr_collations will fix this */
2996 rcexpr->largs = largs;
2997 rcexpr->rargs = rargs;
2998
2999 return (Node *) rcexpr;
3000}
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:1109
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int j
Definition: isn.c:73
int i
Definition: isn.c:72
List * lappend(List *list, void *datum)
Definition: list.c:339
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
List * get_op_btree_interpretation(Oid opno)
Definition: lsyscache.c:601
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:371
bool expression_returns_set(Node *clause)
Definition: nodeFuncs.c:758
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
#define lfirst(lc)
Definition: pg_list.h:172
#define llast(l)
Definition: pg_list.h:198
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
@ AND_EXPR
Definition: primnodes.h:931
@ OR_EXPR
Definition: primnodes.h:931
RowCompareType
Definition: primnodes.h:1453
@ ROWCOMPARE_NE
Definition: primnodes.h:1460
@ ROWCOMPARE_EQ
Definition: primnodes.h:1457
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743
Definition: pg_list.h:54
RowCompareType rctype
Definition: primnodes.h:1468
#define strVal(v)
Definition: value.h:82

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

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

◆ make_row_distinct_op()

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

Definition at line 3008 of file parse_expr.c.

3011{
3012 Node *result = NULL;
3013 List *largs = lrow->args;
3014 List *rargs = rrow->args;
3015 ListCell *l,
3016 *r;
3017
3018 if (list_length(largs) != list_length(rargs))
3019 ereport(ERROR,
3020 (errcode(ERRCODE_SYNTAX_ERROR),
3021 errmsg("unequal number of entries in row expressions"),
3022 parser_errposition(pstate, location)));
3023
3024 forboth(l, largs, r, rargs)
3025 {
3026 Node *larg = (Node *) lfirst(l);
3027 Node *rarg = (Node *) lfirst(r);
3028 Node *cmp;
3029
3030 cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
3031 if (result == NULL)
3032 result = cmp;
3033 else
3034 result = (Node *) makeBoolExpr(OR_EXPR,
3035 list_make2(result, cmp),
3036 location);
3037 }
3038
3039 if (result == NULL)
3040 {
3041 /* zero-length rows? Generate constant FALSE */
3042 result = makeBoolConst(false, false);
3043 }
3044
3045 return result;
3046}
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:359
static Expr * make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_expr.c:3052
List * args
Definition: primnodes.h:1411

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

◆ makeJsonByteaToTextConversion()

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

Definition at line 3256 of file parse_expr.c.

3257{
3259 FuncExpr *fexpr = makeFuncExpr(F_CONVERT_FROM, TEXTOID,
3260 list_make2(expr, encoding),
3263
3264 fexpr->location = location;
3265
3266 return (Node *) fexpr;
3267}

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

Referenced by transformJsonParseArg(), and transformJsonValueExpr().

◆ makeJsonConstructorExpr()

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

Definition at line 3644 of file parse_expr.c.

3647{
3649 Node *placeholder;
3650 Node *coercion;
3651
3652 jsctor->args = args;
3653 jsctor->func = fexpr;
3654 jsctor->type = type;
3655 jsctor->returning = returning;
3656 jsctor->unique = unique;
3657 jsctor->absent_on_null = absent_on_null;
3658 jsctor->location = location;
3659
3660 /*
3661 * Coerce to the RETURNING type and format, if needed. We abuse
3662 * CaseTestExpr here as placeholder to pass the result of either
3663 * evaluating 'fexpr' or whatever is produced by ExecEvalJsonConstructor()
3664 * that is of type JSON or JSONB to the coercion function.
3665 */
3666 if (fexpr)
3667 {
3669
3670 cte->typeId = exprType((Node *) fexpr);
3671 cte->typeMod = exprTypmod((Node *) fexpr);
3672 cte->collation = exprCollation((Node *) fexpr);
3673
3674 placeholder = (Node *) cte;
3675 }
3676 else
3677 {
3679
3680 cte->typeId = returning->format->format_type == JS_FORMAT_JSONB ?
3681 JSONBOID : JSONOID;
3682 cte->typeMod = -1;
3683 cte->collation = InvalidOid;
3684
3685 placeholder = (Node *) cte;
3686 }
3687
3688 coercion = coerceJsonFuncExpr(pstate, placeholder, returning, true);
3689
3690 if (coercion != placeholder)
3691 jsctor->coercion = (Expr *) coercion;
3692
3693 return (Node *) jsctor;
3694}
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:298
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:816
static Node * coerceJsonFuncExpr(ParseState *pstate, Node *expr, const JsonReturning *returning, bool report_error)
Definition: parse_expr.c:3580
@ JS_FORMAT_JSONB
Definition: primnodes.h:1640
JsonReturning * returning
Definition: primnodes.h:1710
JsonConstructorType type
Definition: primnodes.h:1706
const char * type

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

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

◆ ParseExprKindName()

const char * ParseExprKindName ( ParseExprKind  exprKind)

Definition at line 3111 of file parse_expr.c.

3112{
3113 switch (exprKind)
3114 {
3115 case EXPR_KIND_NONE:
3116 return "invalid expression context";
3117 case EXPR_KIND_OTHER:
3118 return "extension expression";
3119 case EXPR_KIND_JOIN_ON:
3120 return "JOIN/ON";
3122 return "JOIN/USING";
3124 return "sub-SELECT in FROM";
3126 return "function in FROM";
3127 case EXPR_KIND_WHERE:
3128 return "WHERE";
3129 case EXPR_KIND_POLICY:
3130 return "POLICY";
3131 case EXPR_KIND_HAVING:
3132 return "HAVING";
3133 case EXPR_KIND_FILTER:
3134 return "FILTER";
3136 return "window PARTITION BY";
3138 return "window ORDER BY";
3140 return "window RANGE";
3142 return "window ROWS";
3144 return "window GROUPS";
3146 return "SELECT";
3148 return "INSERT";
3151 return "UPDATE";
3153 return "MERGE WHEN";
3154 case EXPR_KIND_GROUP_BY:
3155 return "GROUP BY";
3156 case EXPR_KIND_ORDER_BY:
3157 return "ORDER BY";
3159 return "DISTINCT ON";
3160 case EXPR_KIND_LIMIT:
3161 return "LIMIT";
3162 case EXPR_KIND_OFFSET:
3163 return "OFFSET";
3166 return "RETURNING";
3167 case EXPR_KIND_VALUES:
3169 return "VALUES";
3172 return "CHECK";
3175 return "DEFAULT";
3177 return "index expression";
3179 return "index predicate";
3181 return "statistics expression";
3183 return "USING";
3185 return "EXECUTE";
3187 return "WHEN";
3189 return "partition bound";
3191 return "PARTITION BY";
3193 return "CALL";
3195 return "WHERE";
3197 return "GENERATED AS";
3199 return "CYCLE";
3200
3201 /*
3202 * There is intentionally no default: case here, so that the
3203 * compiler will warn if we add a new ParseExprKind without
3204 * extending this switch. If we do see an unrecognized value at
3205 * runtime, we'll fall through to the "unrecognized" return.
3206 */
3207 }
3208 return "unrecognized expression kind";
3209}
@ EXPR_KIND_EXECUTE_PARAMETER
Definition: parse_node.h:76
@ EXPR_KIND_DOMAIN_CHECK
Definition: parse_node.h:69
@ EXPR_KIND_COPY_WHERE
Definition: parse_node.h:82
@ EXPR_KIND_COLUMN_DEFAULT
Definition: parse_node.h:70
@ 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:74
@ EXPR_KIND_INDEX_EXPRESSION
Definition: parse_node.h:72
@ EXPR_KIND_MERGE_RETURNING
Definition: parse_node.h:65
@ EXPR_KIND_PARTITION_BOUND
Definition: parse_node.h:79
@ EXPR_KIND_FUNCTION_DEFAULT
Definition: parse_node.h:71
@ EXPR_KIND_WINDOW_FRAME_RANGE
Definition: parse_node.h:51
@ EXPR_KIND_VALUES
Definition: parse_node.h:66
@ EXPR_KIND_FROM_SUBSELECT
Definition: parse_node.h:44
@ EXPR_KIND_POLICY
Definition: parse_node.h:78
@ EXPR_KIND_WINDOW_FRAME_GROUPS
Definition: parse_node.h:53
@ EXPR_KIND_PARTITION_EXPRESSION
Definition: parse_node.h:80
@ EXPR_KIND_JOIN_USING
Definition: parse_node.h:43
@ EXPR_KIND_INDEX_PREDICATE
Definition: parse_node.h:73
@ 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:75
@ 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:83
@ EXPR_KIND_NONE
Definition: parse_node.h:40
@ EXPR_KIND_CALL_ARGUMENT
Definition: parse_node.h:81
@ 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:77
@ 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:68
@ EXPR_KIND_WINDOW_PARTITION
Definition: parse_node.h:49
@ EXPR_KIND_CYCLE_MARK
Definition: parse_node.h:84
@ 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:67

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_RETURNING, 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 1282 of file parse_expr.c.

1283{
1284 Node *aexpr;
1285 Node *bexpr;
1286 Node *cexpr;
1287 Node *result;
1288 Node *sub1;
1289 Node *sub2;
1290 List *args;
1291
1292 /* Deconstruct A_Expr into three subexprs */
1293 aexpr = a->lexpr;
1294 args = castNode(List, a->rexpr);
1295 Assert(list_length(args) == 2);
1296 bexpr = (Node *) linitial(args);
1297 cexpr = (Node *) lsecond(args);
1298
1299 /*
1300 * Build the equivalent comparison expression. Make copies of
1301 * multiply-referenced subexpressions for safety. (XXX this is really
1302 * wrong since it results in multiple runtime evaluations of what may be
1303 * volatile expressions ...)
1304 *
1305 * Ideally we would not use hard-wired operators here but instead use
1306 * opclasses. However, mixed data types and other issues make this
1307 * difficult:
1308 * http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
1309 */
1310 switch (a->kind)
1311 {
1312 case AEXPR_BETWEEN:
1314 aexpr, bexpr,
1315 a->location),
1317 copyObject(aexpr), cexpr,
1318 a->location));
1319 result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1320 break;
1321 case AEXPR_NOT_BETWEEN:
1323 aexpr, bexpr,
1324 a->location),
1326 copyObject(aexpr), cexpr,
1327 a->location));
1328 result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1329 break;
1330 case AEXPR_BETWEEN_SYM:
1332 aexpr, bexpr,
1333 a->location),
1335 copyObject(aexpr), cexpr,
1336 a->location));
1337 sub1 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1339 copyObject(aexpr), copyObject(cexpr),
1340 a->location),
1342 copyObject(aexpr), copyObject(bexpr),
1343 a->location));
1344 sub2 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1345 args = list_make2(sub1, sub2);
1346 result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1347 break;
1350 aexpr, bexpr,
1351 a->location),
1353 copyObject(aexpr), cexpr,
1354 a->location));
1355 sub1 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1357 copyObject(aexpr), copyObject(cexpr),
1358 a->location),
1360 copyObject(aexpr), copyObject(bexpr),
1361 a->location));
1362 sub2 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1363 args = list_make2(sub1, sub2);
1364 result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1365 break;
1366 default:
1367 elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
1368 result = NULL; /* keep compiler quiet */
1369 break;
1370 }
1371
1372 return transformExprRecurse(pstate, result);
1373}
int a
Definition: isn.c:68
A_Expr * makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location)
Definition: makefuncs.c:48
#define copyObject(obj)
Definition: nodes.h:224
@ AEXPR_BETWEEN
Definition: parsenodes.h:325
@ AEXPR_BETWEEN_SYM
Definition: parsenodes.h:327
@ AEXPR_NOT_BETWEEN_SYM
Definition: parsenodes.h:328
@ AEXPR_NOT_BETWEEN
Definition: parsenodes.h:326
@ AEXPR_OP
Definition: parsenodes.h:315

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

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

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

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

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

Referenced by transformExprRecurse().

◆ transformAExprNullIf()

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

Definition at line 1081 of file parse_expr.c.

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

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

Referenced by transformExprRecurse().

◆ transformAExprOp()

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

Definition at line 921 of file parse_expr.c.

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

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

Referenced by transformExprRecurse().

◆ transformAExprOpAll()

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

Definition at line 1016 of file parse_expr.c.

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

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

Referenced by transformExprRecurse().

◆ transformAExprOpAny()

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

Definition at line 1002 of file parse_expr.c.

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

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

2015{
2016 ArrayExpr *newa = makeNode(ArrayExpr);
2017 List *newelems = NIL;
2018 List *newcoercedelems = NIL;
2021 bool coerce_hard;
2022
2023 /*
2024 * Transform the element expressions
2025 *
2026 * Assume that the array is one-dimensional unless we find an array-type
2027 * element expression.
2028 */
2029 newa->multidims = false;
2030 foreach(element, a->elements)
2031 {
2032 Node *e = (Node *) lfirst(element);
2033 Node *newe;
2034
2035 /*
2036 * If an element is itself an A_ArrayExpr, recurse directly so that we
2037 * can pass down any target type we were given.
2038 */
2039 if (IsA(e, A_ArrayExpr))
2040 {
2041 newe = transformArrayExpr(pstate,
2042 (A_ArrayExpr *) e,
2043 array_type,
2044 element_type,
2045 typmod);
2046 /* we certainly have an array here */
2047 Assert(array_type == InvalidOid || array_type == exprType(newe));
2048 newa->multidims = true;
2049 }
2050 else
2051 {
2052 newe = transformExprRecurse(pstate, e);
2053
2054 /*
2055 * Check for sub-array expressions, if we haven't already found
2056 * one.
2057 */
2058 if (!newa->multidims && type_is_array(exprType(newe)))
2059 newa->multidims = true;
2060 }
2061
2062 newelems = lappend(newelems, newe);
2063 }
2064
2065 /*
2066 * Select a target type for the elements.
2067 *
2068 * If we haven't been given a target array type, we must try to deduce a
2069 * common type based on the types of the individual elements present.
2070 */
2071 if (OidIsValid(array_type))
2072 {
2073 /* Caller must ensure array_type matches element_type */
2074 Assert(OidIsValid(element_type));
2075 coerce_type = (newa->multidims ? array_type : element_type);
2076 coerce_hard = true;
2077 }
2078 else
2079 {
2080 /* Can't handle an empty array without a target type */
2081 if (newelems == NIL)
2082 ereport(ERROR,
2083 (errcode(ERRCODE_INDETERMINATE_DATATYPE),
2084 errmsg("cannot determine type of empty array"),
2085 errhint("Explicitly cast to the desired type, "
2086 "for example ARRAY[]::integer[]."),
2087 parser_errposition(pstate, a->location)));
2088
2089 /* Select a common type for the elements */
2090 coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
2091
2092 if (newa->multidims)
2093 {
2094 array_type = coerce_type;
2095 element_type = get_element_type(array_type);
2096 if (!OidIsValid(element_type))
2097 ereport(ERROR,
2098 (errcode(ERRCODE_UNDEFINED_OBJECT),
2099 errmsg("could not find element type for data type %s",
2100 format_type_be(array_type)),
2101 parser_errposition(pstate, a->location)));
2102 }
2103 else
2104 {
2105 element_type = coerce_type;
2106 array_type = get_array_type(element_type);
2107 if (!OidIsValid(array_type))
2108 ereport(ERROR,
2109 (errcode(ERRCODE_UNDEFINED_OBJECT),
2110 errmsg("could not find array type for data type %s",
2111 format_type_be(element_type)),
2112 parser_errposition(pstate, a->location)));
2113 }
2114 coerce_hard = false;
2115 }
2116
2117 /*
2118 * Coerce elements to target type
2119 *
2120 * If the array has been explicitly cast, then the elements are in turn
2121 * explicitly coerced.
2122 *
2123 * If the array's type was merely derived from the common type of its
2124 * elements, then the elements are implicitly coerced to the common type.
2125 * This is consistent with other uses of select_common_type().
2126 */
2127 foreach(element, newelems)
2128 {
2129 Node *e = (Node *) lfirst(element);
2130 Node *newe;
2131
2132 if (coerce_hard)
2133 {
2134 newe = coerce_to_target_type(pstate, e,
2135 exprType(e),
2137 typmod,
2140 -1);
2141 if (newe == NULL)
2142 ereport(ERROR,
2143 (errcode(ERRCODE_CANNOT_COERCE),
2144 errmsg("cannot cast type %s to %s",
2147 parser_errposition(pstate, exprLocation(e))));
2148 }
2149 else
2150 newe = coerce_to_common_type(pstate, e,
2152 "ARRAY");
2153 newcoercedelems = lappend(newcoercedelems, newe);
2154 }
2155
2156 newa->array_typeid = array_type;
2157 /* array_collid will be set by parse_collate.c */
2158 newa->element_typeid = element_type;
2159 newa->elements = newcoercedelems;
2160 newa->location = a->location;
2161
2162 return (Node *) newa;
2163}
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2759
#define type_is_array(typid)
Definition: lsyscache.h:209
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:2013
e
Definition: preproc-init.c:82
@ COERCE_EXPLICIT_CAST
Definition: primnodes.h:735
@ COERCION_EXPLICIT
Definition: primnodes.h:717
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:376

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

Referenced by transformArrayExpr(), transformExprRecurse(), and transformTypeCast().

◆ transformBooleanTest()

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

Definition at line 2518 of file parse_expr.c.

2519{
2520 const char *clausename;
2521
2522 switch (b->booltesttype)
2523 {
2524 case IS_TRUE:
2525 clausename = "IS TRUE";
2526 break;
2527 case IS_NOT_TRUE:
2528 clausename = "IS NOT TRUE";
2529 break;
2530 case IS_FALSE:
2531 clausename = "IS FALSE";
2532 break;
2533 case IS_NOT_FALSE:
2534 clausename = "IS NOT FALSE";
2535 break;
2536 case IS_UNKNOWN:
2537 clausename = "IS UNKNOWN";
2538 break;
2539 case IS_NOT_UNKNOWN:
2540 clausename = "IS NOT UNKNOWN";
2541 break;
2542 default:
2543 elog(ERROR, "unrecognized booltesttype: %d",
2544 (int) b->booltesttype);
2545 clausename = NULL; /* keep compiler quiet */
2546 }
2547
2548 b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
2549
2550 b->arg = (Expr *) coerce_to_boolean(pstate,
2551 (Node *) b->arg,
2552 clausename);
2553
2554 return (Node *) b;
2555}
int b
Definition: isn.c:69
@ IS_NOT_TRUE
Definition: primnodes.h:1976
@ IS_NOT_FALSE
Definition: primnodes.h:1976
@ IS_NOT_UNKNOWN
Definition: primnodes.h:1976
@ IS_TRUE
Definition: primnodes.h:1976
@ IS_UNKNOWN
Definition: primnodes.h:1976
@ IS_FALSE
Definition: primnodes.h:1976

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

1402{
1403 List *args = NIL;
1404 const char *opname;
1405 ListCell *lc;
1406
1407 switch (a->boolop)
1408 {
1409 case AND_EXPR:
1410 opname = "AND";
1411 break;
1412 case OR_EXPR:
1413 opname = "OR";
1414 break;
1415 case NOT_EXPR:
1416 opname = "NOT";
1417 break;
1418 default:
1419 elog(ERROR, "unrecognized boolop: %d", (int) a->boolop);
1420 opname = NULL; /* keep compiler quiet */
1421 break;
1422 }
1423
1424 foreach(lc, a->args)
1425 {
1426 Node *arg = (Node *) lfirst(lc);
1427
1428 arg = transformExprRecurse(pstate, arg);
1429 arg = coerce_to_boolean(pstate, arg, opname);
1430 args = lappend(args, arg);
1431 }
1432
1433 return (Node *) makeBoolExpr(a->boolop, args, a->location);
1434}

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

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

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

Referenced by transformExprRecurse().

◆ transformCoalesceExpr()

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

Definition at line 2204 of file parse_expr.c.

2205{
2207 Node *last_srf = pstate->p_last_srf;
2208 List *newargs = NIL;
2209 List *newcoercedargs = NIL;
2210 ListCell *args;
2211
2212 foreach(args, c->args)
2213 {
2214 Node *e = (Node *) lfirst(args);
2215 Node *newe;
2216
2217 newe = transformExprRecurse(pstate, e);
2218 newargs = lappend(newargs, newe);
2219 }
2220
2221 newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
2222 /* coalescecollid will be set by parse_collate.c */
2223
2224 /* Convert arguments if necessary */
2225 foreach(args, newargs)
2226 {
2227 Node *e = (Node *) lfirst(args);
2228 Node *newe;
2229
2230 newe = coerce_to_common_type(pstate, e,
2231 newc->coalescetype,
2232 "COALESCE");
2233 newcoercedargs = lappend(newcoercedargs, newe);
2234 }
2235
2236 /* if any subexpression contained a SRF, complain */
2237 if (pstate->p_last_srf != last_srf)
2238 ereport(ERROR,
2239 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2240 /* translator: %s is name of a SQL construct, eg GROUP BY */
2241 errmsg("set-returning functions are not allowed in %s",
2242 "COALESCE"),
2243 errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
2244 parser_errposition(pstate,
2245 exprLocation(pstate->p_last_srf))));
2246
2247 newc->args = newcoercedargs;
2248 newc->location = c->location;
2249 return (Node *) newc;
2250}
List * args
Definition: primnodes.h:1492
ParseLoc location
Definition: primnodes.h:1494

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

Referenced by transformExprRecurse().

◆ transformCollateClause()

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

Definition at line 2766 of file parse_expr.c.

2767{
2768 CollateExpr *newc;
2769 Oid argtype;
2770
2771 newc = makeNode(CollateExpr);
2772 newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
2773
2774 argtype = exprType((Node *) newc->arg);
2775
2776 /*
2777 * The unknown type is not collatable, but coerce_type() takes care of it
2778 * separately, so we'll let it go here.
2779 */
2780 if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
2781 ereport(ERROR,
2782 (errcode(ERRCODE_DATATYPE_MISMATCH),
2783 errmsg("collations are not supported by type %s",
2784 format_type_be(argtype)),
2785 parser_errposition(pstate, c->location)));
2786
2787 newc->collOid = LookupCollation(pstate, c->collname, c->location);
2788 newc->location = c->location;
2789
2790 return (Node *) newc;
2791}
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:3081
Oid LookupCollation(ParseState *pstate, List *collnames, int location)
Definition: parse_type.c:515
Expr * arg
Definition: primnodes.h:1279
ParseLoc location
Definition: primnodes.h:1281

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

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

References _, Assert, colNameToVar(), ereport, err(), errcode(), errmsg(), errmsg_internal(), ERROR, errorMissingColumn(), errorMissingRTE(), EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CALL_ARGUMENT, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, EXPR_KIND_COPY_WHERE, EXPR_KIND_CYCLE_MARK, EXPR_KIND_DISTINCT_ON, EXPR_KIND_DOMAIN_CHECK, EXPR_KIND_EXECUTE_PARAMETER, EXPR_KIND_FILTER, EXPR_KIND_FROM_FUNCTION, EXPR_KIND_FROM_SUBSELECT, EXPR_KIND_FUNCTION_DEFAULT, EXPR_KIND_GENERATED_COLUMN, EXPR_KIND_GROUP_BY, EXPR_KIND_HAVING, EXPR_KIND_INDEX_EXPRESSION, EXPR_KIND_INDEX_PREDICATE, EXPR_KIND_INSERT_TARGET, EXPR_KIND_JOIN_ON, EXPR_KIND_JOIN_USING, EXPR_KIND_LIMIT, EXPR_KIND_MERGE_RETURNING, 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 2558 of file parse_expr.c.

2559{
2560 /* CURRENT OF can only appear at top level of UPDATE/DELETE */
2561 Assert(pstate->p_target_nsitem != NULL);
2562 cexpr->cvarno = pstate->p_target_nsitem->p_rtindex;
2563
2564 /*
2565 * Check to see if the cursor name matches a parameter of type REFCURSOR.
2566 * If so, replace the raw name reference with a parameter reference. (This
2567 * is a hack for the convenience of plpgsql.)
2568 */
2569 if (cexpr->cursor_name != NULL) /* in case already transformed */
2570 {
2571 ColumnRef *cref = makeNode(ColumnRef);
2572 Node *node = NULL;
2573
2574 /* Build an unqualified ColumnRef with the given name */
2575 cref->fields = list_make1(makeString(cexpr->cursor_name));
2576 cref->location = -1;
2577
2578 /* See if there is a translation available from a parser hook */
2579 if (pstate->p_pre_columnref_hook != NULL)
2580 node = pstate->p_pre_columnref_hook(pstate, cref);
2581 if (node == NULL && pstate->p_post_columnref_hook != NULL)
2582 node = pstate->p_post_columnref_hook(pstate, cref, NULL);
2583
2584 /*
2585 * XXX Should we throw an error if we get a translation that isn't a
2586 * refcursor Param? For now it seems best to silently ignore false
2587 * matches.
2588 */
2589 if (node != NULL && IsA(node, Param))
2590 {
2591 Param *p = (Param *) node;
2592
2593 if (p->paramkind == PARAM_EXTERN &&
2594 p->paramtype == REFCURSOROID)
2595 {
2596 /* Matches, so convert CURRENT OF to a param reference */
2597 cexpr->cursor_name = NULL;
2598 cexpr->cursor_param = p->paramid;
2599 }
2600 }
2601 }
2602
2603 return (Node *) cexpr;
2604}
@ PARAM_EXTERN
Definition: primnodes.h:367
char * cursor_name
Definition: primnodes.h:2098
int paramid
Definition: primnodes.h:377
Oid paramtype
Definition: primnodes.h:378
ParamKind paramkind
Definition: primnodes.h:376
ParseNamespaceItem * p_target_nsitem
Definition: parse_node.h:226

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

137{
138 Node *result;
139
140 if (expr == NULL)
141 return NULL;
142
143 /* Guard against stack overflow due to overly complex expressions */
145
146 switch (nodeTag(expr))
147 {
148 case T_ColumnRef:
149 result = transformColumnRef(pstate, (ColumnRef *) expr);
150 break;
151
152 case T_ParamRef:
153 result = transformParamRef(pstate, (ParamRef *) expr);
154 break;
155
156 case T_A_Const:
157 result = (Node *) make_const(pstate, (A_Const *) expr);
158 break;
159
160 case T_A_Indirection:
161 result = transformIndirection(pstate, (A_Indirection *) expr);
162 break;
163
164 case T_A_ArrayExpr:
165 result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
167 break;
168
169 case T_TypeCast:
170 result = transformTypeCast(pstate, (TypeCast *) expr);
171 break;
172
173 case T_CollateClause:
174 result = transformCollateClause(pstate, (CollateClause *) expr);
175 break;
176
177 case T_A_Expr:
178 {
179 A_Expr *a = (A_Expr *) expr;
180
181 switch (a->kind)
182 {
183 case AEXPR_OP:
184 result = transformAExprOp(pstate, a);
185 break;
186 case AEXPR_OP_ANY:
187 result = transformAExprOpAny(pstate, a);
188 break;
189 case AEXPR_OP_ALL:
190 result = transformAExprOpAll(pstate, a);
191 break;
192 case AEXPR_DISTINCT:
194 result = transformAExprDistinct(pstate, a);
195 break;
196 case AEXPR_NULLIF:
197 result = transformAExprNullIf(pstate, a);
198 break;
199 case AEXPR_IN:
200 result = transformAExprIn(pstate, a);
201 break;
202 case AEXPR_LIKE:
203 case AEXPR_ILIKE:
204 case AEXPR_SIMILAR:
205 /* we can transform these just like AEXPR_OP */
206 result = transformAExprOp(pstate, a);
207 break;
208 case AEXPR_BETWEEN:
212 result = transformAExprBetween(pstate, a);
213 break;
214 default:
215 elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
216 result = NULL; /* keep compiler quiet */
217 break;
218 }
219 break;
220 }
221
222 case T_BoolExpr:
223 result = transformBoolExpr(pstate, (BoolExpr *) expr);
224 break;
225
226 case T_FuncCall:
227 result = transformFuncCall(pstate, (FuncCall *) expr);
228 break;
229
230 case T_MultiAssignRef:
231 result = transformMultiAssignRef(pstate, (MultiAssignRef *) expr);
232 break;
233
234 case T_GroupingFunc:
235 result = transformGroupingFunc(pstate, (GroupingFunc *) expr);
236 break;
237
238 case T_MergeSupportFunc:
239 result = transformMergeSupportFunc(pstate,
240 (MergeSupportFunc *) expr);
241 break;
242
243 case T_NamedArgExpr:
244 {
245 NamedArgExpr *na = (NamedArgExpr *) expr;
246
247 na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
248 result = expr;
249 break;
250 }
251
252 case T_SubLink:
253 result = transformSubLink(pstate, (SubLink *) expr);
254 break;
255
256 case T_CaseExpr:
257 result = transformCaseExpr(pstate, (CaseExpr *) expr);
258 break;
259
260 case T_RowExpr:
261 result = transformRowExpr(pstate, (RowExpr *) expr, false);
262 break;
263
264 case T_CoalesceExpr:
265 result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
266 break;
267
268 case T_MinMaxExpr:
269 result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
270 break;
271
272 case T_SQLValueFunction:
273 result = transformSQLValueFunction(pstate,
274 (SQLValueFunction *) expr);
275 break;
276
277 case T_XmlExpr:
278 result = transformXmlExpr(pstate, (XmlExpr *) expr);
279 break;
280
281 case T_XmlSerialize:
282 result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
283 break;
284
285 case T_NullTest:
286 {
287 NullTest *n = (NullTest *) expr;
288
289 n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
290 /* the argument can be any type, so don't coerce it */
291 n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
292 result = expr;
293 break;
294 }
295
296 case T_BooleanTest:
297 result = transformBooleanTest(pstate, (BooleanTest *) expr);
298 break;
299
300 case T_CurrentOfExpr:
301 result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
302 break;
303
304 /*
305 * In all places where DEFAULT is legal, the caller should have
306 * processed it rather than passing it to transformExpr().
307 */
308 case T_SetToDefault:
310 (errcode(ERRCODE_SYNTAX_ERROR),
311 errmsg("DEFAULT is not allowed in this context"),
312 parser_errposition(pstate,
313 ((SetToDefault *) expr)->location)));
314 break;
315
316 /*
317 * CaseTestExpr doesn't require any processing; it is only
318 * injected into parse trees in a fully-formed state.
319 *
320 * Ordinarily we should not see a Var here, but it is convenient
321 * for transformJoinUsingClause() to create untransformed operator
322 * trees containing already-transformed Vars. The best
323 * alternative would be to deconstruct and reconstruct column
324 * references, which seems expensively pointless. So allow it.
325 */
326 case T_CaseTestExpr:
327 case T_Var:
328 {
329 result = (Node *) expr;
330 break;
331 }
332
333 case T_JsonObjectConstructor:
334 result = transformJsonObjectConstructor(pstate, (JsonObjectConstructor *) expr);
335 break;
336
337 case T_JsonArrayConstructor:
338 result = transformJsonArrayConstructor(pstate, (JsonArrayConstructor *) expr);
339 break;
340
341 case T_JsonArrayQueryConstructor:
343 break;
344
345 case T_JsonObjectAgg:
346 result = transformJsonObjectAgg(pstate, (JsonObjectAgg *) expr);
347 break;
348
349 case T_JsonArrayAgg:
350 result = transformJsonArrayAgg(pstate, (JsonArrayAgg *) expr);
351 break;
352
353 case T_JsonIsPredicate:
354 result = transformJsonIsPredicate(pstate, (JsonIsPredicate *) expr);
355 break;
356
357 case T_JsonParseExpr:
358 result = transformJsonParseExpr(pstate, (JsonParseExpr *) expr);
359 break;
360
361 case T_JsonScalarExpr:
362 result = transformJsonScalarExpr(pstate, (JsonScalarExpr *) expr);
363 break;
364
365 case T_JsonSerializeExpr:
366 result = transformJsonSerializeExpr(pstate, (JsonSerializeExpr *) expr);
367 break;
368
369 case T_JsonFuncExpr:
370 result = transformJsonFuncExpr(pstate, (JsonFuncExpr *) expr);
371 break;
372
373 default:
374 /* should not reach here */
375 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
376 result = NULL; /* keep compiler quiet */
377 break;
378 }
379
380 return result;
381}
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2655
#define nodeTag(nodeptr)
Definition: nodes.h:133
Node * transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
Definition: parse_agg.c:265
static Node * transformMergeSupportFunc(ParseState *pstate, MergeSupportFunc *f)
Definition: parse_expr.c:1376
static Node * transformJsonArrayConstructor(ParseState *pstate, JsonArrayConstructor *ctor)
Definition: parse_expr.c:4000
static Node * transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
Definition: parse_expr.c:2558
static Node * transformAExprOpAll(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1016
static Node * transformJsonParseExpr(ParseState *pstate, JsonParseExpr *jsexpr)
Definition: parse_expr.c:4143
static Node * transformAExprIn(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1124
static Node * transformAExprOpAny(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1002
static Node * transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
Definition: parse_expr.c:2474
static Node * transformAExprNullIf(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1081
static Node * transformJsonScalarExpr(ParseState *pstate, JsonScalarExpr *jsexpr)
Definition: parse_expr.c:4192
static Node * transformJsonArrayQueryConstructor(ParseState *pstate, JsonArrayQueryConstructor *ctor)
Definition: parse_expr.c:3741
static Node * transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf)
Definition: parse_expr.c:2292
static Node * transformColumnRef(ParseState *pstate, ColumnRef *cref)
Definition: parse_expr.c:508
static Node * transformCollateClause(ParseState *pstate, CollateClause *c)
Definition: parse_expr.c:2766
static Node * transformBoolExpr(ParseState *pstate, BoolExpr *a)
Definition: parse_expr.c:1401
static Node * transformFuncCall(ParseState *pstate, FuncCall *fn)
Definition: parse_expr.c:1437
static Node * transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
Definition: parse_expr.c:2253
static Node * transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
Definition: parse_expr.c:2204
static Node * transformSubLink(ParseState *pstate, SubLink *sublink)
Definition: parse_expr.c:1770
static Node * transformJsonObjectConstructor(ParseState *pstate, JsonObjectConstructor *ctor)
Definition: parse_expr.c:3704
static Node * transformAExprOp(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:921
static Node * transformJsonArrayAgg(ParseState *pstate, JsonArrayAgg *agg)
Definition: parse_expr.c:3962
static Node * transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
Definition: parse_expr.c:1482
static Node * transformBooleanTest(ParseState *pstate, BooleanTest *b)
Definition: parse_expr.c:2518
static Node * transformTypeCast(ParseState *pstate, TypeCast *tc)
Definition: parse_expr.c:2682
static Node * transformParamRef(ParseState *pstate, ParamRef *pref)
Definition: parse_expr.c:884
static Node * transformCaseExpr(ParseState *pstate, CaseExpr *c)
Definition: parse_expr.c:1630
static Node * transformIndirection(ParseState *pstate, A_Indirection *ind)
Definition: parse_expr.c:436
static Node * transformJsonSerializeExpr(ParseState *pstate, JsonSerializeExpr *expr)
Definition: parse_expr.c:4215
static Node * transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
Definition: parse_expr.c:2166
static Node * transformXmlExpr(ParseState *pstate, XmlExpr *x)
Definition: parse_expr.c:2345
static Node * transformAExprBetween(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1282
static Node * transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
Definition: parse_expr.c:4261
static Node * transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
Definition: parse_expr.c:4080
static Node * transformJsonObjectAgg(ParseState *pstate, JsonObjectAgg *agg)
Definition: parse_expr.c:3898
static Node * transformAExprDistinct(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1030
Const * make_const(ParseState *pstate, A_Const *aconst)
Definition: parse_node.c:347
@ AEXPR_NULLIF
Definition: parsenodes.h:320
@ AEXPR_ILIKE
Definition: parsenodes.h:323
@ AEXPR_IN
Definition: parsenodes.h:321
@ AEXPR_DISTINCT
Definition: parsenodes.h:318
@ AEXPR_SIMILAR
Definition: parsenodes.h:324
@ AEXPR_LIKE
Definition: parsenodes.h:322
@ AEXPR_OP_ANY
Definition: parsenodes.h:316
@ AEXPR_OP_ALL
Definition: parsenodes.h:317
void check_stack_depth(void)
Definition: stack_depth.c:95
Expr * arg
Definition: primnodes.h:791

References a, AEXPR_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_DISTINCT, AEXPR_ILIKE, AEXPR_IN, AEXPR_LIKE, AEXPR_NOT_BETWEEN, AEXPR_NOT_BETWEEN_SYM, AEXPR_NOT_DISTINCT, AEXPR_NULLIF, AEXPR_OP, AEXPR_OP_ALL, AEXPR_OP_ANY, AEXPR_SIMILAR, NamedArgExpr::arg, NullTest::arg, check_stack_depth(), elog, ereport, errcode(), errmsg(), ERROR, exprType(), InvalidOid, make_const(), nodeTag, parser_errposition(), transformAExprBetween(), transformAExprDistinct(), transformAExprIn(), transformAExprNullIf(), transformAExprOp(), transformAExprOpAll(), transformAExprOpAny(), transformArrayExpr(), transformBooleanTest(), transformBoolExpr(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformColumnRef(), transformCurrentOfExpr(), transformExprRecurse(), transformFuncCall(), transformGroupingFunc(), transformIndirection(), transformJsonArrayAgg(), transformJsonArrayConstructor(), transformJsonArrayQueryConstructor(), transformJsonFuncExpr(), transformJsonIsPredicate(), transformJsonObjectAgg(), transformJsonObjectConstructor(), transformJsonParseExpr(), transformJsonScalarExpr(), transformJsonSerializeExpr(), transformMergeSupportFunc(), 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(), transformExprRecurse(), transformFuncCall(), transformIndirection(), transformJsonArrayQueryConstructor(), transformJsonBehavior(), transformJsonFuncExpr(), transformJsonObjectAgg(), transformJsonObjectConstructor(), transformJsonParseArg(), transformJsonScalarExpr(), transformJsonValueExpr(), transformMinMaxExpr(), transformMultiAssignRef(), transformSubLink(), transformTypeCast(), transformXmlExpr(), and transformXmlSerialize().

◆ transformFuncCall()

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

Definition at line 1437 of file parse_expr.c.

1438{
1439 Node *last_srf = pstate->p_last_srf;
1440 List *targs;
1441 ListCell *args;
1442
1443 /* Transform the list of arguments ... */
1444 targs = NIL;
1445 foreach(args, fn->args)
1446 {
1447 targs = lappend(targs, transformExprRecurse(pstate,
1448 (Node *) lfirst(args)));
1449 }
1450
1451 /*
1452 * When WITHIN GROUP is used, we treat its ORDER BY expressions as
1453 * additional arguments to the function, for purposes of function lookup
1454 * and argument type coercion. So, transform each such expression and add
1455 * them to the targs list. We don't explicitly mark where each argument
1456 * came from, but ParseFuncOrColumn can tell what's what by reference to
1457 * list_length(fn->agg_order).
1458 */
1459 if (fn->agg_within_group)
1460 {
1461 Assert(fn->agg_order != NIL);
1462 foreach(args, fn->agg_order)
1463 {
1464 SortBy *arg = (SortBy *) lfirst(args);
1465
1466 targs = lappend(targs, transformExpr(pstate, arg->node,
1468 }
1469 }
1470
1471 /* ... and hand off to ParseFuncOrColumn */
1472 return ParseFuncOrColumn(pstate,
1473 fn->funcname,
1474 targs,
1475 last_srf,
1476 fn,
1477 false,
1478 fn->location);
1479}
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:118
static void * fn(void *arg)
Definition: thread-alloc.c:119

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

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

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

Referenced by transformExprRecurse().

◆ transformJsonAggConstructor()

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

Definition at line 3812 of file parse_expr.c.

3817{
3818 Node *node;
3819 Expr *aggfilter;
3820
3821 aggfilter = agg_ctor->agg_filter ? (Expr *)
3822 transformWhereClause(pstate, agg_ctor->agg_filter,
3823 EXPR_KIND_FILTER, "FILTER") : NULL;
3824
3825 if (agg_ctor->over)
3826 {
3827 /* window function */
3828 WindowFunc *wfunc = makeNode(WindowFunc);
3829
3830 wfunc->winfnoid = aggfnoid;
3831 wfunc->wintype = aggtype;
3832 /* wincollid and inputcollid will be set by parse_collate.c */
3833 wfunc->args = args;
3834 wfunc->aggfilter = aggfilter;
3835 wfunc->runCondition = NIL;
3836 /* winref will be set by transformWindowFuncCall */
3837 wfunc->winstar = false;
3838 wfunc->winagg = true;
3839 wfunc->location = agg_ctor->location;
3840
3841 /*
3842 * ordered aggs not allowed in windows yet
3843 */
3844 if (agg_ctor->agg_order != NIL)
3845 ereport(ERROR,
3846 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3847 errmsg("aggregate ORDER BY is not implemented for window functions"),
3848 parser_errposition(pstate, agg_ctor->location));
3849
3850 /* parse_agg.c does additional window-func-specific processing */
3851 transformWindowFuncCall(pstate, wfunc, agg_ctor->over);
3852
3853 node = (Node *) wfunc;
3854 }
3855 else
3856 {
3857 Aggref *aggref = makeNode(Aggref);
3858
3859 aggref->aggfnoid = aggfnoid;
3860 aggref->aggtype = aggtype;
3861
3862 /* aggcollid and inputcollid will be set by parse_collate.c */
3863 /* aggtranstype will be set by planner */
3864 /* aggargtypes will be set by transformAggregateCall */
3865 /* aggdirectargs and args will be set by transformAggregateCall */
3866 /* aggorder and aggdistinct will be set by transformAggregateCall */
3867 aggref->aggfilter = aggfilter;
3868 aggref->aggstar = false;
3869 aggref->aggvariadic = false;
3870 aggref->aggkind = AGGKIND_NORMAL;
3871 aggref->aggpresorted = false;
3872 /* agglevelsup will be set by transformAggregateCall */
3873 aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
3874 aggref->aggno = -1; /* planner will set aggno and aggtransno */
3875 aggref->aggtransno = -1;
3876 aggref->location = agg_ctor->location;
3877
3878 transformAggregateCall(pstate, aggref, args, agg_ctor->agg_order, false);
3879
3880 node = (Node *) aggref;
3881 }
3882
3883 return makeJsonConstructorExpr(pstate, ctor_type, NIL, (Expr *) node,
3884 returning, unique, absent_on_null,
3885 agg_ctor->location);
3886}
@ AGGSPLIT_SIMPLE
Definition: nodes.h:377
void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, WindowDef *windef)
Definition: parse_agg.c:825
void transformAggregateCall(ParseState *pstate, Aggref *agg, List *args, List *aggorder, bool agg_distinct)
Definition: parse_agg.c:109
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:3644
Oid aggfnoid
Definition: primnodes.h:444
Expr * aggfilter
Definition: primnodes.h:477
ParseLoc location
Definition: primnodes.h:507
struct WindowDef * over
Definition: parsenodes.h:1968
List * args
Definition: primnodes.h:575
Expr * aggfilter
Definition: primnodes.h:577
ParseLoc location
Definition: primnodes.h:587
Oid winfnoid
Definition: primnodes.h:567

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

Referenced by transformJsonArrayAgg(), and transformJsonObjectAgg().

◆ transformJsonArrayAgg()

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

Definition at line 3962 of file parse_expr.c.

3963{
3964 JsonReturning *returning;
3965 Node *arg;
3966 Oid aggfnoid;
3967 Oid aggtype;
3968
3969 arg = transformJsonValueExpr(pstate, "JSON_ARRAYAGG()", agg->arg,
3971
3972 returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
3973 list_make1(arg));
3974
3975 if (returning->format->format_type == JS_FORMAT_JSONB)
3976 {
3977 aggfnoid = agg->absent_on_null ? F_JSONB_AGG_STRICT : F_JSONB_AGG;
3978 aggtype = JSONBOID;
3979 }
3980 else
3981 {
3982 aggfnoid = agg->absent_on_null ? F_JSON_AGG_STRICT : F_JSON_AGG;
3983 aggtype = JSONOID;
3984 }
3985
3986 return transformJsonAggConstructor(pstate, agg->constructor, returning,
3987 list_make1(arg), aggfnoid, aggtype,
3989 false, agg->absent_on_null);
3990}
static JsonReturning * transformJsonConstructorOutput(ParseState *pstate, JsonOutput *output, List *args)
Definition: parse_expr.c:3537
static Node * transformJsonAggConstructor(ParseState *pstate, JsonAggConstructor *agg_ctor, JsonReturning *returning, List *args, Oid aggfnoid, Oid aggtype, JsonConstructorType ctor_type, bool unique, bool absent_on_null)
Definition: parse_expr.c:3812
static Node * transformJsonValueExpr(ParseState *pstate, const char *constructName, JsonValueExpr *ve, JsonFormatType default_format, Oid targettype, bool isarg)
Definition: parse_expr.c:3278
@ JSCTOR_JSON_ARRAYAGG
Definition: primnodes.h:1693
JsonOutput * output
Definition: parsenodes.h:1965
bool absent_on_null
Definition: parsenodes.h:1994
JsonValueExpr * arg
Definition: parsenodes.h:1993
JsonAggConstructor * constructor
Definition: parsenodes.h:1992

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

Referenced by transformExprRecurse().

◆ transformJsonArrayConstructor()

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

Definition at line 4000 of file parse_expr.c.

4001{
4002 JsonReturning *returning;
4003 List *args = NIL;
4004
4005 /* transform element expressions, if any */
4006 if (ctor->exprs)
4007 {
4008 ListCell *lc;
4009
4010 /* transform and append element arguments */
4011 foreach(lc, ctor->exprs)
4012 {
4014 Node *val = transformJsonValueExpr(pstate, "JSON_ARRAY()",
4015 jsval, JS_FORMAT_DEFAULT,
4016 InvalidOid, false);
4017
4018 args = lappend(args, val);
4019 }
4020 }
4021
4022 returning = transformJsonConstructorOutput(pstate, ctor->output, args);
4023
4024 return makeJsonConstructorExpr(pstate, JSCTOR_JSON_ARRAY, args, NULL,
4025 returning, false, ctor->absent_on_null,
4026 ctor->location);
4027}
@ JSCTOR_JSON_ARRAY
Definition: primnodes.h:1691
JsonOutput * output
Definition: parsenodes.h:1938

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

Referenced by transformExprRecurse().

◆ transformJsonArrayQueryConstructor()

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

Definition at line 3741 of file parse_expr.c.

3743{
3744 SubLink *sublink = makeNode(SubLink);
3747 Alias *alias = makeNode(Alias);
3748 ResTarget *target = makeNode(ResTarget);
3750 ColumnRef *colref = makeNode(ColumnRef);
3751 Query *query;
3752 ParseState *qpstate;
3753
3754 /* Transform query only for counting target list entries. */
3755 qpstate = make_parsestate(pstate);
3756
3757 query = transformStmt(qpstate, ctor->query);
3758
3759 if (count_nonjunk_tlist_entries(query->targetList) != 1)
3760 ereport(ERROR,
3761 errcode(ERRCODE_SYNTAX_ERROR),
3762 errmsg("subquery must return only one column"),
3763 parser_errposition(pstate, ctor->location));
3764
3765 free_parsestate(qpstate);
3766
3767 colref->fields = list_make2(makeString(pstrdup("q")),
3768 makeString(pstrdup("a")));
3769 colref->location = ctor->location;
3770
3771 /*
3772 * No formatting necessary, so set formatted_expr to be the same as
3773 * raw_expr.
3774 */
3775 agg->arg = makeJsonValueExpr((Expr *) colref, (Expr *) colref,
3776 ctor->format);
3777 agg->absent_on_null = ctor->absent_on_null;
3779 agg->constructor->agg_order = NIL;
3780 agg->constructor->output = ctor->output;
3781 agg->constructor->location = ctor->location;
3782
3783 target->name = NULL;
3784 target->indirection = NIL;
3785 target->val = (Node *) agg;
3786 target->location = ctor->location;
3787
3788 alias->aliasname = pstrdup("q");
3789 alias->colnames = list_make1(makeString(pstrdup("a")));
3790
3791 range->lateral = false;
3792 range->subquery = ctor->query;
3793 range->alias = alias;
3794
3795 select->targetList = list_make1(target);
3796 select->fromClause = list_make1(range);
3797
3798 sublink->subLinkType = EXPR_SUBLINK;
3799 sublink->subLinkId = 0;
3800 sublink->testexpr = NULL;
3801 sublink->operName = NIL;
3802 sublink->subselect = (Node *) select;
3803 sublink->location = ctor->location;
3804
3805 return transformExprRecurse(pstate, (Node *) sublink);
3806}
JsonValueExpr * makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr, JsonFormat *format)
Definition: makefuncs.c:889
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:72
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:39
Query * transformStmt(ParseState *pstate, Node *parseTree)
Definition: analyze.c:396
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
char * aliasname
Definition: primnodes.h:50
List * colnames
Definition: primnodes.h:51
List * targetList
Definition: parsenodes.h:193
Node * val
Definition: parsenodes.h:521
ParseLoc location
Definition: parsenodes.h:522
List * indirection
Definition: parsenodes.h:520
char * name
Definition: parsenodes.h:519
int count_nonjunk_tlist_entries(List *tlist)
Definition: tlist.c:186
#define select(n, r, w, e, timeout)
Definition: win32_port.h:511

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

Referenced by transformExprRecurse().

◆ transformJsonBehavior()

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

Definition at line 4686 of file parse_expr.c.

4689{
4690 JsonBehaviorType btype = default_behavior;
4691 Node *expr = NULL;
4692 bool coerce_at_runtime = false;
4693 int location = -1;
4694
4695 if (behavior)
4696 {
4697 btype = behavior->btype;
4698 location = behavior->location;
4699 if (btype == JSON_BEHAVIOR_DEFAULT)
4700 {
4701 expr = transformExprRecurse(pstate, behavior->expr);
4702 if (!ValidJsonBehaviorDefaultExpr(expr, NULL))
4703 ereport(ERROR,
4704 (errcode(ERRCODE_DATATYPE_MISMATCH),
4705 errmsg("can only specify a constant, non-aggregate function, or operator expression for DEFAULT"),
4706 parser_errposition(pstate, exprLocation(expr))));
4707 if (contain_var_clause(expr))
4708 ereport(ERROR,
4709 (errcode(ERRCODE_DATATYPE_MISMATCH),
4710 errmsg("DEFAULT expression must not contain column references"),
4711 parser_errposition(pstate, exprLocation(expr))));
4712 if (expression_returns_set(expr))
4713 ereport(ERROR,
4714 (errcode(ERRCODE_DATATYPE_MISMATCH),
4715 errmsg("DEFAULT expression must not return a set"),
4716 parser_errposition(pstate, exprLocation(expr))));
4717 }
4718 }
4719
4720 if (expr == NULL && btype != JSON_BEHAVIOR_ERROR)
4721 expr = GetJsonBehaviorConst(btype, location);
4722
4723 /*
4724 * Try to coerce the expression if needed.
4725 *
4726 * Use runtime coercion using json_populate_type() if the expression is
4727 * NULL, jsonb-valued, or boolean-valued (unless the target type is
4728 * integer or domain over integer, in which case use the
4729 * boolean-to-integer cast function).
4730 *
4731 * For other non-NULL expressions, try to find a cast and error out if one
4732 * is not found.
4733 */
4734 if (expr && exprType(expr) != returning->typid)
4735 {
4736 bool isnull = (IsA(expr, Const) && ((Const *) expr)->constisnull);
4737
4738 if (isnull ||
4739 exprType(expr) == JSONBOID ||
4740 (exprType(expr) == BOOLOID &&
4741 getBaseType(returning->typid) != INT4OID))
4742 {
4743 coerce_at_runtime = true;
4744
4745 /*
4746 * json_populate_type() expects to be passed a jsonb value, so gin
4747 * up a Const containing the appropriate boolean value represented
4748 * as jsonb, discarding the original Const containing a plain
4749 * boolean.
4750 */
4751 if (exprType(expr) == BOOLOID)
4752 {
4753 char *val = btype == JSON_BEHAVIOR_TRUE ? "true" : "false";
4754
4755 expr = (Node *) makeConst(JSONBOID, -1, InvalidOid, -1,
4758 false, false);
4759 }
4760 }
4761 else
4762 {
4763 Node *coerced_expr;
4764 char typcategory = TypeCategory(returning->typid);
4765
4766 /*
4767 * Use an assignment cast if coercing to a string type so that
4768 * build_coercion_expression() assumes implicit coercion when
4769 * coercing the typmod, so that inputs exceeding length cause an
4770 * error instead of silent truncation.
4771 */
4772 coerced_expr =
4773 coerce_to_target_type(pstate, expr, exprType(expr),
4774 returning->typid, returning->typmod,
4775 (typcategory == TYPCATEGORY_STRING ||
4776 typcategory == TYPCATEGORY_BITSTRING) ?
4780 exprLocation((Node *) behavior));
4781
4782 if (coerced_expr == NULL)
4783 {
4784 /*
4785 * Provide a HINT if the expression comes from a DEFAULT
4786 * clause.
4787 */
4788 if (btype == JSON_BEHAVIOR_DEFAULT)
4789 ereport(ERROR,
4790 errcode(ERRCODE_CANNOT_COERCE),
4791 errmsg("cannot cast behavior expression of type %s to %s",
4792 format_type_be(exprType(expr)),
4793 format_type_be(returning->typid)),
4794 errhint("You will need to explicitly cast the expression to type %s.",
4795 format_type_be(returning->typid)),
4796 parser_errposition(pstate, exprLocation(expr)));
4797 else
4798 ereport(ERROR,
4799 errcode(ERRCODE_CANNOT_COERCE),
4800 errmsg("cannot cast behavior expression of type %s to %s",
4801 format_type_be(exprType(expr)),
4802 format_type_be(returning->typid)),
4803 parser_errposition(pstate, exprLocation(expr)));
4804 }
4805
4806 expr = coerced_expr;
4807 }
4808 }
4809
4810 if (behavior)
4811 behavior->expr = expr;
4812 else
4813 behavior = makeJsonBehavior(btype, expr, location);
4814
4815 behavior->coerce = coerce_at_runtime;
4816
4817 return behavior;
4818}
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2521
JsonBehavior * makeJsonBehavior(JsonBehaviorType btype, Node *expr, int location)
Definition: makefuncs.c:906
TYPCATEGORY TypeCategory(Oid type)
static bool ValidJsonBehaviorDefaultExpr(Node *expr, void *context)
Definition: parse_expr.c:4653
static Node * GetJsonBehaviorConst(JsonBehaviorType btype, int location)
Definition: parse_expr.c:4825
JsonBehaviorType
Definition: primnodes.h:1764
Node * expr
Definition: primnodes.h:1791
ParseLoc location
Definition: primnodes.h:1793
JsonBehaviorType btype
Definition: primnodes.h:1790
bool contain_var_clause(Node *node)
Definition: var.c:405

References JsonBehavior::btype, JsonBehavior::coerce, COERCE_EXPLICIT_CAST, coerce_to_target_type(), COERCION_ASSIGNMENT, COERCION_EXPLICIT, contain_var_clause(), CStringGetDatum(), DirectFunctionCall1, ereport, errcode(), errhint(), errmsg(), ERROR, JsonBehavior::expr, expression_returns_set(), exprLocation(), exprType(), format_type_be(), getBaseType(), GetJsonBehaviorConst(), InvalidOid, IsA, JSON_BEHAVIOR_DEFAULT, JSON_BEHAVIOR_ERROR, JSON_BEHAVIOR_TRUE, jsonb_in(), JsonBehavior::location, makeConst(), makeJsonBehavior(), parser_errposition(), transformExprRecurse(), TypeCategory(), JsonReturning::typid, JsonReturning::typmod, val, and ValidJsonBehaviorDefaultExpr().

Referenced by transformJsonFuncExpr().

◆ transformJsonConstructorOutput()

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

Definition at line 3537 of file parse_expr.c.

3539{
3540 JsonReturning *returning = transformJsonOutput(pstate, output, true);
3541
3542 if (!OidIsValid(returning->typid))
3543 {
3544 ListCell *lc;
3545 bool have_jsonb = false;
3546
3547 foreach(lc, args)
3548 {
3549 Node *expr = lfirst(lc);
3550 Oid typid = exprType(expr);
3551
3552 have_jsonb |= typid == JSONBOID;
3553
3554 if (have_jsonb)
3555 break;
3556 }
3557
3558 if (have_jsonb)
3559 {
3560 returning->typid = JSONBOID;
3561 returning->format->format_type = JS_FORMAT_JSONB;
3562 }
3563 else
3564 {
3565 /* XXX TEXT is default by the standard, but we return JSON */
3566 returning->typid = JSONOID;
3567 returning->format->format_type = JS_FORMAT_JSON;
3568 }
3569
3570 returning->typmod = -1;
3571 }
3572
3573 return returning;
3574}
FILE * output
static JsonReturning * transformJsonOutput(ParseState *pstate, const JsonOutput *output, bool allow_format)
Definition: parse_expr.c:3490

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

◆ transformJsonFuncExpr()

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

Definition at line 4261 of file parse_expr.c.

4262{
4263 JsonExpr *jsexpr;
4264 Node *path_spec;
4265 const char *func_name = NULL;
4266 JsonFormatType default_format;
4267
4268 switch (func->op)
4269 {
4270 case JSON_EXISTS_OP:
4271 func_name = "JSON_EXISTS";
4272 default_format = JS_FORMAT_DEFAULT;
4273 break;
4274 case JSON_QUERY_OP:
4275 func_name = "JSON_QUERY";
4276 default_format = JS_FORMAT_JSONB;
4277 break;
4278 case JSON_VALUE_OP:
4279 func_name = "JSON_VALUE";
4280 default_format = JS_FORMAT_DEFAULT;
4281 break;
4282 case JSON_TABLE_OP:
4283 func_name = "JSON_TABLE";
4284 default_format = JS_FORMAT_JSONB;
4285 break;
4286 default:
4287 elog(ERROR, "invalid JsonFuncExpr op %d", (int) func->op);
4288 default_format = JS_FORMAT_DEFAULT; /* keep compiler quiet */
4289 break;
4290 }
4291
4292 /*
4293 * Even though the syntax allows it, FORMAT JSON specification in
4294 * RETURNING is meaningless except for JSON_QUERY(). Flag if not
4295 * JSON_QUERY().
4296 */
4297 if (func->output && func->op != JSON_QUERY_OP)
4298 {
4300
4301 if (format->format_type != JS_FORMAT_DEFAULT ||
4302 format->encoding != JS_ENC_DEFAULT)
4303 ereport(ERROR,
4304 errcode(ERRCODE_SYNTAX_ERROR),
4305 errmsg("cannot specify FORMAT JSON in RETURNING clause of %s()",
4306 func_name),
4307 parser_errposition(pstate, format->location));
4308 }
4309
4310 /* OMIT QUOTES is meaningless when strings are wrapped. */
4311 if (func->op == JSON_QUERY_OP)
4312 {
4313 if (func->quotes == JS_QUOTES_OMIT &&
4314 (func->wrapper == JSW_CONDITIONAL ||
4315 func->wrapper == JSW_UNCONDITIONAL))
4316 ereport(ERROR,
4317 errcode(ERRCODE_SYNTAX_ERROR),
4318 errmsg("SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used"),
4319 parser_errposition(pstate, func->location));
4320 if (func->on_empty != NULL &&
4322 func->on_empty->btype != JSON_BEHAVIOR_NULL &&
4327 {
4328 if (func->column_name == NULL)
4329 ereport(ERROR,
4330 errcode(ERRCODE_SYNTAX_ERROR),
4331 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4332 errmsg("invalid %s behavior", "ON EMPTY"),
4333 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
4334 second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
4335 errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s.",
4336 "ON EMPTY", "JSON_QUERY()"),
4337 parser_errposition(pstate, func->on_empty->location));
4338 else
4339 ereport(ERROR,
4340 errcode(ERRCODE_SYNTAX_ERROR),
4341 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4342 errmsg("invalid %s behavior for column \"%s\"",
4343 "ON EMPTY", func->column_name),
4344 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4345 errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns.",
4346 "ON EMPTY"),
4347 parser_errposition(pstate, func->on_empty->location));
4348 }
4349 if (func->on_error != NULL &&
4351 func->on_error->btype != JSON_BEHAVIOR_NULL &&
4356 {
4357 if (func->column_name == NULL)
4358 ereport(ERROR,
4359 errcode(ERRCODE_SYNTAX_ERROR),
4360 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4361 errmsg("invalid %s behavior", "ON ERROR"),
4362 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
4363 second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
4364 errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for %s.",
4365 "ON ERROR", "JSON_QUERY()"),
4366 parser_errposition(pstate, func->on_error->location));
4367 else
4368 ereport(ERROR,
4369 errcode(ERRCODE_SYNTAX_ERROR),
4370 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4371 errmsg("invalid %s behavior for column \"%s\"",
4372 "ON ERROR", func->column_name),
4373 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4374 errdetail("Only ERROR, NULL, EMPTY ARRAY, EMPTY OBJECT, or DEFAULT expression is allowed in %s for formatted columns.",
4375 "ON ERROR"),
4376 parser_errposition(pstate, func->on_error->location));
4377 }
4378 }
4379
4380 /* Check that ON ERROR/EMPTY behavior values are valid for the function. */
4381 if (func->op == JSON_EXISTS_OP &&
4382 func->on_error != NULL &&
4384 func->on_error->btype != JSON_BEHAVIOR_TRUE &&
4387 {
4388 if (func->column_name == NULL)
4389 ereport(ERROR,
4390 errcode(ERRCODE_SYNTAX_ERROR),
4391 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4392 errmsg("invalid %s behavior", "ON ERROR"),
4393 errdetail("Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for %s.",
4394 "ON ERROR", "JSON_EXISTS()"),
4395 parser_errposition(pstate, func->on_error->location));
4396 else
4397 ereport(ERROR,
4398 errcode(ERRCODE_SYNTAX_ERROR),
4399 /*- translator: first %s is name a SQL/JSON clause (eg. ON EMPTY) */
4400 errmsg("invalid %s behavior for column \"%s\"",
4401 "ON ERROR", func->column_name),
4402 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4403 errdetail("Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in %s for EXISTS columns.",
4404 "ON ERROR"),
4405 parser_errposition(pstate, func->on_error->location));
4406 }
4407 if (func->op == JSON_VALUE_OP)
4408 {
4409 if (func->on_empty != NULL &&
4411 func->on_empty->btype != JSON_BEHAVIOR_NULL &&
4413 {
4414 if (func->column_name == NULL)
4415 ereport(ERROR,
4416 errcode(ERRCODE_SYNTAX_ERROR),
4417 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4418 errmsg("invalid %s behavior", "ON EMPTY"),
4419 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
4420 second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
4421 errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s.",
4422 "ON EMPTY", "JSON_VALUE()"),
4423 parser_errposition(pstate, func->on_empty->location));
4424 else
4425 ereport(ERROR,
4426 errcode(ERRCODE_SYNTAX_ERROR),
4427 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4428 errmsg("invalid %s behavior for column \"%s\"",
4429 "ON EMPTY", func->column_name),
4430 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4431 errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns.",
4432 "ON EMPTY"),
4433 parser_errposition(pstate, func->on_empty->location));
4434 }
4435 if (func->on_error != NULL &&
4437 func->on_error->btype != JSON_BEHAVIOR_NULL &&
4439 {
4440 if (func->column_name == NULL)
4441 ereport(ERROR,
4442 errcode(ERRCODE_SYNTAX_ERROR),
4443 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4444 errmsg("invalid %s behavior", "ON ERROR"),
4445 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY),
4446 second %s is a SQL/JSON function name (e.g. JSON_QUERY) */
4447 errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for %s.",
4448 "ON ERROR", "JSON_VALUE()"),
4449 parser_errposition(pstate, func->on_error->location));
4450 else
4451 ereport(ERROR,
4452 errcode(ERRCODE_SYNTAX_ERROR),
4453 /*- translator: first %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4454 errmsg("invalid %s behavior for column \"%s\"",
4455 "ON ERROR", func->column_name),
4456 /*- translator: %s is name of a SQL/JSON clause (eg. ON EMPTY) */
4457 errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in %s for scalar columns.",
4458 "ON ERROR"),
4459 parser_errposition(pstate, func->on_error->location));
4460 }
4461 }
4462
4463 jsexpr = makeNode(JsonExpr);
4464 jsexpr->location = func->location;
4465 jsexpr->op = func->op;
4466 jsexpr->column_name = func->column_name;
4467
4468 /*
4469 * jsonpath machinery can only handle jsonb documents, so coerce the input
4470 * if not already of jsonb type.
4471 */
4472 jsexpr->formatted_expr = transformJsonValueExpr(pstate, func_name,
4473 func->context_item,
4474 default_format,
4475 JSONBOID,
4476 false);
4477 jsexpr->format = func->context_item->format;
4478
4479 path_spec = transformExprRecurse(pstate, func->pathspec);
4480 path_spec = coerce_to_target_type(pstate, path_spec, exprType(path_spec),
4481 JSONPATHOID, -1,
4483 exprLocation(path_spec));
4484 if (path_spec == NULL)
4485 ereport(ERROR,
4486 (errcode(ERRCODE_DATATYPE_MISMATCH),
4487 errmsg("JSON path expression must be of type %s, not of type %s",
4488 "jsonpath", format_type_be(exprType(path_spec))),
4489 parser_errposition(pstate, exprLocation(path_spec))));
4490 jsexpr->path_spec = path_spec;
4491
4492 /* Transform and coerce the PASSING arguments to jsonb. */
4493 transformJsonPassingArgs(pstate, func_name,
4495 func->passing,
4496 &jsexpr->passing_values,
4497 &jsexpr->passing_names);
4498
4499 /* Transform the JsonOutput into JsonReturning. */
4500 jsexpr->returning = transformJsonOutput(pstate, func->output, false);
4501
4502 switch (func->op)
4503 {
4504 case JSON_EXISTS_OP:
4505 /* JSON_EXISTS returns boolean by default. */
4506 if (!OidIsValid(jsexpr->returning->typid))
4507 {
4508 jsexpr->returning->typid = BOOLOID;
4509 jsexpr->returning->typmod = -1;
4510 }
4511
4512 /* JSON_TABLE() COLUMNS can specify a non-boolean type. */
4513 if (jsexpr->returning->typid != BOOLOID)
4514 jsexpr->use_json_coercion = true;
4515
4516 jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4518 jsexpr->returning);
4519 break;
4520
4521 case JSON_QUERY_OP:
4522 /* JSON_QUERY returns jsonb by default. */
4523 if (!OidIsValid(jsexpr->returning->typid))
4524 {
4525 JsonReturning *ret = jsexpr->returning;
4526
4527 ret->typid = JSONBOID;
4528 ret->typmod = -1;
4529 }
4530
4531 /*
4532 * Keep quotes on scalar strings by default, omitting them only if
4533 * OMIT QUOTES is specified.
4534 */
4535 jsexpr->omit_quotes = (func->quotes == JS_QUOTES_OMIT);
4536 jsexpr->wrapper = func->wrapper;
4537
4538 /*
4539 * Set up to coerce the result value of JsonPathValue() to the
4540 * RETURNING type (default or user-specified), if needed. Also if
4541 * OMIT QUOTES is specified.
4542 */
4543 if (jsexpr->returning->typid != JSONBOID || jsexpr->omit_quotes)
4544 jsexpr->use_json_coercion = true;
4545
4546 /* Assume NULL ON EMPTY when ON EMPTY is not specified. */
4547 jsexpr->on_empty = transformJsonBehavior(pstate, func->on_empty,
4549 jsexpr->returning);
4550 /* Assume NULL ON ERROR when ON ERROR is not specified. */
4551 jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4553 jsexpr->returning);
4554 break;
4555
4556 case JSON_VALUE_OP:
4557 /* JSON_VALUE returns text by default. */
4558 if (!OidIsValid(jsexpr->returning->typid))
4559 {
4560 jsexpr->returning->typid = TEXTOID;
4561 jsexpr->returning->typmod = -1;
4562 }
4563
4564 /*
4565 * Override whatever transformJsonOutput() set these to, which
4566 * assumes that output type to be jsonb.
4567 */
4570
4571 /* Always omit quotes from scalar strings. */
4572 jsexpr->omit_quotes = true;
4573
4574 /*
4575 * Set up to coerce the result value of JsonPathValue() to the
4576 * RETURNING type (default or user-specified), if needed.
4577 */
4578 if (jsexpr->returning->typid != TEXTOID)
4579 {
4580 if (get_typtype(jsexpr->returning->typid) == TYPTYPE_DOMAIN &&
4582 jsexpr->use_json_coercion = true;
4583 else
4584 jsexpr->use_io_coercion = true;
4585 }
4586
4587 /* Assume NULL ON EMPTY when ON EMPTY is not specified. */
4588 jsexpr->on_empty = transformJsonBehavior(pstate, func->on_empty,
4590 jsexpr->returning);
4591 /* Assume NULL ON ERROR when ON ERROR is not specified. */
4592 jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4594 jsexpr->returning);
4595 break;
4596
4597 case JSON_TABLE_OP:
4598 if (!OidIsValid(jsexpr->returning->typid))
4599 {
4600 jsexpr->returning->typid = exprType(jsexpr->formatted_expr);
4601 jsexpr->returning->typmod = -1;
4602 }
4603
4604 /*
4605 * Assume EMPTY ARRAY ON ERROR when ON ERROR is not specified.
4606 *
4607 * ON EMPTY cannot be specified at the top level but it can be for
4608 * the individual columns.
4609 */
4610 jsexpr->on_error = transformJsonBehavior(pstate, func->on_error,
4612 jsexpr->returning);
4613 break;
4614
4615 default:
4616 elog(ERROR, "invalid JsonFuncExpr op %d", (int) func->op);
4617 break;
4618 }
4619
4620 return (Node *) jsexpr;
4621}
char get_typtype(Oid typid)
Definition: lsyscache.c:2629
static void transformJsonPassingArgs(ParseState *pstate, const char *constructName, JsonFormatType format, List *args, List **passing_values, List **passing_names)
Definition: parse_expr.c:4627
static JsonBehavior * transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior, JsonBehaviorType default_behavior, JsonReturning *returning)
Definition: parse_expr.c:4686
@ JS_QUOTES_OMIT
Definition: parsenodes.h:1777
JsonFormatType
Definition: primnodes.h:1637
@ JSW_UNCONDITIONAL
Definition: primnodes.h:1753
@ JSW_CONDITIONAL
Definition: primnodes.h:1752
@ JSON_QUERY_OP
Definition: primnodes.h:1803
@ JSON_TABLE_OP
Definition: primnodes.h:1805
@ JSON_EXISTS_OP
Definition: primnodes.h:1802
@ JSON_VALUE_OP
Definition: primnodes.h:1804
char * column_name
Definition: primnodes.h:1819
Node * formatted_expr
Definition: primnodes.h:1823
ParseLoc location
Definition: primnodes.h:1859
List * passing_values
Definition: primnodes.h:1836
JsonBehavior * on_empty
Definition: primnodes.h:1839
JsonFormat * format
Definition: primnodes.h:1826
List * passing_names
Definition: primnodes.h:1835
Node * path_spec
Definition: primnodes.h:1829
bool use_io_coercion
Definition: primnodes.h:1846
JsonReturning * returning
Definition: primnodes.h:1832
bool use_json_coercion
Definition: primnodes.h:1847
JsonWrapper wrapper
Definition: primnodes.h:1850
JsonExprOp op
Definition: primnodes.h:1817
JsonBehavior * on_error
Definition: primnodes.h:1840
bool omit_quotes
Definition: primnodes.h:1853
JsonEncoding encoding
Definition: primnodes.h:1652
JsonOutput * output
Definition: parsenodes.h:1794
char * column_name
Definition: parsenodes.h:1789
JsonWrapper wrapper
Definition: parsenodes.h:1797
JsonQuotes quotes
Definition: parsenodes.h:1798
JsonExprOp op
Definition: parsenodes.h:1788
List * passing
Definition: parsenodes.h:1793
JsonBehavior * on_empty
Definition: parsenodes.h:1795
ParseLoc location
Definition: parsenodes.h:1799
Node * pathspec
Definition: parsenodes.h:1792
JsonBehavior * on_error
Definition: parsenodes.h:1796
JsonValueExpr * context_item
Definition: parsenodes.h:1791
JsonReturning * returning
Definition: parsenodes.h:1755
JsonFormat * format
Definition: primnodes.h:1685
bool DomainHasConstraints(Oid type_id)
Definition: typcache.c:1487

References JsonBehavior::btype, COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_EXPLICIT, JsonFuncExpr::column_name, JsonExpr::column_name, JsonFuncExpr::context_item, DomainHasConstraints(), elog, JsonFormat::encoding, ereport, errcode(), errdetail(), errmsg(), ERROR, exprLocation(), exprType(), format, JsonReturning::format, JsonValueExpr::format, JsonExpr::format, JsonFormat::format_type, format_type_be(), JsonExpr::formatted_expr, get_typtype(), JS_ENC_DEFAULT, JS_FORMAT_DEFAULT, JS_FORMAT_JSONB, JS_QUOTES_OMIT, JSON_BEHAVIOR_DEFAULT, JSON_BEHAVIOR_EMPTY, JSON_BEHAVIOR_EMPTY_ARRAY, JSON_BEHAVIOR_EMPTY_OBJECT, JSON_BEHAVIOR_ERROR, JSON_BEHAVIOR_FALSE, JSON_BEHAVIOR_NULL, JSON_BEHAVIOR_TRUE, JSON_BEHAVIOR_UNKNOWN, JSON_EXISTS_OP, JSON_QUERY_OP, JSON_TABLE_OP, JSON_VALUE_OP, JSW_CONDITIONAL, JSW_UNCONDITIONAL, JsonFuncExpr::location, JsonBehavior::location, JsonExpr::location, makeNode, OidIsValid, JsonExpr::omit_quotes, JsonFuncExpr::on_empty, JsonExpr::on_empty, JsonFuncExpr::on_error, JsonExpr::on_error, JsonFuncExpr::op, JsonExpr::op, JsonFuncExpr::output, parser_errposition(), JsonFuncExpr::passing, JsonExpr::passing_names, JsonExpr::passing_values, JsonExpr::path_spec, JsonFuncExpr::pathspec, JsonFuncExpr::quotes, JsonOutput::returning, JsonExpr::returning, transformExprRecurse(), transformJsonBehavior(), transformJsonOutput(), transformJsonPassingArgs(), transformJsonValueExpr(), JsonReturning::typid, JsonReturning::typmod, JsonExpr::use_io_coercion, JsonExpr::use_json_coercion, JsonFuncExpr::wrapper, and JsonExpr::wrapper.

Referenced by transformExprRecurse().

◆ transformJsonIsPredicate()

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

Definition at line 4080 of file parse_expr.c.

4081{
4082 Oid exprtype;
4083 Node *expr = transformJsonParseArg(pstate, pred->expr, pred->format,
4084 &exprtype);
4085
4086 /* make resulting expression */
4087 if (exprtype != TEXTOID && exprtype != JSONOID && exprtype != JSONBOID)
4088 ereport(ERROR,
4089 (errcode(ERRCODE_DATATYPE_MISMATCH),
4090 errmsg("cannot use type %s in IS JSON predicate",
4091 format_type_be(exprtype))));
4092
4093 /* This intentionally(?) drops the format clause. */
4094 return makeJsonIsPredicate(expr, NULL, pred->item_type,
4095 pred->unique_keys, pred->location);
4096}
Node * makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type, bool unique_keys, int location)
Definition: makefuncs.c:937
static Node * transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format, Oid *exprtype)
Definition: parse_expr.c:4030
JsonFormat * format
Definition: primnodes.h:1736
JsonValueType item_type
Definition: primnodes.h:1737
ParseLoc location
Definition: primnodes.h:1739

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

3899{
3900 JsonReturning *returning;
3901 Node *key;
3902 Node *val;
3903 List *args;
3904 Oid aggfnoid;
3905 Oid aggtype;
3906
3907 key = transformExprRecurse(pstate, (Node *) agg->arg->key);
3908 val = transformJsonValueExpr(pstate, "JSON_OBJECTAGG()",
3909 agg->arg->value,
3911 InvalidOid, false);
3912 args = list_make2(key, val);
3913
3914 returning = transformJsonConstructorOutput(pstate, agg->constructor->output,
3915 args);
3916
3917 if (returning->format->format_type == JS_FORMAT_JSONB)
3918 {
3919 if (agg->absent_on_null)
3920 if (agg->unique)
3921 aggfnoid = F_JSONB_OBJECT_AGG_UNIQUE_STRICT;
3922 else
3923 aggfnoid = F_JSONB_OBJECT_AGG_STRICT;
3924 else if (agg->unique)
3925 aggfnoid = F_JSONB_OBJECT_AGG_UNIQUE;
3926 else
3927 aggfnoid = F_JSONB_OBJECT_AGG;
3928
3929 aggtype = JSONBOID;
3930 }
3931 else
3932 {
3933 if (agg->absent_on_null)
3934 if (agg->unique)
3935 aggfnoid = F_JSON_OBJECT_AGG_UNIQUE_STRICT;
3936 else
3937 aggfnoid = F_JSON_OBJECT_AGG_STRICT;
3938 else if (agg->unique)
3939 aggfnoid = F_JSON_OBJECT_AGG_UNIQUE;
3940 else
3941 aggfnoid = F_JSON_OBJECT_AGG;
3942
3943 aggtype = JSONOID;
3944 }
3945
3946 return transformJsonAggConstructor(pstate, agg->constructor, returning,
3947 args, aggfnoid, aggtype,
3949 agg->unique, agg->absent_on_null);
3950}
@ JSCTOR_JSON_OBJECTAGG
Definition: primnodes.h:1692
JsonValueExpr * value
Definition: parsenodes.h:1876
JsonAggConstructor * constructor
Definition: parsenodes.h:1979
JsonKeyValue * arg
Definition: parsenodes.h:1980
bool absent_on_null
Definition: parsenodes.h:1981

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

Referenced by transformExprRecurse().

◆ transformJsonObjectConstructor()

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

Definition at line 3704 of file parse_expr.c.

3705{
3706 JsonReturning *returning;
3707 List *args = NIL;
3708
3709 /* transform key-value pairs, if any */
3710 if (ctor->exprs)
3711 {
3712 ListCell *lc;
3713
3714 /* transform and append key-value arguments */
3715 foreach(lc, ctor->exprs)
3716 {
3718 Node *key = transformExprRecurse(pstate, (Node *) kv->key);
3719 Node *val = transformJsonValueExpr(pstate, "JSON_OBJECT()",
3720 kv->value,
3722 InvalidOid, false);
3723
3724 args = lappend(args, key);
3725 args = lappend(args, val);
3726 }
3727 }
3728
3729 returning = transformJsonConstructorOutput(pstate, ctor->output, args);
3730
3731 return makeJsonConstructorExpr(pstate, JSCTOR_JSON_OBJECT, args, NULL,
3732 returning, ctor->unique,
3733 ctor->absent_on_null, ctor->location);
3734}
@ JSCTOR_JSON_OBJECT
Definition: primnodes.h:1690
JsonOutput * output
Definition: parsenodes.h:1924

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

Referenced by transformExprRecurse().

◆ transformJsonOutput()

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

Definition at line 3490 of file parse_expr.c.

3492{
3493 JsonReturning *ret;
3494
3495 /* if output clause is not specified, make default clause value */
3496 if (!output)
3497 {
3498 ret = makeNode(JsonReturning);
3499
3501 ret->typid = InvalidOid;
3502 ret->typmod = -1;
3503
3504 return ret;
3505 }
3506
3507 ret = copyObject(output->returning);
3508
3509 typenameTypeIdAndMod(pstate, output->typeName, &ret->typid, &ret->typmod);
3510
3511 if (output->typeName->setof)
3512 ereport(ERROR,
3513 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3514 errmsg("returning SETOF types is not supported in SQL/JSON functions"));
3515
3516 if (get_typtype(ret->typid) == TYPTYPE_PSEUDO)
3517 ereport(ERROR,
3518 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3519 errmsg("returning pseudo-types is not supported in SQL/JSON functions"));
3520
3522 /* assign JSONB format when returning jsonb, or JSON format otherwise */
3523 ret->format->format_type =
3524 ret->typid == JSONBOID ? JS_FORMAT_JSONB : JS_FORMAT_JSON;
3525 else
3526 checkJsonOutputFormat(pstate, ret->format, ret->typid, allow_format);
3527
3528 return ret;
3529}
JsonFormat * makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
Definition: makefuncs.c:873
static void checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format, Oid targettype, bool allow_format_for_non_strings)
Definition: parse_expr.c:3440
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, get_typtype(), 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(), transformJsonFuncExpr(), transformJsonReturning(), and transformJsonSerializeExpr().

◆ transformJsonParseArg()

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

Definition at line 4030 of file parse_expr.c.

4032{
4033 Node *raw_expr = transformExprRecurse(pstate, jsexpr);
4034 Node *expr = raw_expr;
4035
4036 *exprtype = exprType(expr);
4037
4038 /* prepare input document */
4039 if (*exprtype == BYTEAOID)
4040 {
4041 JsonValueExpr *jve;
4042
4043 expr = raw_expr;
4045 *exprtype = TEXTOID;
4046
4047 jve = makeJsonValueExpr((Expr *) raw_expr, (Expr *) expr, format);
4048 expr = (Node *) jve;
4049 }
4050 else
4051 {
4052 char typcategory;
4053 bool typispreferred;
4054
4055 get_type_category_preferred(*exprtype, &typcategory, &typispreferred);
4056
4057 if (*exprtype == UNKNOWNOID || typcategory == TYPCATEGORY_STRING)
4058 {
4059 expr = coerce_to_target_type(pstate, (Node *) expr, *exprtype,
4060 TEXTOID, -1,
4063 *exprtype = TEXTOID;
4064 }
4065
4066 if (format->encoding != JS_ENC_DEFAULT)
4067 ereport(ERROR,
4068 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4069 parser_errposition(pstate, format->location),
4070 errmsg("cannot use JSON FORMAT ENCODING clause for non-bytea input types")));
4071 }
4072
4073 return expr;
4074}
static Node * makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
Definition: parse_expr.c:3256
@ COERCION_IMPLICIT
Definition: primnodes.h:714

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

Referenced by transformJsonIsPredicate(), and transformJsonParseExpr().

◆ transformJsonParseExpr()

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

Definition at line 4143 of file parse_expr.c.

4144{
4145 JsonOutput *output = jsexpr->output;
4146 JsonReturning *returning;
4147 Node *arg;
4148
4149 returning = transformJsonReturning(pstate, output, "JSON()");
4150
4151 if (jsexpr->unique_keys)
4152 {
4153 /*
4154 * Coerce string argument to text and then to json[b] in the executor
4155 * node with key uniqueness check.
4156 */
4157 JsonValueExpr *jve = jsexpr->expr;
4158 Oid arg_type;
4159
4160 arg = transformJsonParseArg(pstate, (Node *) jve->raw_expr, jve->format,
4161 &arg_type);
4162
4163 if (arg_type != TEXTOID)
4164 ereport(ERROR,
4165 (errcode(ERRCODE_DATATYPE_MISMATCH),
4166 errmsg("cannot use non-string types with WITH UNIQUE KEYS clause"),
4167 parser_errposition(pstate, jsexpr->location)));
4168 }
4169 else
4170 {
4171 /*
4172 * Coerce argument to target type using CAST for compatibility with PG
4173 * function-like CASTs.
4174 */
4175 arg = transformJsonValueExpr(pstate, "JSON()", jsexpr->expr,
4176 JS_FORMAT_JSON, returning->typid, false);
4177 }
4178
4180 returning, jsexpr->unique_keys, false,
4181 jsexpr->location);
4182}
static JsonReturning * transformJsonReturning(ParseState *pstate, JsonOutput *output, const char *fname)
Definition: parse_expr.c:4103
@ JSCTOR_JSON_PARSE
Definition: primnodes.h:1694
JsonValueExpr * expr
Definition: parsenodes.h:1886
ParseLoc location
Definition: parsenodes.h:1889
JsonOutput * output
Definition: parsenodes.h:1887
Expr * raw_expr
Definition: primnodes.h:1683

References arg, ereport, errcode(), errmsg(), ERROR, JsonParseExpr::expr, JsonValueExpr::format, JS_FORMAT_JSON, JSCTOR_JSON_PARSE, list_make1, JsonParseExpr::location, makeJsonConstructorExpr(), JsonParseExpr::output, output, parser_errposition(), JsonValueExpr::raw_expr, transformJsonParseArg(), transformJsonReturning(), transformJsonValueExpr(), JsonReturning::typid, and JsonParseExpr::unique_keys.

Referenced by transformExprRecurse().

◆ transformJsonPassingArgs()

static void transformJsonPassingArgs ( ParseState pstate,
const char *  constructName,
JsonFormatType  format,
List args,
List **  passing_values,
List **  passing_names 
)
static

Definition at line 4627 of file parse_expr.c.

4630{
4631 ListCell *lc;
4632
4633 *passing_values = NIL;
4634 *passing_names = NIL;
4635
4636 foreach(lc, args)
4637 {
4639 Node *expr = transformJsonValueExpr(pstate, constructName,
4640 arg->val, format,
4641 InvalidOid, true);
4642
4643 *passing_values = lappend(*passing_values, expr);
4644 *passing_names = lappend(*passing_names, makeString(arg->name));
4645 }
4646}

References arg, generate_unaccent_rules::args, castNode, format, InvalidOid, lappend(), lfirst, makeString(), NIL, and transformJsonValueExpr().

Referenced by transformJsonFuncExpr().

◆ transformJsonReturning()

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

Definition at line 4103 of file parse_expr.c.

4104{
4105 JsonReturning *returning;
4106
4107 if (output)
4108 {
4109 returning = transformJsonOutput(pstate, output, false);
4110
4111 Assert(OidIsValid(returning->typid));
4112
4113 if (returning->typid != JSONOID && returning->typid != JSONBOID)
4114 ereport(ERROR,
4115 (errcode(ERRCODE_DATATYPE_MISMATCH),
4116 errmsg("cannot use type %s in RETURNING clause of %s",
4117 format_type_be(returning->typid), fname),
4118 errhint("Try returning json or jsonb."),
4119 parser_errposition(pstate, output->typeName->location)));
4120 }
4121 else
4122 {
4123 /* Output type is JSON by default. */
4124 Oid targettype = JSONOID;
4126
4127 returning = makeNode(JsonReturning);
4128 returning->format = makeJsonFormat(format, JS_ENC_DEFAULT, -1);
4129 returning->typid = targettype;
4130 returning->typmod = -1;
4131 }
4132
4133 return returning;
4134}

References Assert, ereport, errcode(), errhint(), 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().

◆ transformJsonScalarExpr()

static Node * transformJsonScalarExpr ( ParseState pstate,
JsonScalarExpr jsexpr 
)
static

Definition at line 4192 of file parse_expr.c.

4193{
4194 Node *arg = transformExprRecurse(pstate, (Node *) jsexpr->expr);
4195 JsonOutput *output = jsexpr->output;
4196 JsonReturning *returning;
4197
4198 returning = transformJsonReturning(pstate, output, "JSON_SCALAR()");
4199
4200 if (exprType(arg) == UNKNOWNOID)
4201 arg = coerce_to_specific_type(pstate, arg, TEXTOID, "JSON_SCALAR");
4202
4204 returning, false, false, jsexpr->location);
4205}
@ JSCTOR_JSON_SCALAR
Definition: primnodes.h:1695
ParseLoc location
Definition: parsenodes.h:1901
JsonOutput * output
Definition: parsenodes.h:1900

References arg, coerce_to_specific_type(), JsonScalarExpr::expr, exprType(), JSCTOR_JSON_SCALAR, list_make1, JsonScalarExpr::location, makeJsonConstructorExpr(), JsonScalarExpr::output, output, transformExprRecurse(), and transformJsonReturning().

Referenced by transformExprRecurse().

◆ transformJsonSerializeExpr()

static Node * transformJsonSerializeExpr ( ParseState pstate,
JsonSerializeExpr expr 
)
static

Definition at line 4215 of file parse_expr.c.

4216{
4217 JsonReturning *returning;
4218 Node *arg = transformJsonValueExpr(pstate, "JSON_SERIALIZE()",
4219 expr->expr,
4221 InvalidOid, false);
4222
4223 if (expr->output)
4224 {
4225 returning = transformJsonOutput(pstate, expr->output, true);
4226
4227 if (returning->typid != BYTEAOID)
4228 {
4229 char typcategory;
4230 bool typispreferred;
4231
4232 get_type_category_preferred(returning->typid, &typcategory,
4233 &typispreferred);
4234 if (typcategory != TYPCATEGORY_STRING)
4235 ereport(ERROR,
4236 (errcode(ERRCODE_DATATYPE_MISMATCH),
4237 errmsg("cannot use type %s in RETURNING clause of %s",
4238 format_type_be(returning->typid),
4239 "JSON_SERIALIZE()"),
4240 errhint("Try returning a string type or bytea.")));
4241 }
4242 }
4243 else
4244 {
4245 /* RETURNING TEXT FORMAT JSON is by default */
4246 returning = makeNode(JsonReturning);
4248 returning->typid = TEXTOID;
4249 returning->typmod = -1;
4250 }
4251
4253 NULL, returning, false, false, expr->location);
4254}
@ JSCTOR_JSON_SERIALIZE
Definition: primnodes.h:1696
JsonOutput * output
Definition: parsenodes.h:1912
JsonValueExpr * expr
Definition: parsenodes.h:1911

References arg, ereport, errcode(), errhint(), errmsg(), ERROR, JsonSerializeExpr::expr, JsonReturning::format, format_type_be(), get_type_category_preferred(), InvalidOid, JS_ENC_DEFAULT, JS_FORMAT_JSON, JSCTOR_JSON_SERIALIZE, list_make1, JsonSerializeExpr::location, makeJsonConstructorExpr(), makeJsonFormat(), makeNode, JsonSerializeExpr::output, transformJsonOutput(), transformJsonValueExpr(), JsonReturning::typid, and JsonReturning::typmod.

Referenced by transformExprRecurse().

◆ transformJsonValueExpr()

static Node * transformJsonValueExpr ( ParseState pstate,
const char *  constructName,
JsonValueExpr ve,
JsonFormatType  default_format,
Oid  targettype,
bool  isarg 
)
static

Definition at line 3278 of file parse_expr.c.

3281{
3282 Node *expr = transformExprRecurse(pstate, (Node *) ve->raw_expr);
3283 Node *rawexpr;
3285 Oid exprtype;
3286 int location;
3287 char typcategory;
3288 bool typispreferred;
3289
3290 if (exprType(expr) == UNKNOWNOID)
3291 expr = coerce_to_specific_type(pstate, expr, TEXTOID, constructName);
3292
3293 rawexpr = expr;
3294 exprtype = exprType(expr);
3295 location = exprLocation(expr);
3296
3297 get_type_category_preferred(exprtype, &typcategory, &typispreferred);
3298
3300 {
3301 if (ve->format->encoding != JS_ENC_DEFAULT && exprtype != BYTEAOID)
3302 ereport(ERROR,
3303 errcode(ERRCODE_DATATYPE_MISMATCH),
3304 errmsg("JSON ENCODING clause is only allowed for bytea input type"),
3305 parser_errposition(pstate, ve->format->location));
3306
3307 if (exprtype == JSONOID || exprtype == JSONBOID)
3308 format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
3309 else
3310 format = ve->format->format_type;
3311 }
3312 else if (isarg)
3313 {
3314 /*
3315 * Special treatment for PASSING arguments.
3316 *
3317 * Pass types supported by GetJsonPathVar() / JsonItemFromDatum()
3318 * directly without converting to json[b].
3319 */
3320 switch (exprtype)
3321 {
3322 case BOOLOID:
3323 case NUMERICOID:
3324 case INT2OID:
3325 case INT4OID:
3326 case INT8OID:
3327 case FLOAT4OID:
3328 case FLOAT8OID:
3329 case TEXTOID:
3330 case VARCHAROID:
3331 case DATEOID:
3332 case TIMEOID:
3333 case TIMETZOID:
3334 case TIMESTAMPOID:
3335 case TIMESTAMPTZOID:
3336 return expr;
3337
3338 default:
3339 if (typcategory == TYPCATEGORY_STRING)
3340 return expr;
3341 /* else convert argument to json[b] type */
3342 break;
3343 }
3344
3345 format = default_format;
3346 }
3347 else if (exprtype == JSONOID || exprtype == JSONBOID)
3348 format = JS_FORMAT_DEFAULT; /* do not format json[b] types */
3349 else
3350 format = default_format;
3351
3352 if (format != JS_FORMAT_DEFAULT ||
3353 (OidIsValid(targettype) && exprtype != targettype))
3354 {
3355 Node *coerced;
3356 bool only_allow_cast = OidIsValid(targettype);
3357
3358 /*
3359 * PASSING args are handled appropriately by GetJsonPathVar() /
3360 * JsonItemFromDatum().
3361 */
3362 if (!isarg &&
3363 !only_allow_cast &&
3364 exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING)
3365 ereport(ERROR,
3366 errcode(ERRCODE_DATATYPE_MISMATCH),
3368 errmsg("cannot use non-string types with implicit FORMAT JSON clause") :
3369 errmsg("cannot use non-string types with explicit FORMAT JSON clause"),
3370 parser_errposition(pstate, ve->format->location >= 0 ?
3371 ve->format->location : location));
3372
3373 /* Convert encoded JSON text from bytea. */
3374 if (format == JS_FORMAT_JSON && exprtype == BYTEAOID)
3375 {
3376 expr = makeJsonByteaToTextConversion(expr, ve->format, location);
3377 exprtype = TEXTOID;
3378 }
3379
3380 if (!OidIsValid(targettype))
3381 targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
3382
3383 /* Try to coerce to the target type. */
3384 coerced = coerce_to_target_type(pstate, expr, exprtype,
3385 targettype, -1,
3388 location);
3389
3390 if (!coerced)
3391 {
3392 /* If coercion failed, use to_json()/to_jsonb() functions. */
3393 FuncExpr *fexpr;
3394 Oid fnoid;
3395
3396 /*
3397 * Though only allow a cast when the target type is specified by
3398 * the caller.
3399 */
3400 if (only_allow_cast)
3401 ereport(ERROR,
3402 (errcode(ERRCODE_CANNOT_COERCE),
3403 errmsg("cannot cast type %s to %s",
3404 format_type_be(exprtype),
3405 format_type_be(targettype)),
3406 parser_errposition(pstate, location)));
3407
3408 fnoid = targettype == JSONOID ? F_TO_JSON : F_TO_JSONB;
3409 fexpr = makeFuncExpr(fnoid, targettype, list_make1(expr),
3411
3412 fexpr->location = location;
3413
3414 coerced = (Node *) fexpr;
3415 }
3416
3417 if (coerced == expr)
3418 expr = rawexpr;
3419 else
3420 {
3421 ve = copyObject(ve);
3422 ve->raw_expr = (Expr *) rawexpr;
3423 ve->formatted_expr = (Expr *) coerced;
3424
3425 expr = (Node *) ve;
3426 }
3427 }
3428
3429 /* If returning a JsonValueExpr, formatted_expr must have been set. */
3430 Assert(!IsA(expr, JsonValueExpr) ||
3431 ((JsonValueExpr *) expr)->formatted_expr != NULL);
3432
3433 return expr;
3434}
Expr * formatted_expr
Definition: primnodes.h:1684

References Assert, COERCE_EXPLICIT_CALL, COERCE_EXPLICIT_CAST, coerce_to_specific_type(), coerce_to_target_type(), COERCION_EXPLICIT, copyObject,