PostgreSQL Source Code  git master
parse_node.h File Reference
Include dependency graph for parse_node.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ParseState
 
struct  ParseNamespaceItem
 
struct  ParseCallbackState
 

Typedefs

typedef enum ParseExprKind ParseExprKind
 
typedef struct ParseState ParseState
 
typedef Node *(* PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref)
 
typedef Node *(* PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var)
 
typedef Node *(* ParseParamRefHook) (ParseState *pstate, ParamRef *pref)
 
typedef Node *(* CoerceParamHook) (ParseState *pstate, Param *param, Oid targetTypeId, int32 targetTypeMod, int location)
 
typedef struct ParseNamespaceItem ParseNamespaceItem
 
typedef struct ParseCallbackState ParseCallbackState
 

Enumerations

enum  ParseExprKind {
  EXPR_KIND_NONE = 0, EXPR_KIND_OTHER, EXPR_KIND_JOIN_ON, EXPR_KIND_JOIN_USING,
  EXPR_KIND_FROM_SUBSELECT, EXPR_KIND_FROM_FUNCTION, EXPR_KIND_WHERE, EXPR_KIND_HAVING,
  EXPR_KIND_FILTER, EXPR_KIND_WINDOW_PARTITION, EXPR_KIND_WINDOW_ORDER, EXPR_KIND_WINDOW_FRAME_RANGE,
  EXPR_KIND_WINDOW_FRAME_ROWS, EXPR_KIND_SELECT_TARGET, EXPR_KIND_INSERT_TARGET, EXPR_KIND_UPDATE_SOURCE,
  EXPR_KIND_UPDATE_TARGET, EXPR_KIND_GROUP_BY, EXPR_KIND_ORDER_BY, EXPR_KIND_DISTINCT_ON,
  EXPR_KIND_LIMIT, EXPR_KIND_OFFSET, EXPR_KIND_RETURNING, EXPR_KIND_VALUES,
  EXPR_KIND_VALUES_SINGLE, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_DOMAIN_CHECK, EXPR_KIND_COLUMN_DEFAULT,
  EXPR_KIND_FUNCTION_DEFAULT, EXPR_KIND_INDEX_EXPRESSION, EXPR_KIND_INDEX_PREDICATE, EXPR_KIND_ALTER_COL_TRANSFORM,
  EXPR_KIND_EXECUTE_PARAMETER, EXPR_KIND_TRIGGER_WHEN, EXPR_KIND_POLICY, EXPR_KIND_PARTITION_EXPRESSION
}
 

Functions

ParseStatemake_parsestate (ParseState *parentParseState)
 
void free_parsestate (ParseState *pstate)
 
int parser_errposition (ParseState *pstate, int location)
 
void setup_parser_errposition_callback (ParseCallbackState *pcbstate, ParseState *pstate, int location)
 
void cancel_parser_errposition_callback (ParseCallbackState *pcbstate)
 
Varmake_var (ParseState *pstate, RangeTblEntry *rte, int attrno, int location)
 
Oid transformArrayType (Oid *arrayType, int32 *arrayTypmod)
 
ArrayReftransformArraySubscripts (ParseState *pstate, Node *arrayBase, Oid arrayType, Oid elementType, int32 arrayTypMod, List *indirection, Node *assignFrom)
 
Constmake_const (ParseState *pstate, Value *value, int location)
 

Typedef Documentation

◆ CoerceParamHook

typedef Node*(* CoerceParamHook) (ParseState *pstate, Param *param, Oid targetTypeId, int32 targetTypeMod, int location)

Definition at line 82 of file parse_node.h.

◆ ParseCallbackState

◆ ParseExprKind

◆ ParseNamespaceItem

◆ ParseParamRefHook

typedef Node*(* ParseParamRefHook) (ParseState *pstate, ParamRef *pref)

Definition at line 81 of file parse_node.h.

◆ ParseState

Definition at line 77 of file parse_node.h.

◆ PostParseColumnRefHook

typedef Node*(* PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var)

Definition at line 80 of file parse_node.h.

◆ PreParseColumnRefHook

typedef Node*(* PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref)

Definition at line 79 of file parse_node.h.

Enumeration Type Documentation

◆ ParseExprKind

