diff options
author | Thomas G. Lockhart <lockhart@fourpalms.org> | 1998-05-29 14:00:24 +0000 |
---|---|---|
committer | Thomas G. Lockhart <lockhart@fourpalms.org> | 1998-05-29 14:00:24 +0000 |
commit | 8536c962614a55d33baa283a7901bb167a43978a (patch) | |
tree | d674201859f82cf92296a5fc079b5bfcaf1c4f8b /src/backend/parser/parse_node.c | |
parent | 329083a97e2b5de1191f50451a253c224c833605 (diff) | |
download | postgresql-8536c962614a55d33baa283a7901bb167a43978a.tar.gz postgresql-8536c962614a55d33baa283a7901bb167a43978a.zip |
Do type conversion to match columns in UNION clauses.
Currently force the type to match the _first_ select in the union.
Move oper_select_candidate() from parse_func.c to parse_oper.c.
Throw error inside of oper_inexact() if no match for binary operators.
Check more carefully that types can be coerced
even if there is only one candidate operator in oper_inexact().
Fix up error messages for more uniform look.
Remove unused code.
Fix up comments.
Diffstat (limited to 'src/backend/parser/parse_node.c')
-rw-r--r-- | src/backend/parser/parse_node.c | 137 |
1 files changed, 22 insertions, 115 deletions
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 140ca3df47e..1b0982d3bce 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.15 1998/05/09 23:29:53 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.16 1998/05/29 14:00:21 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +25,7 @@ #include "parser/parse_oper.h" #include "parser/parse_relation.h" #include "parser/parse_type.h" +#include "parser/parse_coerce.h" #include "utils/builtins.h" #include "utils/syscache.h" #include "utils/lsyscache.h" @@ -36,13 +37,10 @@ make_operand(char *opname, Oid orig_typeId, Oid true_typeId); -/* - * make_parsestate() -- - * allocate and initialize a new ParseState. - * the CALLER is responsible for freeing the ParseState* returned - * +/* make_parsestate() + * Allocate and initialize a new ParseState. + * The CALLER is responsible for freeing the ParseState* returned. */ - ParseState * make_parsestate(ParseState *parentParseState) { @@ -58,11 +56,6 @@ make_parsestate(ParseState *parentParseState) } -extern -Node * -coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId); - - /* make_operand() * Ensure argument type match by forcing conversion of constants. */ @@ -74,10 +67,6 @@ make_operand(char *opname, { Node *result; Type true_type; -#if FALSE - Datum val; - Oid infunc; -#endif #ifdef PARSEDEBUG printf("make_operand: constructing operand for '%s' %s->%s\n", @@ -133,36 +122,6 @@ disallow_setop(char *op, Type optype, Node *operand) } -/* CoerceType() - * Try to force type of node. - */ -Oid CoerceType(Oid typeId, Node *node); - -Oid -CoerceType(Oid typeId, Node *node) -{ - switch (nodeTag(node)) - { - case T_Const: - { - Const *con = (Const *) node; - -#ifdef PARSEDEBUG -printf( "Convert node %d to text\n", nodeTag(node)); -#endif - - typeId = TEXTOID; - con->consttype = typeId; - } - break; - - default: - break; - } - return typeId; -} /* CoerceType() */ - - /* make_op() * Operator construction. * @@ -174,7 +133,7 @@ make_op(char *opname, Node *ltree, Node *rtree) { Oid ltypeId, rtypeId; - Operator temp; + Operator tup; OperatorTupleForm opform; Oper *newop; Node *left, @@ -185,8 +144,8 @@ make_op(char *opname, Node *ltree, Node *rtree) if (rtree == NULL) { ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree); - temp = right_oper(opname, ltypeId); - opform = (OperatorTupleForm) GETSTRUCT(temp); + tup = right_oper(opname, ltypeId); + opform = (OperatorTupleForm) GETSTRUCT(tup); left = make_operand(opname, ltree, ltypeId, opform->oprleft); right = NULL; @@ -196,11 +155,11 @@ make_op(char *opname, Node *ltree, Node *rtree) else if (ltree == NULL) { rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree); - temp = left_oper(opname, rtypeId); + tup = left_oper(opname, rtypeId); #ifdef PARSEDEBUG -printf("make_op: returned from left_oper() with structure at %p\n", (void *)temp); +printf("make_op: returned from left_oper() with structure at %p\n", (void *)tup); #endif - opform = (OperatorTupleForm) GETSTRUCT(temp); + opform = (OperatorTupleForm) GETSTRUCT(tup); #ifdef PARSEDEBUG printf("make_op: calling make_operand()\n"); #endif @@ -212,80 +171,28 @@ printf("make_op: calling make_operand()\n"); /* otherwise, binary operator */ else { - -#define CONVERTIBLE_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); -#if FALSE - /* Both operands of unknown type? - * Then they are strings and we should force at least one to text - * - thomas 1998-03-16 - */ - ltypeId = exprType(ltree); - rtypeId = exprType(rtree); - - if ((ltypeId == UNKNOWNOID) - && (rtypeId == UNKNOWNOID)) - { -#ifdef PARSEDEBUG -printf( "Convert left-hand constant to text for node %d\n", nodeTag(ltree)); -#endif - - ltypeId = CoerceType(TEXTOID, ltree); - } -#endif - -#if FALSE - /* - * convert constant when using a const of a numeric type and a - * non-const of another numeric type - */ - if (CONVERTIBLE_TYPE(ltypeId) && nodeTag(ltree) != T_Const && - CONVERTIBLE_TYPE(rtypeId) && nodeTag(rtree) == T_Const && - !((Const *) rtree)->constiscast) + /* check for exact match on this operator... */ + if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId, <ree, &rtree, TRUE))) { - outfunc = typeidOutfunc(rtypeId); - infunc = typeidInfunc(ltypeId); - outstr = (char *) fmgr(outfunc, ((Const *) rtree)->constvalue); - ((Const *) rtree)->constvalue = (Datum) fmgr(infunc, outstr, -1); - pfree(outstr); - ((Const *) rtree)->consttype = rtypeId = ltypeId; - newtype = typeidType(rtypeId); - ((Const *) rtree)->constlen = typeLen(newtype); - ((Const *) rtree)->constbyval = typeByVal(newtype); + ltypeId = exprType(ltree); + rtypeId = exprType(rtree); } - - if (CONVERTIBLE_TYPE(rtypeId) && nodeTag(rtree) != T_Const && - CONVERTIBLE_TYPE(ltypeId) && nodeTag(ltree) == T_Const && - !((Const *) ltree)->constiscast) + /* try to find a match on likely candidates... */ + else if (!HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId, <ree, &rtree, FALSE))) { - outfunc = typeidOutfunc(ltypeId); - infunc = typeidInfunc(rtypeId); - outstr = (char *) fmgr(outfunc, ((Const *) ltree)->constvalue); - ((Const *) ltree)->constvalue = (Datum) fmgr(infunc, outstr, -1); - pfree(outstr); - ((Const *) ltree)->consttype = ltypeId = rtypeId; - newtype = typeidType(ltypeId); - ((Const *) ltree)->constlen = typeLen(newtype); - ((Const *) ltree)->constbyval = typeByVal(newtype); + /* Won't return from oper_inexact() without a candidate... */ } -#endif - temp = oper(opname, ltypeId, rtypeId, false); - opform = (OperatorTupleForm) GETSTRUCT(temp); + opform = (OperatorTupleForm) GETSTRUCT(tup); left = make_operand(opname, ltree, ltypeId, opform->oprleft); right = make_operand(opname, rtree, rtypeId, opform->oprright); } - newop = makeOper(oprid(temp), /* opno */ + newop = makeOper(oprid(tup), /* opno */ InvalidOid, /* opid */ opform->oprresult, /* operator result type */ 0, @@ -304,7 +211,7 @@ printf( "Convert left-hand constant to text for node %d\n", nodeTag(ltree)); result->args = lcons(left, lcons(right, NIL)); return result; -} +} /* make_op() */ Var * @@ -538,7 +445,7 @@ make_const(Value *value) default: { if (nodeTag(value) != T_Null) - elog(NOTICE, "unknown type : %d\n", nodeTag(value)); + elog(NOTICE, "make_const: unknown type %d\n", nodeTag(value)); /* null const */ con = makeConst(0, 0, (Datum) NULL, true, false, false, false); |