aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_query.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_query.c')
-rw-r--r--src/backend/parser/parse_query.c1340
1 files changed, 705 insertions, 635 deletions
diff --git a/src/backend/parser/parse_query.c b/src/backend/parser/parse_query.c
index b19b291769f..5d144660a48 100644
--- a/src/backend/parser/parse_query.c
+++ b/src/backend/parser/parse_query.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* parse_query.c--
- * take an "optimizable" stmt and make the query tree that
- * the planner requires.
+ * take an "optimizable" stmt and make the query tree that
+ * the planner requires.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.18 1997/08/22 00:02:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.19 1997/09/07 04:44:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,8 +23,8 @@
#include "utils/builtins.h"
#include "utils/elog.h"
#include "utils/palloc.h"
-#include "utils/acl.h" /* for ACL_NO_PRIV_WARNING */
-#include "utils/rel.h" /* Relation stuff */
+#include "utils/acl.h" /* for ACL_NO_PRIV_WARNING */
+#include "utils/rel.h" /* Relation stuff */
#include "utils/syscache.h"
#include "catalog/pg_type.h"
@@ -38,680 +38,744 @@
#include "nodes/parsenodes.h"
#include "nodes/makefuncs.h"
-static void checkTargetTypes(ParseState *pstate, char *target_colname,
- char *refname, char *colname);
+static void
+checkTargetTypes(ParseState * pstate, char *target_colname,
+ char *refname, char *colname);
-Oid *param_type_info;
-int pfunc_num_args;
+Oid *param_type_info;
+int pfunc_num_args;
/* given refname, return a pointer to the range table entry */
-RangeTblEntry *
-refnameRangeTableEntry(List *rtable, char *refname)
+RangeTblEntry *
+refnameRangeTableEntry(List * rtable, char *refname)
{
- List *temp;
-
- foreach(temp, rtable) {
- RangeTblEntry *rte = lfirst(temp);
-
- if (!strcmp(rte->refname, refname))
- return rte;
- }
- return NULL;
+ List *temp;
+
+ foreach(temp, rtable)
+ {
+ RangeTblEntry *rte = lfirst(temp);
+
+ if (!strcmp(rte->refname, refname))
+ return rte;
+ }
+ return NULL;
}
/* given refname, return id of variable; position starts with 1 */
int
-refnameRangeTablePosn(List *rtable, char *refname)
+refnameRangeTablePosn(List * rtable, char *refname)
{
- int index;
- List *temp;
-
- index = 1;
- foreach(temp, rtable) {
- RangeTblEntry *rte = lfirst(temp);
-
- if (!strcmp(rte->refname, refname))
- return index;
- index++;
- }
- return(0);
+ int index;
+ List *temp;
+
+ index = 1;
+ foreach(temp, rtable)
+ {
+ RangeTblEntry *rte = lfirst(temp);
+
+ if (!strcmp(rte->refname, refname))
+ return index;
+ index++;
+ }
+ return (0);
}
/*
* returns range entry if found, else NULL
*/
-RangeTblEntry *
-colnameRangeTableEntry(ParseState *pstate, char *colname)
+RangeTblEntry *
+colnameRangeTableEntry(ParseState * pstate, char *colname)
{
- List *et;
- List *rtable;
- RangeTblEntry *rte_result;
+ List *et;
+ List *rtable;
+ RangeTblEntry *rte_result;
- if (pstate->p_is_rule)
- rtable = lnext(lnext(pstate->p_rtable));
- else
- rtable = pstate->p_rtable;
+ if (pstate->p_is_rule)
+ rtable = lnext(lnext(pstate->p_rtable));
+ else
+ rtable = pstate->p_rtable;
- rte_result = NULL;
- foreach(et, rtable) {
- RangeTblEntry *rte = lfirst(et);
+ rte_result = NULL;
+ foreach(et, rtable)
+ {
+ RangeTblEntry *rte = lfirst(et);
/* only entries on outer(non-function?) scope */
- if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
- continue;
-
- if (get_attnum(rte->relid, colname) != InvalidAttrNumber) {
- if (rte_result != NULL) {
- if (!pstate->p_is_insert ||
- rte != pstate->p_target_rangetblentry)
- elog(WARN, "Column %s is ambiguous", colname);
- }
- else rte_result = rte;
+ if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
+ continue;
+
+ if (get_attnum(rte->relid, colname) != InvalidAttrNumber)
+ {
+ if (rte_result != NULL)
+ {
+ if (!pstate->p_is_insert ||
+ rte != pstate->p_target_rangetblentry)
+ elog(WARN, "Column %s is ambiguous", colname);
+ }
+ else
+ rte_result = rte;
+ }
}
- }
- return rte_result;
+ return rte_result;
}
/*
* put new entry in pstate p_rtable structure, or return pointer
* if pstate null
*/
-RangeTblEntry *
-addRangeTableEntry(ParseState *pstate,
- char *relname,
- char *refname,
- bool inh, bool inFromCl,
- TimeRange *timeRange)
+RangeTblEntry *
+addRangeTableEntry(ParseState * pstate,
+ char *relname,
+ char *refname,
+ bool inh, bool inFromCl,
+ TimeRange * timeRange)
{
- Relation relation;
- RangeTblEntry *rte = makeNode(RangeTblEntry);
-
- if (pstate != NULL &&
- refnameRangeTableEntry(pstate->p_rtable, refname) != NULL)
- elog(WARN,"Table name %s specified more than once",refname);
-
- rte->relname = pstrdup(relname);
- rte->refname = pstrdup(refname);
-
- relation = heap_openr(relname);
- if (relation == NULL) {
- elog(WARN,"%s: %s",
- relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
- }
-
- /*
- * Flags - zero or more from archive,inheritance,union,version
- * or recursive (transitive closure)
- * [we don't support them all -- ay 9/94 ]
- */
- rte->inh = inh;
-
- rte->timeRange = timeRange;
-
- /* RelOID */
- rte->relid = RelationGetRelationId(relation);
-
- rte->archive = false;
-
- rte->inFromCl = inFromCl;
-
- /*
- * close the relation we're done with it for now.
- */
- if (pstate != NULL)
- pstate->p_rtable = lappend(pstate->p_rtable, rte);
-
- heap_close(relation);
-
- return rte;
+ Relation relation;
+ RangeTblEntry *rte = makeNode(RangeTblEntry);
+
+ if (pstate != NULL &&
+ refnameRangeTableEntry(pstate->p_rtable, refname) != NULL)
+ elog(WARN, "Table name %s specified more than once", refname);
+
+ rte->relname = pstrdup(relname);
+ rte->refname = pstrdup(refname);
+
+ relation = heap_openr(relname);
+ if (relation == NULL)
+ {
+ elog(WARN, "%s: %s",
+ relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
+ }
+
+ /*
+ * Flags - zero or more from archive,inheritance,union,version or
+ * recursive (transitive closure) [we don't support them all -- ay
+ * 9/94 ]
+ */
+ rte->inh = inh;
+
+ rte->timeRange = timeRange;
+
+ /* RelOID */
+ rte->relid = RelationGetRelationId(relation);
+
+ rte->archive = false;
+
+ rte->inFromCl = inFromCl;
+
+ /*
+ * close the relation we're done with it for now.
+ */
+ if (pstate != NULL)
+ pstate->p_rtable = lappend(pstate->p_rtable, rte);
+
+ heap_close(relation);
+
+ return rte;
}
/*
* expandAll -
- * makes a list of attributes
- * assumes reldesc caching works
+ * makes a list of attributes
+ * assumes reldesc caching works
*/
-List *
-expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
+List *
+expandAll(ParseState * pstate, char *relname, char *refname, int *this_resno)
{
- Relation rdesc;
- List *te_tail = NIL, *te_head = NIL;
- Var *varnode;
- int varattno, maxattrs;
- Oid type_id;
- int type_len;
- RangeTblEntry *rte;
-
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- if (rte == NULL)
- rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE, NULL);
-
- rdesc = heap_open(rte->relid);
-
- if (rdesc == NULL ) {
- elog(WARN,"Unable to expand all -- heap_open failed on %s",
- rte->refname);
- return NIL;
- }
- maxattrs = RelationGetNumberOfAttributes(rdesc);
-
- for ( varattno = 0; varattno <= maxattrs-1 ; varattno++ ) {
- char *attrname;
- char *resname = NULL;
- TargetEntry *te = makeNode(TargetEntry);
-
- attrname = pstrdup ((rdesc->rd_att->attrs[varattno]->attname).data);
- varnode = (Var*)make_var(pstate, refname, attrname, &type_id);
- type_len = (int)tlen(get_id_type(type_id));
-
- handleTargetColname(pstate, &resname, refname, attrname);
- if (resname != NULL)
- attrname = resname;
-
- /* Even if the elements making up a set are complex, the
- * set itself is not. */
-
- te->resdom = makeResdom((AttrNumber) (*this_resno)++,
- type_id,
- (Size)type_len,
- attrname,
- (Index)0,
- (Oid)0,
- 0);
- te->expr = (Node *)varnode;
- if (te_head == NIL)
- te_head = te_tail = lcons(te, NIL);
- else te_tail = lappend(te_tail, te);
- }
-
- heap_close(rdesc);
- return(te_head);
+ Relation rdesc;
+ List *te_tail = NIL,
+ *te_head = NIL;
+ Var *varnode;
+ int varattno,
+ maxattrs;
+ Oid type_id;
+ int type_len;
+ RangeTblEntry *rte;
+
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ if (rte == NULL)
+ rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE, NULL);
+
+ rdesc = heap_open(rte->relid);
+
+ if (rdesc == NULL)
+ {
+ elog(WARN, "Unable to expand all -- heap_open failed on %s",
+ rte->refname);
+ return NIL;
+ }
+ maxattrs = RelationGetNumberOfAttributes(rdesc);
+
+ for (varattno = 0; varattno <= maxattrs - 1; varattno++)
+ {
+ char *attrname;
+ char *resname = NULL;
+ TargetEntry *te = makeNode(TargetEntry);
+
+ attrname = pstrdup((rdesc->rd_att->attrs[varattno]->attname).data);
+ varnode = (Var *) make_var(pstate, refname, attrname, &type_id);
+ type_len = (int) tlen(get_id_type(type_id));
+
+ handleTargetColname(pstate, &resname, refname, attrname);
+ if (resname != NULL)
+ attrname = resname;
+
+ /*
+ * Even if the elements making up a set are complex, the set
+ * itself is not.
+ */
+
+ te->resdom = makeResdom((AttrNumber) (*this_resno)++,
+ type_id,
+ (Size) type_len,
+ attrname,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ te->expr = (Node *) varnode;
+ if (te_head == NIL)
+ te_head = te_tail = lcons(te, NIL);
+ else
+ te_tail = lappend(te_tail, te);
+ }
+
+ heap_close(rdesc);
+ return (te_head);
}
TimeQual
makeTimeRange(char *datestring1,
- char *datestring2,
- int timecode) /* 0 = snapshot , 1 = timerange */
+ char *datestring2,
+ int timecode) /* 0 = snapshot , 1 = timerange */
{
- TimeQual qual = NULL;
- AbsoluteTime t1,t2;
-
- switch (timecode) {
- case 0:
- if (datestring1 == NULL) {
- elog(WARN, "MakeTimeRange: bad snapshot arg");
- }
- t1 = nabstimein(datestring1);
- if (!AbsoluteTimeIsValid(t1)) {
- elog(WARN, "bad snapshot time: \"%s\"",
- datestring1);
- }
- qual = TimeFormSnapshotTimeQual(t1);
- break;
- case 1:
- if (datestring1 == NULL) {
- t1 = NOSTART_ABSTIME;
- } else {
- t1 = nabstimein(datestring1);
- if (!AbsoluteTimeIsValid(t1)) {
- elog(WARN,
- "bad range start time: \"%s\"",
- datestring1);
- }
- }
- if (datestring2 == NULL) {
- t2 = NOEND_ABSTIME;
- } else {
- t2 = nabstimein(datestring2);
- if (!AbsoluteTimeIsValid(t2)) {
- elog(WARN,
- "bad range end time: \"%s\"",
- datestring2);
- }
+ TimeQual qual = NULL;
+ AbsoluteTime t1,
+ t2;
+
+ switch (timecode)
+ {
+ case 0:
+ if (datestring1 == NULL)
+ {
+ elog(WARN, "MakeTimeRange: bad snapshot arg");
+ }
+ t1 = nabstimein(datestring1);
+ if (!AbsoluteTimeIsValid(t1))
+ {
+ elog(WARN, "bad snapshot time: \"%s\"",
+ datestring1);
+ }
+ qual = TimeFormSnapshotTimeQual(t1);
+ break;
+ case 1:
+ if (datestring1 == NULL)
+ {
+ t1 = NOSTART_ABSTIME;
+ }
+ else
+ {
+ t1 = nabstimein(datestring1);
+ if (!AbsoluteTimeIsValid(t1))
+ {
+ elog(WARN,
+ "bad range start time: \"%s\"",
+ datestring1);
+ }
+ }
+ if (datestring2 == NULL)
+ {
+ t2 = NOEND_ABSTIME;
+ }
+ else
+ {
+ t2 = nabstimein(datestring2);
+ if (!AbsoluteTimeIsValid(t2))
+ {
+ elog(WARN,
+ "bad range end time: \"%s\"",
+ datestring2);
+ }
+ }
+ qual = TimeFormRangedTimeQual(t1, t2);
+ break;
+ default:
+ elog(WARN, "MakeTimeRange: internal parser error");
}
- qual = TimeFormRangedTimeQual(t1,t2);
- break;
- default:
- elog(WARN, "MakeTimeRange: internal parser error");
- }
- return qual;
+ return qual;
}
static void
-disallow_setop(char *op, Type optype, Node *operand)
+disallow_setop(char *op, Type optype, Node * operand)
{
- if (operand==NULL)
- return;
-
- if (nodeTag(operand) == T_Iter) {
- elog(NOTICE, "An operand to the '%s' operator returns a set of %s,",
- op, tname(optype));
- elog(WARN, "but '%s' takes single values, not sets.",
- op);
- }
+ if (operand == NULL)
+ return;
+
+ if (nodeTag(operand) == T_Iter)
+ {
+ elog(NOTICE, "An operand to the '%s' operator returns a set of %s,",
+ op, tname(optype));
+ elog(WARN, "but '%s' takes single values, not sets.",
+ op);
+ }
}
-static Node *
+static Node *
make_operand(char *opname,
- Node *tree,
- Oid orig_typeId,
- Oid true_typeId)
+ Node * tree,
+ Oid orig_typeId,
+ Oid true_typeId)
{
- Node *result;
- Type true_type;
- Datum val;
- Oid infunc;
-
- if (tree != NULL) {
- result = tree;
- true_type = get_id_type(true_typeId);
- disallow_setop(opname, true_type, result);
- if (true_typeId != orig_typeId) { /* must coerce */
- Const *con= (Const *)result;
-
- Assert(nodeTag(result)==T_Const);
- val = (Datum)textout((struct varlena *)
- con->constvalue);
- infunc = typeid_get_retinfunc(true_typeId);
- con = makeNode(Const);
- con->consttype = true_typeId;
- con->constlen = tlen(true_type);
- con->constvalue = (Datum)fmgr(infunc,
- val,
- get_typelem(true_typeId),
- -1 /* for varchar() type */);
- con->constisnull = false;
- con->constbyval = true;
- con->constisset = false;
- result = (Node *)con;
+ Node *result;
+ Type true_type;
+ Datum val;
+ Oid infunc;
+
+ if (tree != NULL)
+ {
+ result = tree;
+ true_type = get_id_type(true_typeId);
+ disallow_setop(opname, true_type, result);
+ if (true_typeId != orig_typeId)
+ { /* must coerce */
+ Const *con = (Const *) result;
+
+ Assert(nodeTag(result) == T_Const);
+ val = (Datum) textout((struct varlena *)
+ con->constvalue);
+ infunc = typeid_get_retinfunc(true_typeId);
+ con = makeNode(Const);
+ con->consttype = true_typeId;
+ con->constlen = tlen(true_type);
+ con->constvalue = (Datum) fmgr(infunc,
+ val,
+ get_typelem(true_typeId),
+ -1 /* for varchar() type */ );
+ con->constisnull = false;
+ con->constbyval = true;
+ con->constisset = false;
+ result = (Node *) con;
+ }
+ }
+ else
+ {
+ Const *con = makeNode(Const);
+
+ con->consttype = true_typeId;
+ con->constlen = 0;
+ con->constvalue = (Datum) (struct varlena *) NULL;
+ con->constisnull = true;
+ con->constbyval = true;
+ con->constisset = false;
+ result = (Node *) con;
}
- }else {
- Const *con= makeNode(Const);
-
- con->consttype = true_typeId;
- con->constlen = 0;
- con->constvalue = (Datum)(struct varlena *)NULL;
- con->constisnull = true;
- con->constbyval = true;
- con->constisset = false;
- result = (Node *)con;
- }
-
- return result;
+
+ return result;
}
-Expr *
-make_op(char *opname, Node *ltree, Node *rtree)
+Expr *
+make_op(char *opname, Node * ltree, Node * rtree)
{
- Oid ltypeId, rtypeId;
- Operator temp;
- OperatorTupleForm opform;
- Oper *newop;
- Node *left, *right;
- Expr *result;
-
- if (rtree == NULL) {
-
- /* right operator */
- ltypeId = (ltree==NULL) ? UNKNOWNOID : exprType(ltree);
- temp = right_oper(opname, ltypeId);
- opform = (OperatorTupleForm) GETSTRUCT(temp);
- left = make_operand(opname, ltree, ltypeId, opform->oprleft);
- right = NULL;
-
- }else if (ltree == NULL) {
-
- /* left operator */
- rtypeId = (rtree==NULL) ? UNKNOWNOID : exprType(rtree);
- temp = left_oper(opname, rtypeId);
- opform = (OperatorTupleForm) GETSTRUCT(temp);
- right = make_operand(opname, rtree, rtypeId, opform->oprright);
- left = NULL;
-
- }else {
- char *outstr;
- Oid infunc, outfunc;
- Type newtype;
+ Oid ltypeId,
+ rtypeId;
+ Operator temp;
+ OperatorTupleForm opform;
+ Oper *newop;
+ Node *left,
+ *right;
+ Expr *result;
+
+ if (rtree == NULL)
+ {
+
+ /* right operator */
+ ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
+ temp = right_oper(opname, ltypeId);
+ opform = (OperatorTupleForm) GETSTRUCT(temp);
+ left = make_operand(opname, ltree, ltypeId, opform->oprleft);
+ right = NULL;
+
+ }
+ else if (ltree == NULL)
+ {
+
+ /* left operator */
+ rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
+ temp = left_oper(opname, rtypeId);
+ opform = (OperatorTupleForm) GETSTRUCT(temp);
+ right = make_operand(opname, rtree, rtypeId, opform->oprright);
+ left = NULL;
+
+ }
+ else
+ {
+ char *outstr;
+ Oid infunc,
+ outfunc;
+ Type newtype;
#define CONVERTABLE_TYPE(t) ( (t) == INT2OID || \
- (t) == INT4OID || \
- (t) == OIDOID || \
- (t) == FLOAT4OID || \
- (t) == FLOAT8OID || \
- (t) == CASHOID)
-
- /* binary operator */
- ltypeId = (ltree==NULL) ? UNKNOWNOID : exprType(ltree);
- rtypeId = (rtree==NULL) ? UNKNOWNOID : exprType(rtree);
-
- /* convert constant when using a const of a numeric type
- and a non-const of another numeric type */
- if (CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) != T_Const &&
- CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) == T_Const &&
- !((Const *)rtree)->constiscast) {
- outfunc = typeid_get_retoutfunc(rtypeId);
- infunc = typeid_get_retinfunc(ltypeId);
- outstr = (char *)fmgr(outfunc, ((Const *)rtree)->constvalue);
- ((Const *)rtree)->constvalue = (Datum)fmgr(infunc, outstr);
- pfree(outstr);
- ((Const *)rtree)->consttype = rtypeId = ltypeId;
- newtype = get_id_type(rtypeId);
- ((Const *)rtree)->constlen = tlen(newtype);
- ((Const *)rtree)->constbyval = tbyval(newtype);
+ (t) == INT4OID || \
+ (t) == OIDOID || \
+ (t) == FLOAT4OID || \
+ (t) == FLOAT8OID || \
+ (t) == CASHOID)
+
+ /* binary operator */
+ ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
+ rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
+
+ /*
+ * convert constant when using a const of a numeric type and a
+ * non-const of another numeric type
+ */
+ if (CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) != T_Const &&
+ CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) == T_Const &&
+ !((Const *) rtree)->constiscast)
+ {
+ outfunc = typeid_get_retoutfunc(rtypeId);
+ infunc = typeid_get_retinfunc(ltypeId);
+ outstr = (char *) fmgr(outfunc, ((Const *) rtree)->constvalue);
+ ((Const *) rtree)->constvalue = (Datum) fmgr(infunc, outstr);
+ pfree(outstr);
+ ((Const *) rtree)->consttype = rtypeId = ltypeId;
+ newtype = get_id_type(rtypeId);
+ ((Const *) rtree)->constlen = tlen(newtype);
+ ((Const *) rtree)->constbyval = tbyval(newtype);
+ }
+
+ if (CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) != T_Const &&
+ CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) == T_Const &&
+ !((Const *) ltree)->constiscast)
+ {
+ outfunc = typeid_get_retoutfunc(ltypeId);
+ infunc = typeid_get_retinfunc(rtypeId);
+ outstr = (char *) fmgr(outfunc, ((Const *) ltree)->constvalue);
+ ((Const *) ltree)->constvalue = (Datum) fmgr(infunc, outstr);
+ pfree(outstr);
+ ((Const *) ltree)->consttype = ltypeId = rtypeId;
+ newtype = get_id_type(ltypeId);
+ ((Const *) ltree)->constlen = tlen(newtype);
+ ((Const *) ltree)->constbyval = tbyval(newtype);
+ }
+
+ temp = oper(opname, ltypeId, rtypeId, false);
+ opform = (OperatorTupleForm) GETSTRUCT(temp);
+ left = make_operand(opname, ltree, ltypeId, opform->oprleft);
+ right = make_operand(opname, rtree, rtypeId, opform->oprright);
}
- if (CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) != T_Const &&
- CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) == T_Const &&
- !((Const *)ltree)->constiscast) {
- outfunc = typeid_get_retoutfunc(ltypeId);
- infunc = typeid_get_retinfunc(rtypeId);
- outstr = (char *)fmgr(outfunc, ((Const *)ltree)->constvalue);
- ((Const *)ltree)->constvalue = (Datum)fmgr(infunc, outstr);
- pfree(outstr);
- ((Const *)ltree)->consttype = ltypeId = rtypeId;
- newtype = get_id_type(ltypeId);
- ((Const *)ltree)->constlen = tlen(newtype);
- ((Const *)ltree)->constbyval = tbyval(newtype);
+ newop = makeOper(oprid(temp), /* opno */
+ InvalidOid,/* opid */
+ opform->oprresult, /* operator result type */
+ 0,
+ NULL);
+
+ result = makeNode(Expr);
+ result->typeOid = opform->oprresult;
+ result->opType = OP_EXPR;
+ result->oper = (Node *) newop;
+
+ if (!left)
+ {
+ result->args = lcons(right, NIL);
+ }
+ else if (!right)
+ {
+ result->args = lcons(left, NIL);
+ }
+ else
+ {
+ result->args = lcons(left, lcons(right, NIL));
}
- temp = oper(opname, ltypeId, rtypeId, false);
- opform = (OperatorTupleForm) GETSTRUCT(temp);
- left = make_operand(opname, ltree, ltypeId, opform->oprleft);
- right = make_operand(opname, rtree, rtypeId, opform->oprright);
- }
-
- newop = makeOper(oprid(temp), /* opno */
- InvalidOid, /* opid */
- opform->oprresult, /* operator result type */
- 0,
- NULL);
-
- result = makeNode(Expr);
- result->typeOid = opform->oprresult;
- result->opType = OP_EXPR;
- result->oper = (Node *)newop;
-
- if (!left) {
- result->args = lcons(right, NIL);
- } else if (!right) {
- result->args = lcons(left, NIL);
- } else {
- result->args = lcons(left, lcons(right, NIL));
- }
-
- return result;
+ return result;
}
Oid
find_atttype(Oid relid, char *attrname)
{
- int attid;
- Oid vartype;
- Relation rd;
-
- rd = heap_open(relid);
- if (!RelationIsValid(rd)) {
- rd = heap_openr(tname(get_id_type(relid)));
+ int attid;
+ Oid vartype;
+ Relation rd;
+
+ rd = heap_open(relid);
if (!RelationIsValid(rd))
- elog(WARN, "cannot compute type of att %s for relid %d",
- attrname, relid);
- }
-
- attid = nf_varattno(rd, attrname);
-
- if (attid == InvalidAttrNumber)
- elog(WARN, "Invalid attribute %s\n", attrname);
-
- vartype = att_typeid(rd , attid);
-
- /*
- * close relation we're done with it now
- */
- heap_close(rd);
-
- return (vartype);
+ {
+ rd = heap_openr(tname(get_id_type(relid)));
+ if (!RelationIsValid(rd))
+ elog(WARN, "cannot compute type of att %s for relid %d",
+ attrname, relid);
+ }
+
+ attid = nf_varattno(rd, attrname);
+
+ if (attid == InvalidAttrNumber)
+ elog(WARN, "Invalid attribute %s\n", attrname);
+
+ vartype = att_typeid(rd, attid);
+
+ /*
+ * close relation we're done with it now
+ */
+ heap_close(rd);
+
+ return (vartype);
}
-Var *
-make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id)
+Var *
+make_var(ParseState * pstate, char *refname, char *attrname, Oid * type_id)
{
- Var *varnode;
- int vnum, attid;
- Oid vartypeid;
- Relation rd;
- RangeTblEntry *rte;
+ Var *varnode;
+ int vnum,
+ attid;
+ Oid vartypeid;
+ Relation rd;
+ RangeTblEntry *rte;
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- if (rte == NULL)
- rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ if (rte == NULL)
+ rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
- vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
+ vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
- rd = heap_open(rte->relid);
+ rd = heap_open(rte->relid);
- attid = nf_varattno(rd, attrname);
- if (attid == InvalidAttrNumber)
- elog(WARN, "Invalid attribute %s\n", attrname);
- vartypeid = att_typeid(rd, attid);
+ attid = nf_varattno(rd, attrname);
+ if (attid == InvalidAttrNumber)
+ elog(WARN, "Invalid attribute %s\n", attrname);
+ vartypeid = att_typeid(rd, attid);
- varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
+ varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
- heap_close(rd);
+ heap_close(rd);
- *type_id = vartypeid;
- return varnode;
+ *type_id = vartypeid;
+ return varnode;
}
/*
- * make_array_ref() -- Make an array reference node.
+ * make_array_ref() -- Make an array reference node.
*
- * Array references can hang off of arbitrary nested dot (or
- * function invocation) expressions. This routine takes a
- * tree generated by ParseFunc() and an array index and
- * generates a new array reference tree. We do some simple
- * typechecking to be sure the dereference is valid in the
- * type system, but we don't do any bounds checking here.
+ * Array references can hang off of arbitrary nested dot (or
+ * function invocation) expressions. This routine takes a
+ * tree generated by ParseFunc() and an array index and
+ * generates a new array reference tree. We do some simple
+ * typechecking to be sure the dereference is valid in the
+ * type system, but we don't do any bounds checking here.
*
- * indirection is a list of A_Indices
+ * indirection is a list of A_Indices
*/
-ArrayRef *
-make_array_ref(Node *expr,
- List *indirection)
+ArrayRef *
+make_array_ref(Node * expr,
+ List * indirection)
{
- Oid typearray;
- HeapTuple type_tuple;
- TypeTupleForm type_struct_array, type_struct_element;
- ArrayRef *aref;
- Oid reftype;
- List *upperIndexpr=NIL;
- List *lowerIndexpr=NIL;
-
- typearray = exprType(expr);
-
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typearray),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- /* get the array type struct from the type tuple */
- type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- if (type_struct_array->typelem == InvalidOid) {
- elog(WARN, "make_array_ref: type %s is not an array",
- (Name)&(type_struct_array->typname.data[0]));
- }
-
- /* get the type tuple for the element type */
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_struct_array->typelem),
- 0,0,0);
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- while(indirection!=NIL) {
- A_Indices *ind = lfirst(indirection);
- if (ind->lidx) {
- /* XXX assumes all lower indices non null in this case
- */
- lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
+ Oid typearray;
+ HeapTuple type_tuple;
+ TypeTupleForm type_struct_array,
+ type_struct_element;
+ ArrayRef *aref;
+ Oid reftype;
+ List *upperIndexpr = NIL;
+ List *lowerIndexpr = NIL;
+
+ typearray = exprType(expr);
+
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typearray),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ /* get the array type struct from the type tuple */
+ type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ if (type_struct_array->typelem == InvalidOid)
+ {
+ elog(WARN, "make_array_ref: type %s is not an array",
+ (Name) & (type_struct_array->typname.data[0]));
+ }
+
+ /* get the type tuple for the element type */
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_struct_array->typelem),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ while (indirection != NIL)
+ {
+ A_Indices *ind = lfirst(indirection);
+
+ if (ind->lidx)
+ {
+
+ /*
+ * XXX assumes all lower indices non null in this case
+ */
+ lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
+ }
+ upperIndexpr = lappend(upperIndexpr, ind->uidx);
+ indirection = lnext(indirection);
}
- upperIndexpr = lappend(upperIndexpr, ind->uidx);
- indirection = lnext(indirection);
- }
- aref = makeNode(ArrayRef);
- aref->refattrlength = type_struct_array->typlen;
- aref->refelemlength = type_struct_element->typlen;
- aref->refelemtype = type_struct_array->typelem;
- aref->refelembyval = type_struct_element->typbyval;
- aref->refupperindexpr = upperIndexpr;
- aref->reflowerindexpr = lowerIndexpr;
- aref->refexpr = expr;
- aref->refassgnexpr = NULL;
-
- if (lowerIndexpr == NIL) /* accessing a single array element */
- reftype = aref->refelemtype;
- else /* request to clip a part of the array, the result is another array */
- reftype = typearray;
-
- /* we change it to reflect the true type; since the original refelemtype
- * doesn't seem to get used anywhere. - ay 10/94
- */
- aref->refelemtype = reftype;
-
- return aref;
+ aref = makeNode(ArrayRef);
+ aref->refattrlength = type_struct_array->typlen;
+ aref->refelemlength = type_struct_element->typlen;
+ aref->refelemtype = type_struct_array->typelem;
+ aref->refelembyval = type_struct_element->typbyval;
+ aref->refupperindexpr = upperIndexpr;
+ aref->reflowerindexpr = lowerIndexpr;
+ aref->refexpr = expr;
+ aref->refassgnexpr = NULL;
+
+ if (lowerIndexpr == NIL) /* accessing a single array element */
+ reftype = aref->refelemtype;
+ else
+/* request to clip a part of the array, the result is another array */
+ reftype = typearray;
+
+ /*
+ * we change it to reflect the true type; since the original
+ * refelemtype doesn't seem to get used anywhere. - ay 10/94
+ */
+ aref->refelemtype = reftype;
+
+ return aref;
}
-ArrayRef *
-make_array_set(Expr *target_expr,
- List *upperIndexpr,
- List *lowerIndexpr,
- Expr *expr)
+ArrayRef *
+make_array_set(Expr * target_expr,
+ List * upperIndexpr,
+ List * lowerIndexpr,
+ Expr * expr)
{
- Oid typearray;
- HeapTuple type_tuple;
- TypeTupleForm type_struct_array;
- TypeTupleForm type_struct_element;
- ArrayRef *aref;
- Oid reftype;
-
- typearray = exprType((Node*)target_expr);
-
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typearray),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- /* get the array type struct from the type tuple */
- type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- if (type_struct_array->typelem == InvalidOid) {
- elog(WARN, "make_array_ref: type %s is not an array",
- (Name)&(type_struct_array->typname.data[0]));
- }
- /* get the type tuple for the element type */
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_struct_array->typelem),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- aref = makeNode(ArrayRef);
- aref->refattrlength = type_struct_array->typlen;
- aref->refelemlength = type_struct_element->typlen;
- aref->refelemtype = type_struct_array->typelem;
- aref->refelembyval = type_struct_element->typbyval;
- aref->refupperindexpr = upperIndexpr;
- aref->reflowerindexpr = lowerIndexpr;
- aref->refexpr = (Node*)target_expr;
- aref->refassgnexpr = (Node*)expr;
-
- if (lowerIndexpr == NIL) /* accessing a single array element */
- reftype = aref->refelemtype;
- else /* request to set a part of the array, by another array */
- reftype = typearray;
-
- aref->refelemtype = reftype;
-
- return aref;
+ Oid typearray;
+ HeapTuple type_tuple;
+ TypeTupleForm type_struct_array;
+ TypeTupleForm type_struct_element;
+ ArrayRef *aref;
+ Oid reftype;
+
+ typearray = exprType((Node *) target_expr);
+
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typearray),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ /* get the array type struct from the type tuple */
+ type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ if (type_struct_array->typelem == InvalidOid)
+ {
+ elog(WARN, "make_array_ref: type %s is not an array",
+ (Name) & (type_struct_array->typname.data[0]));
+ }
+ /* get the type tuple for the element type */
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_struct_array->typelem),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ aref = makeNode(ArrayRef);
+ aref->refattrlength = type_struct_array->typlen;
+ aref->refelemlength = type_struct_element->typlen;
+ aref->refelemtype = type_struct_array->typelem;
+ aref->refelembyval = type_struct_element->typbyval;
+ aref->refupperindexpr = upperIndexpr;
+ aref->reflowerindexpr = lowerIndexpr;
+ aref->refexpr = (Node *) target_expr;
+ aref->refassgnexpr = (Node *) expr;
+
+ if (lowerIndexpr == NIL) /* accessing a single array element */
+ reftype = aref->refelemtype;
+ else
+/* request to set a part of the array, by another array */
+ reftype = typearray;
+
+ aref->refelemtype = reftype;
+
+ return aref;
}
/*
- *
+ *
* make_const -
- *
+ *
* - takes a lispvalue, (as returned to the yacc routine by the lexer)
- * extracts the type, and makes the appropriate type constant
- * by invoking the (c-callable) lisp routine c-make-const
- * via the lisp_call() mechanism
+ * extracts the type, and makes the appropriate type constant
+ * by invoking the (c-callable) lisp routine c-make-const
+ * via the lisp_call() mechanism
*
* eventually, produces a "const" lisp-struct as per nodedefs.cl
- */
-Const *
-make_const(Value *value)
+ */
+Const *
+make_const(Value * value)
{
- Type tp;
- Datum val;
- Const *con;
-
- switch(nodeTag(value)) {
- case T_Integer:
- tp = type("int4");
- val = Int32GetDatum(intVal(value));
- break;
-
- case T_Float:
- {
- float64 dummy;
- tp = type("float8");
-
- dummy = (float64)palloc(sizeof(float64data));
- *dummy = floatVal(value);
-
- val = Float64GetDatum(dummy);
- }
- break;
-
- case T_String:
- tp = type("unknown"); /* unknown for now, will be type coerced */
- val = PointerGetDatum(textin(strVal(value)));
- break;
-
- case T_Null:
- default:
- {
- if (nodeTag(value)!=T_Null)
- elog(NOTICE,"unknown type : %d\n", nodeTag(value));
+ Type tp;
+ Datum val;
+ Const *con;
- /* null const */
- con = makeConst(0, 0, (Datum)NULL, true, false, false, false);
- return con;
+ switch (nodeTag(value))
+ {
+ case T_Integer:
+ tp = type("int4");
+ val = Int32GetDatum(intVal(value));
+ break;
+
+ case T_Float:
+ {
+ float64 dummy;
+
+ tp = type("float8");
+
+ dummy = (float64) palloc(sizeof(float64data));
+ *dummy = floatVal(value);
+
+ val = Float64GetDatum(dummy);
+ }
+ break;
+
+ case T_String:
+ tp = type("unknown"); /* unknown for now, will be type coerced */
+ val = PointerGetDatum(textin(strVal(value)));
+ break;
+
+ case T_Null:
+ default:
+ {
+ if (nodeTag(value) != T_Null)
+ elog(NOTICE, "unknown type : %d\n", nodeTag(value));
+
+ /* null const */
+ con = makeConst(0, 0, (Datum) NULL, true, false, false, false);
+ return con;
+ }
}
- }
- con = makeConst(typeid(tp),
- tlen(tp),
- val,
- false,
- tbyval(tp),
- false, /* not a set */
- false);
+ con = makeConst(typeid(tp),
+ tlen(tp),
+ val,
+ false,
+ tbyval(tp),
+ false, /* not a set */
+ false);
- return (con);
+ return (con);
}
/*
@@ -721,87 +785,93 @@ make_const(Value *value)
* used in postquel functions
*/
void
-param_type_init(Oid* typev, int nargs)
+param_type_init(Oid * typev, int nargs)
{
- pfunc_num_args = nargs;
- param_type_info = typev;
+ pfunc_num_args = nargs;
+ param_type_info = typev;
}
Oid
param_type(int t)
{
- if ((t >pfunc_num_args) ||(t ==0)) return InvalidOid;
- return param_type_info[t-1];
+ if ((t > pfunc_num_args) || (t == 0))
+ return InvalidOid;
+ return param_type_info[t - 1];
}
/*
* handleTargetColname -
- * use column names from insert
+ * use column names from insert
*/
void
-handleTargetColname(ParseState *pstate, char **resname,
+handleTargetColname(ParseState * pstate, char **resname,
char *refname, char *colname)
{
- if (pstate->p_is_insert) {
- if (pstate->p_insert_columns != NIL ) {
- Ident *id = lfirst(pstate->p_insert_columns);
- *resname = id->name;
- pstate->p_insert_columns = lnext(pstate->p_insert_columns);
- }
- else
- elog(WARN, "insert: more expressions than target columns");
- }
- if (pstate->p_is_insert||pstate->p_is_update)
- checkTargetTypes(pstate, *resname, refname, colname);
+ if (pstate->p_is_insert)
+ {
+ if (pstate->p_insert_columns != NIL)
+ {
+ Ident *id = lfirst(pstate->p_insert_columns);
+
+ *resname = id->name;
+ pstate->p_insert_columns = lnext(pstate->p_insert_columns);
+ }
+ else
+ elog(WARN, "insert: more expressions than target columns");
+ }
+ if (pstate->p_is_insert || pstate->p_is_update)
+ checkTargetTypes(pstate, *resname, refname, colname);
}
/*
* checkTargetTypes -
- * checks value and target column types
+ * checks value and target column types
*/
static void
-checkTargetTypes(ParseState *pstate, char *target_colname,
- char *refname, char *colname)
+checkTargetTypes(ParseState * pstate, char *target_colname,
+ char *refname, char *colname)
{
- Oid attrtype_id, attrtype_target;
- int resdomno_id, resdomno_target;
- Relation rd;
- RangeTblEntry *rte;
-
- if (target_colname == NULL || colname == NULL)
- return;
-
- if (refname != NULL)
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- else {
- rte = colnameRangeTableEntry(pstate, colname);
- if ( rte == (RangeTblEntry *) NULL )
- elog (WARN, "attribute %s not found", colname);
- refname = rte->refname;
- }
+ Oid attrtype_id,
+ attrtype_target;
+ int resdomno_id,
+ resdomno_target;
+ Relation rd;
+ RangeTblEntry *rte;
+
+ if (target_colname == NULL || colname == NULL)
+ return;
+
+ if (refname != NULL)
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ else
+ {
+ rte = colnameRangeTableEntry(pstate, colname);
+ if (rte == (RangeTblEntry *) NULL)
+ elog(WARN, "attribute %s not found", colname);
+ refname = rte->refname;
+ }
/*
- if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry)
- elog(WARN, "%s not available in this context", colname);
+ if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry)
+ elog(WARN, "%s not available in this context", colname);
*/
- rd = heap_open(rte->relid);
+ rd = heap_open(rte->relid);
- resdomno_id = varattno(rd,colname);
- attrtype_id = att_typeid(rd,resdomno_id);
+ resdomno_id = varattno(rd, colname);
+ attrtype_id = att_typeid(rd, resdomno_id);
- resdomno_target = varattno(pstate->p_target_relation,target_colname);
- attrtype_target = att_typeid(pstate->p_target_relation, resdomno_target);
+ resdomno_target = varattno(pstate->p_target_relation, target_colname);
+ attrtype_target = att_typeid(pstate->p_target_relation, resdomno_target);
- if (attrtype_id != attrtype_target)
- elog(WARN, "Type of %s does not match target column %s",
- colname, target_colname);
+ if (attrtype_id != attrtype_target)
+ elog(WARN, "Type of %s does not match target column %s",
+ colname, target_colname);
- if ((attrtype_id == BPCHAROID || attrtype_id == VARCHAROID) &&
- rd->rd_att->attrs[resdomno_id-1]->attlen !=
- pstate->p_target_relation->rd_att->attrs[resdomno_target-1]->attlen)
- elog(WARN, "Length of %s does not match length of target column %s",
- colname, target_colname);
+ if ((attrtype_id == BPCHAROID || attrtype_id == VARCHAROID) &&
+ rd->rd_att->attrs[resdomno_id - 1]->attlen !=
+ pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->attlen)
+ elog(WARN, "Length of %s does not match length of target column %s",
+ colname, target_colname);
- heap_close(rd);
+ heap_close(rd);
}
-