Enumerator
EXPR_KIND_NONE 
EXPR_KIND_OTHER 
EXPR_KIND_JOIN_ON 
EXPR_KIND_JOIN_USING 
EXPR_KIND_FROM_SUBSELECT 
EXPR_KIND_FROM_FUNCTION 
EXPR_KIND_WHERE 
EXPR_KIND_HAVING 
EXPR_KIND_FILTER 
EXPR_KIND_WINDOW_PARTITION 
EXPR_KIND_WINDOW_ORDER 
EXPR_KIND_WINDOW_FRAME_RANGE 
EXPR_KIND_WINDOW_FRAME_ROWS 
EXPR_KIND_SELECT_TARGET 
EXPR_KIND_INSERT_TARGET 
EXPR_KIND_UPDATE_SOURCE 
EXPR_KIND_UPDATE_TARGET 
EXPR_KIND_GROUP_BY 
EXPR_KIND_ORDER_BY 
EXPR_KIND_DISTINCT_ON 
EXPR_KIND_LIMIT 
EXPR_KIND_OFFSET 
EXPR_KIND_RETURNING 
EXPR_KIND_VALUES 
EXPR_KIND_VALUES_SINGLE 
EXPR_KIND_CHECK_CONSTRAINT 
EXPR_KIND_DOMAIN_CHECK 
EXPR_KIND_COLUMN_DEFAULT 
EXPR_KIND_FUNCTION_DEFAULT 
EXPR_KIND_INDEX_EXPRESSION 
EXPR_KIND_INDEX_PREDICATE 
EXPR_KIND_ALTER_COL_TRANSFORM 
EXPR_KIND_EXECUTE_PARAMETER 
EXPR_KIND_TRIGGER_WHEN 
EXPR_KIND_POLICY 
EXPR_KIND_PARTITION_EXPRESSION 

Definition at line 33 of file parse_node.h.

