PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
parse_expr.c File Reference
#include "postgres.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/analyze.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 "parser/parse_agg.h"
#include "utils/builtins.h"
#include "utils/date.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.

Macros

#define PREC_GROUP_POSTFIX_IS   1 /* postfix IS tests (NullTest, etc) */
 
#define PREC_GROUP_INFIX_IS   2 /* infix IS (IS DISTINCT FROM, etc) */
 
#define PREC_GROUP_LESS   3 /* < > */
 
#define PREC_GROUP_EQUAL   4 /* = */
 
#define PREC_GROUP_LESS_EQUAL   5 /* <= >= <> */
 
#define PREC_GROUP_LIKE   6 /* LIKE ILIKE SIMILAR */
 
#define PREC_GROUP_BETWEEN   7 /* BETWEEN */
 
#define PREC_GROUP_IN   8 /* IN */
 
#define PREC_GROUP_NOT_LIKE   9 /* NOT LIKE/ILIKE/SIMILAR */
 
#define PREC_GROUP_NOT_BETWEEN   10 /* NOT BETWEEN */
 
#define PREC_GROUP_NOT_IN   11 /* NOT IN */
 
#define PREC_GROUP_POSTFIX_OP   12 /* generic postfix operators */
 
#define PREC_GROUP_INFIX_OP   13 /* generic infix operators */
 
#define PREC_GROUP_PREFIX_OP   14 /* generic prefix operators */
 

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 NodetransformAExprOf (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprIn (ParseState *pstate, A_Expr *a)
 
static NodetransformAExprBetween (ParseState *pstate, A_Expr *a)
 
static NodetransformBoolExpr (ParseState *pstate, BoolExpr *a)
 
static NodetransformFuncCall (ParseState *pstate, FuncCall *fn)
 
static NodetransformMultiAssignRef (ParseState *pstate, MultiAssignRef *maref)
 
static NodetransformCaseExpr (ParseState *pstate, CaseExpr *c)
 
static NodetransformSubLink (ParseState *pstate, SubLink *sublink)
 
static NodetransformArrayExpr (ParseState *pstate, A_ArrayExpr *a, Oid array_type, Oid element_type, int32 typmod)
 
static NodetransformRowExpr (ParseState *pstate, RowExpr *r, bool allowDefault)
 
static NodetransformCoalesceExpr (ParseState *pstate, CoalesceExpr *c)
 
static NodetransformMinMaxExpr (ParseState *pstate, MinMaxExpr *m)
 
static NodetransformSQLValueFunction (ParseState *pstate, SQLValueFunction *svf)
 
static NodetransformXmlExpr (ParseState *pstate, XmlExpr *x)
 
static NodetransformXmlSerialize (ParseState *pstate, XmlSerialize *xs)
 
static NodetransformBooleanTest (ParseState *pstate, BooleanTest *b)
 
static NodetransformCurrentOfExpr (ParseState *pstate, CurrentOfExpr *cexpr)
 
static NodetransformColumnRef (ParseState *pstate, ColumnRef *cref)
 
static NodetransformWholeRowRef (ParseState *pstate, RangeTblEntry *rte, int location)
 
static NodetransformIndirection (ParseState *pstate, Node *basenode, List *indirection)
 
static NodetransformTypeCast (ParseState *pstate, TypeCast *tc)
 
static NodetransformCollateClause (ParseState *pstate, CollateClause *c)
 
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)
 
static int operator_precedence_group (Node *node, const char **nodename)
 
