diff options
Diffstat (limited to 'src/backend/parser/parse_query.c')
-rw-r--r-- | src/backend/parser/parse_query.c | 1340 |
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); } - |