34 {
35  EXPR_KIND_NONE = 0, /* "not in an expression" */
36  EXPR_KIND_OTHER, /* reserved for extensions */
37  EXPR_KIND_JOIN_ON, /* JOIN ON */
38  EXPR_KIND_JOIN_USING, /* JOIN USING */
39  EXPR_KIND_FROM_SUBSELECT, /* sub-SELECT in FROM clause */
40  EXPR_KIND_FROM_FUNCTION, /* function in FROM clause */
41  EXPR_KIND_WHERE, /* WHERE */
42  EXPR_KIND_HAVING, /* HAVING */
43  EXPR_KIND_FILTER, /* FILTER */
44  EXPR_KIND_WINDOW_PARTITION, /* window definition PARTITION BY */
45  EXPR_KIND_WINDOW_ORDER, /* window definition ORDER BY */
46  EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */
47  EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */
48  EXPR_KIND_SELECT_TARGET, /* SELECT target list item */
49  EXPR_KIND_INSERT_TARGET, /* INSERT target list item */
50  EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */
51  EXPR_KIND_UPDATE_TARGET, /* UPDATE assignment target item */
52  EXPR_KIND_GROUP_BY, /* GROUP BY */
53  EXPR_KIND_ORDER_BY, /* ORDER BY */
54  EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */
55  EXPR_KIND_LIMIT, /* LIMIT */
56  EXPR_KIND_OFFSET, /* OFFSET */
57  EXPR_KIND_RETURNING, /* RETURNING */
58  EXPR_KIND_VALUES, /* VALUES */
59  EXPR_KIND_VALUES_SINGLE, /* single-row VALUES (in INSERT only) */
60  EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */
61  EXPR_KIND_DOMAIN_CHECK, /* CHECK constraint for a domain */
62  EXPR_KIND_COLUMN_DEFAULT, /* default value for a table column */
63  EXPR_KIND_FUNCTION_DEFAULT, /* default parameter value for function */
64  EXPR_KIND_INDEX_EXPRESSION, /* index expression */
65  EXPR_KIND_INDEX_PREDICATE, /* index predicate */
66  EXPR_KIND_ALTER_COL_TRANSFORM, /* transform expr in ALTER COLUMN TYPE */
67  EXPR_KIND_EXECUTE_PARAMETER, /* parameter value in EXECUTE */
68  EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */
69  EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */
70  EXPR_KIND_PARTITION_EXPRESSION /* PARTITION BY expression */
ParseExprKind
Definition: parse_node.h:33

Function Documentation

◆ cancel_parser_errposition_callback()

void cancel_parser_errposition_callback ( ParseCallbackState pcbstate)

◆ free_parsestate()

void free_parsestate ( ParseState pstate)

Definition at line 77 of file parse_node.c.

References ereport, errcode(), errmsg(), ERROR, heap_close, MaxTupleAttributeNumber, NoLock, ParseState::p_next_resno, ParseState::p_target_relation, and pfree().

Referenced by AlterPolicy(), CreatePolicy(), CreateTrigger(), inline_function(), parse_analyze(), parse_analyze_varparams(), parse_sub_analyze(), pg_analyze_and_rewrite_params(), RemoveRoleFromObjectPolicy(), standard_ProcessUtility(), transformIndexStmt(), transformInsertStmt(), and transformRuleStmt().

78 {
79  /*
80  * Check that we did not produce too many resnos; at the very least we
81  * cannot allow more than 2^16, since that would exceed the range of a
82  * AttrNumber. It seems safest to use MaxTupleAttributeNumber.
83  */
84  if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber)
85  ereport(ERROR,
86  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
87  errmsg("target lists can have at most %d entries",
89 
90  if (pstate->p_target_relation != NULL)
92 
93  pfree(pstate);
94 }
#define MaxTupleAttributeNumber
Definition: htup_details.h:33
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void pfree(void *pointer)
Definition: mcxt.c:949
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
int p_next_resno
Definition: parse_node.h:187
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
Relation p_target_relation
Definition: parse_node.h:182

◆ make_const()

Const* make_const ( ParseState pstate,
Value value,
int  location 
)

Definition at line 470 of file parse_node.c.

References bit_in(), BITOID, cancel_parser_errposition_callback(), CStringGetDatum, DirectFunctionCall3, elog, ERROR, Int32GetDatum, INT4OID, Int64GetDatum(), INT8OID, intVal, InvalidOid, Const::location, makeConst(), nodeTag, numeric_in(), NUMERICOID, ObjectIdGetDatum, scanint8(), setup_parser_errposition_callback(), strVal, T_BitString, T_Float, T_Integer, T_Null, T_String, UNKNOWNOID, and val.

Referenced by transformExprRecurse(), and transformPartitionBoundValue().

471 {
472  Const *con;
473  Datum val;
474  int64 val64;
475  Oid typeid;
476  int typelen;
477  bool typebyval;
478  ParseCallbackState pcbstate;
479 
480  switch (nodeTag(value))
481  {
482  case T_Integer:
483  val = Int32GetDatum(intVal(value));
484 
485  typeid = INT4OID;
486  typelen = sizeof(int32);
487  typebyval = true;
488  break;
489 
490  case T_Float:
491  /* could be an oversize integer as well as a float ... */
492  if (scanint8(strVal(value), true, &val64))
493  {
494  /*
495  * It might actually fit in int32. Probably only INT_MIN can
496  * occur, but we'll code the test generally just to be sure.
497  */
498  int32 val32 = (int32) val64;
499 
500  if (val64 == (int64) val32)
501  {
502  val = Int32GetDatum(val32);
503 
504  typeid = INT4OID;
505  typelen = sizeof(int32);
506  typebyval = true;
507  }
508  else
509  {
510  val = Int64GetDatum(val64);
511 
512  typeid = INT8OID;
513  typelen = sizeof(int64);
514  typebyval = FLOAT8PASSBYVAL; /* int8 and float8 alike */
515  }
516  }
517  else
518  {
519  /* arrange to report location if numeric_in() fails */
520  setup_parser_errposition_callback(&pcbstate, pstate, location);
522  CStringGetDatum(strVal(value)),
524  Int32GetDatum(-1));
526 
527  typeid = NUMERICOID;
528  typelen = -1; /* variable len */
529  typebyval = false;
530  }
531  break;
532 
533  case T_String:
534 
535  /*
536  * We assume here that UNKNOWN's internal representation is the
537  * same as CSTRING
538  */
539  val = CStringGetDatum(strVal(value));
540 
541  typeid = UNKNOWNOID; /* will be coerced later */
542  typelen = -2; /* cstring-style varwidth type */
543  typebyval = false;
544  break;
545 
546  case T_BitString:
547  /* arrange to report location if bit_in() fails */
548  setup_parser_errposition_callback(&pcbstate, pstate, location);
550  CStringGetDatum(strVal(value)),
552  Int32GetDatum(-1));
554  typeid = BITOID;
555  typelen = -1;
556  typebyval = false;
557  break;
558 
559  case T_Null:
560  /* return a null const */
561  con = makeConst(UNKNOWNOID,
562  -1,
563  InvalidOid,
564  -2,
565  (Datum) 0,
566  true,
567  false);
568  con->location = location;
569  return con;
570 
571  default:
572  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
573  return NULL; /* keep compiler quiet */
574  }
575 
576  con = makeConst(typeid,
577  -1, /* typmod -1 is OK for all cases */
578  InvalidOid, /* all cases are uncollatable types */
579  typelen,
580  val,
581  false,
582  typebyval);
583  con->location = location;
584 
585  return con;
586 }
#define NUMERICOID
Definition: pg_type.h:554
#define INT4OID
Definition: pg_type.h:316
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:298
signed int int32
Definition: c.h:284
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:161
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Datum bit_in(PG_FUNCTION_ARGS)
Definition: varbit.c:113
#define CStringGetDatum(X)
Definition: postgres.h:584
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:569
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:145
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:589
int location
Definition: primnodes.h:203
uintptr_t Datum
Definition: postgres.h:372
#define InvalidOid
Definition: postgres_ext.h:36
#define INT8OID
Definition: pg_type.h:304
#define BITOID
Definition: pg_type.h:542
#define UNKNOWNOID
Definition: pg_type.h:431
#define nodeTag(nodeptr)
Definition: nodes.h:515
Definition: nodes.h:286
Definition: nodes.h:283
#define Int32GetDatum(X)
Definition: postgres.h:485
#define intVal(v)
Definition: value.h:52
#define elog
Definition: elog.h:219
long val
Definition: informix.c:689
bool scanint8(const char *str, bool errorOK, int64 *result)
Definition: int8.c:55

