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  ParseNamespaceColumn
 
struct  ParseCallbackState
 

Typedefs

typedef struct ParseState ParseState
 
typedef struct ParseNamespaceItem ParseNamespaceItem
 
typedef struct ParseNamespaceColumn ParseNamespaceColumn
 
typedef enum ParseExprKind ParseExprKind
 
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 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_WINDOW_FRAME_GROUPS, 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_BOUND, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_CALL_ARGUMENT, EXPR_KIND_COPY_WHERE,
  EXPR_KIND_GENERATED_COLUMN
}
 

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)
 
Oid transformContainerType (Oid *containerType, int32 *containerTypmod)
 
SubscriptingReftransformContainerSubscripts (ParseState *pstate, Node *containerBase, Oid containerType, Oid elementType, int32 containerTypMod, 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 90 of file parse_node.h.

◆ ParseCallbackState

◆ ParseExprKind

◆ ParseNamespaceColumn

Definition at line 25 of file parse_node.h.

◆ ParseNamespaceItem

Definition at line 24 of file parse_node.h.

◆ ParseParamRefHook

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

Definition at line 89 of file parse_node.h.

◆ ParseState

typedef struct ParseState ParseState

Definition at line 23 of file parse_node.h.

◆ PostParseColumnRefHook

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

Definition at line 88 of file parse_node.h.

◆ PreParseColumnRefHook

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

Definition at line 87 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_WINDOW_FRAME_GROUPS 
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_BOUND 
EXPR_KIND_PARTITION_EXPRESSION 
EXPR_KIND_CALL_ARGUMENT 
EXPR_KIND_COPY_WHERE 
EXPR_KIND_GENERATED_COLUMN 

Definition at line 38 of file parse_node.h.

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

Function Documentation

◆ cancel_parser_errposition_callback()

void cancel_parser_errposition_callback ( ParseCallbackState pcbstate)

◆ free_parsestate()

void free_parsestate ( ParseState pstate)

Definition at line 76 of file parse_node.c.

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

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

77 {
78  /*
79  * Check that we did not produce too many resnos; at the very least we
80  * cannot allow more than 2^16, since that would exceed the range of a
81  * AttrNumber. It seems safest to use MaxTupleAttributeNumber.
82  */
83  if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber)
84  ereport(ERROR,
85  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
86  errmsg("target lists can have at most %d entries",
88 
89  if (pstate->p_target_relation != NULL)
91 
92  pfree(pstate);
93 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define MaxTupleAttributeNumber
Definition: htup_details.h:33
int errcode(int sqlerrcode)
Definition: elog.c:610
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
int p_next_resno
Definition: parse_node.h:195
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
Relation p_target_relation
Definition: parse_node.h:190

◆ make_const()

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

Definition at line 455 of file parse_node.c.

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

Referenced by transformExprRecurse().

456 {
457  Const *con;
458  Datum val;
459  int64 val64;
460  Oid typeid;
461  int typelen;
462  bool typebyval;
463  ParseCallbackState pcbstate;
464 
465  switch (nodeTag(value))
466  {
467  case T_Integer:
468  val = Int32GetDatum(intVal(value));
469 
470  typeid = INT4OID;
471  typelen = sizeof(int32);
472  typebyval = true;
473  break;
474 
475  case T_Float:
476  /* could be an oversize integer as well as a float ... */
477  if (scanint8(strVal(value), true, &val64))
478  {
479  /*
480  * It might actually fit in int32. Probably only INT_MIN can
481  * occur, but we'll code the test generally just to be sure.
482  */
483  int32 val32 = (int32) val64;
484 
485  if (val64 == (int64) val32)
486  {
487  val = Int32GetDatum(val32);
488 
489  typeid = INT4OID;
490  typelen = sizeof(int32);
491  typebyval = true;
492  }
493  else
494  {
495  val = Int64GetDatum(val64);
496 
497  typeid = INT8OID;
498  typelen = sizeof(int64);
499  typebyval = FLOAT8PASSBYVAL; /* int8 and float8 alike */
500  }
501  }
502  else
503  {
504  /* arrange to report location if numeric_in() fails */
505  setup_parser_errposition_callback(&pcbstate, pstate, location);
507  CStringGetDatum(strVal(value)),
509  Int32GetDatum(-1));
511 
512  typeid = NUMERICOID;
513  typelen = -1; /* variable len */
514  typebyval = false;
515  }
516  break;
517 
518  case T_String:
519 
520  /*
521  * We assume here that UNKNOWN's internal representation is the
522  * same as CSTRING
523  */
524  val = CStringGetDatum(strVal(value));
525 
526  typeid = UNKNOWNOID; /* will be coerced later */
527  typelen = -2; /* cstring-style varwidth type */
528  typebyval = false;
529  break;
530 
531  case T_BitString:
532  /* arrange to report location if bit_in() fails */
533  setup_parser_errposition_callback(&pcbstate, pstate, location);
535  CStringGetDatum(strVal(value)),
537  Int32GetDatum(-1));
539  typeid = BITOID;
540  typelen = -1;
541  typebyval = false;
542  break;
543 
544  case T_Null:
545  /* return a null const */
546  con = makeConst(UNKNOWNOID,
547  -1,
548  InvalidOid,
549  -2,
550  (Datum) 0,
551  true,
552  false);
553  con->location = location;
554  return con;
555 
556  default:
557  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
558  return NULL; /* keep compiler quiet */
559  }
560 
561  con = makeConst(typeid,
562  -1, /* typmod -1 is OK for all cases */
563  InvalidOid, /* all cases are uncollatable types */
564  typelen,
565  val,
566  false,
567  typebyval);
568  con->location = location;
569 
570  return con;
571 }
#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:299
signed int int32
Definition: c.h:362
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:160
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Datum bit_in(PG_FUNCTION_ARGS)
Definition: varbit.c:146
#define CStringGetDatum(X)
Definition: postgres.h:578
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:620
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1701
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:144
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:628
int location
Definition: primnodes.h:221
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define FLOAT8PASSBYVAL
Definition: c.h:503
#define nodeTag(nodeptr)
Definition: nodes.h:534
Definition: nodes.h:295
Definition: nodes.h:292
#define Int32GetDatum(X)
Definition: postgres.h:479
#define intVal(v)
Definition: value.h:52
#define elog(elevel,...)
Definition: elog.h:214
long val
Definition: informix.c:664
bool scanint8(const char *str, bool errorOK, int64 *result)
Definition: int8.c:55

◆ make_parsestate()

ParseState* make_parsestate ( ParseState parentParseState)

Definition at line 43 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(), ExplainExecuteQuery(), inline_function(), parse_analyze(), parse_analyze_varparams(), parse_sub_analyze(), pg_analyze_and_rewrite_params(), RemoveRoleFromObjectPolicy(), rewriteTargetView(), standard_ProcessUtility(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), transformAlterTableStmt(), transformCreateStmt(), transformIndexStmt(), transformInsertStmt(), transformPartitionSpec(), transformRuleStmt(), and UpdateRangeTableOfViewParse().

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

◆ parser_errposition()

int parser_errposition ( ParseState pstate,
int  location 
)

Definition at line 110 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_nested_generated_walker(), 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_common_attribute(), compute_function_attributes(), ComputePartitionAttrs(), createdb(), CreateExtension(), CreateRole(), CreateTrigger(), DefineCollation(), DefineType(), DropDatabase(), emit_precedence_warnings(), errorMissingColumn(), errorMissingRTE(), EvaluateParams(), ExecAlterDefaultPrivilegesStmt(), ExecAlterExtensionStmt(), ExecVacuum(), ExpandAllTables(), ExpandColumnRefStar(), ExplainQuery(), finalize_grouping_exprs_walker(), findTargetlistEntrySQL92(), fixed_paramref_hook(), GetColumnDefCollation(), init_params(), LookupOperName(), LookupTypeNameExtended(), 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(), scanNSItemForColumn(), scanRTEForColumn(), select_common_collation(), select_common_type(), TopologicalSort(), transformAExprNullIf(), transformAggregateCall(), transformArrayExpr(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCoalesceExpr(), transformCollateClause(), transformColumnDefinition(), transformColumnRef(), transformColumnType(), transformConstraintAttrs(), transformContainerSubscripts(), transformDistinctClause(), transformDistinctOnClause(), transformExprRecurse(), transformFrameOffset(), transformFromClauseItem(), transformGroupingFunc(), transformGroupingSet(), transformIndexConstraint(), transformIndirection(), transformInsertRow(), transformInsertStmt(), transformLockingClause(), transformMultiAssignRef(), transformOnConflictArbiter(), transformParamRef(), transformPartitionBound(), transformPartitionBoundValue(), 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().

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

◆ setup_parser_errposition_callback()

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

Definition at line 144 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(), LookupTypeNameExtended(), make_const(), make_oper_cache_key(), ParseFuncOrColumn(), parserOpenTable(), transformCreateStmt(), transformSetOperationTree(), transformTableLikeClause(), and typenameTypeMod().

146 {
147  /* Setup error traceback support for ereport() */
148  pcbstate->pstate = pstate;
149  pcbstate->location = location;
151  pcbstate->errcallback.arg = (void *) pcbstate;
153  error_context_stack = &pcbstate->errcallback;
154 }
ErrorContextCallback errcallback
Definition: parse_node.h:304
void(* callback)(void *arg)
Definition: elog.h:229
struct ErrorContextCallback * previous
Definition: elog.h:228
ErrorContextCallback * error_context_stack
Definition: elog.c:92
ParseState * pstate
Definition: parse_node.h:302
static void pcb_error_callback(void *arg)
Definition: parse_node.c:174

◆ transformContainerSubscripts()

SubscriptingRef* transformContainerSubscripts ( ParseState pstate,
Node containerBase,
Oid  containerType,
Oid  elementType,
int32  containerTypMod,
List indirection,
Node assignFrom 
)

Definition at line 276 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, InvalidOid, A_Indices::is_slice, lappend(), lfirst, lfirst_node, A_Indices::lidx, makeConst(), makeNode, NIL, OidIsValid, ParseState::p_expr_kind, parser_errposition(), SubscriptingRef::refassgnexpr, SubscriptingRef::refcontainertype, SubscriptingRef::refelemtype, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::reftypmod, SubscriptingRef::refupperindexpr, transformContainerType(), transformExpr(), and A_Indices::uidx.

Referenced by transformAssignmentSubscripts(), and transformIndirection().

283 {
284  bool isSlice = false;
285  List *upperIndexpr = NIL;
286  List *lowerIndexpr = NIL;
287  ListCell *idx;
288  SubscriptingRef *sbsref;
289 
290  /*
291  * Caller may or may not have bothered to determine elementType. Note
292  * that if the caller did do so, containerType/containerTypMod must be as
293  * modified by transformContainerType, ie, smash domain to base type.
294  */
295  if (!OidIsValid(elementType))
296  elementType = transformContainerType(&containerType, &containerTypMod);
297 
298  /*
299  * A list containing only simple subscripts refers to a single container
300  * element. If any of the items are slice specifiers (lower:upper), then
301  * the subscript expression means a container slice operation. In this
302  * case, we convert any non-slice items to slices by treating the single
303  * subscript as the upper bound and supplying an assumed lower bound of 1.
304  * We have to prescan the list to see if there are any slice items.
305  */
306  foreach(idx, indirection)
307  {
308  A_Indices *ai = (A_Indices *) lfirst(idx);
309 
310  if (ai->is_slice)
311  {
312  isSlice = true;
313  break;
314  }
315  }
316 
317  /*
318  * Transform the subscript expressions.
319  */
320  foreach(idx, indirection)
321  {
322  A_Indices *ai = lfirst_node(A_Indices, idx);
323  Node *subexpr;
324 
325  if (isSlice)
326  {
327  if (ai->lidx)
328  {
329  subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind);
330  /* If it's not int4 already, try to coerce */
331  subexpr = coerce_to_target_type(pstate,
332  subexpr, exprType(subexpr),
333  INT4OID, -1,
336  -1);
337  if (subexpr == NULL)
338  ereport(ERROR,
339  (errcode(ERRCODE_DATATYPE_MISMATCH),
340  errmsg("array subscript must have type integer"),
341  parser_errposition(pstate, exprLocation(ai->lidx))));
342  }
343  else if (!ai->is_slice)
344  {
345  /* Make a constant 1 */
346  subexpr = (Node *) makeConst(INT4OID,
347  -1,
348  InvalidOid,
349  sizeof(int32),
350  Int32GetDatum(1),
351  false,
352  true); /* pass by value */
353  }
354  else
355  {
356  /* Slice with omitted lower bound, put NULL into the list */
357  subexpr = NULL;
358  }
359  lowerIndexpr = lappend(lowerIndexpr, subexpr);
360  }
361  else
362  Assert(ai->lidx == NULL && !ai->is_slice);
363 
364  if (ai->uidx)
365  {
366  subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind);
367  /* If it's not int4 already, try to coerce */
368  subexpr = coerce_to_target_type(pstate,
369  subexpr, exprType(subexpr),
370  INT4OID, -1,
373  -1);
374  if (subexpr == NULL)
375  ereport(ERROR,
376  (errcode(ERRCODE_DATATYPE_MISMATCH),
377  errmsg("array subscript must have type integer"),
378  parser_errposition(pstate, exprLocation(ai->uidx))));
379  }
380  else
381  {
382  /* Slice with omitted upper bound, put NULL into the list */
383  Assert(isSlice && ai->is_slice);
384  subexpr = NULL;
385  }
386  upperIndexpr = lappend(upperIndexpr, subexpr);
387  }
388 
389  /*
390  * If doing an array store, coerce the source value to the right type.
391  * (This should agree with the coercion done by transformAssignedExpr.)
392  */
393  if (assignFrom != NULL)
394  {
395  Oid typesource = exprType(assignFrom);
396  Oid typeneeded = isSlice ? containerType : elementType;
397  Node *newFrom;
398 
399  newFrom = coerce_to_target_type(pstate,
400  assignFrom, typesource,
401  typeneeded, containerTypMod,
404  -1);
405  if (newFrom == NULL)
406  ereport(ERROR,
407  (errcode(ERRCODE_DATATYPE_MISMATCH),
408  errmsg("array assignment requires type %s"
409  " but expression is of type %s",
410  format_type_be(typeneeded),
411  format_type_be(typesource)),
412  errhint("You will need to rewrite or cast the expression."),
413  parser_errposition(pstate, exprLocation(assignFrom))));
414  assignFrom = newFrom;
415  }
416 
417  /*
418  * Ready to build the SubscriptingRef node.
419  */
421  if (assignFrom != NULL)
422  sbsref->refassgnexpr = (Expr *) assignFrom;
423 
424  sbsref->refcontainertype = containerType;
425  sbsref->refelemtype = elementType;
426  sbsref->reftypmod = containerTypMod;
427  /* refcollid will be set by parse_collate.c */
428  sbsref->refupperindexpr = upperIndexpr;
429  sbsref->reflowerindexpr = lowerIndexpr;
430  sbsref->refexpr = (Expr *) containerBase;
431  sbsref->refassgnexpr = (Expr *) assignFrom;
432 
433  return sbsref;
434 }
#define NIL
Definition: pg_list.h:65
int errhint(const char *fmt,...)
Definition: elog.c:1071
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1191
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:145
Definition: nodes.h:529
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
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:299
List * refupperindexpr
Definition: primnodes.h:422
#define OidIsValid(objectId)
Definition: c.h:651
signed int int32
Definition: c.h:362
bool is_slice
Definition: parsenodes.h:383
#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
#define lfirst_node(type, lc)
Definition: pg_list.h:193
List * lappend(List *list, void *datum)
Definition: list.c:321
ParseExprKind p_expr_kind
Definition: parse_node.h:194
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define makeNode(_type_)
Definition: nodes.h:577
#define Assert(condition)
Definition: c.h:745
#define lfirst(lc)
Definition: pg_list.h:190
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:110
Node * lidx
Definition: parsenodes.h:384
Expr * refassgnexpr
Definition: primnodes.h:430
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:824
List * reflowerindexpr
Definition: primnodes.h:424
Node * uidx
Definition: parsenodes.h:385
Oid refcontainertype
Definition: primnodes.h:418
Expr * refexpr
Definition: primnodes.h:427
Definition: pg_list.h:50
Oid transformContainerType(Oid *containerType, int32 *containerTypmod)
Definition: parse_node.c:195