static void emit_precedence_warnings (ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
 
NodetransformExpr (ParseState *pstate, Node *expr, ParseExprKind exprKind)
 
static void unknown_attribute (ParseState *pstate, Node *relref, char *attname, int location)
 
static bool exprIsNullConstant (Node *arg)
 
const char * ParseExprKindName (ParseExprKind exprKind)
 

Variables

bool operator_precedence_warning = false
 
bool Transform_null_equals = false
 
static const int oldprecedence_l []
 
static const int oldprecedence_r []
 

Macro Definition Documentation

#define PREC_GROUP_BETWEEN   7 /* BETWEEN */

Definition at line 57 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_EQUAL   4 /* = */

Definition at line 54 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_IN   8 /* IN */
#define PREC_GROUP_INFIX_IS   2 /* infix IS (IS DISTINCT FROM, etc) */

Definition at line 52 of file parse_expr.c.

Referenced by operator_precedence_group(), and transformAExprDistinct().

#define PREC_GROUP_INFIX_OP   13 /* generic infix operators */

Definition at line 63 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_LESS   3 /* < > */

Definition at line 53 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_LESS_EQUAL   5 /* <= >= <> */

Definition at line 55 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_LIKE   6 /* LIKE ILIKE SIMILAR */

Definition at line 56 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_NOT_BETWEEN   10 /* NOT BETWEEN */

Definition at line 60 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_NOT_IN   11 /* NOT IN */
#define PREC_GROUP_NOT_LIKE   9 /* NOT LIKE/ILIKE/SIMILAR */

Definition at line 59 of file parse_expr.c.

Referenced by operator_precedence_group().

#define PREC_GROUP_POSTFIX_IS   1 /* postfix IS tests (NullTest, etc) */
#define PREC_GROUP_POSTFIX_OP   12 /* generic postfix operators */
#define PREC_GROUP_PREFIX_OP   14 /* generic prefix operators */

Definition at line 64 of file parse_expr.c.

Referenced by emit_precedence_warnings(), and operator_precedence_group().

Function Documentation

static void emit_precedence_warnings ( ParseState pstate,
int  opgroup,
const char *  opname,
Node lchild,
Node rchild,
int  location 
)
static

Definition at line 3293 of file parse_expr.c.

References Assert, ereport, errmsg(), oldprecedence_l, oldprecedence_r, operator_precedence_group(), parser_errposition(), PREC_GROUP_IN, PREC_GROUP_NOT_IN, PREC_GROUP_POSTFIX_IS, PREC_GROUP_POSTFIX_OP, PREC_GROUP_PREFIX_OP, and WARNING.

Referenced by transformAExprBetween(), transformAExprDistinct(), transformAExprIn(), transformAExprOf(), transformAExprOp(), transformAExprOpAll(), transformAExprOpAny(), transformBooleanTest(), transformExprRecurse(), transformSubLink(), and transformXmlExpr().

3297 {
3298  int cgroup;
3299  const char *copname;
3300 
3301  Assert(opgroup > 0);
3302 
3303  /*
3304  * Complain if left child, which should be same or higher precedence
3305  * according to current rules, used to be lower precedence.
3306  *
3307  * Exception to precedence rules: if left child is IN or NOT IN or a
3308  * postfix operator, the grouping is syntactically forced regardless of
3309  * precedence.
3310  */
3311  cgroup = operator_precedence_group(lchild, &copname);
3312  if (cgroup > 0)
3313  {
3314  if (oldprecedence_l[cgroup] < oldprecedence_r[opgroup] &&
3315  cgroup != PREC_GROUP_IN &&
3316  cgroup != PREC_GROUP_NOT_IN &&
3317  cgroup != PREC_GROUP_POSTFIX_OP &&
3318  cgroup != PREC_GROUP_POSTFIX_IS)
3319  ereport(WARNING,
3320  (errmsg("operator precedence change: %s is now lower precedence than %s",
3321  opname, copname),
3322  parser_errposition(pstate, location)));
3323  }
3324 
3325  /*
3326  * Complain if right child, which should be higher precedence according to
3327  * current rules, used to be same or lower precedence.
3328  *
3329  * Exception to precedence rules: if right child is a prefix operator, the
3330  * grouping is syntactically forced regardless of precedence.
3331  */
3332  cgroup = operator_precedence_group(rchild, &copname);
3333  if (cgroup > 0)
3334  {
3335  if (oldprecedence_r[cgroup] <= oldprecedence_l[opgroup] &&
3336  cgroup != PREC_GROUP_PREFIX_OP)
3337  ereport(WARNING,
3338  (errmsg("operator precedence change: %s is now lower precedence than %s",
3339  opname, copname),
3340  parser_errposition(pstate, location)));
3341  }
3342 }
#define PREC_GROUP_PREFIX_OP
Definition: parse_expr.c:64
#define PREC_GROUP_POSTFIX_IS
Definition: parse_expr.c:51
static int operator_precedence_group(Node *node, const char **nodename)
Definition: parse_expr.c:3050
#define PREC_GROUP_IN
Definition: parse_expr.c:58
#define PREC_GROUP_NOT_IN
Definition: parse_expr.c:61
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
#define Assert(condition)
Definition: c.h:675
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
static const int oldprecedence_l[]
Definition: parse_expr.c:85
int errmsg(const char *fmt,...)
Definition: elog.c:797
static const int oldprecedence_r[]
Definition: parse_expr.c:88
#define PREC_GROUP_POSTFIX_OP
Definition: parse_expr.c:62
static bool exprIsNullConstant ( Node arg)
static

Definition at line 833 of file parse_expr.c.

References IsA, T_Null, Value::type, and A_Const::val.

Referenced by transformAExprDistinct(), and transformAExprOp().

834 {
835  if (arg && IsA(arg, A_Const))
836  {
837  A_Const *con = (A_Const *) arg;
838 
839  if (con->val.type == T_Null)
840  return true;
841  }
842  return false;
843 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:286
Value val
Definition: parsenodes.h:288
NodeTag type
Definition: value.h:44
static Expr * make_distinct_op ( ParseState pstate,
List opname,
Node ltree,
Node rtree,
int  location 
)
static

Definition at line 2998 of file parse_expr.c.

References BOOLOID, ereport, errcode(), errmsg(), ERROR, make_op(), NodeSetTag, parser_errposition(), result, and T_DistinctExpr.

Referenced by make_row_distinct_op(), and transformAExprDistinct().

3000 {
3001  Expr *result;
3002 
3003  result = make_op(pstate, opname, ltree, rtree, location);
3004  if (((OpExpr *) result)->opresulttype != BOOLOID)
3005  ereport(ERROR,
3006  (errcode(ERRCODE_DATATYPE_MISMATCH),
3007  errmsg("IS DISTINCT FROM requires = operator to yield boolean"),
3008  parser_errposition(pstate, location)));
3009 
3010  /*
3011  * We rely on DistinctExpr and OpExpr being same struct
3012  */
3013  NodeSetTag(result, T_DistinctExpr);
3014 
3015  return result;
3016 }
#define NodeSetTag(nodeptr, t)
Definition: nodes.h:558
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1632
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:742
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
#define BOOLOID
Definition: pg_type.h:288
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Node * make_nulltest_from_distinct ( ParseState pstate,
A_Expr distincta,
Node arg 
)
static

Definition at line 3024 of file parse_expr.c.

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

Referenced by transformAExprDistinct().

3025 {
3026  NullTest *nt = makeNode(NullTest);
3027 
3028  nt->arg = (Expr *) transformExprRecurse(pstate, arg);
3029  /* the argument can be any type, so don't coerce it */
3030  if (distincta->kind == AEXPR_NOT_DISTINCT)
3031  nt->nulltesttype = IS_NULL;
3032  else
3033  nt->nulltesttype = IS_NOT_NULL;
3034  /* argisrow = false is correct whether or not arg is composite */
3035  nt->argisrow = false;
3036  nt->location = distincta->location;
3037  return (Node *) nt;
3038 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
A_Expr_Kind kind
Definition: parsenodes.h:275
Definition: nodes.h:509
Expr * arg
Definition: primnodes.h:1179
int location
Definition: parsenodes.h:279
NullTestType nulltesttype
Definition: primnodes.h:1180
#define makeNode(_type_)
Definition: nodes.h:557
int location
Definition: primnodes.h:1182
bool argisrow
Definition: primnodes.h:1181
static Node * make_row_comparison_op ( ParseState pstate,
List opname,
List largs,
List rargs,
int  location 
)
static

Definition at line 2753 of file parse_expr.c.

References AND_EXPR, OpExpr::args, bms_add_member(), bms_first_member(), bms_int_members(), BOOLOID, castNode, cmp(), ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, expression_returns_set(), forboth, format_type_be(), get_op_btree_interpretation(), i, RowCompareExpr::inputcollids, InvalidOid, lappend(), lappend_oid(), RowCompareExpr::largs, lfirst, linitial, list_length(), llast, lsecond, make_op(), makeBoolExpr(), makeNode, NIL, NULL, OidIsValid, RowCompareExpr::opfamilies, OpBtreeInterpretation::opfamily_id, OpExpr::opno, RowCompareExpr::opnos, OpExpr::opresulttype, OR_EXPR, palloc(), parser_errposition(), RowCompareExpr::rargs, RowCompareExpr::rctype, ROWCOMPARE_EQ, ROWCOMPARE_NE, OpBtreeInterpretation::strategy, and strVal.

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

2755 {
2756  RowCompareExpr *rcexpr;
2757  RowCompareType rctype;
2758  List *opexprs;
2759  List *opnos;
2760  List *opfamilies;
2761  ListCell *l,
2762  *r;
2763  List **opinfo_lists;
2764  Bitmapset *strats;
2765  int nopers;
2766  int i;
2767 
2768  nopers = list_length(largs);
2769  if (nopers != list_length(rargs))
2770  ereport(ERROR,
2771  (errcode(ERRCODE_SYNTAX_ERROR),
2772  errmsg("unequal number of entries in row expressions"),
2773  parser_errposition(pstate, location)));
2774 
2775  /*
2776  * We can't compare zero-length rows because there is no principled basis
2777  * for figuring out what the operator is.
2778  */
2779  if (nopers == 0)
2780  ereport(ERROR,
2781  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2782  errmsg("cannot compare rows of zero length"),
2783  parser_errposition(pstate, location)));
2784 
2785  /*
2786  * Identify all the pairwise operators, using make_op so that behavior is
2787  * the same as in the simple scalar case.
2788  */
2789  opexprs = NIL;
2790  forboth(l, largs, r, rargs)
2791  {
2792  Node *larg = (Node *) lfirst(l);
2793  Node *rarg = (Node *) lfirst(r);
2794  OpExpr *cmp;
2795 
2796  cmp = castNode(OpExpr, make_op(pstate, opname, larg, rarg, location));
2797 
2798  /*
2799  * We don't use coerce_to_boolean here because we insist on the
2800  * operator yielding boolean directly, not via coercion. If it
2801  * doesn't yield bool it won't be in any index opfamilies...
2802  */
2803  if (cmp->opresulttype != BOOLOID)
2804  ereport(ERROR,
2805  (errcode(ERRCODE_DATATYPE_MISMATCH),
2806  errmsg("row comparison operator must yield type boolean, "
2807  "not type %s",
2809  parser_errposition(pstate, location)));
2810  if (expression_returns_set((Node *) cmp))
2811  ereport(ERROR,
2812  (errcode(ERRCODE_DATATYPE_MISMATCH),
2813  errmsg("row comparison operator must not return a set"),
2814  parser_errposition(pstate, location)));
2815  opexprs = lappend(opexprs, cmp);
2816  }
2817 
2818  /*
2819  * If rows are length 1, just return the single operator. In this case we
2820  * don't insist on identifying btree semantics for the operator (but we
2821  * still require it to return boolean).
2822  */
2823  if (nopers == 1)
2824  return (Node *) linitial(opexprs);
2825 
2826  /*
2827  * Now we must determine which row comparison semantics (= <> < <= > >=)
2828  * apply to this set of operators. We look for btree opfamilies
2829  * containing the operators, and see which interpretations (strategy
2830  * numbers) exist for each operator.
2831  */
2832  opinfo_lists = (List **) palloc(nopers * sizeof(List *));
2833  strats = NULL;
2834  i = 0;
2835  foreach(l, opexprs)
2836  {
2837  Oid opno = ((OpExpr *) lfirst(l))->opno;
2838  Bitmapset *this_strats;
2839  ListCell *j;
2840 
2841  opinfo_lists[i] = get_op_btree_interpretation(opno);
2842 
2843  /*
2844  * convert strategy numbers into a Bitmapset to make the intersection
2845  * calculation easy.
2846  */
2847  this_strats = NULL;
2848  foreach(j, opinfo_lists[i])
2849  {
2850  OpBtreeInterpretation *opinfo = lfirst(j);
2851 
2852  this_strats = bms_add_member(this_strats, opinfo->strategy);
2853  }
2854  if (i == 0)
2855  strats = this_strats;
2856  else
2857  strats = bms_int_members(strats, this_strats);
2858  i++;
2859  }
2860 
2861  /*
2862  * If there are multiple common interpretations, we may use any one of
2863  * them ... this coding arbitrarily picks the lowest btree strategy
2864  * number.
2865  */
2866  i = bms_first_member(strats);
2867  if (i < 0)
2868  {
2869  /* No common interpretation, so fail */
2870  ereport(ERROR,
2871  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2872  errmsg("could not determine interpretation of row comparison operator %s",
2873  strVal(llast(opname))),
2874  errhint("Row comparison operators must be associated with btree operator families."),
2875  parser_errposition(pstate, location)));
2876  }
2877  rctype = (RowCompareType) i;
2878 
2879  /*
2880  * For = and <> cases, we just combine the pairwise operators with AND or
2881  * OR respectively.
2882  */
2883  if (rctype == ROWCOMPARE_EQ)
2884  return (Node *) makeBoolExpr(AND_EXPR, opexprs, location);
2885  if (rctype == ROWCOMPARE_NE)
2886  return (Node *) makeBoolExpr(OR_EXPR, opexprs, location);
2887 
2888  /*
2889  * Otherwise we need to choose exactly which opfamily to associate with
2890  * each operator.
2891  */
2892  opfamilies = NIL;
2893  for (i = 0; i < nopers; i++)
2894  {
2895  Oid opfamily = InvalidOid;
2896  ListCell *j;
2897 
2898  foreach(j, opinfo_lists[i])
2899  {
2900  OpBtreeInterpretation *opinfo = lfirst(j);
2901 
2902  if (opinfo->strategy == rctype)
2903  {
2904  opfamily = opinfo->opfamily_id;
2905  break;
2906  }
2907  }
2908  if (OidIsValid(opfamily))
2909  opfamilies = lappend_oid(opfamilies, opfamily);
2910  else /* should not happen */
2911  ereport(ERROR,
2912  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2913  errmsg("could not determine interpretation of row comparison operator %s",
2914  strVal(llast(opname))),
2915  errdetail("There are multiple equally-plausible candidates."),
2916  parser_errposition(pstate, location)));
2917  }
2918 
2919  /*
2920  * Now deconstruct the OpExprs and create a RowCompareExpr.
2921  *
2922  * Note: can't just reuse the passed largs/rargs lists, because of
2923  * possibility that make_op inserted coercion operations.
2924  */
2925  opnos = NIL;
2926  largs = NIL;
2927  rargs = NIL;
2928  foreach(l, opexprs)
2929  {
2930  OpExpr *cmp = (OpExpr *) lfirst(l);
2931 
2932  opnos = lappend_oid(opnos, cmp->opno);
2933  largs = lappend(largs, linitial(cmp->args));
2934  rargs = lappend(rargs, lsecond(cmp->args));
2935  }
2936 
2937  rcexpr = makeNode(RowCompareExpr);
2938  rcexpr->rctype = rctype;
2939  rcexpr->opnos = opnos;
2940  rcexpr->opfamilies = opfamilies;
2941  rcexpr->inputcollids = NIL; /* assign_expr_collations will fix this */
2942  rcexpr->largs = largs;
2943  rcexpr->rargs = rargs;
2944 
2945  return (Node *) rcexpr;
2946 }
#define NIL
Definition: pg_list.h:69
int bms_first_member(Bitmapset *a)
Definition: bitmapset.c:885
int errhint(const char *fmt,...)
Definition: elog.c:987
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:180
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
RowCompareType rctype
Definition: primnodes.h:1030
List * opfamilies
Definition: primnodes.h:1032
bool expression_returns_set(Node *clause)
Definition: nodeFuncs.c:670
#define llast(l)
Definition: pg_list.h:131
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:742
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:538
#define lsecond(l)
Definition: pg_list.h:116
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:366
Oid opresulttype
Definition: primnodes.h:497
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
List * get_op_btree_interpretation(Oid opno)
Definition: lsyscache.c:598
#define InvalidOid
Definition: postgres_ext.h:36
RowCompareType
Definition: primnodes.h:1016
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define BOOLOID
Definition: pg_type.h:288
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Oid opno
Definition: primnodes.h:495
List * args
Definition: primnodes.h:501
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:791
List * inputcollids
Definition: primnodes.h:1033
Definition: pg_list.h:45
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742
static Node * make_row_distinct_op ( ParseState pstate,
List opname,
RowExpr lrow,
RowExpr rrow,
int  location 
)
static

Definition at line 2954 of file parse_expr.c.

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

Referenced by transformAExprDistinct().

2957 {
2958  Node *result = NULL;
2959  List *largs = lrow->args;
2960  List *rargs = rrow->args;
2961  ListCell *l,
2962  *r;
2963 
2964  if (list_length(largs) != list_length(rargs))
2965  ereport(ERROR,
2966  (errcode(ERRCODE_SYNTAX_ERROR),
2967  errmsg("unequal number of entries in row expressions"),
2968  parser_errposition(pstate, location)));
2969 
2970  forboth(l, largs, r, rargs)
2971  {
2972  Node *larg = (Node *) lfirst(l);
2973  Node *rarg = (Node *) lfirst(r);
2974  Node *cmp;
2975 
2976  cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
2977  if (result == NULL)
2978  result = cmp;
2979  else
2980  result = (Node *) makeBoolExpr(OR_EXPR,
2981  list_make2(result, cmp),
2982  location);
2983  }
2984 
2985  if (result == NULL)
2986  {
2987  /* zero-length rows? Generate constant FALSE */
2988  result = makeBoolConst(false, false);
2989  }
2990 
2991  return result;
2992 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
List * args
Definition: primnodes.h:985
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:180
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
static Expr * make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_expr.c:2998
return result
Definition: formatting.c:1632
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:366
#define ERROR
Definition: elog.h:43
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:354
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: pg_list.h:45
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742
static int operator_precedence_group ( Node node,
const char **  nodename 
)
static

Definition at line 3050 of file parse_expr.c.

References AEXPR_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_DISTINCT, AEXPR_ILIKE, AEXPR_IN, AEXPR_LIKE, AEXPR_NOT_BETWEEN, AEXPR_NOT_BETWEEN_SYM, AEXPR_NOT_DISTINCT, AEXPR_OF, AEXPR_OP, AEXPR_OP_ALL, AEXPR_OP_ANY, AEXPR_SIMILAR, ALL_SUBLINK, ANY_SUBLINK, BoolExpr::args, Assert, BoolExpr::boolop, IS_DOCUMENT, IsA, A_Expr::kind, A_Expr::lexpr, linitial, list_length(), llast, BoolExpr::location, SubLink::location, XmlExpr::location, A_Expr::name, NIL, NOT_EXPR, NULL, XmlExpr::op, SubLink::operName, PREC_GROUP_BETWEEN, PREC_GROUP_EQUAL, PREC_GROUP_IN, PREC_GROUP_INFIX_IS, PREC_GROUP_INFIX_OP, PREC_GROUP_LESS, PREC_GROUP_LESS_EQUAL, PREC_GROUP_LIKE, PREC_GROUP_NOT_BETWEEN, PREC_GROUP_NOT_IN, PREC_GROUP_NOT_LIKE, PREC_GROUP_POSTFIX_IS, PREC_GROUP_POSTFIX_OP, PREC_GROUP_PREFIX_OP, A_Expr::rexpr, strVal, and SubLink::subLinkType.

Referenced by emit_precedence_warnings(), transformAExprBetween(), and transformAExprOp().

3051 {
3052  int group = 0;
3053 
3054  *nodename = NULL;
3055  if (node == NULL)
3056  return 0;
3057 
3058  if (IsA(node, A_Expr))
3059  {
3060  A_Expr *aexpr = (A_Expr *) node;
3061 
3062  if (aexpr->kind == AEXPR_OP &&
3063  aexpr->lexpr != NULL &&
3064  aexpr->rexpr != NULL)
3065  {
3066  /* binary operator */
3067  if (list_length(aexpr->name) == 1)
3068  {
3069  *nodename = strVal(linitial(aexpr->name));
3070  /* Ignore if op was always higher priority than IS-tests */
3071  if (strcmp(*nodename, "+") == 0 ||
3072  strcmp(*nodename, "-") == 0 ||
3073  strcmp(*nodename, "*") == 0 ||
3074  strcmp(*nodename, "/") == 0 ||
3075  strcmp(*nodename, "%") == 0 ||
3076  strcmp(*nodename, "^") == 0)
3077  group = 0;
3078  else if (strcmp(*nodename, "<") == 0 ||
3079  strcmp(*nodename, ">") == 0)
3080  group = PREC_GROUP_LESS;
3081  else if (strcmp(*nodename, "=") == 0)
3082  group = PREC_GROUP_EQUAL;
3083  else if (strcmp(*nodename, "<=") == 0 ||
3084  strcmp(*nodename, ">=") == 0 ||
3085  strcmp(*nodename, "<>") == 0)
3086  group = PREC_GROUP_LESS_EQUAL;
3087  else
3088  group = PREC_GROUP_INFIX_OP;
3089  }
3090  else
3091  {
3092  /* schema-qualified operator syntax */
3093  *nodename = "OPERATOR()";
3094  group = PREC_GROUP_INFIX_OP;
3095  }
3096  }
3097  else if (aexpr->kind == AEXPR_OP &&
3098  aexpr->lexpr == NULL &&
3099  aexpr->rexpr != NULL)
3100  {
3101  /* prefix operator */
3102  if (list_length(aexpr->name) == 1)
3103  {
3104  *nodename = strVal(linitial(aexpr->name));
3105  /* Ignore if op was always higher priority than IS-tests */
3106  if (strcmp(*nodename, "+") == 0 ||
3107  strcmp(*nodename, "-"))
3108  group = 0;
3109  else
3110  group = PREC_GROUP_PREFIX_OP;
3111  }
3112  else
3113  {
3114  /* schema-qualified operator syntax */
3115  *nodename = "OPERATOR()";
3116  group = PREC_GROUP_PREFIX_OP;
3117  }
3118  }
3119  else if (aexpr->kind == AEXPR_OP &&
3120  aexpr->lexpr != NULL &&
3121  aexpr->rexpr == NULL)
3122  {
3123  /* postfix operator */
3124  if (list_length(aexpr->name) == 1)
3125  {
3126  *nodename = strVal(linitial(aexpr->name));
3127  group = PREC_GROUP_POSTFIX_OP;
3128  }
3129  else
3130  {
3131  /* schema-qualified operator syntax */
3132  *nodename = "OPERATOR()";
3133  group = PREC_GROUP_POSTFIX_OP;
3134  }
3135  }
3136  else if (aexpr->kind == AEXPR_OP_ANY ||
3137  aexpr->kind == AEXPR_OP_ALL)
3138  {
3139  *nodename = strVal(llast(aexpr->name));
3140  group = PREC_GROUP_POSTFIX_OP;
3141  }
3142  else if (aexpr->kind == AEXPR_DISTINCT ||
3143  aexpr->kind == AEXPR_NOT_DISTINCT)
3144  {
3145  *nodename = "IS";
3146  group = PREC_GROUP_INFIX_IS;
3147  }
3148  else if (aexpr->kind == AEXPR_OF)
3149  {
3150  *nodename = "IS";
3151  group = PREC_GROUP_POSTFIX_IS;
3152  }
3153  else if (aexpr->kind == AEXPR_IN)
3154  {
3155  *nodename = "IN";
3156  if (strcmp(strVal(linitial(aexpr->name)), "=") == 0)
3157  group = PREC_GROUP_IN;
3158  else
3159  group = PREC_GROUP_NOT_IN;
3160  }
3161  else if (aexpr->kind == AEXPR_LIKE)
3162  {
3163  *nodename = "LIKE";
3164  if (strcmp(strVal(linitial(aexpr->name)), "~~") == 0)
3165  group = PREC_GROUP_LIKE;
3166  else
3167  group = PREC_GROUP_NOT_LIKE;
3168  }
3169  else if (aexpr->kind == AEXPR_ILIKE)
3170  {
3171  *nodename = "ILIKE";
3172  if (strcmp(strVal(linitial(aexpr->name)), "~~*") == 0)
3173  group = PREC_GROUP_LIKE;
3174  else
3175  group = PREC_GROUP_NOT_LIKE;
3176  }
3177  else if (aexpr->kind == AEXPR_SIMILAR)
3178  {
3179  *nodename = "SIMILAR";
3180  if (strcmp(strVal(linitial(aexpr->name)), "~") == 0)
3181  group = PREC_GROUP_LIKE;
3182  else
3183  group = PREC_GROUP_NOT_LIKE;
3184  }
3185  else if (aexpr->kind == AEXPR_BETWEEN ||
3186  aexpr->kind == AEXPR_BETWEEN_SYM)
3187  {
3188  Assert(list_length(aexpr->name) == 1);
3189  *nodename = strVal(linitial(aexpr->name));
3190  group = PREC_GROUP_BETWEEN;
3191  }
3192  else if (aexpr->kind == AEXPR_NOT_BETWEEN ||
3193  aexpr->kind == AEXPR_NOT_BETWEEN_SYM)
3194  {
3195  Assert(list_length(aexpr->name) == 1);
3196  *nodename = strVal(linitial(aexpr->name));
3197  group = PREC_GROUP_NOT_BETWEEN;
3198  }
3199  }
3200  else if (IsA(node, NullTest) ||
3201  IsA(node, BooleanTest))
3202  {
3203  *nodename = "IS";
3204  group = PREC_GROUP_POSTFIX_IS;
3205  }
3206  else if (IsA(node, XmlExpr))
3207  {
3208  XmlExpr *x = (XmlExpr *) node;
3209 
3210  if (x->op == IS_DOCUMENT)
3211  {
3212  *nodename = "IS";
3213  group = PREC_GROUP_POSTFIX_IS;
3214  }
3215  }
3216  else if (IsA(node, SubLink))
3217  {
3218  SubLink *s = (SubLink *) node;
3219 
3220  if (s->subLinkType == ANY_SUBLINK ||
3221  s->subLinkType == ALL_SUBLINK)
3222  {
3223  if (s->operName == NIL)
3224  {
3225  *nodename = "IN";
3226  group = PREC_GROUP_IN;
3227  }
3228  else
3229  {
3230  *nodename = strVal(llast(s->operName));
3231  group = PREC_GROUP_POSTFIX_OP;
3232  }
3233  }
3234  }
3235  else if (IsA(node, BoolExpr))
3236  {
3237  /*
3238  * Must dig into NOTs to see if it's IS NOT DOCUMENT or NOT IN. This
3239  * opens us to possibly misrecognizing, eg, NOT (x IS DOCUMENT) as a
3240  * problematic construct. We can tell the difference by checking
3241  * whether the parse locations of the two nodes are identical.
3242  *
3243  * Note that when we are comparing the child node to its own children,
3244  * we will not know that it was a NOT. Fortunately, that doesn't
3245  * matter for these cases.
3246  */
3247  BoolExpr *b = (BoolExpr *) node;
3248 
3249  if (b->boolop == NOT_EXPR)
3250  {
3251  Node *child = (Node *) linitial(b->args);
3252 
3253  if (IsA(child, XmlExpr))
3254  {
3255  XmlExpr *x = (XmlExpr *) child;
3256 
3257  if (x->op == IS_DOCUMENT &&
3258  x->location == b->location)
3259  {
3260  *nodename = "IS";
3261  group = PREC_GROUP_POSTFIX_IS;
3262  }
3263  }
3264  else if (IsA(child, SubLink))
3265  {
3266  SubLink *s = (SubLink *) child;
3267 
3268  if (s->subLinkType == ANY_SUBLINK && s->operName == NIL &&
3269  s->location == b->location)
3270  {
3271  *nodename = "IN";
3272  group = PREC_GROUP_NOT_IN;
3273  }
3274  }
3275  }
3276  }
3277  return group;
3278 }
#define NIL
Definition: pg_list.h:69
#define PREC_GROUP_PREFIX_OP
Definition: parse_expr.c:64
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
#define PREC_GROUP_INFIX_OP
Definition: parse_expr.c:63
A_Expr_Kind kind
Definition: parsenodes.h:275
#define PREC_GROUP_POSTFIX_IS
Definition: parse_expr.c:51
int location
Definition: primnodes.h:1149
#define PREC_GROUP_IN
Definition: parse_expr.c:58
#define llast(l)
Definition: pg_list.h:131
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
#define PREC_GROUP_INFIX_IS
Definition: parse_expr.c:52
int location
Definition: primnodes.h:563
#define linitial(l)
Definition: pg_list.h:111
#define PREC_GROUP_BETWEEN
Definition: parse_expr.c:57
BoolExprType boolop
Definition: primnodes.h:561
#define PREC_GROUP_NOT_IN
Definition: parse_expr.c:61
Node * rexpr
Definition: parsenodes.h:278
#define PREC_GROUP_NOT_LIKE
Definition: parse_expr.c:59
Node * lexpr
Definition: parsenodes.h:277
#define PREC_GROUP_LIKE
Definition: parse_expr.c:56
XmlExprOp op
Definition: primnodes.h:1141
#define PREC_GROUP_EQUAL
Definition: parse_expr.c:54
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static int list_length(const List *l)
Definition: pg_list.h:89
List * args
Definition: primnodes.h:562
List * name
Definition: parsenodes.h:276
#define PREC_GROUP_LESS
Definition: parse_expr.c:53
#define PREC_GROUP_LESS_EQUAL
Definition: parse_expr.c:55
#define PREC_GROUP_POSTFIX_OP
Definition: parse_expr.c:62
#define PREC_GROUP_NOT_BETWEEN
Definition: parse_expr.c:60
const char* ParseExprKindName ( ParseExprKind  exprKind)

Definition at line 3352 of file parse_expr.c.

References EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, 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_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_NONE, EXPR_KIND_OFFSET, EXPR_KIND_ORDER_BY, EXPR_KIND_OTHER, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_POLICY, EXPR_KIND_RETURNING, EXPR_KIND_SELECT_TARGET, 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_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().

3353 {
3354  switch (exprKind)
3355  {
3356  case EXPR_KIND_NONE:
3357  return "invalid expression context";
3358  case EXPR_KIND_OTHER:
3359  return "extension expression";
3360  case EXPR_KIND_JOIN_ON:
3361  return "JOIN/ON";
3362  case EXPR_KIND_JOIN_USING:
3363  return "JOIN/USING";
3365  return "sub-SELECT in FROM";
3367  return "function in FROM";
3368  case EXPR_KIND_WHERE:
3369  return "WHERE";
3370  case EXPR_KIND_POLICY:
3371  return "POLICY";
3372  case EXPR_KIND_HAVING:
3373  return "HAVING";
3374  case EXPR_KIND_FILTER:
3375  return "FILTER";
3377  return "window PARTITION BY";
3379  return "window ORDER BY";
3381  return "window RANGE";
3383  return "window ROWS";
3385  return "SELECT";
3387  return "INSERT";
3390  return "UPDATE";
3391  case EXPR_KIND_GROUP_BY:
3392  return "GROUP BY";
3393  case EXPR_KIND_ORDER_BY:
3394  return "ORDER BY";
3395  case EXPR_KIND_DISTINCT_ON:
3396  return "DISTINCT ON";
3397  case EXPR_KIND_LIMIT:
3398  return "LIMIT";
3399  case EXPR_KIND_OFFSET:
3400  return "OFFSET";
3401  case EXPR_KIND_RETURNING:
3402  return "RETURNING";
3403  case EXPR_KIND_VALUES:
3405  return "VALUES";
3408  return "CHECK";
3411  return "DEFAULT";
3413  return "index expression";
3415  return "index predicate";
3417  return "USING";
3419  return "EXECUTE";
3421  return "WHEN";
3423  return "PARTITION BY";
3424 
3425  /*
3426  * There is intentionally no default: case here, so that the
3427  * compiler will warn if we add a new ParseExprKind without
3428  * extending this switch. If we do see an unrecognized value at
3429  * runtime, we'll fall through to the "unrecognized" return.
3430  */
3431  }
3432  return "unrecognized expression kind";
3433 }
static Node * transformAExprBetween ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1285 of file parse_expr.c.

References AEXPR_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_NOT_BETWEEN, AEXPR_NOT_BETWEEN_SYM, AEXPR_OP, AEXPR_PAREN, AND_EXPR, generate_unaccent_rules::args, Assert, castNode, copyObject, elog, emit_precedence_warnings(), ERROR, A_Expr::kind, A_Expr::lexpr, linitial, list_length(), list_make2, A_Expr::location, lsecond, makeA_Expr(), makeBoolExpr(), makeSimpleA_Expr(), NIL, NULL, operator_precedence_group(), operator_precedence_warning, OR_EXPR, result, A_Expr::rexpr, and transformExprRecurse().

Referenced by transformExprRecurse().

1286 {
1287  Node *aexpr;
1288  Node *bexpr;
1289  Node *cexpr;
1290  Node *result;
1291  Node *sub1;
1292  Node *sub2;
1293  List *args;
1294 
1295  /* Deconstruct A_Expr into three subexprs */
1296  aexpr = a->lexpr;
1297  args = castNode(List, a->rexpr);
1298  Assert(list_length(args) == 2);
1299  bexpr = (Node *) linitial(args);
1300  cexpr = (Node *) lsecond(args);
1301 
1303  {
1304  int opgroup;
1305  const char *opname;
1306 
1307  opgroup = operator_precedence_group((Node *) a, &opname);
1308  emit_precedence_warnings(pstate, opgroup, opname,
1309  aexpr, cexpr,
1310  a->location);
1311  /* We can ignore bexpr thanks to syntactic restrictions */
1312  /* Wrap subexpressions to prevent extra warnings */
1313  aexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, aexpr, NULL, -1);
1314  bexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, bexpr, NULL, -1);
1315  cexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, cexpr, NULL, -1);
1316  }
1317 
1318  /*
1319  * Build the equivalent comparison expression. Make copies of
1320  * multiply-referenced subexpressions for safety. (XXX this is really
1321  * wrong since it results in multiple runtime evaluations of what may be
1322  * volatile expressions ...)
1323  *
1324  * Ideally we would not use hard-wired operators here but instead use
1325  * opclasses. However, mixed data types and other issues make this
1326  * difficult:
1327  * http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
1328  */
1329  switch (a->kind)
1330  {
1331  case AEXPR_BETWEEN:
1332  args = list_make2(makeSimpleA_Expr(AEXPR_OP, ">=",
1333  aexpr, bexpr,
1334  a->location),
1335  makeSimpleA_Expr(AEXPR_OP, "<=",
1336  copyObject(aexpr), cexpr,
1337  a->location));
1338  result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1339  break;
1340  case AEXPR_NOT_BETWEEN:
1341  args = list_make2(makeSimpleA_Expr(AEXPR_OP, "<",
1342  aexpr, bexpr,
1343  a->location),
1345  copyObject(aexpr), cexpr,
1346  a->location));
1347  result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1348  break;
1349  case AEXPR_BETWEEN_SYM:
1350  args = list_make2(makeSimpleA_Expr(AEXPR_OP, ">=",
1351  aexpr, bexpr,
1352  a->location),
1353  makeSimpleA_Expr(AEXPR_OP, "<=",
1354  copyObject(aexpr), cexpr,
1355  a->location));
1356  sub1 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1357  args = list_make2(makeSimpleA_Expr(AEXPR_OP, ">=",
1358  copyObject(aexpr), copyObject(cexpr),
1359  a->location),
1360  makeSimpleA_Expr(AEXPR_OP, "<=",
1361  copyObject(aexpr), copyObject(bexpr),
1362  a->location));
1363  sub2 = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1364  args = list_make2(sub1, sub2);
1365  result = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1366  break;
1367  case AEXPR_NOT_BETWEEN_SYM:
1368  args = list_make2(makeSimpleA_Expr(AEXPR_OP, "<",
1369  aexpr, bexpr,
1370  a->location),
1372  copyObject(aexpr), cexpr,
1373  a->location));
1374  sub1 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1375  args = list_make2(makeSimpleA_Expr(AEXPR_OP, "<",
1376  copyObject(aexpr), copyObject(cexpr),
1377  a->location),
1379  copyObject(aexpr), copyObject(bexpr),
1380  a->location));
1381  sub2 = (Node *) makeBoolExpr(OR_EXPR, args, a->location);
1382  args = list_make2(sub1, sub2);
1383  result = (Node *) makeBoolExpr(AND_EXPR, args, a->location);
1384  break;
1385  default:
1386  elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
1387  result = NULL; /* keep compiler quiet */
1388  break;
1389  }
1390 
1391  return transformExprRecurse(pstate, result);
1392 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
A_Expr_Kind kind
Definition: parsenodes.h:275
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
static int operator_precedence_group(Node *node, const char **nodename)
Definition: parse_expr.c:3050
Definition: nodes.h:509
return result
Definition: formatting.c:1632
A_Expr * makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location)
Definition: makefuncs.c:49
#define lsecond(l)
Definition: pg_list.h:116
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:366
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
A_Expr * makeA_Expr(A_Expr_Kind kind, List *name, Node *lexpr, Node *rexpr, int location)
Definition: makefuncs.c:31
Node * lexpr
Definition: parsenodes.h:277
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static int list_length(const List *l)
Definition: pg_list.h:89
#define elog
Definition: elog.h:219
#define copyObject(obj)
Definition: nodes.h:621
Definition: pg_list.h:45
static Node * transformAExprDistinct ( ParseState pstate,
A_Expr a 
)
static