◆ make_parsestate()

ParseState* make_parsestate ( ParseState parentParseState)

Definition at line 44 of file parse_node.c.

References ParseState::p_coerce_param_hook, ParseState::p_next_resno, ParseState::p_paramref_hook, ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseState::p_queryEnv, ParseState::p_ref_hook_state, ParseState::p_resolve_unknowns, ParseState::p_sourcetext, palloc0(), and ParseState::parentParseState.

Referenced by AddRelationNewConstraints(), AlterDomainDefault(), AlterPolicy(), ATPrepAlterColumnType(), check_new_partition_bound(), convert_ANY_sublink_to_join(), copy_table(), CreatePolicy(), CreateTrigger(), DefineDomain(), DefineRelation(), domainAddConstraint(), EvaluateParams(), inline_function(), parse_analyze(), parse_analyze_varparams(), parse_sub_analyze(), pg_analyze_and_rewrite_params(), PrepareQuery(), RemoveRoleFromObjectPolicy(), standard_ProcessUtility(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), transformAlterTableStmt(), transformCreateStmt(), transformIndexStmt(), transformInsertStmt(), transformPartitionSpec(), transformRuleStmt(), and UpdateRangeTableOfViewParse().

45 {
46  ParseState *pstate;
47 
48  pstate = palloc0(sizeof(ParseState));
49 
50  pstate->parentParseState = parentParseState;
51 
52  /* Fill in fields that don't start at null/false/zero */
53  pstate->p_next_resno = 1;
54  pstate->p_resolve_unknowns = true;
55 
56  if (parentParseState)
57  {
58  pstate->p_sourcetext = parentParseState->p_sourcetext;
59  /* all hooks are copied from parent */
60  pstate->p_pre_columnref_hook = parentParseState->p_pre_columnref_hook;
61  pstate->p_post_columnref_hook = parentParseState->p_post_columnref_hook;
62  pstate->p_paramref_hook = parentParseState->p_paramref_hook;
63  pstate->p_coerce_param_hook = parentParseState->p_coerce_param_hook;
64  pstate->p_ref_hook_state = parentParseState->p_ref_hook_state;
65  /* query environment stays in context for the whole parse analysis */
66  pstate->p_queryEnv = parentParseState->p_queryEnv;
67  }
68 
69  return pstate;
70 }
QueryEnvironment * p_queryEnv
Definition: parse_node.h:195
CoerceParamHook p_coerce_param_hook
Definition: parse_node.h:213
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:211
bool p_resolve_unknowns
Definition: parse_node.h:192
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:212
int p_next_resno
Definition: parse_node.h:187
const char * p_sourcetext
Definition: parse_node.h:171
struct ParseState * parentParseState
Definition: parse_node.h:170
void * palloc0(Size size)
Definition: mcxt.c:877
void * p_ref_hook_state
Definition: parse_node.h:214
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:210

