1 /*-------------------------------------------------------------------------
4 * various routines that make nodes for querytrees
6 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.78 2003/04/29 22:13:10 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "catalog/pg_type.h"
18 #include "nodes/makefuncs.h"
19 #include "parser/parsetree.h"
20 #include "parser/parse_coerce.h"
21 #include "parser/parse_expr.h"
22 #include "parser/parse_node.h"
23 #include "parser/parse_relation.h"
24 #include "utils/builtins.h"
25 #include "utils/int8.h"
26 #include "utils/syscache.h"
27 #include "utils/varbit.h"
31 * Allocate and initialize a new ParseState.
32 * The CALLER is responsible for freeing the ParseState* returned.
35 make_parsestate(ParseState *parentParseState)
39 pstate = palloc0(sizeof(ParseState));
41 pstate->parentParseState = parentParseState;
43 /* Fill in fields that don't start at null/false/zero */
44 pstate->p_next_resno = 1;
47 pstate->p_variableparams = parentParseState->p_variableparams;
55 * Build a Var node for an attribute identified by RTE and attrno
58 make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
65 vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
66 get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod);
67 return makeVar(vnum, attrno, vartypeid, type_mod, sublevels_up);
71 * transformArraySubscripts()
72 * Transform array subscripting. This is used for both
73 * array fetch and array assignment.
75 * In an array fetch, we are given a source array value and we produce an
76 * expression that represents the result of extracting a single array element
79 * In an array assignment, we are given a destination array value plus a
80 * source value that is to be assigned to a single element or a slice of
81 * that array. We produce an expression that represents the new array value
82 * with the source data inserted into the right part of the array.
85 * arrayBase Already-transformed expression for the array as a whole
86 * (may be NULL if we are handling an INSERT)
87 * arrayType OID of array's datatype
88 * arrayTypMod typmod to be applied to array elements
89 * indirection Untransformed list of subscripts (must not be NIL)
90 * forceSlice If true, treat subscript as array slice in all cases
91 * assignFrom NULL for array fetch, else transformed expression for source.
94 transformArraySubscripts(ParseState *pstate,
104 HeapTuple type_tuple_array;
105 Form_pg_type type_struct_array;
106 bool isSlice = forceSlice;
107 List *upperIndexpr = NIL;
108 List *lowerIndexpr = NIL;
112 /* Get the type tuple for the array */
113 type_tuple_array = SearchSysCache(TYPEOID,
114 ObjectIdGetDatum(arrayType),
116 if (!HeapTupleIsValid(type_tuple_array))
117 elog(ERROR, "transformArraySubscripts: Cache lookup failed for array type %u",
119 type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
121 elementType = type_struct_array->typelem;
122 if (elementType == InvalidOid)
123 elog(ERROR, "transformArraySubscripts: type %s is not an array",
124 NameStr(type_struct_array->typname));
127 * A list containing only single subscripts refers to a single array
128 * element. If any of the items are double subscripts (lower:upper),
129 * then the subscript expression means an array slice operation. In
130 * this case, we supply a default lower bound of 1 for any items that
131 * contain only a single subscript. The forceSlice parameter forces us
132 * to treat the operation as a slice, even if no lower bounds are
133 * mentioned. Otherwise, we have to prescan the indirection list to
134 * see if there are any double subscripts.
138 foreach(idx, indirection)
140 A_Indices *ai = (A_Indices *) lfirst(idx);
142 if (ai->lidx != NULL)
151 * The type represented by the subscript expression is the element
152 * type if we are fetching a single element, but it is the same as the
153 * array type if we are fetching a slice or storing.
155 if (isSlice || assignFrom != NULL)
156 resultType = arrayType;
158 resultType = elementType;
161 * Transform the subscript expressions.
163 foreach(idx, indirection)
165 A_Indices *ai = (A_Indices *) lfirst(idx);
172 subexpr = transformExpr(pstate, ai->lidx);
173 /* If it's not int4 already, try to coerce */
174 subexpr = coerce_to_target_type(pstate,
175 subexpr, exprType(subexpr),
178 COERCE_IMPLICIT_CAST);
180 elog(ERROR, "array index expressions must be integers");
184 /* Make a constant 1 */
185 subexpr = (Node *) makeConst(INT4OID,
189 true); /* pass by value */
191 lowerIndexpr = lappend(lowerIndexpr, subexpr);
193 subexpr = transformExpr(pstate, ai->uidx);
194 /* If it's not int4 already, try to coerce */
195 subexpr = coerce_to_target_type(pstate,
196 subexpr, exprType(subexpr),
199 COERCE_IMPLICIT_CAST);
201 elog(ERROR, "array index expressions must be integers");
202 upperIndexpr = lappend(upperIndexpr, subexpr);
206 * If doing an array store, coerce the source value to the right type.
208 if (assignFrom != NULL)
210 Oid typesource = exprType(assignFrom);
211 Oid typeneeded = isSlice ? arrayType : elementType;
213 if (typesource != InvalidOid)
215 assignFrom = coerce_to_target_type(pstate,
216 assignFrom, typesource,
217 typeneeded, arrayTypMod,
219 COERCE_IMPLICIT_CAST);
220 if (assignFrom == NULL)
221 elog(ERROR, "Array assignment requires type %s"
222 " but expression is of type %s"
223 "\n\tYou will need to rewrite or cast the expression",
224 format_type_be(typeneeded),
225 format_type_be(typesource));
230 * Ready to build the ArrayRef node.
232 aref = makeNode(ArrayRef);
233 aref->refrestype = resultType;
234 aref->refarraytype = arrayType;
235 aref->refelemtype = elementType;
236 aref->refupperindexpr = upperIndexpr;
237 aref->reflowerindexpr = lowerIndexpr;
238 aref->refexpr = (Expr *) arrayBase;
239 aref->refassgnexpr = (Expr *) assignFrom;
241 ReleaseSysCache(type_tuple_array);
249 * Convert a Value node (as returned by the grammar) to a Const node
250 * of the "natural" type for the constant. Note that this routine is
251 * only used when there is no explicit cast for the constant, so we
252 * have to guess what type is wanted.
254 * For string literals we produce a constant of type UNKNOWN ---- whose
255 * representation is the same as text, but it indicates to later type
256 * resolution that we're not sure that it should be considered text.
257 * Explicit "NULL" constants are also typed as UNKNOWN.
259 * For integers and floats we produce int4, int8, or numeric depending
260 * on the value of the number. XXX This should include int2 as well,
261 * but additional cleanup is needed before we can do that; else cases
262 * like "WHERE int4var = 42" will fail to be indexable.
265 make_const(Value *value)
274 switch (nodeTag(value))
277 val = Int32GetDatum(intVal(value));
280 typelen = sizeof(int32);
285 /* could be an oversize integer as well as a float ... */
286 if (scanint8(strVal(value), true, &val64))
288 val = Int64GetDatum(val64);
291 typelen = sizeof(int64);
292 typebyval = false; /* XXX might change someday */
296 val = DirectFunctionCall3(numeric_in,
297 CStringGetDatum(strVal(value)),
298 ObjectIdGetDatum(InvalidOid),
302 typelen = -1; /* variable len */
308 val = DirectFunctionCall1(unknownin,
309 CStringGetDatum(strVal(value)));
311 typeid = UNKNOWNOID; /* will be coerced later */
312 typelen = -1; /* variable len */
317 val = DirectFunctionCall3(bit_in,
318 CStringGetDatum(strVal(value)),
319 ObjectIdGetDatum(InvalidOid),
327 elog(WARNING, "make_const: unknown type %d", nodeTag(value));
331 /* return a null const */
332 con = makeConst(UNKNOWNOID,
340 con = makeConst(typeid,