1 /*-------------------------------------------------------------------------
4 * take an "optimizable" stmt and make the query tree that
5 * the planner requires.
7 * Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.25 1997/11/24 05:08:27 momjian Exp $
13 *-------------------------------------------------------------------------
20 #include "access/heapam.h"
21 #include "access/tupmacs.h"
22 #include "utils/builtins.h"
23 #include "utils/elog.h"
24 #include "utils/palloc.h"
25 #include "utils/acl.h" /* for ACL_NO_PRIV_WARNING */
26 #include "utils/rel.h" /* Relation stuff */
28 #include "utils/syscache.h"
29 #include "catalog/pg_type.h"
30 #include "catalog/pg_operator.h"
31 #include "parser/catalog_utils.h"
32 #include "parser/parse_query.h"
33 #include "utils/lsyscache.h"
35 #include "nodes/pg_list.h"
36 #include "nodes/primnodes.h"
37 #include "nodes/parsenodes.h"
38 #include "nodes/makefuncs.h"
41 checkTargetTypes(ParseState *pstate, char *target_colname,
42 char *refname, char *colname);
47 /* given refname, return a pointer to the range table entry */
49 refnameRangeTableEntry(List *rtable, char *refname)
55 RangeTblEntry *rte = lfirst(temp);
57 if (!strcmp(rte->refname, refname))
63 /* given refname, return id of variable; position starts with 1 */
65 refnameRangeTablePosn(List *rtable, char *refname)
73 RangeTblEntry *rte = lfirst(temp);
75 if (!strcmp(rte->refname, refname))
83 * returns range entry if found, else NULL
86 colnameRangeTableEntry(ParseState *pstate, char *colname)
90 RangeTblEntry *rte_result;
92 if (pstate->p_is_rule)
93 rtable = lnext(lnext(pstate->p_rtable));
95 rtable = pstate->p_rtable;
100 RangeTblEntry *rte = lfirst(et);
102 /* only entries on outer(non-function?) scope */
103 if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
106 if (get_attnum(rte->relid, colname) != InvalidAttrNumber)
108 if (rte_result != NULL)
110 if (!pstate->p_is_insert ||
111 rte != pstate->p_target_rangetblentry)
112 elog(WARN, "Column %s is ambiguous", colname);
122 * put new entry in pstate p_rtable structure, or return pointer
126 addRangeTableEntry(ParseState *pstate,
133 RangeTblEntry *rte = makeNode(RangeTblEntry);
135 if (pstate != NULL &&
136 refnameRangeTableEntry(pstate->p_rtable, refname) != NULL)
137 elog(WARN, "Table name %s specified more than once", refname);
139 rte->relname = pstrdup(relname);
140 rte->refname = pstrdup(refname);
142 relation = heap_openr(relname);
143 if (relation == NULL)
146 relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
150 * Flags - zero or more from inheritance,union,version or
151 * recursive (transitive closure) [we don't support them all -- ay
157 rte->relid = RelationGetRelationId(relation);
159 rte->inFromCl = inFromCl;
162 * close the relation we're done with it for now.
165 pstate->p_rtable = lappend(pstate->p_rtable, rte);
167 heap_close(relation);
174 * makes a list of attributes
175 * assumes reldesc caching works
178 expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
190 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
192 rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE);
194 rdesc = heap_open(rte->relid);
198 elog(WARN, "Unable to expand all -- heap_open failed on %s",
202 maxattrs = RelationGetNumberOfAttributes(rdesc);
204 for (varattno = 0; varattno <= maxattrs - 1; varattno++)
207 char *resname = NULL;
208 TargetEntry *te = makeNode(TargetEntry);
210 attrname = pstrdup((rdesc->rd_att->attrs[varattno]->attname).data);
211 varnode = (Var *) make_var(pstate, refname, attrname, &type_id);
212 type_len = (int) tlen(get_id_type(type_id));
214 handleTargetColname(pstate, &resname, refname, attrname);
219 * Even if the elements making up a set are complex, the set
223 te->resdom = makeResdom((AttrNumber) (*this_resno)++,
230 te->expr = (Node *) varnode;
232 te_head = te_tail = lcons(te, NIL);
234 te_tail = lappend(te_tail, te);
242 disallow_setop(char *op, Type optype, Node *operand)
247 if (nodeTag(operand) == T_Iter)
249 elog(NOTICE, "An operand to the '%s' operator returns a set of %s,",
251 elog(WARN, "but '%s' takes single values, not sets.",
257 make_operand(char *opname,
270 true_type = get_id_type(true_typeId);
271 disallow_setop(opname, true_type, result);
272 if (true_typeId != orig_typeId)
274 Const *con = (Const *) result;
276 Assert(nodeTag(result) == T_Const);
277 val = (Datum) textout((struct varlena *)
279 infunc = typeid_get_retinfunc(true_typeId);
280 con = makeNode(Const);
281 con->consttype = true_typeId;
282 con->constlen = tlen(true_type);
283 con->constvalue = (Datum) fmgr(infunc,
285 get_typelem(true_typeId),
286 -1 /* for varchar() type */ );
287 con->constisnull = false;
288 con->constbyval = true;
289 con->constisset = false;
290 result = (Node *) con;
295 Const *con = makeNode(Const);
297 con->consttype = true_typeId;
299 con->constvalue = (Datum) (struct varlena *) NULL;
300 con->constisnull = true;
301 con->constbyval = true;
302 con->constisset = false;
303 result = (Node *) con;
311 make_op(char *opname, Node *ltree, Node *rtree)
316 OperatorTupleForm opform;
326 ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
327 temp = right_oper(opname, ltypeId);
328 opform = (OperatorTupleForm) GETSTRUCT(temp);
329 left = make_operand(opname, ltree, ltypeId, opform->oprleft);
333 else if (ltree == NULL)
337 rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
338 temp = left_oper(opname, rtypeId);
339 opform = (OperatorTupleForm) GETSTRUCT(temp);
340 right = make_operand(opname, rtree, rtypeId, opform->oprright);
351 #define CONVERTABLE_TYPE(t) ( (t) == INT2OID || \
354 (t) == FLOAT4OID || \
355 (t) == FLOAT8OID || \
358 /* binary operator */
359 ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
360 rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
363 * convert constant when using a const of a numeric type and a
364 * non-const of another numeric type
366 if (CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) != T_Const &&
367 CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) == T_Const &&
368 !((Const *) rtree)->constiscast)
370 outfunc = typeid_get_retoutfunc(rtypeId);
371 infunc = typeid_get_retinfunc(ltypeId);
372 outstr = (char *) fmgr(outfunc, ((Const *) rtree)->constvalue);
373 ((Const *) rtree)->constvalue = (Datum) fmgr(infunc, outstr);
375 ((Const *) rtree)->consttype = rtypeId = ltypeId;
376 newtype = get_id_type(rtypeId);
377 ((Const *) rtree)->constlen = tlen(newtype);
378 ((Const *) rtree)->constbyval = tbyval(newtype);
381 if (CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) != T_Const &&
382 CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) == T_Const &&
383 !((Const *) ltree)->constiscast)
385 outfunc = typeid_get_retoutfunc(ltypeId);
386 infunc = typeid_get_retinfunc(rtypeId);
387 outstr = (char *) fmgr(outfunc, ((Const *) ltree)->constvalue);
388 ((Const *) ltree)->constvalue = (Datum) fmgr(infunc, outstr);
390 ((Const *) ltree)->consttype = ltypeId = rtypeId;
391 newtype = get_id_type(ltypeId);
392 ((Const *) ltree)->constlen = tlen(newtype);
393 ((Const *) ltree)->constbyval = tbyval(newtype);
396 temp = oper(opname, ltypeId, rtypeId, false);
397 opform = (OperatorTupleForm) GETSTRUCT(temp);
398 left = make_operand(opname, ltree, ltypeId, opform->oprleft);
399 right = make_operand(opname, rtree, rtypeId, opform->oprright);
402 newop = makeOper(oprid(temp), /* opno */
403 InvalidOid,/* opid */
404 opform->oprresult, /* operator result type */
408 result = makeNode(Expr);
409 result->typeOid = opform->oprresult;
410 result->opType = OP_EXPR;
411 result->oper = (Node *) newop;
415 result->args = lcons(right, NIL);
419 result->args = lcons(left, NIL);
423 result->args = lcons(left, lcons(right, NIL));
430 find_atttype(Oid relid, char *attrname)
436 rd = heap_open(relid);
437 if (!RelationIsValid(rd))
439 rd = heap_openr(tname(get_id_type(relid)));
440 if (!RelationIsValid(rd))
441 elog(WARN, "cannot compute type of att %s for relid %d",
445 attid = nf_varattno(rd, attrname);
447 if (attid == InvalidAttrNumber)
448 elog(WARN, "Invalid attribute %s\n", attrname);
450 vartype = att_typeid(rd, attid);
453 * close relation we're done with it now
462 make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id)
471 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
473 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE);
475 vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
477 rd = heap_open(rte->relid);
479 attid = nf_varattno(rd, attrname);
480 if (attid == InvalidAttrNumber)
481 elog(WARN, "Invalid attribute %s\n", attrname);
482 vartypeid = att_typeid(rd, attid);
484 varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
488 *type_id = vartypeid;
493 * make_array_ref() -- Make an array reference node.
495 * Array references can hang off of arbitrary nested dot (or
496 * function invocation) expressions. This routine takes a
497 * tree generated by ParseFunc() and an array index and
498 * generates a new array reference tree. We do some simple
499 * typechecking to be sure the dereference is valid in the
500 * type system, but we don't do any bounds checking here.
502 * indirection is a list of A_Indices
505 make_array_ref(Node *expr,
509 HeapTuple type_tuple;
510 TypeTupleForm type_struct_array,
514 List *upperIndexpr = NIL;
515 List *lowerIndexpr = NIL;
517 typearray = exprType(expr);
519 type_tuple = SearchSysCacheTuple(TYPOID,
520 ObjectIdGetDatum(typearray),
523 if (!HeapTupleIsValid(type_tuple))
524 elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
527 /* get the array type struct from the type tuple */
528 type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
530 if (type_struct_array->typelem == InvalidOid)
532 elog(WARN, "make_array_ref: type %s is not an array",
533 (Name) &(type_struct_array->typname.data[0]));
536 /* get the type tuple for the element type */
537 type_tuple = SearchSysCacheTuple(TYPOID,
538 ObjectIdGetDatum(type_struct_array->typelem),
540 if (!HeapTupleIsValid(type_tuple))
541 elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
544 type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
546 while (indirection != NIL)
548 A_Indices *ind = lfirst(indirection);
554 * XXX assumes all lower indices non null in this case
556 lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
558 upperIndexpr = lappend(upperIndexpr, ind->uidx);
559 indirection = lnext(indirection);
561 aref = makeNode(ArrayRef);
562 aref->refattrlength = type_struct_array->typlen;
563 aref->refelemlength = type_struct_element->typlen;
564 aref->refelemtype = type_struct_array->typelem;
565 aref->refelembyval = type_struct_element->typbyval;
566 aref->refupperindexpr = upperIndexpr;
567 aref->reflowerindexpr = lowerIndexpr;
568 aref->refexpr = expr;
569 aref->refassgnexpr = NULL;
571 if (lowerIndexpr == NIL) /* accessing a single array element */
572 reftype = aref->refelemtype;
574 /* request to clip a part of the array, the result is another array */
578 * we change it to reflect the true type; since the original
579 * refelemtype doesn't seem to get used anywhere. - ay 10/94
581 aref->refelemtype = reftype;
587 make_array_set(Expr *target_expr,
593 HeapTuple type_tuple;
594 TypeTupleForm type_struct_array;
595 TypeTupleForm type_struct_element;
599 typearray = exprType((Node *) target_expr);
601 type_tuple = SearchSysCacheTuple(TYPOID,
602 ObjectIdGetDatum(typearray),
605 if (!HeapTupleIsValid(type_tuple))
606 elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
609 /* get the array type struct from the type tuple */
610 type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
612 if (type_struct_array->typelem == InvalidOid)
614 elog(WARN, "make_array_ref: type %s is not an array",
615 (Name) &(type_struct_array->typname.data[0]));
617 /* get the type tuple for the element type */
618 type_tuple = SearchSysCacheTuple(TYPOID,
619 ObjectIdGetDatum(type_struct_array->typelem),
622 if (!HeapTupleIsValid(type_tuple))
623 elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
626 type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
628 aref = makeNode(ArrayRef);
629 aref->refattrlength = type_struct_array->typlen;
630 aref->refelemlength = type_struct_element->typlen;
631 aref->refelemtype = type_struct_array->typelem;
632 aref->refelembyval = type_struct_element->typbyval;
633 aref->refupperindexpr = upperIndexpr;
634 aref->reflowerindexpr = lowerIndexpr;
635 aref->refexpr = (Node *) target_expr;
636 aref->refassgnexpr = (Node *) expr;
638 if (lowerIndexpr == NIL) /* accessing a single array element */
639 reftype = aref->refelemtype;
641 /* request to set a part of the array, by another array */
644 aref->refelemtype = reftype;
653 * - takes a lispvalue, (as returned to the yacc routine by the lexer)
654 * extracts the type, and makes the appropriate type constant
655 * by invoking the (c-callable) lisp routine c-make-const
656 * via the lisp_call() mechanism
658 * eventually, produces a "const" lisp-struct as per nodedefs.cl
661 make_const(Value *value)
667 switch (nodeTag(value))
671 val = Int32GetDatum(intVal(value));
680 dummy = (float64) palloc(sizeof(float64data));
681 *dummy = floatVal(value);
683 val = Float64GetDatum(dummy);
688 tp = type("unknown"); /* unknown for now, will be type
690 val = PointerGetDatum(textin(strVal(value)));
696 if (nodeTag(value) != T_Null)
697 elog(NOTICE, "unknown type : %d\n", nodeTag(value));
700 con = makeConst(0, 0, (Datum) NULL, true, false, false, false);
705 con = makeConst(typeid(tp),
710 false, /* not a set */
719 * keep enough information around fill out the type of param nodes
720 * used in postquel functions
723 param_type_init(Oid *typev, int nargs)
725 pfunc_num_args = nargs;
726 param_type_info = typev;
732 if ((t > pfunc_num_args) || (t == 0))
734 return param_type_info[t - 1];
738 * handleTargetColname -
739 * use column names from insert
742 handleTargetColname(ParseState *pstate, char **resname,
743 char *refname, char *colname)
745 if (pstate->p_is_insert)
747 if (pstate->p_insert_columns != NIL)
749 Ident *id = lfirst(pstate->p_insert_columns);
752 pstate->p_insert_columns = lnext(pstate->p_insert_columns);
755 elog(WARN, "insert: more expressions than target columns");
757 if (pstate->p_is_insert || pstate->p_is_update)
758 checkTargetTypes(pstate, *resname, refname, colname);
763 * checks value and target column types
766 checkTargetTypes(ParseState *pstate, char *target_colname,
767 char *refname, char *colname)
776 if (target_colname == NULL || colname == NULL)
780 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
783 rte = colnameRangeTableEntry(pstate, colname);
784 if (rte == (RangeTblEntry *) NULL)
785 elog(WARN, "attribute %s not found", colname);
786 refname = rte->refname;
790 if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry)
791 elog(WARN, "%s not available in this context", colname);
793 rd = heap_open(rte->relid);
795 resdomno_id = varattno(rd, colname);
796 attrtype_id = att_typeid(rd, resdomno_id);
798 resdomno_target = varattno(pstate->p_target_relation, target_colname);
799 attrtype_target = att_typeid(pstate->p_target_relation, resdomno_target);
801 if (attrtype_id != attrtype_target)
802 elog(WARN, "Type of %s does not match target column %s",
803 colname, target_colname);
805 if ((attrtype_id == BPCHAROID || attrtype_id == VARCHAROID) &&
806 rd->rd_att->attrs[resdomno_id - 1]->attlen !=
807 pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->attlen)
808 elog(WARN, "Length of %s does not match length of target column %s",
809 colname, target_colname);