◆ make_var()

Var* make_var ( ParseState pstate,
RangeTblEntry rte,
int  attrno,
int  location 
)

Definition at line 189 of file parse_node.c.

References get_rte_attribute_type(), Var::location, makeVar(), and RTERangeTablePosn().

Referenced by scanRTEForColumn(), and transformAssignedExpr().

190 {
191  Var *result;
192  int vnum,
193  sublevels_up;
194  Oid vartypeid;
195  int32 type_mod;
196  Oid varcollid;
197 
198  vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
199  get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod, &varcollid);
200  result = makeVar(vnum, attrno, vartypeid, type_mod, varcollid, sublevels_up);
201  result->location = location;
202  return result;
203 }
void get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, Oid *vartype, int32 *vartypmod, Oid *varcollid)
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
signed int int32
Definition: c.h:284
int location
Definition: primnodes.h:178
Var * makeVar(Index varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition: makefuncs.c:67
int RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)

◆ parser_errposition()

int parser_errposition ( ParseState pstate,
int  location 
)

Definition at line 111 of file parse_node.c.

References errposition(), ParseState::p_sourcetext, and pg_mbstrlen_with_len().

Referenced by addRangeTableEntryForCTE(), addRangeTableEntryForFunction(), AlterDatabase(), analyzeCTE(), analyzeCTETargetList(), assign_collations_walker(), assign_hypothetical_collations(), check_agg_arguments(), check_agg_arguments_walker(), check_agglevels_and_constraints(), check_lateral_ref_ok(), check_new_partition_bound(), check_parameter_resolution_walker(), check_srf_call_placement(), check_ungrouped_columns_walker(), checkExprIsVarFree(), checkInsertTargets(), checkTargetlistEntrySQL92(), checkWellFormedRecursion(), checkWellFormedRecursionWalker(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), colNameToVar(), compatible_oper(), compute_attributes_sql_style(), compute_attributes_with_style(), compute_common_attribute(), createdb(), CreateExtension(), CreateRole(), CreateTrigger(), DefineCollation(), DefineType(), emit_precedence_warnings(), errorMissingColumn(), errorMissingRTE(), ExecAlterDefaultPrivilegesStmt(), ExecAlterExtensionStmt(), ExpandAllTables(), ExpandColumnRefStar(), ExplainQuery(), finalize_grouping_exprs_walker(), findTargetlistEntrySQL92(), fixed_paramref_hook(), GetColumnDefCollation(), init_params(), LookupOperName(), LookupTypeName(), LookupTypeNameOid(), make_distinct_op(), make_op(), make_row_comparison_op(), make_row_distinct_op(), make_scalar_array_op(), merge_collation_state(), op_error(), parseCheckAggregates(), ParseFuncOrColumn(), parser_coercion_errposition(), parseTypeString(), pcb_error_callback(), plpgsql_post_column_ref(), ProcessCopyOptions(), resolve_column_ref(), resolve_unique_index_expr(), scanNameSpaceForRefname(), scanNameSpaceForRelid(), scanRTEForColumn(), select_common_collation(), select_common_type(), TopologicalSort(), transformAExprNullIf(), transformAggregateCall(), transformArrayExpr(), transformArraySubscripts(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformColumnDefinition(), transformColumnRef(), transformColumnType(), transformConstraintAttrs(), transformDistinctClause(), transformDistinctOnClause(), transformExprRecurse(), transformFromClauseItem(), transformGroupingFunc(), transformGroupingSet(), transformIndexConstraint(), transformIndirection(), transformInsertRow(), transformInsertStmt(), transformLockingClause(), transformMultiAssignRef(), transformOnConflictArbiter(), transformParamRef(), transformPartitionBound(), transformPartitionBoundValue(), transformPartitionSpec(), transformRangeFunction(), transformRangeTableFunc(), transformRangeTableSample(), transformReturningList(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), transformSubLink(), transformTableConstraint(), transformUpdateTargetList(), transformValuesClause(), transformWindowDefinitions(), transformWindowFuncCall(), transformWithClause(), transformXmlExpr(), transformXmlSerialize(), typenameType(), typenameTypeMod(), unknown_attribute(), validateInfiniteBounds(), variable_coerce_param_hook(), and variable_paramref_hook().

112 {
113  int pos;
114 
115  /* No-op if location was not provided */
116  if (location < 0)
117  return 0;
118  /* Can't do anything if source text is not available */
119  if (pstate == NULL || pstate->p_sourcetext == NULL)
120  return 0;
121  /* Convert offset to character number */
122  pos = pg_mbstrlen_with_len(pstate->p_sourcetext, location) + 1;
123  /* And pass it to the ereport mechanism */
124  return errposition(pos);
125 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
const char * p_sourcetext
Definition: parse_node.h:171
int errposition(int cursorpos)
Definition: elog.c:1125

◆ setup_parser_errposition_callback()

void setup_parser_errposition_callback ( ParseCallbackState pcbstate,
ParseState pstate,
int  location 
)

Definition at line 145 of file parse_node.c.

References ErrorContextCallback::arg, ErrorContextCallback::callback, ParseCallbackState::errcallback, error_context_stack, ParseCallbackState::location, pcb_error_callback(), ErrorContextCallback::previous, and ParseCallbackState::pstate.

Referenced by addTargetToGroupList(), addTargetToSortList(), coerce_type(), LookupCollation(), LookupTypeName(), make_const(), make_oper_cache_key(), ParseFuncOrColumn(), parserOpenTable(), transformCreateStmt(), transformSetOperationTree(), transformTableLikeClause(), and typenameTypeMod().

147 {
148  /* Setup error traceback support for ereport() */
149  pcbstate->pstate = pstate;
150  pcbstate->location = location;
152  pcbstate->errcallback.arg = (void *) pcbstate;
154  error_context_stack = &pcbstate->errcallback;
155 }
ErrorContextCallback errcallback
Definition: parse_node.h:258
void(* callback)(void *arg)
Definition: elog.h:239
struct ErrorContextCallback * previous
Definition: elog.h:238
ErrorContextCallback * error_context_stack
Definition: elog.c:88
ParseState * pstate
Definition: parse_node.h:256
static void pcb_error_callback(void *arg)
Definition: parse_node.c:175

◆ transformArraySubscripts()

ArrayRef* transformArraySubscripts ( ParseState pstate,
Node arrayBase,
Oid  arrayType,
Oid  elementType,
int32  arrayTypMod,
List indirection,
Node assignFrom 
)

Definition at line 294 of file parse_node.c.

References Assert, COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_ASSIGNMENT, ereport, errcode(), errhint(), errmsg(), ERROR, exprLocation(), exprType(), format_type_be(), idx(), Int32GetDatum, INT4OID, InvalidOid, A_Indices::is_slice, lappend(), lfirst, lfirst_node, A_Indices::lidx, makeConst(), makeNode, NIL, OidIsValid, ParseState::p_expr_kind, parser_errposition(), ArrayRef::refarraytype, ArrayRef::refassgnexpr, ArrayRef::refelemtype, ArrayRef::refexpr, ArrayRef::reflowerindexpr, ArrayRef::reftypmod, ArrayRef::refupperindexpr, transformArrayType(), transformExpr(), and A_Indices::uidx.

Referenced by transformAssignmentSubscripts(), and transformIndirection().

301 {
302  bool isSlice = false;
303  List *upperIndexpr = NIL;
304  List *lowerIndexpr = NIL;
305  ListCell *idx;
306  ArrayRef *aref;
307 
308  /*
309  * Caller may or may not have bothered to determine elementType. Note
310  * that if the caller did do so, arrayType/arrayTypMod must be as modified
311  * by transformArrayType, ie, smash domain to base type.
312  */
313  if (!OidIsValid(elementType))
314  elementType = transformArrayType(&arrayType, &arrayTypMod);
315 
316  /*
317  * A list containing only simple subscripts refers to a single array
318  * element. If any of the items are slice specifiers (lower:upper), then
319  * the subscript expression means an array slice operation. In this case,
320  * we convert any non-slice items to slices by treating the single
321  * subscript as the upper bound and supplying an assumed lower bound of 1.
322  * We have to prescan the list to see if there are any slice items.
323  */
324  foreach(idx, indirection)
325  {
326  A_Indices *ai = (A_Indices *) lfirst(idx);
327 
328  if (ai->is_slice)
329  {
330  isSlice = true;
331  break;
332  }
333  }
334 
335  /*
336  * Transform the subscript expressions.
337  */
338  foreach(idx, indirection)
339  {
340  A_Indices *ai = lfirst_node(A_Indices, idx);
341  Node *subexpr;
342 
343  if (isSlice)
344  {
345  if (ai->lidx)
346  {
347  subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind);
348  /* If it's not int4 already, try to coerce */
349  subexpr = coerce_to_target_type(pstate,
350  subexpr, exprType(subexpr),
351  INT4OID, -1,
354  -1);
355  if (subexpr == NULL)
356  ereport(ERROR,
357  (errcode(ERRCODE_DATATYPE_MISMATCH),
358  errmsg("array subscript must have type integer"),
359  parser_errposition(pstate, exprLocation(ai->lidx))));
360  }
361  else if (!ai->is_slice)
362  {
363  /* Make a constant 1 */
364  subexpr = (Node *) makeConst(INT4OID,
365  -1,
366  InvalidOid,
367  sizeof(int32),
368  Int32GetDatum(1),
369  false,
370  true); /* pass by value */
371  }
372  else
373  {
374  /* Slice with omitted lower bound, put NULL into the list */
375  subexpr = NULL;
376  }
377  lowerIndexpr = lappend(lowerIndexpr, subexpr);
378  }
379  else
380  Assert(ai->lidx == NULL && !ai->is_slice);
381 
382  if (ai->uidx)
383  {
384  subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
385  /* If it's not int4 already, try to coerce */
386  subexpr = coerce_to_target_type(pstate,
387  subexpr, exprType(subexpr),
388  INT4OID, -1,
391  -1);
392  if (subexpr == NULL)
393  ereport(ERROR,
394  (errcode(ERRCODE_DATATYPE_MISMATCH),
395  errmsg("array subscript must have type integer"),
396  parser_errposition(pstate, exprLocation(ai->uidx))));
397  }
398  else
399  {
400  /* Slice with omitted upper bound, put NULL into the list */
401  Assert(isSlice && ai->is_slice);
402  subexpr = NULL;
403  }
404  upperIndexpr = lappend(upperIndexpr, subexpr);
405  }
406 
407  /*
408  * If doing an array store, coerce the source value to the right type.
409  * (This should agree with the coercion done by transformAssignedExpr.)
410  */
411  if (assignFrom != NULL)
412  {
413  Oid typesource = exprType(assignFrom);
414  Oid typeneeded = isSlice ? arrayType : elementType;
415  Node *newFrom;
416 
417  newFrom = coerce_to_target_type(pstate,
418  assignFrom, typesource,
419  typeneeded, arrayTypMod,
422  -1);
423  if (newFrom == NULL)
424  ereport(ERROR,
425  (errcode(ERRCODE_DATATYPE_MISMATCH),
426  errmsg("array assignment requires type %s"
427  " but expression is of type %s",
428  format_type_be(typeneeded),
429  format_type_be(typesource)),
430  errhint("You will need to rewrite or cast the expression."),
431  parser_errposition(pstate, exprLocation(assignFrom))));
432  assignFrom = newFrom;
433  }
434 
435  /*
436  * Ready to build the ArrayRef node.
437  */
438  aref = makeNode(ArrayRef);
439  aref->refarraytype = arrayType;
440  aref->refelemtype = elementType;
441  aref->reftypmod = arrayTypMod;
442  /* refcollid will be set by parse_collate.c */
443  aref->refupperindexpr = upperIndexpr;
444  aref->reflowerindexpr = lowerIndexpr;
445  aref->refexpr = (Expr *) arrayBase;
446  aref->refassgnexpr = (Expr *) assignFrom;
447 
448  return aref;
449 }
#define NIL
Definition: pg_list.h:69
Expr * refassgnexpr
Definition: primnodes.h:410
int errhint(const char *fmt,...)
Definition: elog.c:987
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1186
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:146
#define INT4OID
Definition: pg_type.h:316
Definition: nodes.h:510
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:264
unsigned int Oid
Definition: postgres_ext.h:31
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:298
#define OidIsValid(objectId)
Definition: c.h:576
signed int int32
Definition: c.h:284
bool is_slice
Definition: parsenodes.h:381
#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:78
#define lfirst_node(type, lc)
Definition: pg_list.h:109
List * refupperindexpr
Definition: primnodes.h:403
List * reflowerindexpr
Definition: primnodes.h:405
int32 reftypmod
Definition: primnodes.h:401
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
Oid refelemtype
Definition: primnodes.h:400
ParseExprKind p_expr_kind
Definition: parse_node.h:186
#define InvalidOid
Definition: postgres_ext.h:36
#define makeNode(_type_)
Definition: nodes.h:558
#define Assert(condition)
Definition: c.h:670
#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
Node * lidx
Definition: parsenodes.h:382
Oid refarraytype
Definition: primnodes.h:399
#define Int32GetDatum(X)
Definition: postgres.h:485
Oid transformArrayType(Oid *arrayType, int32 *arrayTypmod)
Definition: parse_node.c:216
int errmsg(const char *fmt,...)
Definition: elog.c:797
Node * uidx
Definition: parsenodes.h:383
Definition: pg_list.h:45
Expr * refexpr
Definition: primnodes.h:408

◆ transformArrayType()

Oid transformArrayType ( Oid arrayType,
int32 arrayTypmod 
)

Definition at line 216 of file parse_node.c.

References elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), getBaseTypeAndTypmod(), GETSTRUCT, HeapTupleIsValid, INT2ARRAYOID, INT2VECTOROID, InvalidOid, ObjectIdGetDatum, OIDARRAYOID, OIDVECTOROID, ReleaseSysCache(), SearchSysCache1(), and TYPEOID.