◆ transformContainerType()

Oid transformContainerType ( Oid containerType,
int32 containerTypmod 
)

Definition at line 195 of file parse_node.c.

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

Referenced by transformAssignmentSubscripts(), and transformContainerSubscripts().

196 {
197  Oid origContainerType = *containerType;
198  Oid elementType;
199  HeapTuple type_tuple_container;
200  Form_pg_type type_struct_container;
201 
202  /*
203  * If the input is a domain, smash to base type, and extract the actual
204  * typmod to be applied to the base type. Subscripting a domain is an
205  * operation that necessarily works on the base container type, not the
206  * domain itself. (Note that we provide no method whereby the creator of a
207  * domain over a container type could hide its ability to be subscripted.)
208  */
209  *containerType = getBaseTypeAndTypmod(*containerType, containerTypmod);
210 
211  /*
212  * Here is an array specific code. We treat int2vector and oidvector as
213  * though they were domains over int2[] and oid[]. This is needed because
214  * array slicing could create an array that doesn't satisfy the
215  * dimensionality constraints of the xxxvector type; so we want the result
216  * of a slice operation to be considered to be of the more general type.
217  */
218  if (*containerType == INT2VECTOROID)
219  *containerType = INT2ARRAYOID;
220  else if (*containerType == OIDVECTOROID)
221  *containerType = OIDARRAYOID;
222 
223  /* Get the type tuple for the container */
224  type_tuple_container = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*containerType));
225  if (!HeapTupleIsValid(type_tuple_container))
226  elog(ERROR, "cache lookup failed for type %u", *containerType);
227  type_struct_container = (Form_pg_type) GETSTRUCT(type_tuple_container);
228 
229  /* needn't check typisdefined since this will fail anyway */
230 
231  elementType = type_struct_container->typelem;
232  if (elementType == InvalidOid)
233  ereport(ERROR,
234  (errcode(ERRCODE_DATATYPE_MISMATCH),
235  errmsg("cannot subscript type %s because it is not an array",
236  format_type_be(origContainerType))));
237 
238  ReleaseSysCache(type_tuple_container);
239 
240  return elementType;
241 }
Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod)
Definition: lsyscache.c:2426
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:255
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214