Definition at line 990 of file parse_expr.c.

References AEXPR_NOT_DISTINCT, emit_precedence_warnings(), exprIsNullConstant(), IsA, A_Expr::kind, A_Expr::lexpr, list_make1, A_Expr::location, make_distinct_op(), make_nulltest_from_distinct(), make_row_distinct_op(), makeBoolExpr(), A_Expr::name, NOT_EXPR, operator_precedence_warning, PREC_GROUP_INFIX_IS, result, A_Expr::rexpr, and transformExprRecurse().

Referenced by transformExprRecurse().

991 {
992  Node *lexpr = a->lexpr;
993  Node *rexpr = a->rexpr;
994  Node *result;
995 
998  lexpr, rexpr,
999  a->location);
1000 
1001  /*
1002  * If either input is an undecorated NULL literal, transform to a NullTest
1003  * on the other input. That's simpler to process than a full DistinctExpr,
1004  * and it avoids needing to require that the datatype have an = operator.
1005  */
1006  if (exprIsNullConstant(rexpr))
1007  return make_nulltest_from_distinct(pstate, a, lexpr);
1008  if (exprIsNullConstant(lexpr))
1009  return make_nulltest_from_distinct(pstate, a, rexpr);
1010 
1011  lexpr = transformExprRecurse(pstate, lexpr);
1012  rexpr = transformExprRecurse(pstate, rexpr);
1013 
1014  if (lexpr && IsA(lexpr, RowExpr) &&
1015  rexpr && IsA(rexpr, RowExpr))
1016  {
1017  /* ROW() op ROW() is handled specially */
1018  result = make_row_distinct_op(pstate, a->name,
1019  (RowExpr *) lexpr,
1020  (RowExpr *) rexpr,
1021  a->location);
1022  }
1023  else
1024  {
1025  /* Ordinary scalar operator */
1026  result = (Node *) make_distinct_op(pstate,
1027  a->name,
1028  lexpr,
1029  rexpr,
1030  a->location);
1031  }
1032 
1033  /*
1034  * If it's NOT DISTINCT, we first build a DistinctExpr and then stick a
1035  * NOT on top.
1036  */
1037  if (a->kind == AEXPR_NOT_DISTINCT)
1038  result = (Node *) makeBoolExpr(NOT_EXPR,
1039  list_make1(result),
1040  a->location);
1041 
1042  return result;
1043 }
static bool exprIsNullConstant(Node *arg)
Definition: parse_expr.c:833
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
A_Expr_Kind kind
Definition: parsenodes.h:275
Definition: nodes.h:509
static Expr * make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_expr.c:2998
#define PREC_GROUP_INFIX_IS
Definition: parse_expr.c:52
return result
Definition: formatting.c:1632
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:366
#define list_make1(x1)
Definition: pg_list.h:139
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
Node * lexpr
Definition: parsenodes.h:277
bool operator_precedence_warning
Definition: parse_expr.c:44
static Node * make_row_distinct_op(ParseState *pstate, List *opname, RowExpr *lrow, RowExpr *rrow, int location)
Definition: parse_expr.c:2954
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
static Node * make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg)
Definition: parse_expr.c:3024
List * name
Definition: parsenodes.h:276
static Node * transformAExprIn ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1126 of file parse_expr.c.

References AND_EXPR, generate_unaccent_rules::args, ArrayExpr::array_typeid, cmp(), coerce_to_boolean(), coerce_to_common_type(), contain_vars_of_level(), copyObject, ArrayExpr::element_typeid, ArrayExpr::elements, emit_precedence_warnings(), get_array_type(), InvalidOid, IsA, lappend(), A_Expr::lexpr, lfirst, linitial, list_concat(), list_length(), list_make1, list_make2, A_Expr::location, ArrayExpr::location, make_op(), make_row_comparison_op(), make_scalar_array_op(), makeBoolExpr(), makeNode, ArrayExpr::multidims, A_Expr::name, NIL, NULL, OidIsValid, operator_precedence_warning, OR_EXPR, PREC_GROUP_IN, PREC_GROUP_NOT_IN, RECORDOID, result, A_Expr::rexpr, select_common_type(), strVal, and transformExprRecurse().

Referenced by transformExprRecurse().

1127 {
1128  Node *result = NULL;
1129  Node *lexpr;
1130  List *rexprs;
1131  List *rvars;
1132  List *rnonvars;
1133  bool useOr;
1134  ListCell *l;
1135 
1136  /*
1137  * If the operator is <>, combine with AND not OR.
1138  */
1139  if (strcmp(strVal(linitial(a->name)), "<>") == 0)
1140  useOr = false;
1141  else
1142  useOr = true;
1143 
1145  emit_precedence_warnings(pstate,
1146  useOr ? PREC_GROUP_IN : PREC_GROUP_NOT_IN,
1147  "IN",
1148  a->lexpr, NULL,
1149  a->location);
1150 
1151  /*
1152  * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
1153  * possible if there is a suitable array type available. If not, we fall
1154  * back to a boolean condition tree with multiple copies of the lefthand
1155  * expression. Also, any IN-list items that contain Vars are handled as
1156  * separate boolean conditions, because that gives the planner more scope
1157  * for optimization on such clauses.
1158  *
1159  * First step: transform all the inputs, and detect whether any contain
1160  * Vars.
1161  */
1162  lexpr = transformExprRecurse(pstate, a->lexpr);
1163  rexprs = rvars = rnonvars = NIL;
1164  foreach(l, (List *) a->rexpr)
1165  {
1166  Node *rexpr = transformExprRecurse(pstate, lfirst(l));
1167 
1168  rexprs = lappend(rexprs, rexpr);
1169  if (contain_vars_of_level(rexpr, 0))
1170  rvars = lappend(rvars, rexpr);
1171  else
1172  rnonvars = lappend(rnonvars, rexpr);
1173  }
1174 
1175  /*
1176  * ScalarArrayOpExpr is only going to be useful if there's more than one
1177  * non-Var righthand item.
1178  */
1179  if (list_length(rnonvars) > 1)
1180  {
1181  List *allexprs;
1182  Oid scalar_type;
1183  Oid array_type;
1184 
1185  /*
1186  * Try to select a common type for the array elements. Note that
1187  * since the LHS' type is first in the list, it will be preferred when
1188  * there is doubt (eg, when all the RHS items are unknown literals).
1189  *
1190  * Note: use list_concat here not lcons, to avoid damaging rnonvars.
1191  */
1192  allexprs = list_concat(list_make1(lexpr), rnonvars);
1193  scalar_type = select_common_type(pstate, allexprs, NULL, NULL);
1194 
1195  /*
1196  * Do we have an array type to use? Aside from the case where there
1197  * isn't one, we don't risk using ScalarArrayOpExpr when the common
1198  * type is RECORD, because the RowExpr comparison logic below can cope
1199  * with some cases of non-identical row types.
1200  */
1201  if (OidIsValid(scalar_type) && scalar_type != RECORDOID)
1202  array_type = get_array_type(scalar_type);
1203  else
1204  array_type = InvalidOid;
1205  if (array_type != InvalidOid)
1206  {
1207  /*
1208  * OK: coerce all the right-hand non-Var inputs to the common type
1209  * and build an ArrayExpr for them.
1210  */
1211  List *aexprs;
1212  ArrayExpr *newa;
1213 
1214  aexprs = NIL;
1215  foreach(l, rnonvars)
1216  {
1217  Node *rexpr = (Node *) lfirst(l);
1218 
1219  rexpr = coerce_to_common_type(pstate, rexpr,
1220  scalar_type,
1221  "IN");
1222  aexprs = lappend(aexprs, rexpr);
1223  }
1224  newa = makeNode(ArrayExpr);
1225  newa->array_typeid = array_type;
1226  /* array_collid will be set by parse_collate.c */
1227  newa->element_typeid = scalar_type;
1228  newa->elements = aexprs;
1229  newa->multidims = false;
1230  newa->location = -1;
1231 
1232  result = (Node *) make_scalar_array_op(pstate,
1233  a->name,
1234  useOr,
1235  lexpr,
1236  (Node *) newa,
1237  a->location);
1238 
1239  /* Consider only the Vars (if any) in the loop below */
1240  rexprs = rvars;
1241  }
1242  }
1243 
1244  /*
1245  * Must do it the hard way, ie, with a boolean expression tree.
1246  */
1247  foreach(l, rexprs)
1248  {
1249  Node *rexpr = (Node *) lfirst(l);
1250  Node *cmp;
1251 
1252  if (IsA(lexpr, RowExpr) &&
1253  IsA(rexpr, RowExpr))
1254  {
1255  /* ROW() op ROW() is handled specially */
1256  cmp = make_row_comparison_op(pstate,
1257  a->name,
1258  copyObject(((RowExpr *) lexpr)->args),
1259  ((RowExpr *) rexpr)->args,
1260  a->location);
1261  }
1262  else
1263  {
1264  /* Ordinary scalar operator */
1265  cmp = (Node *) make_op(pstate,
1266  a->name,
1267  copyObject(lexpr),
1268  rexpr,
1269  a->location);
1270  }
1271 
1272  cmp = coerce_to_boolean(pstate, cmp, "IN");
1273  if (result == NULL)
1274  result = cmp;
1275  else
1276  result = (Node *) makeBoolExpr(useOr ? OR_EXPR : AND_EXPR,
1277  list_make2(result, cmp),
1278  a->location);
1279  }
1280 
1281  return result;
1282 }
#define list_make2(x1, x2)
Definition: pg_list.h:140
bool multidims
Definition: primnodes.h:955
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:858
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2512
#define PREC_GROUP_IN
Definition: parse_expr.c:58
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
Oid array_typeid
Definition: primnodes.h:951
List * list_concat(List *list1, List *list2)
Definition: list.c:321
return result
Definition: formatting.c:1632
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:742
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static Node * make_row_comparison_op(ParseState *pstate, List *opname, List *largs, List *rargs, int location)
Definition: parse_expr.c:2753
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:366
#define list_make1(x1)
Definition: pg_list.h:139
#define linitial(l)
Definition: pg_list.h:111
#define PREC_GROUP_NOT_IN
Definition: parse_expr.c:61
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
#define RECORDOID
Definition: pg_type.h:680
List * elements
Definition: primnodes.h:954
Node * lexpr
Definition: parsenodes.h:277
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
List * lappend(List *list, void *datum)
Definition: list.c:128
int location
Definition: primnodes.h:956
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define InvalidOid
Definition: postgres_ext.h:36
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:369
static int list_length(const List *l)
Definition: pg_list.h:89
List * name
Definition: parsenodes.h:276
Oid element_typeid
Definition: primnodes.h:953
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
#define copyObject(obj)
Definition: nodes.h:621
Definition: pg_list.h:45
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
static Node * transformAExprNullIf ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1046 of file parse_expr.c.

References OpExpr::args, BOOLOID, ereport, errcode(), errmsg(), ERROR, exprType(), A_Expr::lexpr, linitial, A_Expr::location, make_op(), A_Expr::name, NodeSetTag, OpExpr::opresulttype, parser_errposition(), result, A_Expr::rexpr, T_NullIfExpr, and transformExprRecurse().

Referenced by transformExprRecurse().

