]> granicus.if.org Git - postgresql/blob - src/backend/parser/parse_node.c
Preliminary code review for domain CHECK constraints patch: add documentation,
[postgresql] / src / backend / parser / parse_node.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_node.c
4  *        various routines that make nodes for querytrees
5  *
6  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.76 2002/12/12 20:35:13 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "access/heapam.h"
18 #include "catalog/pg_operator.h"
19 #include "catalog/pg_type.h"
20 #include "nodes/makefuncs.h"
21 #include "parser/parsetree.h"
22 #include "parser/parse_coerce.h"
23 #include "parser/parse_expr.h"
24 #include "parser/parse_node.h"
25 #include "parser/parse_oper.h"
26 #include "parser/parse_relation.h"
27 #include "utils/builtins.h"
28 #include "utils/int8.h"
29 #include "utils/lsyscache.h"
30 #include "utils/syscache.h"
31 #include "utils/varbit.h"
32
33
34 /* make_parsestate()
35  * Allocate and initialize a new ParseState.
36  * The CALLER is responsible for freeing the ParseState* returned.
37  */
38 ParseState *
39 make_parsestate(ParseState *parentParseState)
40 {
41         ParseState *pstate;
42
43         pstate = palloc0(sizeof(ParseState));
44
45         pstate->parentParseState = parentParseState;
46         pstate->p_last_resno = 1;
47
48         return pstate;
49 }
50
51
52 /* make_operand()
53  * Ensure argument type match by forcing conversion of constants.
54  */
55 Node *
56 make_operand(Node *tree, Oid orig_typeId, Oid target_typeId)
57 {
58         Node       *result;
59
60         if (tree != NULL)
61         {
62                 /* must coerce? */
63                 if (target_typeId != orig_typeId)
64                         result = coerce_type(tree, orig_typeId, target_typeId,
65                                                                  COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
66                 else
67                         result = tree;
68         }
69         else
70         {
71                 /* otherwise, this is a NULL value */
72                 result = (Node *) makeNullConst(target_typeId);
73         }
74
75         return result;
76 }       /* make_operand() */
77
78
79 /* make_op()
80  * Operator construction.
81  *
82  * Transform operator expression ensuring type compatibility.
83  * This is where some type conversion happens.
84  */
85 Expr *
86 make_op(List *opname, Node *ltree, Node *rtree)
87 {
88         Oid                     ltypeId,
89                                 rtypeId;
90         Operator        tup;
91         Form_pg_operator opform;
92         Node       *left,
93                            *right;
94         OpExpr     *result;
95
96         ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
97         rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
98
99         /* right operator? */
100         if (rtree == NULL)
101         {
102                 tup = right_oper(opname, ltypeId, false);
103                 opform = (Form_pg_operator) GETSTRUCT(tup);
104                 left = make_operand(ltree, ltypeId, opform->oprleft);
105                 right = NULL;
106         }
107
108         /* left operator? */
109         else if (ltree == NULL)
110         {
111                 tup = left_oper(opname, rtypeId, false);
112                 opform = (Form_pg_operator) GETSTRUCT(tup);
113                 right = make_operand(rtree, rtypeId, opform->oprright);
114                 left = NULL;
115         }
116
117         /* otherwise, binary operator */
118         else
119         {
120                 tup = oper(opname, ltypeId, rtypeId, false);
121                 opform = (Form_pg_operator) GETSTRUCT(tup);
122                 left = make_operand(ltree, ltypeId, opform->oprleft);
123                 right = make_operand(rtree, rtypeId, opform->oprright);
124         }
125
126         result = makeNode(OpExpr);
127         result->opno = oprid(tup);
128         result->opfuncid = InvalidOid;
129         result->opresulttype = opform->oprresult;
130         result->opretset = get_func_retset(opform->oprcode);
131
132         if (!left)
133                 result->args = makeList1(right);
134         else if (!right)
135                 result->args = makeList1(left);
136         else
137                 result->args = makeList2(left, right);
138
139         ReleaseSysCache(tup);
140
141         return (Expr *) result;
142 }       /* make_op() */
143
144
145 /*
146  * make_var
147  *              Build a Var node for an attribute identified by RTE and attrno
148  */
149 Var *
150 make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
151 {
152         int                     vnum,
153                                 sublevels_up;
154         Oid                     vartypeid;
155         int32           type_mod;
156
157         vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
158         get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod);
159         return makeVar(vnum, attrno, vartypeid, type_mod, sublevels_up);
160 }
161
162 /*
163  * transformArraySubscripts()
164  *              Transform array subscripting.  This is used for both
165  *              array fetch and array assignment.
166  *
167  * In an array fetch, we are given a source array value and we produce an
168  * expression that represents the result of extracting a single array element
169  * or an array slice.
170  *
171  * In an array assignment, we are given a destination array value plus a
172  * source value that is to be assigned to a single element or a slice of
173  * that array.  We produce an expression that represents the new array value
174  * with the source data inserted into the right part of the array.
175  *
176  * pstate               Parse state
177  * arrayBase    Already-transformed expression for the array as a whole
178  *                              (may be NULL if we are handling an INSERT)
179  * arrayType    OID of array's datatype
180  * arrayTypMod  typmod to be applied to array elements
181  * indirection  Untransformed list of subscripts (must not be NIL)
182  * forceSlice   If true, treat subscript as array slice in all cases
183  * assignFrom   NULL for array fetch, else transformed expression for source.
184  */
185 ArrayRef *
186 transformArraySubscripts(ParseState *pstate,
187                                                  Node *arrayBase,
188                                                  Oid arrayType,
189                                                  int32 arrayTypMod,
190                                                  List *indirection,
191                                                  bool forceSlice,
192                                                  Node *assignFrom)
193 {
194         Oid                     elementType,
195                                 resultType;
196         HeapTuple       type_tuple_array,
197                                 type_tuple_element;
198         Form_pg_type type_struct_array,
199                                 type_struct_element;
200         bool            isSlice = forceSlice;
201         List       *upperIndexpr = NIL;
202         List       *lowerIndexpr = NIL;
203         List       *idx;
204         ArrayRef   *aref;
205
206         /* Get the type tuple for the array */
207         type_tuple_array = SearchSysCache(TYPEOID,
208                                                                           ObjectIdGetDatum(arrayType),
209                                                                           0, 0, 0);
210         if (!HeapTupleIsValid(type_tuple_array))
211                 elog(ERROR, "transformArraySubscripts: Cache lookup failed for array type %u",
212                          arrayType);
213         type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
214
215         elementType = type_struct_array->typelem;
216         if (elementType == InvalidOid)
217                 elog(ERROR, "transformArraySubscripts: type %s is not an array",
218                          NameStr(type_struct_array->typname));
219
220         /* Get the type tuple for the array element type */
221         type_tuple_element = SearchSysCache(TYPEOID,
222                                                                                 ObjectIdGetDatum(elementType),
223                                                                                 0, 0, 0);
224         if (!HeapTupleIsValid(type_tuple_element))
225                 elog(ERROR, "transformArraySubscripts: Cache lookup failed for array element type %u",
226                          elementType);
227         type_struct_element = (Form_pg_type) GETSTRUCT(type_tuple_element);
228
229         /*
230          * A list containing only single subscripts refers to a single array
231          * element.  If any of the items are double subscripts (lower:upper),
232          * then the subscript expression means an array slice operation. In
233          * this case, we supply a default lower bound of 1 for any items that
234          * contain only a single subscript. The forceSlice parameter forces us
235          * to treat the operation as a slice, even if no lower bounds are
236          * mentioned.  Otherwise, we have to prescan the indirection list to
237          * see if there are any double subscripts.
238          */
239         if (!isSlice)
240         {
241                 foreach(idx, indirection)
242                 {
243                         A_Indices  *ai = (A_Indices *) lfirst(idx);
244
245                         if (ai->lidx != NULL)
246                         {
247                                 isSlice = true;
248                                 break;
249                         }
250                 }
251         }
252
253         /*
254          * The type represented by the subscript expression is the element
255          * type if we are fetching a single element, but it is the same as the
256          * array type if we are fetching a slice or storing.
257          */
258         if (isSlice || assignFrom != NULL)
259                 resultType = arrayType;
260         else
261                 resultType = elementType;
262
263         /*
264          * Transform the subscript expressions.
265          */
266         foreach(idx, indirection)
267         {
268                 A_Indices  *ai = (A_Indices *) lfirst(idx);
269                 Node       *subexpr;
270
271                 if (isSlice)
272                 {
273                         if (ai->lidx)
274                         {
275                                 subexpr = transformExpr(pstate, ai->lidx);
276                                 /* If it's not int4 already, try to coerce */
277                                 subexpr = coerce_to_target_type(subexpr, exprType(subexpr),
278                                                                                                 INT4OID, -1,
279                                                                                                 COERCION_ASSIGNMENT,
280                                                                                                 COERCE_IMPLICIT_CAST);
281                                 if (subexpr == NULL)
282                                         elog(ERROR, "array index expressions must be integers");
283                         }
284                         else
285                         {
286                                 /* Make a constant 1 */
287                                 subexpr = (Node *) makeConst(INT4OID,
288                                                                                          sizeof(int32),
289                                                                                          Int32GetDatum(1),
290                                                                                          false,
291                                                                                          true);         /* pass by value */
292                         }
293                         lowerIndexpr = lappend(lowerIndexpr, subexpr);
294                 }
295                 subexpr = transformExpr(pstate, ai->uidx);
296                 /* If it's not int4 already, try to coerce */
297                 subexpr = coerce_to_target_type(subexpr, exprType(subexpr),
298                                                                                 INT4OID, -1,
299                                                                                 COERCION_ASSIGNMENT,
300                                                                                 COERCE_IMPLICIT_CAST);
301                 if (subexpr == NULL)
302                         elog(ERROR, "array index expressions must be integers");
303                 upperIndexpr = lappend(upperIndexpr, subexpr);
304         }
305
306         /*
307          * If doing an array store, coerce the source value to the right type.
308          */
309         if (assignFrom != NULL)
310         {
311                 Oid                     typesource = exprType(assignFrom);
312                 Oid                     typeneeded = isSlice ? arrayType : elementType;
313
314                 if (typesource != InvalidOid)
315                 {
316                         assignFrom = coerce_to_target_type(assignFrom, typesource,
317                                                                                            typeneeded, arrayTypMod,
318                                                                                            COERCION_ASSIGNMENT,
319                                                                                            COERCE_IMPLICIT_CAST);
320                         if (assignFrom == NULL)
321                                 elog(ERROR, "Array assignment requires type %s"
322                                          " but expression is of type %s"
323                                          "\n\tYou will need to rewrite or cast the expression",
324                                          format_type_be(typeneeded),
325                                          format_type_be(typesource));
326                 }
327         }
328
329         /*
330          * Ready to build the ArrayRef node.
331          */
332         aref = makeNode(ArrayRef);
333         aref->refrestype = resultType;          /* XXX should save element type
334                                                                                  * OID too */
335         aref->refattrlength = type_struct_array->typlen;
336         aref->refelemlength = type_struct_element->typlen;
337         aref->refelembyval = type_struct_element->typbyval;
338         aref->refelemalign = type_struct_element->typalign;
339         aref->refupperindexpr = upperIndexpr;
340         aref->reflowerindexpr = lowerIndexpr;
341         aref->refexpr = (Expr *) arrayBase;
342         aref->refassgnexpr = (Expr *) assignFrom;
343
344         ReleaseSysCache(type_tuple_array);
345         ReleaseSysCache(type_tuple_element);
346
347         return aref;
348 }
349
350 /*
351  * make_const
352  *
353  *      Convert a Value node (as returned by the grammar) to a Const node
354  *      of the "natural" type for the constant.  Note that this routine is
355  *      only used when there is no explicit cast for the constant, so we
356  *      have to guess what type is wanted.
357  *
358  *      For string literals we produce a constant of type UNKNOWN ---- whose
359  *      representation is the same as text, but it indicates to later type
360  *      resolution that we're not sure that it should be considered text.
361  *      Explicit "NULL" constants are also typed as UNKNOWN.
362  *
363  *      For integers and floats we produce int4, int8, or numeric depending
364  *      on the value of the number.  XXX This should include int2 as well,
365  *      but additional cleanup is needed before we can do that; else cases
366  *      like "WHERE int4var = 42" will fail to be indexable.
367  */
368 Const *
369 make_const(Value *value)
370 {
371         Datum           val;
372         int64           val64;
373         Oid                     typeid;
374         int                     typelen;
375         bool            typebyval;
376         Const      *con;
377
378         switch (nodeTag(value))
379         {
380                 case T_Integer:
381                         val = Int32GetDatum(intVal(value));
382
383                         typeid = INT4OID;
384                         typelen = sizeof(int32);
385                         typebyval = true;
386                         break;
387
388                 case T_Float:
389                         /* could be an oversize integer as well as a float ... */
390                         if (scanint8(strVal(value), true, &val64))
391                         {
392                                 val = Int64GetDatum(val64);
393
394                                 typeid = INT8OID;
395                                 typelen = sizeof(int64);
396                                 typebyval = false;              /* XXX might change someday */
397                         }
398                         else
399                         {
400                                 val = DirectFunctionCall3(numeric_in,
401                                                                                   CStringGetDatum(strVal(value)),
402                                                                                   ObjectIdGetDatum(InvalidOid),
403                                                                                   Int32GetDatum(-1));
404
405                                 typeid = NUMERICOID;
406                                 typelen = -1;   /* variable len */
407                                 typebyval = false;
408                         }
409                         break;
410
411                 case T_String:
412                         val = DirectFunctionCall1(unknownin,
413                                                                           CStringGetDatum(strVal(value)));
414
415                         typeid = UNKNOWNOID;    /* will be coerced later */
416                         typelen = -1;           /* variable len */
417                         typebyval = false;
418                         break;
419
420                 case T_BitString:
421                         val = DirectFunctionCall3(bit_in,
422                                                                           CStringGetDatum(strVal(value)),
423                                                                           ObjectIdGetDatum(InvalidOid),
424                                                                           Int32GetDatum(-1));
425                         typeid = BITOID;
426                         typelen = -1;
427                         typebyval = false;
428                         break;
429
430                 default:
431                         elog(WARNING, "make_const: unknown type %d", nodeTag(value));
432                         /* FALLTHROUGH */
433
434                 case T_Null:
435                         /* return a null const */
436                         con = makeConst(UNKNOWNOID,
437                                                         -1,
438                                                         (Datum) NULL,
439                                                         true,
440                                                         false);
441                         return con;
442         }
443
444         con = makeConst(typeid,
445                                         typelen,
446                                         val,
447                                         false,
448                                         typebyval);
449
450         return con;
451 }