Referenced by transformArraySubscripts(), and transformAssignmentSubscripts().

217 {
218  Oid origArrayType = *arrayType;
219  Oid elementType;
220  HeapTuple type_tuple_array;
221  Form_pg_type type_struct_array;
222 
223  /*
224  * If the input is a domain, smash to base type, and extract the actual
225  * typmod to be applied to the base type. Subscripting a domain is an
226  * operation that necessarily works on the base array type, not the domain
227  * itself. (Note that we provide no method whereby the creator of a
228  * domain over an array type could hide its ability to be subscripted.)
229  */
230  *arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);
231 
232  /*
233  * We treat int2vector and oidvector as though they were domains over
234  * int2[] and oid[]. This is needed because array slicing could create an
235  * array that doesn't satisfy the dimensionality constraints of the
236  * xxxvector type; so we want the result of a slice operation to be
237  * considered to be of the more general type.
238  */
239  if (*arrayType == INT2VECTOROID)
240  *arrayType = INT2ARRAYOID;
241  else if (*arrayType == OIDVECTOROID)
242  *arrayType = OIDARRAYOID;
243 
244  /* Get the type tuple for the array */
245  type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType));
246  if (!HeapTupleIsValid(type_tuple_array))
247  elog(ERROR, "cache lookup failed for type %u", *arrayType);
248  type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
249 
250  /* needn't check typisdefined since this will fail anyway */
251 
252  elementType = type_struct_array->typelem;
253  if (elementType == InvalidOid)
254  ereport(ERROR,
255  (errcode(ERRCODE_DATATYPE_MISMATCH),
256  errmsg("cannot subscript type %s because it is not an array",
257  format_type_be(origArrayType))));
258 
259  ReleaseSysCache(type_tuple_array);
260 
261  return elementType;
262 }
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2288
#define INT2VECTOROID
Definition: pg_type.h:312
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
unsigned int Oid
Definition: postgres_ext.h:31
#define OIDVECTOROID
Definition: pg_type.h:344
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define INT2ARRAYOID
Definition: pg_type.h:464
#define ereport(elevel, rest)
Definition: elog.h:122
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define OIDARRAYOID
Definition: pg_type.h:472
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219