1047 {
1048  Node *lexpr = transformExprRecurse(pstate, a->lexpr);
1049  Node *rexpr = transformExprRecurse(pstate, a->rexpr);
1050  OpExpr *result;
1051 
1052  result = (OpExpr *) make_op(pstate,
1053  a->name,
1054  lexpr,
1055  rexpr,
1056  a->location);
1057 
1058  /*
1059  * The comparison operator itself should yield boolean ...
1060  */
1061  if (result->opresulttype != BOOLOID)
1062  ereport(ERROR,
1063  (errcode(ERRCODE_DATATYPE_MISMATCH),
1064  errmsg("NULLIF requires = operator to yield boolean"),
1065  parser_errposition(pstate, a->location)));
1066 
1067  /*
1068  * ... but the NullIfExpr will yield the first operand's type.
1069  */
1070  result->opresulttype = exprType((Node *) linitial(result->args));
1071 
1072  /*
1073  * We rely on NullIfExpr and OpExpr being the same struct
1074  */
1075  NodeSetTag(result, T_NullIfExpr);
1076 
1077  return (Node *) result;
1078 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define NodeSetTag(nodeptr, t)
Definition: nodes.h:558
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1632
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:742
Oid opresulttype
Definition: primnodes.h:497
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
#define ereport(elevel, rest)
Definition: elog.h:122
Node * lexpr
Definition: parsenodes.h:277
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
#define BOOLOID
Definition: pg_type.h:288
List * name
Definition: parsenodes.h:276
int errmsg(const char *fmt,...)
Definition: elog.c:797
List * args
Definition: primnodes.h:501
static Node * transformAExprOf ( ParseState pstate,
A_Expr a 
)
static

Definition at line 1085 of file parse_expr.c.

References emit_precedence_warnings(), exprLocation(), exprType(), A_Expr::lexpr, lfirst, linitial, Const::location, A_Expr::location, makeBoolConst(), A_Expr::name, NULL, operator_precedence_warning, PREC_GROUP_POSTFIX_IS, result, A_Expr::rexpr, strVal, transformExprRecurse(), and typenameTypeId().

Referenced by transformExprRecurse().

1086 {
1087  Node *lexpr = a->lexpr;
1088  Const *result;
1089  ListCell *telem;
1090  Oid ltype,
1091  rtype;
1092  bool matched = false;
1093 
1096  lexpr, NULL,
1097  a->location);
1098 
1099  lexpr = transformExprRecurse(pstate, lexpr);
1100 
1101  ltype = exprType(lexpr);
1102  foreach(telem, (List *) a->rexpr)
1103  {
1104  rtype = typenameTypeId(pstate, lfirst(telem));
1105  matched = (rtype == ltype);
1106  if (matched)
1107  break;
1108  }
1109 
1110  /*
1111  * We have two forms: equals or not equals. Flip the sense of the result
1112  * for not equals.
1113  */
1114  if (strcmp(strVal(linitial(a->name)), "<>") == 0)
1115  matched = (!matched);
1116 
1117  result = (Const *) makeBoolConst(matched, false);
1118 
1119  /* Make the result have the original input's parse location */
1120  result->location = exprLocation((Node *) a);
1121 
1122  return (Node *) result;
1123 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1214
#define PREC_GROUP_POSTFIX_IS
Definition: parse_expr.c:51
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
return result
Definition: formatting.c:1632
unsigned int Oid
Definition: postgres_ext.h:31
#define linitial(l)
Definition: pg_list.h:111
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:354
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
Node * lexpr
Definition: parsenodes.h:277
int location
Definition: primnodes.h:203
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
List * name
Definition: parsenodes.h:276
Definition: pg_list.h:45
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:274
static Node * transformAExprOp ( ParseState pstate,
A_Expr a 
)
static

Definition at line 846 of file parse_expr.c.

References AEXPR_PAREN, NullTest::arg, generate_unaccent_rules::args, castNode, emit_precedence_warnings(), EXPR_SUBLINK, exprIsNullConstant(), IS_NULL, IsA, A_Expr::lexpr, linitial, list_length(), A_Expr::location, SubLink::location, NullTest::location, make_op(), make_row_comparison_op(), makeNode, A_Expr::name, NullTest::nulltesttype, operator_precedence_group(), operator_precedence_warning, SubLink::operName, result, A_Expr::rexpr, ROWCOMPARE_SUBLINK, strVal, SubLink::subLinkType, SubLink::testexpr, Transform_null_equals, and transformExprRecurse().

Referenced by transformExprRecurse().

847 {
848  Node *lexpr = a->lexpr;
849  Node *rexpr = a->rexpr;
850  Node *result;
851 
853  {
854  int opgroup;
855  const char *opname;
856 
857  opgroup = operator_precedence_group((Node *) a, &opname);
858  if (opgroup > 0)
859  emit_precedence_warnings(pstate, opgroup, opname,
860  lexpr, rexpr,
861  a->location);
862 
863  /* Look through AEXPR_PAREN nodes so they don't affect tests below */
864  while (lexpr && IsA(lexpr, A_Expr) &&
865  ((A_Expr *) lexpr)->kind == AEXPR_PAREN)
866  lexpr = ((A_Expr *) lexpr)->lexpr;
867  while (rexpr && IsA(rexpr, A_Expr) &&
868  ((A_Expr *) rexpr)->kind == AEXPR_PAREN)
869  rexpr = ((A_Expr *) rexpr)->lexpr;
870  }
871 
872  /*
873  * Special-case "foo = NULL" and "NULL = foo" for compatibility with
874  * standards-broken products (like Microsoft's). Turn these into IS NULL
875  * exprs. (If either side is a CaseTestExpr, then the expression was
876  * generated internally from a CASE-WHEN expression, and
877  * transform_null_equals does not apply.)
878  */
879  if (Transform_null_equals &&
880  list_length(a->name) == 1 &&
881  strcmp(strVal(linitial(a->name)), "=") == 0 &&
882  (exprIsNullConstant(lexpr) || exprIsNullConstant(rexpr)) &&
883  (!IsA(lexpr, CaseTestExpr) &&!IsA(rexpr, CaseTestExpr)))
884  {
885  NullTest *n = makeNode(NullTest);
886 
887  n->nulltesttype = IS_NULL;
888  n->location = a->location;
889 
890  if (exprIsNullConstant(lexpr))
891  n->arg = (Expr *) rexpr;
892  else
893  n->arg = (Expr *) lexpr;
894 
895  result = transformExprRecurse(pstate, (Node *) n);
896  }
897  else if (lexpr && IsA(lexpr, RowExpr) &&
898  rexpr && IsA(rexpr, SubLink) &&
899  ((SubLink *) rexpr)->subLinkType == EXPR_SUBLINK)
900  {
901  /*
902  * Convert "row op subselect" into a ROWCOMPARE sublink. Formerly the
903  * grammar did this, but now that a row construct is allowed anywhere
904  * in expressions, it's easier to do it here.
905  */
906  SubLink *s = (SubLink *) rexpr;
907 
909  s->testexpr = lexpr;
910  s->operName = a->name;
911  s->location = a->location;
912  result = transformExprRecurse(pstate, (Node *) s);
913  }
914  else if (lexpr && IsA(lexpr, RowExpr) &&
915  rexpr && IsA(rexpr, RowExpr))
916  {
917  /* ROW() op ROW() is handled specially */
918  lexpr = transformExprRecurse(pstate, lexpr);
919  rexpr = transformExprRecurse(pstate, rexpr);
920 
921  result = make_row_comparison_op(pstate,
922  a->name,
923  castNode(RowExpr, lexpr)->args,
924  castNode(RowExpr, rexpr)->args,
925  a->location);
926  }
927  else
928  {
929  /* Ordinary scalar operator */
930  lexpr = transformExprRecurse(pstate, lexpr);
931  rexpr = transformExprRecurse(pstate, rexpr);
932 
933  result = (Node *) make_op(pstate,
934  a->name,
935  lexpr,
936  rexpr,
937  a->location);
938  }
939 
940  return result;
941 }
static bool exprIsNullConstant(Node *arg)
Definition: parse_expr.c:833
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
static int operator_precedence_group(Node *node, const char **nodename)
Definition: parse_expr.c:3050
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
return result
Definition: formatting.c:1632
Expr * make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:742
static Node * make_row_comparison_op(ParseState *pstate, List *opname, List *largs, List *rargs, int location)
Definition: parse_expr.c:2753
#define linitial(l)
Definition: pg_list.h:111
Expr * arg
Definition: primnodes.h:1179
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
Node * lexpr
Definition: parsenodes.h:277
bool Transform_null_equals
Definition: parse_expr.c:45
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
NullTestType nulltesttype
Definition: primnodes.h:1180
#define makeNode(_type_)
Definition: nodes.h:557
int location
Definition: primnodes.h:1182
static int list_length(const List *l)
Definition: pg_list.h:89
List * name
Definition: parsenodes.h:276
static Node * transformAExprOpAll ( ParseState pstate,
A_Expr a 
)
static

Definition at line 967 of file parse_expr.c.

References emit_precedence_warnings(), A_Expr::lexpr, llast, A_Expr::location, make_scalar_array_op(), A_Expr::name, NULL, operator_precedence_warning, PREC_GROUP_POSTFIX_OP, A_Expr::rexpr, strVal, and transformExprRecurse().

Referenced by transformExprRecurse().

968 {
969  Node *lexpr = a->lexpr;
970  Node *rexpr = a->rexpr;
971 
974  strVal(llast(a->name)),
975  lexpr, NULL,
976  a->location);
977 
978  lexpr = transformExprRecurse(pstate, lexpr);
979  rexpr = transformExprRecurse(pstate, rexpr);
980 
981  return (Node *) make_scalar_array_op(pstate,
982  a->name,
983  false,
984  lexpr,
985  rexpr,
986  a->location);
987 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:858
#define llast(l)
Definition: pg_list.h:131
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
Node * lexpr
Definition: parsenodes.h:277
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define NULL
Definition: c.h:229
List * name
Definition: parsenodes.h:276
#define PREC_GROUP_POSTFIX_OP
Definition: parse_expr.c:62
static Node * transformAExprOpAny ( ParseState pstate,
A_Expr a 
)
static

Definition at line 944 of file parse_expr.c.

References emit_precedence_warnings(), A_Expr::lexpr, llast, A_Expr::location, make_scalar_array_op(), A_Expr::name, NULL, operator_precedence_warning, PREC_GROUP_POSTFIX_OP, A_Expr::rexpr, strVal, and transformExprRecurse().

Referenced by transformExprRecurse().

945 {
946  Node *lexpr = a->lexpr;
947  Node *rexpr = a->rexpr;
948 
951  strVal(llast(a->name)),
952  lexpr, NULL,
953  a->location);
954 
955  lexpr = transformExprRecurse(pstate, lexpr);
956  rexpr = transformExprRecurse(pstate, rexpr);
957 
958  return (Node *) make_scalar_array_op(pstate,
959  a->name,
960  true,
961  lexpr,
962  rexpr,
963  a->location);
964 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Expr * make_scalar_array_op(ParseState *pstate, List *opname, bool useOr, Node *ltree, Node *rtree, int location)
Definition: parse_oper.c:858
#define llast(l)
Definition: pg_list.h:131
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
Node * rexpr
Definition: parsenodes.h:278
int location
Definition: parsenodes.h:279
Node * lexpr
Definition: parsenodes.h:277
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define NULL
Definition: c.h:229
List * name
Definition: parsenodes.h:276
#define PREC_GROUP_POSTFIX_OP
Definition: parse_expr.c:62
static Node * transformArrayExpr ( ParseState pstate,
A_ArrayExpr a,
Oid  array_type,
Oid  element_type,
int32  typmod 
)
static

Definition at line 1987 of file parse_expr.c.

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

Referenced by transformExprRecurse(), and transformTypeCast().

1989 {
1990  ArrayExpr *newa = makeNode(ArrayExpr);
1991  List *newelems = NIL;
1992  List *newcoercedelems = NIL;
1993  ListCell *element;
1994  Oid coerce_type;
1995  bool coerce_hard;
1996 
1997  /*
1998  * Transform the element expressions
1999  *
2000  * Assume that the array is one-dimensional unless we find an array-type
2001  * element expression.
2002  */
2003  newa->multidims = false;
2004  foreach(element, a->elements)
2005  {
2006  Node *e = (Node *) lfirst(element);
2007  Node *newe;
2008 
2009  /* Look through AEXPR_PAREN nodes so they don't affect test below */
2010  while (e && IsA(e, A_Expr) &&
2011  ((A_Expr *) e)->kind == AEXPR_PAREN)
2012  e = ((A_Expr *) e)->lexpr;
2013 
2014  /*
2015  * If an element is itself an A_ArrayExpr, recurse directly so that we
2016  * can pass down any target type we were given.
2017  */
2018  if (IsA(e, A_ArrayExpr))
2019  {
2020  newe = transformArrayExpr(pstate,
2021  (A_ArrayExpr *) e,
2022  array_type,
2023  element_type,
2024  typmod);
2025  /* we certainly have an array here */
2026  Assert(array_type == InvalidOid || array_type == exprType(newe));
2027  newa->multidims = true;
2028  }
2029  else
2030  {
2031  newe = transformExprRecurse(pstate, e);
2032 
2033  /*
2034  * Check for sub-array expressions, if we haven't already found
2035  * one.
2036  */
2037  if (!newa->multidims && type_is_array(exprType(newe)))
2038  newa->multidims = true;
2039  }
2040 
2041  newelems = lappend(newelems, newe);
2042  }
2043 
2044  /*
2045  * Select a target type for the elements.
2046  *
2047  * If we haven't been given a target array type, we must try to deduce a
2048  * common type based on the types of the individual elements present.
2049  */
2050  if (OidIsValid(array_type))
2051  {
2052  /* Caller must ensure array_type matches element_type */
2053  Assert(OidIsValid(element_type));
2054  coerce_type = (newa->multidims ? array_type : element_type);
2055  coerce_hard = true;
2056  }
2057  else
2058  {
2059  /* Can't handle an empty array without a target type */
2060  if (newelems == NIL)
2061  ereport(ERROR,
2062  (errcode(ERRCODE_INDETERMINATE_DATATYPE),
2063  errmsg("cannot determine type of empty array"),
2064  errhint("Explicitly cast to the desired type, "
2065  "for example ARRAY[]::integer[]."),
2066  parser_errposition(pstate, a->location)));
2067 
2068  /* Select a common type for the elements */
2069  coerce_type = select_common_type(pstate, newelems, "ARRAY", NULL);
2070 
2071  if (newa->multidims)
2072  {
2073  array_type = coerce_type;
2074  element_type = get_element_type(array_type);
2075  if (!OidIsValid(element_type))
2076  ereport(ERROR,
2077  (errcode(ERRCODE_UNDEFINED_OBJECT),
2078  errmsg("could not find element type for data type %s",
2079  format_type_be(array_type)),
2080  parser_errposition(pstate, a->location)));
2081  }
2082  else
2083  {
2084  element_type = coerce_type;
2085  array_type = get_array_type(element_type);
2086  if (!OidIsValid(array_type))
2087  ereport(ERROR,
2088  (errcode(ERRCODE_UNDEFINED_OBJECT),
2089  errmsg("could not find array type for data type %s",
2090  format_type_be(element_type)),
2091  parser_errposition(pstate, a->location)));
2092  }
2093  coerce_hard = false;
2094  }
2095 
2096  /*
2097  * Coerce elements to target type
2098  *
2099  * If the array has been explicitly cast, then the elements are in turn
2100  * explicitly coerced.
2101  *
2102  * If the array's type was merely derived from the common type of its
2103  * elements, then the elements are implicitly coerced to the common type.
2104  * This is consistent with other uses of select_common_type().
2105  */
2106  foreach(element, newelems)
2107  {
2108  Node *e = (Node *) lfirst(element);
2109  Node *newe;
2110 
2111  if (coerce_hard)
2112  {
2113  newe = coerce_to_target_type(pstate, e,
2114  exprType(e),
2115  coerce_type,
2116  typmod,
2119  -1);
2120  if (newe == NULL)
2121  ereport(ERROR,
2122  (errcode(ERRCODE_CANNOT_COERCE),
2123  errmsg("cannot cast type %s to %s",
2125  format_type_be(coerce_type)),
2126  parser_errposition(pstate, exprLocation(e))));
2127  }
2128  else
2129  newe = coerce_to_common_type(pstate, e,
2130  coerce_type,
2131  "ARRAY");
2132  newcoercedelems = lappend(newcoercedelems, newe);
2133  }
2134 
2135  newa->array_typeid = array_type;
2136  /* array_collid will be set by parse_collate.c */
2137  newa->element_typeid = element_type;
2138  newa->elements = newcoercedelems;
2139  newa->location = a->location;
2140 
2141  return (Node *) newa;
2142 }
bool multidims
Definition: primnodes.h:955
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
int errhint(const char *fmt,...)
Definition: elog.c:987
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1214
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2484
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2512
Node * coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:156
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
Oid array_typeid
Definition: primnodes.h:951
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define ERROR
Definition: elog.h:43
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:77
static Node * transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, Oid array_type, Oid element_type, int32 typmod)
Definition: parse_expr.c:1987
List * elements
Definition: parsenodes.h:415
List * elements
Definition: primnodes.h:954
#define ereport(elevel, rest)
Definition: elog.h:122
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
List * lappend(List *list, void *datum)
Definition: list.c:128
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:380
int location
Definition: primnodes.h:956
#define InvalidOid
Definition: postgres_ext.h:36
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
#define type_is_array(typid)
Definition: lsyscache.h:180
Oid element_typeid
Definition: primnodes.h:953
e
Definition: preproc-init.c:82
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
Definition: pg_list.h:45
static Node * transformBooleanTest ( ParseState pstate,
BooleanTest b 
)
static

