aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_node.c
diff options
context:
space:
mode:
authorThomas G. Lockhart <lockhart@fourpalms.org>1998-05-29 14:00:24 +0000
committerThomas G. Lockhart <lockhart@fourpalms.org>1998-05-29 14:00:24 +0000
commit8536c962614a55d33baa283a7901bb167a43978a (patch)
treed674201859f82cf92296a5fc079b5bfcaf1c4f8b /src/backend/parser/parse_node.c
parent329083a97e2b5de1191f50451a253c224c833605 (diff)
downloadpostgresql-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.c137
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, &ltree, &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, &ltree, &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);