TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * parse_node.c
4 : * various routines that make nodes for querytrees
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/parser/parse_node.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "access/htup_details.h"
18 : #include "access/table.h"
19 : #include "catalog/pg_type.h"
20 : #include "mb/pg_wchar.h"
21 : #include "nodes/makefuncs.h"
22 : #include "nodes/miscnodes.h"
23 : #include "nodes/nodeFuncs.h"
24 : #include "nodes/subscripting.h"
25 : #include "parser/parse_coerce.h"
26 : #include "parser/parse_expr.h"
27 : #include "parser/parse_relation.h"
28 : #include "parser/parsetree.h"
29 : #include "utils/builtins.h"
30 : #include "utils/lsyscache.h"
31 : #include "utils/syscache.h"
32 : #include "utils/varbit.h"
33 :
34 : static void pcb_error_callback(void *arg);
35 :
36 :
37 : /*
38 : * make_parsestate
39 : * Allocate and initialize a new ParseState.
40 : *
41 : * Caller should eventually release the ParseState via free_parsestate().
42 : */
43 : ParseState *
44 GIC 1144016 : make_parsestate(ParseState *parentParseState)
45 ECB : {
46 : ParseState *pstate;
47 :
48 GIC 1144016 : pstate = palloc0(sizeof(ParseState));
49 ECB :
50 GIC 1144016 : pstate->parentParseState = parentParseState;
51 ECB :
52 : /* Fill in fields that don't start at null/false/zero */
53 GIC 1144016 : pstate->p_next_resno = 1;
54 CBC 1144016 : pstate->p_resolve_unknowns = true;
55 ECB :
56 GIC 1144016 : if (parentParseState)
57 ECB : {
58 GIC 77714 : pstate->p_sourcetext = parentParseState->p_sourcetext;
59 ECB : /* all hooks are copied from parent */
60 GIC 77714 : pstate->p_pre_columnref_hook = parentParseState->p_pre_columnref_hook;
61 CBC 77714 : pstate->p_post_columnref_hook = parentParseState->p_post_columnref_hook;
62 77714 : pstate->p_paramref_hook = parentParseState->p_paramref_hook;
63 77714 : pstate->p_coerce_param_hook = parentParseState->p_coerce_param_hook;
64 77714 : pstate->p_ref_hook_state = parentParseState->p_ref_hook_state;
65 ECB : /* query environment stays in context for the whole parse analysis */
66 GIC 77714 : pstate->p_queryEnv = parentParseState->p_queryEnv;
67 ECB : }
68 :
69 GIC 1144016 : return pstate;
70 ECB : }
71 :
72 : /*
73 : * free_parsestate
74 : * Release a ParseState and any subsidiary resources.
75 : */
76 : void
77 GIC 1063519 : free_parsestate(ParseState *pstate)
78 ECB : {
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 GIC 1063519 : if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber)
85 LBC 0 : ereport(ERROR,
86 EUB : (errcode(ERRCODE_TOO_MANY_COLUMNS),
87 : errmsg("target lists can have at most %d entries",
88 : MaxTupleAttributeNumber)));
89 :
90 GIC 1063519 : if (pstate->p_target_relation != NULL)
91 CBC 52204 : table_close(pstate->p_target_relation, NoLock);
92 ECB :
93 GIC 1063519 : pfree(pstate);
94 CBC 1063519 : }
95 ECB :
96 :
97 : /*
98 : * parser_errposition
99 : * Report a parse-analysis-time cursor position, if possible.
100 : *
101 : * This is expected to be used within an ereport() call. The return value
102 : * is a dummy (always 0, in fact).
103 : *
104 : * The locations stored in raw parsetrees are byte offsets into the source
105 : * string. We have to convert them to 1-based character indexes for reporting
106 : * to clients. (We do things this way to avoid unnecessary overhead in the
107 : * normal non-error case: computing character indexes would be much more
108 : * expensive than storing token offsets.)
109 : */
110 : int
111 GIC 4027 : parser_errposition(ParseState *pstate, int location)
112 ECB : {
113 : int pos;
114 :
115 : /* No-op if location was not provided */
116 GIC 4027 : if (location < 0)
117 CBC 39 : return 0;
118 ECB : /* Can't do anything if source text is not available */
119 GIC 3988 : if (pstate == NULL || pstate->p_sourcetext == NULL)
120 CBC 67 : return 0;
121 ECB : /* Convert offset to character number */
122 GIC 3921 : pos = pg_mbstrlen_with_len(pstate->p_sourcetext, location) + 1;
123 ECB : /* And pass it to the ereport mechanism */
124 GIC 3921 : return errposition(pos);
125 ECB : }
126 :
127 :
128 : /*
129 : * setup_parser_errposition_callback
130 : * Arrange for non-parser errors to report an error position
131 : *
132 : * Sometimes the parser calls functions that aren't part of the parser
133 : * subsystem and can't reasonably be passed a ParseState; yet we would
134 : * like any errors thrown in those functions to be tagged with a parse
135 : * error location. Use this function to set up an error context stack
136 : * entry that will accomplish that. Usage pattern:
137 : *
138 : * declare a local variable "ParseCallbackState pcbstate"
139 : * ...
140 : * setup_parser_errposition_callback(&pcbstate, pstate, location);
141 : * call function that might throw error;
142 : * cancel_parser_errposition_callback(&pcbstate);
143 : */
144 : void
145 GIC 1504124 : setup_parser_errposition_callback(ParseCallbackState *pcbstate,
146 ECB : ParseState *pstate, int location)
147 : {
148 : /* Setup error traceback support for ereport() */
149 GIC 1504124 : pcbstate->pstate = pstate;
150 CBC 1504124 : pcbstate->location = location;
151 1504124 : pcbstate->errcallback.callback = pcb_error_callback;
152 1504124 : pcbstate->errcallback.arg = (void *) pcbstate;
153 1504124 : pcbstate->errcallback.previous = error_context_stack;
154 1504124 : error_context_stack = &pcbstate->errcallback;
155 1504124 : }
156 ECB :
157 : /*
158 : * Cancel a previously-set-up errposition callback.
159 : */
160 : void
161 GIC 1501867 : cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
162 ECB : {
163 : /* Pop the error context stack */
164 GIC 1501867 : error_context_stack = pcbstate->errcallback.previous;
165 CBC 1501867 : }
166 ECB :
167 : /*
168 : * Error context callback for inserting parser error location.
169 : *
170 : * Note that this will be called for *any* error occurring while the
171 : * callback is installed. We avoid inserting an irrelevant error location
172 : * if the error is a query cancel --- are there any other important cases?
173 : */
174 : static void
175 GIC 2264 : pcb_error_callback(void *arg)
176 ECB : {
177 GIC 2264 : ParseCallbackState *pcbstate = (ParseCallbackState *) arg;
178 ECB :
179 GIC 2264 : if (geterrcode() != ERRCODE_QUERY_CANCELED)
180 CBC 2264 : (void) parser_errposition(pcbstate->pstate, pcbstate->location);
181 2264 : }
182 ECB :
183 :
184 : /*
185 : * transformContainerType()
186 : * Identify the actual container type for a subscripting operation.
187 : *
188 : * containerType/containerTypmod are modified if necessary to identify
189 : * the actual container type and typmod. This mainly involves smashing
190 : * any domain to its base type, but there are some special considerations.
191 : * Note that caller still needs to check if the result type is a container.
192 : */
193 : void
194 GIC 9320 : transformContainerType(Oid *containerType, int32 *containerTypmod)
195 ECB : {
196 : /*
197 : * If the input is a domain, smash to base type, and extract the actual
198 : * typmod to be applied to the base type. Subscripting a domain is an
199 : * operation that necessarily works on the base container type, not the
200 : * domain itself. (Note that we provide no method whereby the creator of a
201 : * domain over a container type could hide its ability to be subscripted.)
202 : */
203 GIC 9320 : *containerType = getBaseTypeAndTypmod(*containerType, containerTypmod);
204 ECB :
205 : /*
206 : * We treat int2vector and oidvector as though they were domains over
207 : * int2[] and oid[]. This is needed because array slicing could create an
208 : * array that doesn't satisfy the dimensionality constraints of the
209 : * xxxvector type; so we want the result of a slice operation to be
210 : * considered to be of the more general type.
211 : */
212 GIC 9320 : if (*containerType == INT2VECTOROID)
213 CBC 1391 : *containerType = INT2ARRAYOID;
214 7929 : else if (*containerType == OIDVECTOROID)
215 411 : *containerType = OIDARRAYOID;
216 9320 : }
217 ECB :
218 : /*
219 : * transformContainerSubscripts()
220 : * Transform container (array, etc) subscripting. This is used for both
221 : * container fetch and container assignment.
222 : *
223 : * In a container fetch, we are given a source container value and we produce
224 : * an expression that represents the result of extracting a single container
225 : * element or a container slice.
226 : *
227 : * Container assignments are treated basically the same as container fetches
228 : * here. The caller will modify the result node to insert the source value
229 : * that is to be assigned to the element or slice that a fetch would have
230 : * retrieved. The execution result will be a new container value with
231 : * the source value inserted into the right part of the container.
232 : *
233 : * For both cases, if the source is of a domain-over-container type, the
234 : * result is the same as if it had been of the container type; essentially,
235 : * we must fold a domain to its base type before applying subscripting.
236 : * (Note that int2vector and oidvector are treated as domains here.)
237 : *
238 : * pstate Parse state
239 : * containerBase Already-transformed expression for the container as a whole
240 : * containerType OID of container's datatype (should match type of
241 : * containerBase, or be the base type of containerBase's
242 : * domain type)
243 : * containerTypMod typmod for the container
244 : * indirection Untransformed list of subscripts (must not be NIL)
245 : * isAssignment True if this will become a container assignment.
246 : */
247 : SubscriptingRef *
248 GIC 9320 : transformContainerSubscripts(ParseState *pstate,
249 ECB : Node *containerBase,
250 : Oid containerType,
251 : int32 containerTypMod,
252 : List *indirection,
253 : bool isAssignment)
254 : {
255 : SubscriptingRef *sbsref;
256 : const SubscriptRoutines *sbsroutines;
257 : Oid elementType;
258 GIC 9320 : bool isSlice = false;
259 ECB : ListCell *idx;
260 :
261 : /*
262 : * Determine the actual container type, smashing any domain. In the
263 : * assignment case the caller already did this, since it also needs to
264 : * know the actual container type.
265 : */
266 GIC 9320 : if (!isAssignment)
267 CBC 8661 : transformContainerType(&containerType, &containerTypMod);
268 ECB :
269 : /*
270 : * Verify that the container type is subscriptable, and get its support
271 : * functions and typelem.
272 : */
273 GIC 9320 : sbsroutines = getSubscriptingRoutines(containerType, &elementType);
274 CBC 9320 : if (!sbsroutines)
275 5 : ereport(ERROR,
276 ECB : (errcode(ERRCODE_DATATYPE_MISMATCH),
277 : errmsg("cannot subscript type %s because it does not support subscripting",
278 : format_type_be(containerType)),
279 : parser_errposition(pstate, exprLocation(containerBase))));
280 :
281 : /*
282 : * Detect whether any of the indirection items are slice specifiers.
283 : *
284 : * A list containing only simple subscripts refers to a single container
285 : * element. If any of the items are slice specifiers (lower:upper), then
286 : * the subscript expression means a container slice operation.
287 : */
288 GIC 18648 : foreach(idx, indirection)
289 ECB : {
290 GIC 9554 : A_Indices *ai = lfirst_node(A_Indices, idx);
291 ECB :
292 GIC 9554 : if (ai->is_slice)
293 ECB : {
294 GIC 221 : isSlice = true;
295 CBC 221 : break;
296 ECB : }
297 : }
298 :
299 : /*
300 : * Ready to build the SubscriptingRef node.
301 : */
302 GIC 9315 : sbsref = makeNode(SubscriptingRef);
303 ECB :
304 GIC 9315 : sbsref->refcontainertype = containerType;
305 CBC 9315 : sbsref->refelemtype = elementType;
306 ECB : /* refrestype is to be set by container-specific logic */
307 GIC 9315 : sbsref->reftypmod = containerTypMod;
308 ECB : /* refcollid will be set by parse_collate.c */
309 : /* refupperindexpr, reflowerindexpr are to be set by container logic */
310 GIC 9315 : sbsref->refexpr = (Expr *) containerBase;
311 CBC 9315 : sbsref->refassgnexpr = NULL; /* caller will fill if it's an assignment */
312 ECB :
313 : /*
314 : * Call the container-type-specific logic to transform the subscripts and
315 : * determine the subscripting result type.
316 : */
317 GIC 9315 : sbsroutines->transform(sbsref, indirection, pstate,
318 ECB : isSlice, isAssignment);
319 :
320 : /*
321 : * Verify we got a valid type (this defends, for example, against someone
322 : * using array_subscript_handler as typsubscript without setting typelem).
323 : */
324 GIC 9292 : if (!OidIsValid(sbsref->refrestype))
325 LBC 0 : ereport(ERROR,
326 EUB : (errcode(ERRCODE_DATATYPE_MISMATCH),
327 : errmsg("cannot subscript type %s because it does not support subscripting",
328 : format_type_be(containerType))));
329 :
330 GIC 9292 : return sbsref;
331 ECB : }
332 :
333 : /*
334 : * make_const
335 : *
336 : * Convert an A_Const node (as returned by the grammar) to a Const node
337 : * of the "natural" type for the constant. Note that this routine is
338 : * only used when there is no explicit cast for the constant, so we
339 : * have to guess what type is wanted.
340 : *
341 : * For string literals we produce a constant of type UNKNOWN ---- whose
342 : * representation is the same as cstring, but it indicates to later type
343 : * resolution that we're not sure yet what type it should be considered.
344 : * Explicit "NULL" constants are also typed as UNKNOWN.
345 : *
346 : * For integers and floats we produce int4, int8, or numeric depending
347 : * on the value of the number. XXX We should produce int2 as well,
348 : * but additional cleanup is needed before we can do that; there are
349 : * too many examples that fail if we try.
350 : */
351 : Const *
352 GIC 878012 : make_const(ParseState *pstate, A_Const *aconst)
353 ECB : {
354 : Const *con;
355 : Datum val;
356 : Oid typeid;
357 : int typelen;
358 : bool typebyval;
359 : ParseCallbackState pcbstate;
360 :
361 GIC 878012 : if (aconst->isnull)
362 ECB : {
363 : /* return a null const */
364 GIC 111148 : con = makeConst(UNKNOWNOID,
365 ECB : -1,
366 : InvalidOid,
367 : -2,
368 : (Datum) 0,
369 : true,
370 : false);
371 GIC 111148 : con->location = aconst->location;
372 CBC 111148 : return con;
373 ECB : }
374 :
375 GIC 766864 : switch (nodeTag(&aconst->val))
376 ECB : {
377 GIC 243326 : case T_Integer:
378 CBC 243326 : val = Int32GetDatum(intVal(&aconst->val));
379 ECB :
380 GIC 243326 : typeid = INT4OID;
381 CBC 243326 : typelen = sizeof(int32);
382 243326 : typebyval = true;
383 243326 : break;
384 ECB :
385 GIC 5249 : case T_Float:
386 ECB : {
387 : /* could be an oversize integer as well as a float ... */
388 :
389 GNC 5249 : ErrorSaveContext escontext = {T_ErrorSaveContext};
390 : int64 val64;
391 :
392 5249 : val64 = pg_strtoint64_safe(aconst->val.fval.fval, (Node *) &escontext);
393 5249 : if (!escontext.error_occurred)
394 : {
395 : /*
396 : * It might actually fit in int32. Probably only INT_MIN
397 : * can occur, but we'll code the test generally just to be
398 : * sure.
399 : */
400 CBC 420 : int32 val32 = (int32) val64;
401 :
402 420 : if (val64 == (int64) val32)
403 : {
404 60 : val = Int32GetDatum(val32);
405 :
406 60 : typeid = INT4OID;
407 60 : typelen = sizeof(int32);
408 60 : typebyval = true;
409 : }
410 : else
411 : {
412 360 : val = Int64GetDatum(val64);
413 :
414 360 : typeid = INT8OID;
415 360 : typelen = sizeof(int64);
416 360 : typebyval = FLOAT8PASSBYVAL; /* int8 and float8 alike */
417 : }
418 : }
419 : else
420 : {
421 : /* arrange to report location if numeric_in() fails */
422 4829 : setup_parser_errposition_callback(&pcbstate, pstate, aconst->location);
423 4829 : val = DirectFunctionCall3(numeric_in,
424 : CStringGetDatum(aconst->val.fval.fval),
425 : ObjectIdGetDatum(InvalidOid),
426 : Int32GetDatum(-1));
427 4829 : cancel_parser_errposition_callback(&pcbstate);
428 :
429 4829 : typeid = NUMERICOID;
430 4829 : typelen = -1; /* variable len */
431 4829 : typebyval = false;
432 : }
433 5249 : break;
434 : }
435 :
436 29715 : case T_Boolean:
437 29715 : val = BoolGetDatum(boolVal(&aconst->val));
438 :
439 29715 : typeid = BOOLOID;
440 29715 : typelen = 1;
441 29715 : typebyval = true;
442 29715 : break;
443 :
444 486551 : case T_String:
445 :
446 : /*
447 : * We assume here that UNKNOWN's internal representation is the
448 : * same as CSTRING
449 : */
450 486551 : val = CStringGetDatum(strVal(&aconst->val));
451 :
452 486551 : typeid = UNKNOWNOID; /* will be coerced later */
453 486551 : typelen = -2; /* cstring-style varwidth type */
454 486551 : typebyval = false;
455 486551 : break;
456 :
457 2023 : case T_BitString:
458 : /* arrange to report location if bit_in() fails */
459 2023 : setup_parser_errposition_callback(&pcbstate, pstate, aconst->location);
460 2023 : val = DirectFunctionCall3(bit_in,
461 : CStringGetDatum(aconst->val.bsval.bsval),
462 : ObjectIdGetDatum(InvalidOid),
463 : Int32GetDatum(-1));
464 2023 : cancel_parser_errposition_callback(&pcbstate);
465 2023 : typeid = BITOID;
466 2023 : typelen = -1;
467 2023 : typebyval = false;
468 2023 : break;
469 :
470 UBC 0 : default:
471 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(&aconst->val));
472 : return NULL; /* keep compiler quiet */
473 : }
474 :
475 CBC 766864 : con = makeConst(typeid,
476 : -1, /* typmod -1 is OK for all cases */
477 : InvalidOid, /* all cases are uncollatable types */
478 : typelen,
479 : val,
480 : false,
481 : typebyval);
482 766864 : con->location = aconst->location;
483 :
484 766864 : return con;
485 : }
|