Definition at line 2483 of file parse_expr.c.

References BooleanTest::arg, BooleanTest::booltesttype, coerce_to_boolean(), elog, emit_precedence_warnings(), ERROR, IS_FALSE, IS_NOT_FALSE, IS_NOT_TRUE, IS_NOT_UNKNOWN, IS_TRUE, IS_UNKNOWN, BooleanTest::location, NULL, operator_precedence_warning, PREC_GROUP_POSTFIX_IS, and transformExprRecurse().

Referenced by transformExprRecurse().

2484 {
2485  const char *clausename;
2486 
2489  (Node *) b->arg, NULL,
2490  b->location);
2491 
2492  switch (b->booltesttype)
2493  {
2494  case IS_TRUE:
2495  clausename = "IS TRUE";
2496  break;
2497  case IS_NOT_TRUE:
2498  clausename = "IS NOT TRUE";
2499  break;
2500  case IS_FALSE:
2501  clausename = "IS FALSE";
2502  break;
2503  case IS_NOT_FALSE:
2504  clausename = "IS NOT FALSE";
2505  break;
2506  case IS_UNKNOWN:
2507  clausename = "IS UNKNOWN";
2508  break;
2509  case IS_NOT_UNKNOWN:
2510  clausename = "IS NOT UNKNOWN";
2511  break;
2512  default:
2513  elog(ERROR, "unrecognized booltesttype: %d",
2514  (int) b->booltesttype);
2515  clausename = NULL; /* keep compiler quiet */
2516  }
2517 
2518  b->arg = (Expr *) transformExprRecurse(pstate, (Node *) b->arg);
2519 
2520  b->arg = (Expr *) coerce_to_boolean(pstate,
2521  (Node *) b->arg,
2522  clausename);
2523 
2524  return (Node *) b;
2525 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define PREC_GROUP_POSTFIX_IS
Definition: parse_expr.c:51
Definition: nodes.h:509
#define ERROR
Definition: elog.h:43
Expr * arg
Definition: primnodes.h:1202
BoolTestType booltesttype
Definition: primnodes.h:1203
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define NULL
Definition: c.h:229
#define elog
Definition: elog.h:219
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
static Node * transformBoolExpr ( ParseState pstate,
BoolExpr a 
)
static

Definition at line 1395 of file parse_expr.c.

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

Referenced by transformExprRecurse().

1396 {
1397  List *args = NIL;
1398  const char *opname;
1399  ListCell *lc;
1400 
1401  switch (a->boolop)
1402  {
1403  case AND_EXPR:
1404  opname = "AND";
1405  break;
1406  case OR_EXPR:
1407  opname = "OR";
1408  break;
1409  case NOT_EXPR:
1410  opname = "NOT";
1411  break;
1412  default:
1413  elog(ERROR, "unrecognized boolop: %d", (int) a->boolop);
1414  opname = NULL; /* keep compiler quiet */
1415  break;
1416  }
1417 
1418  foreach(lc, a->args)
1419  {
1420  Node *arg = (Node *) lfirst(lc);
1421 
1422  arg = transformExprRecurse(pstate, arg);
1423  arg = coerce_to_boolean(pstate, arg, opname);
1424  args = lappend(args, arg);
1425  }
1426 
1427  return (Node *) makeBoolExpr(a->boolop, args, a->location);
1428 }
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Definition: nodes.h:509
int location
Definition: primnodes.h:563
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Definition: makefuncs.c:366
#define ERROR
Definition: elog.h:43
BoolExprType boolop
Definition: primnodes.h:561
List * lappend(List *list, void *datum)
Definition: list.c:128
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * args
Definition: primnodes.h:562
void * arg
#define elog
Definition: elog.h:219
Definition: pg_list.h:45
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
static Node * transformCaseExpr ( ParseState pstate,
CaseExpr c 
)
static

Definition at line 1620 of file parse_expr.c.

References AEXPR_OP, arg, CaseExpr::arg, CaseExpr::args, Assert, assign_expr_collations(), CaseExpr::casetype, coerce_to_boolean(), coerce_to_common_type(), CaseTestExpr::collation, CaseExpr::defresult, CaseWhen::expr, exprCollation(), exprType(), exprTypmod(), lappend(), lcons(), lfirst, lfirst_node, A_Const::location, CaseExpr::location, CaseWhen::location, makeNode, makeSimpleA_Expr(), NIL, NULL, OidIsValid, CaseWhen::result, select_common_type(), T_Null, TEXTOID, transformExprRecurse(), Value::type, CaseTestExpr::typeId, CaseTestExpr::typeMod, UNKNOWNOID, and A_Const::val.

Referenced by transformExprRecurse().

1621 {
1622  CaseExpr *newc;
1623  Node *arg;
1624  CaseTestExpr *placeholder;
1625  List *newargs;
1626  List *resultexprs;
1627  ListCell *l;
1628  Node *defresult;
1629  Oid ptype;
1630 
1631  newc = makeNode(CaseExpr);
1632 
1633  /* transform the test expression, if any */
1634  arg = transformExprRecurse(pstate, (Node *) c->arg);
1635 
1636  /* generate placeholder for test expression */
1637  if (arg)
1638  {
1639  /*
1640  * If test expression is an untyped literal, force it to text. We have
1641  * to do something now because we won't be able to do this coercion on
1642  * the placeholder. This is not as flexible as what was done in 7.4
1643  * and before, but it's good enough to handle the sort of silly coding
1644  * commonly seen.
1645  */
1646  if (exprType(arg) == UNKNOWNOID)
1647  arg = coerce_to_common_type(pstate, arg, TEXTOID, "CASE");
1648 
1649  /*
1650  * Run collation assignment on the test expression so that we know
1651  * what collation to mark the placeholder with. In principle we could
1652  * leave it to parse_collate.c to do that later, but propagating the
1653  * result to the CaseTestExpr would be unnecessarily complicated.
1654  */
1655  assign_expr_collations(pstate, arg);
1656 
1657  placeholder = makeNode(CaseTestExpr);
1658  placeholder->typeId = exprType(arg);
1659  placeholder->typeMod = exprTypmod(arg);
1660  placeholder->collation = exprCollation(arg);
1661  }
1662  else
1663  placeholder = NULL;
1664 
1665  newc->arg = (Expr *) arg;
1666 
1667  /* transform the list of arguments */
1668  newargs = NIL;
1669  resultexprs = NIL;
1670  foreach(l, c->args)
1671  {
1672  CaseWhen *w = lfirst_node(CaseWhen, l);
1673  CaseWhen *neww = makeNode(CaseWhen);
1674  Node *warg;
1675 
1676  warg = (Node *) w->expr;
1677  if (placeholder)
1678  {
1679  /* shorthand form was specified, so expand... */
1680  warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
1681  (Node *) placeholder,
1682  warg,
1683  w->location);
1684  }
1685  neww->expr = (Expr *) transformExprRecurse(pstate, warg);
1686 
1687  neww->expr = (Expr *) coerce_to_boolean(pstate,
1688  (Node *) neww->expr,
1689  "CASE/WHEN");
1690 
1691  warg = (Node *) w->result;
1692  neww->result = (Expr *) transformExprRecurse(pstate, warg);
1693  neww->location = w->location;
1694 
1695  newargs = lappend(newargs, neww);
1696  resultexprs = lappend(resultexprs, neww->result);
1697  }
1698 
1699  newc->args = newargs;
1700 
1701  /* transform the default clause */
1702  defresult = (Node *) c->defresult;
1703  if (defresult == NULL)
1704  {
1705  A_Const *n = makeNode(A_Const);
1706 
1707  n->val.type = T_Null;
1708  n->location = -1;
1709  defresult = (Node *) n;
1710  }
1711  newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
1712 
1713  /*
1714  * Note: default result is considered the most significant type in
1715  * determining preferred type. This is how the code worked before, but it
1716  * seems a little bogus to me --- tgl
1717  */
1718  resultexprs = lcons(newc->defresult, resultexprs);
1719 
1720  ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
1721  Assert(OidIsValid(ptype));
1722  newc->casetype = ptype;
1723  /* casecollid will be set by parse_collate.c */
1724 
1725  /* Convert default result clause, if necessary */
1726  newc->defresult = (Expr *)
1727  coerce_to_common_type(pstate,
1728  (Node *) newc->defresult,
1729  ptype,
1730  "CASE/ELSE");
1731 
1732  /* Convert when-clause results, if necessary */
1733  foreach(l, newc->args)
1734  {
1735  CaseWhen *w = (CaseWhen *) lfirst(l);
1736 
1737  w->result = (Expr *)
1738  coerce_to_common_type(pstate,
1739  (Node *) w->result,
1740  ptype,
1741  "CASE/WHEN");
1742  }
1743 
1744  newc->location = c->location;
1745 
1746  return (Node *) newc;
1747 }
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
#define TEXTOID
Definition: pg_type.h:324
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
Definition: nodes.h:509
Oid casetype
Definition: primnodes.h:905
unsigned int Oid
Definition: postgres_ext.h:31
A_Expr * makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location)
Definition: makefuncs.c:49
#define OidIsValid(objectId)
Definition: c.h:538
int32 typeMod
Definition: primnodes.h:936
int location
Definition: primnodes.h:921
void assign_expr_collations(ParseState *pstate, Node *expr)
#define lfirst_node(type, lc)
Definition: pg_list.h:109
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
List * lappend(List *list, void *datum)
Definition: list.c:128
List * args
Definition: primnodes.h:908
List * lcons(void *datum, List *list)
Definition: list.c:259
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
int location
Definition: parsenodes.h:289
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:748
int location
Definition: primnodes.h:910
#define UNKNOWNOID
Definition: pg_type.h:431
Definition: nodes.h:286
void * arg
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
Expr * arg
Definition: primnodes.h:907
Expr * result
Definition: primnodes.h:920
Expr * defresult
Definition: primnodes.h:909
Expr * expr
Definition: primnodes.h:919
Value val
Definition: parsenodes.h:288
Definition: pg_list.h:45
NodeTag type
Definition: value.h:44
Node * coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName)
static Node * transformCoalesceExpr ( ParseState pstate,
CoalesceExpr c 
)
static

Definition at line 2177 of file parse_expr.c.

References generate_unaccent_rules::args, CoalesceExpr::args, CoalesceExpr::coalescetype, coerce_to_common_type(), lappend(), lfirst, CoalesceExpr::location, makeNode, NIL, NULL, select_common_type(), and transformExprRecurse().

Referenced by transformExprRecurse().

2178 {
2180  List *newargs = NIL;
2181  List *newcoercedargs = NIL;
2182  ListCell *args;
2183 
2184  foreach(args, c->args)
2185  {
2186  Node *e = (Node *) lfirst(args);
2187  Node *newe;
2188 
2189  newe = transformExprRecurse(pstate, e);
2190  newargs = lappend(newargs, newe);
2191  }
2192 
2193  newc->coalescetype = select_common_type(pstate, newargs, "COALESCE", NULL);
2194  /* coalescecollid will be set by parse_collate.c */
2195 
2196  /* Convert arguments if necessary */
2197  foreach(args, newargs)
2198  {
2199  Node *e = (Node *) lfirst(args);
2200  Node *newe;
2201 
2202  newe = coerce_to_common_type(pstate, e,
2203  newc->coalescetype,
2204  "COALESCE");
2205  newcoercedargs = lappend(newcoercedargs, newe);
2206  }
2207 
2208  newc->args = newcoercedargs;
2209  newc->location = c->location;
2210  return (Node *) newc;
2211 }
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Definition: nodes.h:509
List * args
Definition: primnodes.h:1046
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
List * lappend(List *list, void *datum)
Definition: list.c:128
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
e
Definition: preproc-init.c:82
Oid coalescetype
Definition: primnodes.h:1044
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
Definition: pg_list.h:45
static Node * transformCollateClause ( ParseState pstate,
CollateClause c 
)
static

Definition at line 2713 of file parse_expr.c.

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

Referenced by transformExprRecurse().

2714 {
2715  CollateExpr *newc;
2716  Oid argtype;
2717 
2718  newc = makeNode(CollateExpr);
2719  newc->arg = (Expr *) transformExprRecurse(pstate, c->arg);
2720 
2721  argtype = exprType((Node *) newc->arg);
2722 
2723  /*
2724  * The unknown type is not collatable, but coerce_type() takes care of it
2725  * separately, so we'll let it go here.
2726  */
2727  if (!type_is_collatable(argtype) && argtype != UNKNOWNOID)
2728  ereport(ERROR,
2729  (errcode(ERRCODE_DATATYPE_MISMATCH),
2730  errmsg("collations are not supported by type %s",
2731  format_type_be(argtype)),
2732  parser_errposition(pstate, c->location)));
2733 
2734  newc->collOid = LookupCollation(pstate, c->collname, c->location);
2735  newc->location = c->location;
2736 
2737  return (Node *) newc;
2738 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Oid LookupCollation(ParseState *pstate, List *collnames, int location)
Definition: parse_type.c:496
#define makeNode(_type_)
Definition: nodes.h:557
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
Expr * arg
Definition: primnodes.h:875
#define UNKNOWNOID
Definition: pg_type.h:431
List * collname
Definition: parsenodes.h:310
int errmsg(const char *fmt,...)
Definition: elog.c:797
int location
Definition: primnodes.h:877
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:2806
static Node * transformColumnRef ( ParseState pstate,
ColumnRef cref 
)
static

Definition at line 513 of file parse_expr.c.

References Assert, colNameToVar(), ereport, errcode(), errmsg(), ERROR, errorMissingColumn(), errorMissingRTE(), ColumnRef::fields, get_database_name(), IsA, lfourth, linitial, list_length(), list_make1, ColumnRef::location, lsecond, lthird, makeRangeVar(), makeString(), MyDatabaseId, NameListToString(), NULL, ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseFuncOrColumn(), parser_errposition(), refnameRangeTblEntry(), scanRTEForColumn(), strVal, and transformWholeRowRef().

Referenced by transformExprRecurse().

514 {
515  Node *node = NULL;
516  char *nspname = NULL;
517  char *relname = NULL;
518  char *colname = NULL;
519  RangeTblEntry *rte;
520  int levels_up;
521  enum
522  {
523  CRERR_NO_COLUMN,
524  CRERR_NO_RTE,
525  CRERR_WRONG_DB,
526  CRERR_TOO_MANY
527  } crerr = CRERR_NO_COLUMN;
528 
529  /*
530  * Give the PreParseColumnRefHook, if any, first shot. If it returns
531  * non-null then that's all, folks.
532  */
533  if (pstate->p_pre_columnref_hook != NULL)
534  {
535  node = (*pstate->p_pre_columnref_hook) (pstate, cref);
536  if (node != NULL)
537  return node;
538  }
539 
540  /*----------
541  * The allowed syntaxes are:
542  *
543  * A First try to resolve as unqualified column name;
544  * if no luck, try to resolve as unqualified table name (A.*).
545  * A.B A is an unqualified table name; B is either a
546  * column or function name (trying column name first).
547  * A.B.C schema A, table B, col or func name C.
548  * A.B.C.D catalog A, schema B, table C, col or func D.
549  * A.* A is an unqualified table name; means whole-row value.
550  * A.B.* whole-row value of table B in schema A.
551  * A.B.C.* whole-row value of table C in schema B in catalog A.
552  *
553  * We do not need to cope with bare "*"; that will only be accepted by
554  * the grammar at the top level of a SELECT list, and transformTargetList
555  * will take care of it before it ever gets here. Also, "A.*" etc will
556  * be expanded by transformTargetList if they appear at SELECT top level,
557  * so here we are only going to see them as function or operator inputs.
558  *
559  * Currently, if a catalog name is given then it must equal the current
560  * database name; we check it here and then discard it.
561  *----------
562  */
563  switch (list_length(cref->fields))
564  {
565  case 1:
566  {
567  Node *field1 = (Node *) linitial(cref->fields);
568 
569  Assert(IsA(field1, String));
570  colname = strVal(field1);
571 
572  /* Try to identify as an unqualified column */
573  node = colNameToVar(pstate, colname, false, cref->location);
574 
575  if (node == NULL)
576  {
577  /*
578  * Not known as a column of any range-table entry.
579  *
580  * Try to find the name as a relation. Note that only
581  * relations already entered into the rangetable will be
582  * recognized.
583  *
584  * This is a hack for backwards compatibility with
585  * PostQUEL-inspired syntax. The preferred form now is
586  * "rel.*".
587  */
588  rte = refnameRangeTblEntry(pstate, NULL, colname,
589  cref->location,
590  &levels_up);
591  if (rte)
592  node = transformWholeRowRef(pstate, rte,
593  cref->location);
594  }
595  break;
596  }
597  case 2:
598  {
599  Node *field1 = (Node *) linitial(cref->fields);
600  Node *field2 = (Node *) lsecond(cref->fields);
601 
602  Assert(IsA(field1, String));
603  relname = strVal(field1);
604 
605  /* Locate the referenced RTE */
606  rte = refnameRangeTblEntry(pstate, nspname, relname,
607  cref->location,
608  &levels_up);
609  if (rte == NULL)
610  {
611  crerr = CRERR_NO_RTE;
612  break;
613  }
614 
615  /* Whole-row reference? */
616  if (IsA(field2, A_Star))
617  {
618  node = transformWholeRowRef(pstate, rte, cref->location);
619  break;
620  }
621 
622  Assert(IsA(field2, String));
623  colname = strVal(field2);
624 
625  /* Try to identify as a column of the RTE */
626  node = scanRTEForColumn(pstate, rte, colname, cref->location,
627  0, NULL);
628  if (node == NULL)
629  {
630  /* Try it as a function call on the whole row */
631  node = transformWholeRowRef(pstate, rte, cref->location);
632  node = ParseFuncOrColumn(pstate,
633  list_make1(makeString(colname)),
634  list_make1(node),
635  NULL,
636  cref->location);
637  }
638  break;
639  }
640  case 3:
641  {
642  Node *field1 = (Node *) linitial(cref->fields);
643  Node *field2 = (Node *) lsecond(cref->fields);
644  Node *field3 = (Node *) lthird(cref->fields);
645 
646  Assert(IsA(field1, String));
647  nspname = strVal(field1);
648  Assert(IsA(field2, String));
649  relname = strVal(field2);
650 
651  /* Locate the referenced RTE */
652  rte = refnameRangeTblEntry(pstate, nspname, relname,
653  cref->location,
654  &levels_up);
655  if (rte == NULL)
656  {
657  crerr = CRERR_NO_RTE;
658  break;
659  }
660 
661  /* Whole-row reference? */
662  if (IsA(field3, A_Star))
663  {
664  node = transformWholeRowRef(pstate, rte, cref->location);
665  break;
666  }
667 
668  Assert(IsA(field3, String));
669  colname = strVal(field3);
670 
671  /* Try to identify as a column of the RTE */
672  node = scanRTEForColumn(pstate, rte, colname, cref->location,
673  0, NULL);
674  if (node == NULL)
675  {
676  /* Try it as a function call on the whole row */
677  node = transformWholeRowRef(pstate, rte, cref->location);
678  node = ParseFuncOrColumn(pstate,
679  list_make1(makeString(colname)),
680  list_make1(node),
681  NULL,
682  cref->location);
683  }
684  break;
685  }
686  case 4:
687  {
688  Node *field1 = (Node *) linitial(cref->fields);
689  Node *field2 = (Node *) lsecond(cref->fields);
690  Node *field3 = (Node *) lthird(cref->fields);
691  Node *field4 = (Node *) lfourth(cref->fields);
692  char *catname;
693 
694  Assert(IsA(field1, String));
695  catname = strVal(field1);
696  Assert(IsA(field2, String));
697  nspname = strVal(field2);
698  Assert(IsA(field3, String));
699  relname = strVal(field3);
700 
701  /*
702  * We check the catalog name and then ignore it.
703  */
704  if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
705  {
706  crerr = CRERR_WRONG_DB;
707  break;
708  }
709 
710  /* Locate the referenced RTE */
711  rte = refnameRangeTblEntry(pstate, nspname, relname,
712  cref->location,
713  &levels_up);
714  if (rte == NULL)
715  {
716  crerr = CRERR_NO_RTE;
717  break;
718  }
719 
720  /* Whole-row reference? */
721  if (IsA(field4, A_Star))
722  {
723  node = transformWholeRowRef(pstate, rte, cref->location);
724  break;
725  }
726 
727  Assert(IsA(field4, String));
728  colname = strVal(field4);
729 
730  /* Try to identify as a column of the RTE */
731  node = scanRTEForColumn(pstate, rte, colname, cref->location,
732  0, NULL);
733  if (node == NULL)
734  {
735  /* Try it as a function call on the whole row */
736  node = transformWholeRowRef(pstate, rte, cref->location);
737  node = ParseFuncOrColumn(pstate,
738  list_make1(makeString(colname)),
739  list_make1(node),
740  NULL,
741  cref->location);
742  }
743  break;
744  }
745  default:
746  crerr = CRERR_TOO_MANY; /* too many dotted names */
747  break;
748  }
749 
750  /*
751  * Now give the PostParseColumnRefHook, if any, a chance. We pass the
752  * translation-so-far so that it can throw an error if it wishes in the
753  * case that it has a conflicting interpretation of the ColumnRef. (If it
754  * just translates anyway, we'll throw an error, because we can't undo
755  * whatever effects the preceding steps may have had on the pstate.) If it
756  * returns NULL, use the standard translation, or throw a suitable error
757  * if there is none.
758  */
759  if (pstate->p_post_columnref_hook != NULL)
760  {
761  Node *hookresult;
762 
763  hookresult = (*pstate->p_post_columnref_hook) (pstate, cref, node);
764  if (node == NULL)
765  node = hookresult;
766  else if (hookresult != NULL)
767  ereport(ERROR,
768  (errcode(ERRCODE_AMBIGUOUS_COLUMN),
769  errmsg("column reference \"%s\" is ambiguous",
770  NameListToString(cref->fields)),
771  parser_errposition(pstate, cref->location)));
772  }
773 
774  /*
775  * Throw error if no translation found.
776  */
777  if (node == NULL)
778  {
779  switch (crerr)
780  {
781  case CRERR_NO_COLUMN:
782  errorMissingColumn(pstate, relname, colname, cref->location);
783  break;
784  case CRERR_NO_RTE:
785  errorMissingRTE(pstate, makeRangeVar(nspname, relname,
786  cref->location));
787  break;
788  case CRERR_WRONG_DB:
789  ereport(ERROR,
790  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
791  errmsg("cross-database references are not implemented: %s",
792  NameListToString(cref->fields)),
793  parser_errposition(pstate, cref->location)));
794  break;
795  case CRERR_TOO_MANY:
796  ereport(ERROR,
797  (errcode(ERRCODE_SYNTAX_ERROR),
798  errmsg("improper qualified name (too many dotted names): %s",
799  NameListToString(cref->fields)),
800  parser_errposition(pstate, cref->location)));
801  break;
802  }
803  }
804 
805  return node;
806 }
Node * scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname, int location, int fuzzy_rte_penalty, FuzzyAttrMatchState *fuzzystate)
Value * makeString(char *str)
Definition: value.c:53
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, FuncCall *fn, int location)
Definition: parse_func.c:69
RangeTblEntry * refnameRangeTblEntry(ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
#define lsecond(l)
Definition: pg_list.h:116
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:207
int location
Definition: parsenodes.h:236
#define list_make1(x1)
Definition: pg_list.h:139
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void errorMissingRTE(ParseState *pstate, RangeVar *relation)
#define ereport(elevel, rest)
Definition: elog.h:122
void errorMissingColumn(ParseState *pstate, char *relname, char *colname, int location)
char * NameListToString(List *names)
Definition: namespace.c:3020
Oid MyDatabaseId
Definition: globals.c:76
static Node * transformWholeRowRef(ParseState *pstate, RangeTblEntry *rte, int location)
Definition: parse_expr.c:2585
Node * colNameToVar(ParseState *pstate, char *colname, bool localonly, int location)
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfourth(l)
Definition: pg_list.h:126
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lthird(l)
Definition: pg_list.h:121
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:206
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:419
List * fields
Definition: parsenodes.h:235
static Node * transformCurrentOfExpr ( ParseState pstate,
CurrentOfExpr cexpr 
)
static

Definition at line 2528 of file parse_expr.c.

References Assert, CurrentOfExpr::cursor_name, CurrentOfExpr::cursor_param, CurrentOfExpr::cvarno, ColumnRef::fields, IsA, list_make1, ColumnRef::location, makeNode, makeString(), NULL, ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseState::p_target_rangetblentry, PARAM_EXTERN, Param::paramid, Param::paramkind, Param::paramtype, REFCURSOROID, and RTERangeTablePosn().

Referenced by transformExprRecurse().

2529 {
2530  int sublevels_up;
2531 
2532  /* CURRENT OF can only appear at top level of UPDATE/DELETE */
2533  Assert(pstate->p_target_rangetblentry != NULL);
2534  cexpr->cvarno = RTERangeTablePosn(pstate,
2535  pstate->p_target_rangetblentry,
2536  &sublevels_up);
2537  Assert(sublevels_up == 0);
2538 
2539  /*
2540  * Check to see if the cursor name matches a parameter of type REFCURSOR.
2541  * If so, replace the raw name reference with a parameter reference. (This
2542  * is a hack for the convenience of plpgsql.)
2543  */
2544  if (cexpr->cursor_name != NULL) /* in case already transformed */
2545  {
2546  ColumnRef *cref = makeNode(ColumnRef);
2547  Node *node = NULL;
2548 
2549  /* Build an unqualified ColumnRef with the given name */
2550  cref->fields = list_make1(makeString(cexpr->cursor_name));
2551  cref->location = -1;
2552 
2553  /* See if there is a translation available from a parser hook */
2554  if (pstate->p_pre_columnref_hook != NULL)
2555  node = (*pstate->p_pre_columnref_hook) (pstate, cref);
2556  if (node == NULL && pstate->p_post_columnref_hook != NULL)
2557  node = (*pstate->p_post_columnref_hook) (pstate, cref, NULL);
2558 
2559  /*
2560  * XXX Should we throw an error if we get a translation that isn't a
2561  * refcursor Param? For now it seems best to silently ignore false
2562  * matches.
2563  */
2564  if (node != NULL && IsA(node, Param))
2565  {
2566  Param *p = (Param *) node;
2567 
2568  if (p->paramkind == PARAM_EXTERN &&
2569  p->paramtype == REFCURSOROID)
2570  {
2571  /* Matches, so convert CURRENT OF to a param reference */
2572  cexpr->cursor_name = NULL;
2573  cexpr->cursor_param = p->paramid;
2574  }
2575  }
2576  }
2577 
2578  return (Node *) cexpr;
2579 }
Value * makeString(char *str)
Definition: value.c:53
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
ParamKind paramkind
Definition: primnodes.h:244
Definition: nodes.h:509
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:207
int location
Definition: parsenodes.h:236
#define list_make1(x1)
Definition: pg_list.h:139
char * cursor_name
Definition: primnodes.h:1277
#define REFCURSOROID
Definition: pg_type.h:558
RangeTblEntry * p_target_rangetblentry
Definition: parse_node.h:180
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
int paramid
Definition: primnodes.h:245
int RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:206
Oid paramtype
Definition: primnodes.h:246
List * fields
Definition: parsenodes.h:235
Node* transformExpr ( ParseState pstate,
Node expr,
ParseExprKind  exprKind 
)

Definition at line 147 of file parse_expr.c.

References Assert, EXPR_KIND_NONE, ParseState::p_expr_kind, result, and transformExprRecurse().

Referenced by cookConstraint(), cookDefault(), domainAddConstraint(), EvaluateParams(), ExpandIndirectionStar(), findTargetlistEntrySQL99(), interpret_function_parameter_list(), resolve_unique_index_expr(), transformAlterTableStmt(), transformArraySubscripts(), transformExpressionList(), transformFrameOffset(), transformFuncCall(), transformGroupingFunc(), transformIndexStmt(), transformJoinUsingClause(), transformLimitClause(), transformOnConflictArbiter(), transformPartitionSpec(), transformRangeFunction(), transformRangeTableFunc(), transformRangeTableSample(), transformTargetEntry(), and transformWhereClause().

148 {
149  Node *result;
150  ParseExprKind sv_expr_kind;
151 
152  /* Save and restore identity of expression type we're parsing */
153  Assert(exprKind != EXPR_KIND_NONE);
154  sv_expr_kind = pstate->p_expr_kind;
155  pstate->p_expr_kind = exprKind;
156 
157  result = transformExprRecurse(pstate, expr);
158 
159  pstate->p_expr_kind = sv_expr_kind;
160 
161  return result;
162 }
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Definition: nodes.h:509
return result
Definition: formatting.c:1632
ParseExprKind
Definition: parse_node.h:33
ParseExprKind p_expr_kind
Definition: parse_node.h:183
#define Assert(condition)
Definition: c.h:675
static Node * transformExprRecurse ( ParseState pstate,
Node expr 
)
static

Definition at line 165 of file parse_expr.c.

References 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_OF, AEXPR_OP, AEXPR_OP_ALL, AEXPR_OP_ANY, AEXPR_PAREN, AEXPR_SIMILAR, A_Indirection::arg, NamedArgExpr::arg, NullTest::arg, NullTest::argisrow, check_stack_depth(), elog, emit_precedence_warnings(), ereport, errcode(), errmsg(), ERROR, exprType(), A_Indirection::indirection, InvalidOid, A_Expr::kind, A_Expr::lexpr, A_Const::location, NullTest::location, make_const(), nodeTag, NULL, operator_precedence_warning, parser_errposition(), PREC_GROUP_POSTFIX_IS, result, T_A_ArrayExpr, T_A_Const, T_A_Expr, T_A_Indirection, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CollateClause, T_ColumnRef, T_CurrentOfExpr, T_FuncCall, T_GroupingFunc, T_MinMaxExpr, T_MultiAssignRef, T_NamedArgExpr, T_NullTest, T_ParamRef, T_RowExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_TypeCast, T_Var, T_XmlExpr, T_XmlSerialize, transformAExprBetween(), transformAExprDistinct(), transformAExprIn(), transformAExprNullIf(), transformAExprOf(), transformAExprOp(), transformAExprOpAll(), transformAExprOpAny(), transformArrayExpr(), transformBooleanTest(), transformBoolExpr(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformColumnRef(), transformCurrentOfExpr(), transformFuncCall(), transformGroupingFunc(), transformIndirection(), transformMinMaxExpr(), transformMultiAssignRef(), transformParamRef(), transformRowExpr(), transformSQLValueFunction(), transformSubLink(), transformTypeCast(), transformXmlExpr(), transformXmlSerialize(), type_is_rowtype(), A_Const::val, and val.

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

166 {
167  Node *result;
168 
169  if (expr == NULL)
170  return NULL;
171 
172  /* Guard against stack overflow due to overly complex expressions */
174 
175  switch (nodeTag(expr))
176  {
177  case T_ColumnRef:
178  result = transformColumnRef(pstate, (ColumnRef *) expr);
179  break;
180 
181  case T_ParamRef:
182  result = transformParamRef(pstate, (ParamRef *) expr);
183  break;
184 
185  case T_A_Const:
186  {
187  A_Const *con = (A_Const *) expr;
188  Value *val = &con->val;
189 
190  result = (Node *) make_const(pstate, val, con->location);
191  break;
192  }
193 
194  case T_A_Indirection:
195  {
196  A_Indirection *ind = (A_Indirection *) expr;
197 
198  result = transformExprRecurse(pstate, ind->arg);
199  result = transformIndirection(pstate, result,
200  ind->indirection);
201  break;
202  }
203 
204  case T_A_ArrayExpr:
205  result = transformArrayExpr(pstate, (A_ArrayExpr *) expr,
206  InvalidOid, InvalidOid, -1);
207  break;
208 
209  case T_TypeCast:
210  result = transformTypeCast(pstate, (TypeCast *) expr);
211  break;
212 
213  case T_CollateClause:
214  result = transformCollateClause(pstate, (CollateClause *) expr);
215  break;
216 
217  case T_A_Expr:
218  {
219  A_Expr *a = (A_Expr *) expr;
220 
221  switch (a->kind)
222  {
223  case AEXPR_OP:
224  result = transformAExprOp(pstate, a);
225  break;
226  case AEXPR_OP_ANY:
227  result = transformAExprOpAny(pstate, a);
228  break;
229  case AEXPR_OP_ALL:
230  result = transformAExprOpAll(pstate, a);
231  break;
232  case AEXPR_DISTINCT:
233  case AEXPR_NOT_DISTINCT:
234  result = transformAExprDistinct(pstate, a);
235  break;
236  case AEXPR_NULLIF:
237  result = transformAExprNullIf(pstate, a);
238  break;
239  case AEXPR_OF:
240  result = transformAExprOf(pstate, a);
241  break;
242  case AEXPR_IN:
243  result = transformAExprIn(pstate, a);
244  break;
245  case AEXPR_LIKE:
246  case AEXPR_ILIKE:
247  case AEXPR_SIMILAR:
248  /* we can transform these just like AEXPR_OP */
249  result = transformAExprOp(pstate, a);
250  break;
251  case AEXPR_BETWEEN:
252  case AEXPR_NOT_BETWEEN:
253  case AEXPR_BETWEEN_SYM:
255  result = transformAExprBetween(pstate, a);
256  break;
257  case AEXPR_PAREN:
258  result = transformExprRecurse(pstate, a->lexpr);
259  break;
260  default:
261  elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
262  result = NULL; /* keep compiler quiet */
263  break;
264  }
265  break;
266  }
267 
268  case T_BoolExpr:
269  result = transformBoolExpr(pstate, (BoolExpr *) expr);
270  break;
271 
272  case T_FuncCall:
273  result = transformFuncCall(pstate, (FuncCall *) expr);
274  break;
275 
276  case T_MultiAssignRef:
277  result = transformMultiAssignRef(pstate, (MultiAssignRef *) expr);
278  break;
279 
280  case T_GroupingFunc:
281  result = transformGroupingFunc(pstate, (GroupingFunc *) expr);
282  break;
283 
284  case T_NamedArgExpr:
285  {
286  NamedArgExpr *na = (NamedArgExpr *) expr;
287 
288  na->arg = (Expr *) transformExprRecurse(pstate, (Node *) na->arg);
289  result = expr;
290  break;
291  }
292 
293  case T_SubLink:
294  result = transformSubLink(pstate, (SubLink *) expr);
295  break;
296 
297  case T_CaseExpr:
298  result = transformCaseExpr(pstate, (CaseExpr *) expr);
299  break;
300 
301  case T_RowExpr:
302  result = transformRowExpr(pstate, (RowExpr *) expr, false);
303  break;
304 
305  case T_CoalesceExpr:
306  result = transformCoalesceExpr(pstate, (CoalesceExpr *) expr);
307  break;
308 
309  case T_MinMaxExpr:
310  result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
311  break;
312 
313  case T_SQLValueFunction:
314  result = transformSQLValueFunction(pstate,
315  (SQLValueFunction *) expr);
316  break;
317 
318  case T_XmlExpr:
319  result = transformXmlExpr(pstate, (XmlExpr *) expr);
320  break;
321 
322  case T_XmlSerialize:
323  result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
324  break;
325 
326  case T_NullTest:
327  {
328  NullTest *n = (NullTest *) expr;
329 
332  (Node *) n->arg, NULL,
333  n->location);
334 
335  n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
336  /* the argument can be any type, so don't coerce it */
337  n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
338  result = expr;
339  break;
340  }
341 
342  case T_BooleanTest:
343  result = transformBooleanTest(pstate, (BooleanTest *) expr);
344  break;
345 
346  case T_CurrentOfExpr:
347  result = transformCurrentOfExpr(pstate, (CurrentOfExpr *) expr);
348  break;
349 
350  /*
351  * In all places where DEFAULT is legal, the caller should have
352  * processed it rather than passing it to transformExpr().
353  */
354  case T_SetToDefault:
355  ereport(ERROR,
356  (errcode(ERRCODE_SYNTAX_ERROR),
357  errmsg("DEFAULT is not allowed in this context"),
358  parser_errposition(pstate,
359  ((SetToDefault *) expr)->location)));
360  break;
361 
362  /*
363  * CaseTestExpr doesn't require any processing; it is only
364  * injected into parse trees in a fully-formed state.
365  *
366  * Ordinarily we should not see a Var here, but it is convenient
367  * for transformJoinUsingClause() to create untransformed operator
368  * trees containing already-transformed Vars. The best
369  * alternative would be to deconstruct and reconstruct column
370  * references, which seems expensively pointless. So allow it.
371  */
372  case T_CaseTestExpr:
373  case T_Var:
374  {
375  result = (Node *) expr;
376  break;
377  }
378 
379  default:
380  /* should not reach here */
381  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
382  result = NULL; /* keep compiler quiet */
383  break;
384  }
385 
386  return result;
387 }
static Node * transformAExprDistinct(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:990
static Node * transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
Definition: parse_expr.c:2145
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
static Node * transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
Definition: parse_expr.c:2528
static Node * transformAExprOpAny(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:944
A_Expr_Kind kind
Definition: parsenodes.h:275
#define PREC_GROUP_POSTFIX_IS
Definition: parse_expr.c:51
static Node * transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
Definition: parse_expr.c:2214
static Node * transformAExprNullIf(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1046
static Node * transformSubLink(ParseState *pstate, SubLink *sublink)
Definition: parse_expr.c:1750
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1632
Const * make_const(ParseState *pstate, Value *value, int location)
Definition: parse_node.c:470
static Node * transformBooleanTest(ParseState *pstate, BooleanTest *b)
Definition: parse_expr.c:2483
static Node * transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
Definition: parse_expr.c:442
static Node * transformXmlExpr(ParseState *pstate, XmlExpr *x)
Definition: parse_expr.c:2306
static Node * transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c)
Definition: parse_expr.c:2177
#define ERROR
Definition: elog.h:43
static Node * transformBoolExpr(ParseState *pstate, BoolExpr *a)
Definition: parse_expr.c:1395
Expr * arg
Definition: primnodes.h:1179
static Node * transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, Oid array_type, Oid element_type, int32 typmod)
Definition: parse_expr.c:1987
static Node * transformAExprOpAll(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:967
static Node * transformFuncCall(ParseState *pstate, FuncCall *fn)
Definition: parse_expr.c:1431
void check_stack_depth(void)
Definition: postgres.c:3102
static Node * transformParamRef(ParseState *pstate, ParamRef *pref)
Definition: parse_expr.c:809
static Node * transformAExprOf(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1085
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2404
#define ereport(elevel, rest)
Definition: elog.h:122
Node * lexpr
Definition: parsenodes.h:277
static Node * transformAExprOp(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:846
Definition: nodes.h:146
static Node * transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
Definition: parse_expr.c:1473
static Node * transformCollateClause(ParseState *pstate, CollateClause *c)
Definition: parse_expr.c:2713
Node * transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
Definition: parse_agg.c:248
bool operator_precedence_warning
Definition: parse_expr.c:44
static void emit_precedence_warnings(ParseState *pstate, int opgroup, const char *opname, Node *lchild, Node *rchild, int location)
Definition: parse_expr.c:3293
#define InvalidOid
Definition: postgres_ext.h:36
Expr * arg
Definition: primnodes.h:477
#define NULL
Definition: c.h:229
int location
Definition: parsenodes.h:289
Definition: value.h:42
List * indirection
Definition: parsenodes.h:406
int location
Definition: primnodes.h:1182
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
static Node * transformCaseExpr(ParseState *pstate, CaseExpr *c)
Definition: parse_expr.c:1620
#define nodeTag(nodeptr)
Definition: nodes.h:514
static Node * transformTypeCast(ParseState *pstate, TypeCast *tc)
Definition: parse_expr.c:2620
static Node * transformColumnRef(ParseState *pstate, ColumnRef *cref)
Definition: parse_expr.c:513
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Node * transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
Definition: parse_expr.c:2440
static Node * transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf)
Definition: parse_expr.c:2253
bool argisrow
Definition: primnodes.h:1181
#define elog
Definition: elog.h:219
Value val
Definition: parsenodes.h:288
long val
Definition: informix.c:689
static Node * transformAExprBetween(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1285
static Node * transformAExprIn(ParseState *pstate, A_Expr *a)
Definition: parse_expr.c:1126
static Node * transformFuncCall ( ParseState pstate,
FuncCall fn 
)
static

Definition at line 1431 of file parse_expr.c.

References FuncCall::agg_order, FuncCall::agg_within_group, arg, generate_unaccent_rules::args, FuncCall::args, Assert, EXPR_KIND_ORDER_BY, FuncCall::funcname, lappend(), lfirst, FuncCall::location, NIL, SortBy::node, ParseFuncOrColumn(), transformExpr(), and transformExprRecurse().

Referenced by transformExprRecurse().

1432 {
1433  List *targs;
1434  ListCell *args;
1435 
1436  /* Transform the list of arguments ... */
1437  targs = NIL;
1438  foreach(args, fn->args)
1439  {
1440  targs = lappend(targs, transformExprRecurse(pstate,
1441  (Node *) lfirst(args)));
1442  }
1443 
1444  /*
1445  * When WITHIN GROUP is used, we treat its ORDER BY expressions as
1446  * additional arguments to the function, for purposes of function lookup
1447  * and argument type coercion. So, transform each such expression and add
1448  * them to the targs list. We don't explicitly mark where each argument
1449  * came from, but ParseFuncOrColumn can tell what's what by reference to
1450  * list_length(fn->agg_order).
1451  */
1452  if (fn->agg_within_group)
1453  {
1454  Assert(fn->agg_order != NIL);
1455  foreach(args, fn->agg_order)
1456  {
1457  SortBy *arg = (SortBy *) lfirst(args);
1458 
1459  targs = lappend(targs, transformExpr(pstate, arg->node,
1461  }
1462  }
1463 
1464  /* ... and hand off to ParseFuncOrColumn */
1465  return ParseFuncOrColumn(pstate,
1466  fn->funcname,
1467  targs,
1468  fn,
1469  fn->location);
1470 }
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:147
Definition: nodes.h:509
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, FuncCall *fn, int location)
Definition: parse_func.c:69
int location
Definition: parsenodes.h:359
List * agg_order
Definition: parsenodes.h:352
List * lappend(List *list, void *datum)
Definition: list.c:128
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
List * args
Definition: parsenodes.h:351
void * arg
List * funcname
Definition: parsenodes.h:350
Node * node
Definition: parsenodes.h:469
bool agg_within_group
Definition: parsenodes.h:354
Definition: pg_list.h:45
static Node * transformIndirection ( ParseState pstate,
Node basenode,
List indirection 
)
static

Definition at line 442 of file parse_expr.c.

References Assert, ereport, errcode(), errmsg(), ERROR, exprLocation(), exprType(), exprTypmod(), i, InvalidOid, IsA, lappend(), lfirst, list_make1, NIL, NULL, ParseFuncOrColumn(), parser_errposition(), result, strVal, transformArraySubscripts(), and unknown_attribute().

Referenced by transformExprRecurse().

443 {
444  Node *result = basenode;
445  List *subscripts = NIL;
446  int location = exprLocation(basenode);
447  ListCell *i;
448 
449  /*
450  * We have to split any field-selection operations apart from
451  * subscripting. Adjacent A_Indices nodes have to be treated as a single
452  * multidimensional subscript operation.
453  */
454  foreach(i, indirection)
455  {
456  Node *n = lfirst(i);
457 
458  if (IsA(n, A_Indices))
459  subscripts = lappend(subscripts, n);
460  else if (IsA(n, A_Star))
461  {
462  ereport(ERROR,
463  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
464  errmsg("row expansion via \"*\" is not supported here"),
465  parser_errposition(pstate, location)));
466  }
467  else
468  {
469  Node *newresult;
470 
471  Assert(IsA(n, String));
472 
473  /* process subscripts before this field selection */
474  if (subscripts)
475  result = (Node *) transformArraySubscripts(pstate,
476  result,
477  exprType(result),
478  InvalidOid,
479  exprTypmod(result),
480  subscripts,
481  NULL);
482  subscripts = NIL;
483 
484  newresult = ParseFuncOrColumn(pstate,
485  list_make1(n),
486  list_make1(result),
487  NULL,
488  location);
489  if (newresult == NULL)
490  unknown_attribute(pstate, result, strVal(n), location);
491  result = newresult;
492  }
493  }
494  /* process trailing subscripts, if any */
495  if (subscripts)
496  result = (Node *) transformArraySubscripts(pstate,
497  result,
498  exprType(result),
499  InvalidOid,
500  exprTypmod(result),
501  subscripts,
502  NULL);
503 
504  return result;
505 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1214
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1632
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, FuncCall *fn, int location)
Definition: parse_func.c:69
#define list_make1(x1)
Definition: pg_list.h:139
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void unknown_attribute(ParseState *pstate, Node *relref, char *attname, int location)
Definition: parse_expr.c:396
int i
Definition: pg_list.h:45
ArrayRef * transformArraySubscripts(ParseState *pstate, Node *arrayBase, Oid arrayType, Oid elementType, int32 arrayTypMod, List *indirection, Node *assignFrom)
Definition: parse_node.c:294
static Node * transformMinMaxExpr ( ParseState pstate,
MinMaxExpr m 
)
static

Definition at line 2214 of file parse_expr.c.

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

Referenced by transformExprRecurse().

2215 {
2216  MinMaxExpr *newm = makeNode(MinMaxExpr);
2217  List *newargs = NIL;
2218  List *newcoercedargs = NIL;
2219  const char *funcname = (m->op == IS_GREATEST) ? "GREATEST" : "LEAST";
2220  ListCell *args;
2221 
2222  newm->op = m->op;
2223  foreach(args, m->args)
2224  {
2225  Node *e = (Node *) lfirst(args);
2226  Node *newe;
2227 
2228  newe = transformExprRecurse(pstate, e);
2229  newargs = lappend(newargs, newe);
2230  }
2231 
2232  newm->minmaxtype = select_common_type(pstate, newargs, funcname, NULL);
2233  /* minmaxcollid and inputcollid will be set by parse_collate.c */
2234 
2235  /* Convert arguments if necessary */
2236  foreach(args, newargs)
2237  {
2238  Node *e = (Node *) lfirst(args);
2239  Node *newe;
2240 
2241  newe = coerce_to_common_type(pstate, e,
2242  newm->minmaxtype,
2243  funcname);
2244  newcoercedargs = lappend(newcoercedargs, newe);
2245  }
2246 
2247  newm->args = newcoercedargs;
2248  newm->location = m->location;
2249  return (Node *) newm;
2250 }
Oid minmaxtype
Definition: primnodes.h:1062
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
List * args
Definition: primnodes.h:1066
Definition: nodes.h:509
int location
Definition: primnodes.h:1067
Node * coerce_to_common_type(ParseState *pstate, Node *node, Oid targetTypeId, const char *context)
List * lappend(List *list, void *datum)
Definition: list.c:128
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
e
Definition: preproc-init.c:82
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
MinMaxOp op
Definition: primnodes.h:1065
Definition: pg_list.h:45
static Node * transformMultiAssignRef ( ParseState pstate,
MultiAssignRef maref 
)
static

Definition at line 1473 of file parse_expr.c.

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

Referenced by transformExprRecurse().

1474 {
1475  SubLink *sublink;
1476  RowExpr *rexpr;
1477  Query *qtree;
1478  TargetEntry *tle;
1479 
1480  /* We should only see this in first-stage processing of UPDATE tlists */
1482 
1483  /* We only need to transform the source if this is the first column */
1484  if (maref->colno == 1)
1485  {
1486  /*
1487  * For now, we only allow EXPR SubLinks and RowExprs as the source of
1488  * an UPDATE multiassignment. This is sufficient to cover interesting
1489  * cases; at worst, someone would have to write (SELECT * FROM expr)
1490  * to expand a composite-returning expression of another form.
1491  */
1492  if (IsA(maref->source, SubLink) &&
1493  ((SubLink *) maref->source)->subLinkType == EXPR_SUBLINK)
1494  {
1495  /* Relabel it as a MULTIEXPR_SUBLINK */
1496  sublink = (SubLink *) maref->source;
1497  sublink->subLinkType = MULTIEXPR_SUBLINK;
1498  /* And transform it */
1499  sublink = (SubLink *) transformExprRecurse(pstate,
1500  (Node *) sublink);
1501 
1502  qtree = castNode(Query, sublink->subselect);
1503 
1504  /* Check subquery returns required number of columns */
1505  if (count_nonjunk_tlist_entries(qtree->targetList) != maref->ncolumns)
1506  ereport(ERROR,
1507  (errcode(ERRCODE_SYNTAX_ERROR),
1508  errmsg("number of columns does not match number of values"),
1509  parser_errposition(pstate, sublink->location)));
1510 
1511  /*
1512  * Build a resjunk tlist item containing the MULTIEXPR SubLink,
1513  * and add it to pstate->p_multiassign_exprs, whence it will later
1514  * get appended to the completed targetlist. We needn't worry
1515  * about selecting a resno for it; transformUpdateStmt will do
1516  * that.
1517  */
1518  tle = makeTargetEntry((Expr *) sublink, 0, NULL, true);
1520  tle);
1521 
1522  /*
1523  * Assign a unique-within-this-targetlist ID to the MULTIEXPR
1524  * SubLink. We can just use its position in the
1525  * p_multiassign_exprs list.
1526  */
1527  sublink->subLinkId = list_length(pstate->p_multiassign_exprs);
1528  }
1529  else if (IsA(maref->source, RowExpr))
1530  {
1531  /* Transform the RowExpr, allowing SetToDefault items */
1532  rexpr = (RowExpr *) transformRowExpr(pstate,
1533  (RowExpr *) maref->source,
1534  true);
1535 
1536  /* Check it returns required number of columns */
1537  if (list_length(rexpr->args) != maref->ncolumns)
1538  ereport(ERROR,
1539  (errcode(ERRCODE_SYNTAX_ERROR),
1540  errmsg("number of columns does not match number of values"),
1541  parser_errposition(pstate, rexpr->location)));
1542 
1543  /*
1544  * Temporarily append it to p_multiassign_exprs, so we can get it
1545  * back when we come back here for additional columns.
1546  */
1547  tle = makeTargetEntry((Expr *) rexpr, 0, NULL, true);
1549  tle);
1550  }
1551  else
1552  ereport(ERROR,
1553  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1554  errmsg("source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression"),
1555  parser_errposition(pstate, exprLocation(maref->source))));
1556  }
1557  else
1558  {
1559  /*
1560  * Second or later column in a multiassignment. Re-fetch the
1561  * transformed SubLink or RowExpr, which we assume is still the last
1562  * entry in p_multiassign_exprs.
1563  */
1564  Assert(pstate->p_multiassign_exprs != NIL);
1565  tle = (TargetEntry *) llast(pstate->p_multiassign_exprs);
1566  }
1567 
1568  /*
1569  * Emit the appropriate output expression for the current column
1570  */
1571  if (IsA(tle->expr, SubLink))
1572  {
1573  Param *param;
1574 
1575  sublink = (SubLink *) tle->expr;
1576  Assert(sublink->subLinkType == MULTIEXPR_SUBLINK);
1577  qtree = castNode(Query, sublink->subselect);
1578 
1579  /* Build a Param representing the current subquery output column */
1580  tle = (TargetEntry *) list_nth(qtree->targetList, maref->colno - 1);
1581  Assert(!tle->resjunk);
1582 
1583  param = makeNode(Param);
1584  param->paramkind = PARAM_MULTIEXPR;
1585  param->paramid = (sublink->subLinkId << 16) | maref->colno;
1586  param->paramtype = exprType((Node *) tle->expr);
1587  param->paramtypmod = exprTypmod((Node *) tle->expr);
1588  param->paramcollid = exprCollation((Node *) tle->expr);
1589  param->location = exprLocation((Node *) tle->expr);
1590 
1591  return (Node *) param;
1592  }
1593 
1594  if (IsA(tle->expr, RowExpr))
1595  {
1596  Node *result;
1597 
1598  rexpr = (RowExpr *) tle->expr;
1599 
1600  /* Just extract and return the next element of the RowExpr */
1601  result = (Node *) list_nth(rexpr->args, maref->colno - 1);
1602 
1603  /*
1604  * If we're at the last column, delete the RowExpr from
1605  * p_multiassign_exprs; we don't need it anymore, and don't want it in
1606  * the finished UPDATE tlist.
1607  */
1608  if (maref->colno == maref->ncolumns)
1609  pstate->p_multiassign_exprs =
1610  list_delete_ptr(pstate->p_multiassign_exprs, tle);
1611 
1612  return result;
1613  }
1614 
1615  elog(ERROR, "unexpected expr type in multiassign list");
1616  return NULL; /* keep compiler quiet */
1617 }
#define NIL
Definition: pg_list.h:69
static Node * transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault)
Definition: parse_expr.c:2145
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
List * args
Definition: primnodes.h:985
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1214
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
#define llast(l)
Definition: pg_list.h:131
ParamKind paramkind
Definition: primnodes.h:244
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
List * p_multiassign_exprs
Definition: parse_node.h:185
return result
Definition: formatting.c:1632
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:590
List * targetList
Definition: parsenodes.h:138
bool resjunk
Definition: primnodes.h:1374
#define ERROR
Definition: elog.h:43
Oid paramcollid
Definition: primnodes.h:248
int location
Definition: primnodes.h:249
int location
Definition: primnodes.h:999
void * list_nth(const List *list, int n)
Definition: list.c:410
#define ereport(elevel, rest)
Definition: elog.h:122
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:235
List * lappend(List *list, void *datum)
Definition: list.c:128
ParseExprKind p_expr_kind
Definition: parse_node.h:183
int32 paramtypmod
Definition: primnodes.h:247
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
Expr * expr
Definition: primnodes.h:1367
int paramid
Definition: primnodes.h:245
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:748
int errmsg(const char *fmt,...)
Definition: elog.c:797
int count_nonjunk_tlist_entries(List *tlist)
Definition: tlist.c:189
#define elog
Definition: elog.h:219
Oid paramtype
Definition: primnodes.h:246
static Node * transformParamRef ( ParseState pstate,
ParamRef pref 
)
static

Definition at line 809 of file parse_expr.c.

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

Referenced by transformExprRecurse().

810 {
811  Node *result;
812 
813  /*
814  * The core parser knows nothing about Params. If a hook is supplied,
815  * call it. If not, or if the hook returns NULL, throw a generic error.
816  */
817  if (pstate->p_paramref_hook != NULL)
818  result = (*pstate->p_paramref_hook) (pstate, pref);
819  else
820  result = NULL;
821 
822  if (result == NULL)
823  ereport(ERROR,
824  (errcode(ERRCODE_UNDEFINED_PARAMETER),
825  errmsg("there is no parameter $%d", pref->number),
826  parser_errposition(pstate, pref->location)));
827 
828  return result;
829 }
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1632
#define ERROR
Definition: elog.h:43
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:208
#define ereport(elevel, rest)
Definition: elog.h:122
int number
Definition: parsenodes.h:245
int location
Definition: parsenodes.h:246
#define NULL
Definition: c.h:229
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Node * transformRowExpr ( ParseState pstate,
RowExpr r,
bool  allowDefault 
)
static

Definition at line 2145 of file parse_expr.c.

References RowExpr::args, COERCE_IMPLICIT_CAST, RowExpr::colnames, lappend(), RowExpr::location, makeNode, makeString(), NIL, ParseState::p_expr_kind, pstrdup(), RECORDOID, RowExpr::row_format, RowExpr::row_typeid, snprintf(), and transformExpressionList().

Referenced by transformExprRecurse(), and transformMultiAssignRef().

2146 {
2147  RowExpr *newr;
2148  char fname[16];
2149  int fnum;
2150  ListCell *lc;
2151 
2152  newr = makeNode(RowExpr);
2153 
2154  /* Transform the field expressions */
2155  newr->args = transformExpressionList(pstate, r->args,
2156  pstate->p_expr_kind, allowDefault);
2157 
2158  /* Barring later casting, we consider the type RECORD */
2159  newr->row_typeid = RECORDOID;
2161 
2162  /* ROW() has anonymous columns, so invent some field names */
2163  newr->colnames = NIL;
2164  fnum = 1;
2165  foreach(lc, newr->args)
2166  {
2167  snprintf(fname, sizeof(fname), "f%d", fnum++);
2168  newr->colnames = lappend(newr->colnames, makeString(pstrdup(fname)));
2169  }
2170 
2171  newr->location = r->location;
2172 
2173  return (Node *) newr;
2174 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:69
List * args
Definition: primnodes.h:985
char * pstrdup(const char *in)
Definition: mcxt.c:1077
Definition: nodes.h:509
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
List * colnames
Definition: primnodes.h:998
int location
Definition: primnodes.h:999
#define RECORDOID
Definition: pg_type.h:680
List * lappend(List *list, void *datum)
Definition: list.c:128
List * transformExpressionList(ParseState *pstate, List *exprlist, ParseExprKind exprKind, bool allowDefault)
Definition: parse_target.c:228
ParseExprKind p_expr_kind
Definition: parse_node.h:183
#define makeNode(_type_)
Definition: nodes.h:557
Oid row_typeid
Definition: primnodes.h:986
CoercionForm row_format
Definition: primnodes.h:997
static Node * transformSQLValueFunction ( ParseState pstate,
SQLValueFunction svf 
)
static

Definition at line 2253 of file parse_expr.c.

References anytime_typmod_check(), anytimestamp_typmod_check(), DATEOID, NAMEOID, SQLValueFunction::op, SVFOP_CURRENT_CATALOG, SVFOP_CURRENT_DATE, SVFOP_CURRENT_ROLE, SVFOP_CURRENT_SCHEMA, SVFOP_CURRENT_TIME, SVFOP_CURRENT_TIME_N, SVFOP_CURRENT_TIMESTAMP, SVFOP_CURRENT_TIMESTAMP_N, SVFOP_CURRENT_USER, SVFOP_LOCALTIME, SVFOP_LOCALTIME_N, SVFOP_LOCALTIMESTAMP, SVFOP_LOCALTIMESTAMP_N, SVFOP_SESSION_USER, SVFOP_USER, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, TIMETZOID, SQLValueFunction::type, and SQLValueFunction::typmod.

Referenced by transformExprRecurse().

2254 {
2255  /*
2256  * All we need to do is insert the correct result type and (where needed)
2257  * validate the typmod, so we just modify the node in-place.
2258  */
2259  switch (svf->op)
2260  {
2261  case SVFOP_CURRENT_DATE:
2262  svf->type = DATEOID;
2263  break;
2264  case SVFOP_CURRENT_TIME:
2265  svf->type = TIMETZOID;
2266  break;
2267  case SVFOP_CURRENT_TIME_N:
2268  svf->type = TIMETZOID;
2269  svf->typmod = anytime_typmod_check(true, svf->typmod);
2270  break;
2272  svf->type = TIMESTAMPTZOID;
2273  break;
2275  svf->type = TIMESTAMPTZOID;
2276  svf->typmod = anytimestamp_typmod_check(true, svf->typmod);
2277  break;
2278  case SVFOP_LOCALTIME:
2279  svf->type = TIMEOID;
2280  break;
2281  case SVFOP_LOCALTIME_N:
2282  svf->type = TIMEOID;
2283  svf->typmod = anytime_typmod_check(false, svf->typmod);
2284  break;
2285  case SVFOP_LOCALTIMESTAMP:
2286  svf->type = TIMESTAMPOID;
2287  break;
2289  svf->type = TIMESTAMPOID;
2290  svf->typmod = anytimestamp_typmod_check(false, svf->typmod);
2291  break;
2292  case SVFOP_CURRENT_ROLE:
2293  case SVFOP_CURRENT_USER:
2294  case SVFOP_USER:
2295  case SVFOP_SESSION_USER:
2296  case SVFOP_CURRENT_CATALOG:
2297  case SVFOP_CURRENT_SCHEMA:
2298  svf->type = NAMEOID;
2299  break;
2300  }
2301 
2302  return (Node *) svf;
2303 }
#define TIMESTAMPTZOID
Definition: pg_type.h:525
#define TIMEOID
Definition: pg_type.h:514
#define DATEOID
Definition: pg_type.h:511
#define NAMEOID
Definition: pg_type.h:300
int32 anytime_typmod_check(bool istz, int32 typmod)
Definition: date.c:74
Definition: nodes.h:509
SQLValueFunctionOp op
Definition: primnodes.h:1103
#define TIMESTAMPOID
Definition: pg_type.h:519
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition: timestamp.c:102
#define TIMETZOID
Definition: pg_type.h:536
static Node * transformSubLink ( ParseState pstate,
SubLink sublink 
)
static

Definition at line 1750 of file parse_expr.c.

References _, ARRAY_SUBLINK, Assert, CMD_SELECT, Query::commandType, count_nonjunk_tlist_entries(), elog, emit_precedence_warnings(), ereport, errcode(), errmsg(), errmsg_internal(), ERROR, EXISTS_SUBLINK, TargetEntry::expr, EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, 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_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_NONE, EXPR_KIND_OFFSET, EXPR_KIND_ORDER_BY, EXPR_KIND_OTHER, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_POLICY, EXPR_KIND_RETURNING, EXPR_KIND_SELECT_TARGET, 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_RANGE, EXPR_KIND_WINDOW_FRAME_ROWS, EXPR_KIND_WINDOW_ORDER, EXPR_KIND_WINDOW_PARTITION, EXPR_SUBLINK, exprCollation(), exprType(), exprTypmod(), IsA, lappend(), lfirst, list_length(), list_make1, llast, Param::location, SubLink::location, make_row_comparison_op(), makeNode, makeString(), MULTIEXPR_SUBLINK, NIL, NULL, operator_precedence_warning, SubLink::operName, ParseState::p_expr_kind, ParseState::p_hasSubLinks, PARAM_SUBLINK, Param::paramcollid, Param::paramid, Param::paramkind, Param::paramtype, Param::paramtypmod, parse_sub_analyze(), parser_errposition(), PREC_GROUP_IN, PREC_GROUP_POSTFIX_OP, TargetEntry::resjunk, TargetEntry::resno, result, strVal, SubLink::subLinkType, SubLink::subselect, Query::targetList, SubLink::testexpr, and transformExprRecurse().

Referenced by transformExprRecurse().

1751 {
1752  Node *result = (Node *) sublink;
1753  Query *qtree;
1754  const char *err;
1755 
1756  /*
1757  * Check to see if the sublink is in an invalid place within the query. We
1758  * allow sublinks everywhere in SELECT/INSERT/UPDATE/DELETE, but generally
1759  * not in utility statements.
1760  */
1761  err = NULL;
1762  switch (pstate->p_expr_kind)
1763  {
1764  case EXPR_KIND_NONE:
1765  Assert(false); /* can't happen */
1766  break;
1767  case EXPR_KIND_OTHER:
1768  /* Accept sublink here; caller must throw error if wanted */
1769  break;
1770  case EXPR_KIND_JOIN_ON:
1771  case EXPR_KIND_JOIN_USING:
1774  case EXPR_KIND_WHERE:
1775  case EXPR_KIND_POLICY:
1776  case EXPR_KIND_HAVING:
1777  case EXPR_KIND_FILTER:
1786  case EXPR_KIND_GROUP_BY:
1787  case EXPR_KIND_ORDER_BY:
1788  case EXPR_KIND_DISTINCT_ON:
1789  case EXPR_KIND_LIMIT:
1790  case EXPR_KIND_OFFSET:
1791  case EXPR_KIND_RETURNING:
1792  case EXPR_KIND_VALUES:
1794  /* okay */
1795  break;
1798  err = _("cannot use subquery in check constraint");
1799  break;
1802  err = _("cannot use subquery in DEFAULT expression");
1803  break;
1805  err = _("cannot use subquery in index expression");
1806  break;
1808  err = _("cannot use subquery in index predicate");
1809  break;
1811  err = _("cannot use subquery in transform expression");
1812  break;
1814  err = _("cannot use subquery in EXECUTE parameter");
1815  break;
1817  err = _("cannot use subquery in trigger WHEN condition");
1818  break;
1820  err = _("cannot use subquery in partition key expression");
1821  break;
1822 
1823  /*
1824  * There is intentionally no default: case here, so that the
1825  * compiler will warn if we add a new ParseExprKind without
1826  * extending this switch. If we do see an unrecognized value at
1827  * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
1828  * which is sane anyway.
1829  */
1830  }
1831  if (err)
1832  ereport(ERROR,
1833  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1834  errmsg_internal("%s", err),
1835  parser_errposition(pstate, sublink->location)));
1836 
1837  pstate->p_hasSubLinks = true;
1838 
1839  /*
1840  * OK, let's transform the sub-SELECT.
1841  */
1842  qtree = parse_sub_analyze(sublink->subselect, pstate, NULL, false, true);
1843 
1844  /*
1845  * Check that we got a SELECT. Anything else should be impossible given
1846  * restrictions of the grammar, but check anyway.
1847  */
1848  if (!IsA(qtree, Query) ||
1849  qtree->commandType != CMD_SELECT)
1850  elog(ERROR, "unexpected non-SELECT command in SubLink");
1851 
1852  sublink->subselect = (Node *) qtree;
1853 
1854  if (sublink->subLinkType == EXISTS_SUBLINK)
1855  {
1856  /*
1857  * EXISTS needs no test expression or combining operator. These fields
1858  * should be null already, but make sure.
1859  */
1860  sublink->testexpr = NULL;
1861  sublink->operName = NIL;
1862  }
1863  else if (sublink->subLinkType == EXPR_SUBLINK ||
1864  sublink->subLinkType == ARRAY_SUBLINK)
1865  {
1866  /*
1867  * Make sure the subselect delivers a single column (ignoring resjunk
1868  * targets).
1869  */
1870  if (count_nonjunk_tlist_entries(qtree->targetList) != 1)
1871  ereport(ERROR,
1872  (errcode(ERRCODE_SYNTAX_ERROR),
1873  errmsg("subquery must return only one column"),
1874  parser_errposition(pstate, sublink->location)));
1875 
1876  /*
1877  * EXPR and ARRAY need no test expression or combining operator. These
1878  * fields should be null already, but make sure.
1879  */
1880  sublink->testexpr = NULL;
1881  sublink->operName = NIL;
1882  }
1883  else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
1884  {
1885  /* Same as EXPR case, except no restriction on number of columns */
1886  sublink->testexpr = NULL;
1887  sublink->operName = NIL;
1888  }
1889  else
1890  {
1891  /* ALL, ANY, or ROWCOMPARE: generate row-comparing expression */
1892  Node *lefthand;
1893  List *left_list;
1894  List *right_list;
1895  ListCell *l;
1896 
1898  {
1899  if (sublink->operName == NIL)
1901  sublink->testexpr, NULL,
1902  sublink->location);
1903  else
1905  strVal(llast(sublink->operName)),
1906  sublink->testexpr, NULL,
1907  sublink->location);
1908  }
1909 
1910  /*
1911  * If the source was "x IN (select)", convert to "x = ANY (select)".
1912  */
1913  if (sublink->operName == NIL)
1914  sublink->operName = list_make1(makeString("="));
1915 
1916  /*
1917  * Transform lefthand expression, and convert to a list
1918  */
1919  lefthand = transformExprRecurse(pstate, sublink->testexpr);
1920  if (lefthand && IsA(lefthand, RowExpr))
1921  left_list = ((RowExpr *) lefthand)->args;
1922  else
1923  left_list = list_make1(lefthand);
1924 
1925  /*
1926  * Build a list of PARAM_SUBLINK nodes representing the output columns
1927  * of the subquery.
1928  */
1929  right_list = NIL;
1930  foreach(l, qtree->targetList)
1931  {
1932  TargetEntry *tent = (TargetEntry *) lfirst(l);
1933  Param *param;
1934 
1935  if (tent->resjunk)
1936  continue;
1937 
1938  param = makeNode(Param);
1939  param->paramkind = PARAM_SUBLINK;
1940  param->paramid = tent->resno;
1941  param->paramtype = exprType((Node *) tent->expr);
1942  param->paramtypmod = exprTypmod((Node *) tent->expr);
1943  param->paramcollid = exprCollation((Node *) tent->expr);
1944  param->location = -1;
1945 
1946  right_list = lappend(right_list, param);
1947  }
1948 
1949  /*
1950  * We could rely on make_row_comparison_op to complain if the list
1951  * lengths differ, but we prefer to generate a more specific error
1952  * message.
1953  */
1954  if (list_length(left_list) < list_length(right_list))
1955  ereport(ERROR,
1956  (errcode(ERRCODE_SYNTAX_ERROR),
1957  errmsg("subquery has too many columns"),
1958  parser_errposition(pstate, sublink->location)));
1959  if (list_length(left_list) > list_length(right_list))
1960  ereport(ERROR,
1961  (errcode(ERRCODE_SYNTAX_ERROR),
1962  errmsg("subquery has too few columns"),
1963  parser_errposition(pstate, sublink->location)));
1964 
1965  /*
1966  * Identify the combining operator(s) and generate a suitable
1967  * row-comparison expression.
1968  */
1969  sublink->testexpr = make_row_comparison_op(pstate,
1970  sublink->operName,
1971  left_list,
1972  right_list,
1973  sublink->location);
1974  }
1975 
1976  return result;
1977 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:69
static Node * transformExprRecurse(ParseState *pstate, Node *expr)
Definition: parse_expr.c:165
bool p_hasSubLinks
Definition: parse_node.h:199
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
#define PREC_GROUP_IN
Definition: parse_expr.c:58
#define llast(l)
Definition: pg_list.h:131
ParamKind paramkind
Definition: primnodes.h:244
Definition: nodes.h:509
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1632
static Node * make_row_comparison_op(ParseState *pstate, List *opname, List *largs, List *rargs, int location)
Definition: parse_expr.c:2753
List * targetList
Definition: parsenodes.h:138