Commit a23faeee authored by Tom Lane's avatar Tom Lane

Remove bogus code in oper_exact --- if it didn't find an exact

match then it tried for a self-commutative operator with the reversed input
data types.  This is pretty silly; there could never be such an operator,
except maybe in binary-compatible-type scenarios, and we have oper_inexact
for that.  Besides which, the oprsanity regress test would complain about
such an operator.  Remove nonfunctional code and simplify routine calling
convention accordingly.
parent e8140adb
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.30 1999/08/22 20:15:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.31 1999/08/23 23:48:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -31,10 +31,6 @@ ...@@ -31,10 +31,6 @@
#include "utils/syscache.h" #include "utils/syscache.h"
static void disallow_setop(char *op, Type optype, Node *operand); static void disallow_setop(char *op, Type optype, Node *operand);
static Node *make_operand(char *opname,
Node *tree,
Oid orig_typeId,
Oid true_typeId);
/* make_parsestate() /* make_parsestate()
* Allocate and initialize a new ParseState. * Allocate and initialize a new ParseState.
...@@ -58,31 +54,31 @@ make_parsestate(ParseState *parentParseState) ...@@ -58,31 +54,31 @@ make_parsestate(ParseState *parentParseState)
/* make_operand() /* make_operand()
* Ensure argument type match by forcing conversion of constants. * Ensure argument type match by forcing conversion of constants.
*/ */
static Node * Node *
make_operand(char *opname, make_operand(char *opname,
Node *tree, Node *tree,
Oid orig_typeId, Oid orig_typeId,
Oid true_typeId) Oid target_typeId)
{ {
Node *result; Node *result;
Type true_type; Type target_type;
if (tree != NULL) if (tree != NULL)
{ {
result = tree; result = tree;
true_type = typeidType(true_typeId); target_type = typeidType(target_typeId);
disallow_setop(opname, true_type, result); disallow_setop(opname, target_type, result);
/* must coerce? */ /* must coerce? */
if (true_typeId != orig_typeId) if (target_typeId != orig_typeId)
result = coerce_type(NULL, tree, orig_typeId, true_typeId, -1); result = coerce_type(NULL, tree, orig_typeId, target_typeId, -1);
} }
/* otherwise, this is a NULL value */ /* otherwise, this is a NULL value */
else else
{ {
Const *con = makeNode(Const); Const *con = makeNode(Const);
con->consttype = true_typeId; con->consttype = target_typeId;
con->constlen = 0; con->constlen = 0;
con->constvalue = (Datum) (struct varlena *) NULL; con->constvalue = (Datum) (struct varlena *) NULL;
con->constisnull = true; con->constisnull = true;
...@@ -128,47 +124,31 @@ make_op(char *opname, Node *ltree, Node *rtree) ...@@ -128,47 +124,31 @@ make_op(char *opname, Node *ltree, Node *rtree)
*right; *right;
Expr *result; Expr *result;
ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
/* right operator? */ /* right operator? */
if (rtree == NULL) if (rtree == NULL)
{ {
ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
tup = right_oper(opname, ltypeId); tup = right_oper(opname, ltypeId);
opform = (Form_pg_operator) GETSTRUCT(tup); opform = (Form_pg_operator) GETSTRUCT(tup);
left = make_operand(opname, ltree, ltypeId, opform->oprleft); left = make_operand(opname, ltree, ltypeId, opform->oprleft);
right = NULL; right = NULL;
} }
/* left operator? */ /* left operator? */
else if (ltree == NULL) else if (ltree == NULL)
{ {
rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
tup = left_oper(opname, rtypeId); tup = left_oper(opname, rtypeId);
opform = (Form_pg_operator) GETSTRUCT(tup); opform = (Form_pg_operator) GETSTRUCT(tup);
right = make_operand(opname, rtree, rtypeId, opform->oprright); right = make_operand(opname, rtree, rtypeId, opform->oprright);
left = NULL; left = NULL;
} }
/* otherwise, binary operator */ /* otherwise, binary operator */
else else
{ {
/* binary operator */ tup = oper(opname, ltypeId, rtypeId, FALSE);
ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
/* check for exact match on this operator... */
if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId, &ltree, &rtree, TRUE)))
{
ltypeId = exprType(ltree);
rtypeId = exprType(rtree);
}
/* try to find a match on likely candidates... */
else if (!HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId, &ltree, &rtree, FALSE)))
{
/* Won't return from oper_inexact() without a candidate... */
}
opform = (Form_pg_operator) GETSTRUCT(tup); opform = (Form_pg_operator) GETSTRUCT(tup);
left = make_operand(opname, ltree, ltypeId, opform->oprleft); left = make_operand(opname, ltree, ltypeId, opform->oprleft);
right = make_operand(opname, rtree, rtypeId, opform->oprright); right = make_operand(opname, rtree, rtypeId, opform->oprright);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.29 1999/07/17 20:17:25 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.30 1999/08/23 23:48:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
static Oid *oper_select_candidate(int nargs, Oid *input_typeids, static Oid *oper_select_candidate(int nargs, Oid *input_typeids,
CandidateList candidates); CandidateList candidates);
static Operator oper_exact(char *op, Oid arg1, Oid arg2);
static Operator oper_inexact(char *op, Oid arg1, Oid arg2);
static int binary_oper_get_candidates(char *opname, static int binary_oper_get_candidates(char *opname,
Oid leftTypeId, Oid leftTypeId,
Oid rightTypeId, Oid rightTypeId,
...@@ -376,15 +378,14 @@ oper_select_candidate(int nargs, ...@@ -376,15 +378,14 @@ oper_select_candidate(int nargs,
/* oper_exact() /* oper_exact()
* Given operator, and arguments, return oper struct. * Given operator, and arguments, return oper struct or NULL.
* Inputs: * Inputs:
* arg1, arg2: Type IDs * arg1, arg2: Type IDs
*/ */
Operator static Operator
oper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings) oper_exact(char *op, Oid arg1, Oid arg2)
{ {
HeapTuple tup; HeapTuple tup;
Node *tree;
/* Unspecified type for one of the arguments? then use the other */ /* Unspecified type for one of the arguments? then use the other */
if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid)) if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
...@@ -398,51 +399,17 @@ oper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarn ...@@ -398,51 +399,17 @@ oper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarn
ObjectIdGetDatum(arg2), ObjectIdGetDatum(arg2),
CharGetDatum('b')); CharGetDatum('b'));
/* return (Operator) tup;
* Did not find anything? then try flipping arguments on a commutative
* operator...
*/
if (!HeapTupleIsValid(tup) && (arg1 != arg2))
{
tup = SearchSysCacheTuple(OPRNAME,
PointerGetDatum(op),
ObjectIdGetDatum(arg2),
ObjectIdGetDatum(arg1),
CharGetDatum('b'));
if (HeapTupleIsValid(tup))
{
Form_pg_operator opform;
opform = (Form_pg_operator) GETSTRUCT(tup);
if (opform->oprcom == tup->t_data->t_oid)
{
if ((ltree != NULL) && (rtree != NULL))
{
tree = *ltree;
*ltree = *rtree;
*rtree = tree;
}
}
/* disable for now... - thomas 1998-05-14 */
else
tup = NULL;
}
if (!HeapTupleIsValid(tup) && (!noWarnings))
op_error(op, arg1, arg2);
}
return tup;
} /* oper_exact() */ } /* oper_exact() */
/* oper_inexact() /* oper_inexact()
* Given operator, types of arg1, and arg2, return oper struct. * Given operator, types of arg1, and arg2, return oper struct or NULL.
* Inputs: * Inputs:
* arg1, arg2: Type IDs * arg1, arg2: Type IDs
*/ */
Operator static Operator
oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings) oper_inexact(char *op, Oid arg1, Oid arg2)
{ {
HeapTuple tup; HeapTuple tup;
CandidateList candidates; CandidateList candidates;
...@@ -458,13 +425,9 @@ oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWa ...@@ -458,13 +425,9 @@ oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWa
ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates); ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates);
/* No operators found? Then throw error or return null... */ /* No operators found? Then return null... */
if (ncandidates == 0) if (ncandidates == 0)
{
if (!noWarnings)
op_error(op, arg1, arg2);
return NULL; return NULL;
}
/* Or found exactly one? Then proceed... */ /* Or found exactly one? Then proceed... */
else if (ncandidates == 1) else if (ncandidates == 1)
...@@ -493,18 +456,6 @@ oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWa ...@@ -493,18 +456,6 @@ oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWa
} }
else else
tup = NULL; tup = NULL;
/* Could not choose one, for whatever reason... */
if (!HeapTupleIsValid(tup))
{
if (!noWarnings)
{
elog(ERROR, "Unable to identify an operator '%s' for types '%s' and '%s'"
"\n\tYou will have to retype this query using an explicit cast",
op, typeTypeName(typeidType(arg1)), typeTypeName(typeidType(arg2)));
}
return NULL;
}
} }
return (Operator) tup; return (Operator) tup;
} /* oper_inexact() */ } /* oper_inexact() */
...@@ -521,17 +472,16 @@ oper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings) ...@@ -521,17 +472,16 @@ oper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings)
HeapTuple tup; HeapTuple tup;
/* check for exact match on this operator... */ /* check for exact match on this operator... */
if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId, NULL, NULL, TRUE))) if (HeapTupleIsValid(tup = oper_exact(opname, ltypeId, rtypeId)))
{ {
} }
/* try to find a match on likely candidates... */ /* try to find a match on likely candidates... */
else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId, NULL, NULL, TRUE))) else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId)))
{ {
} }
else if (!noWarnings) else if (!noWarnings)
{ {
elog(ERROR, "Unable to identify a binary operator '%s' for types %s and %s", op_error(opname, ltypeId, rtypeId);
opname, typeTypeName(typeidType(ltypeId)), typeTypeName(typeidType(rtypeId)));
} }
return (Operator) tup; return (Operator) tup;
...@@ -741,8 +691,7 @@ op_error(char *op, Oid arg1, Oid arg2) ...@@ -741,8 +691,7 @@ op_error(char *op, Oid arg1, Oid arg2)
"\n\tProbably a bad attribute name", op); "\n\tProbably a bad attribute name", op);
} }
elog(ERROR, "There is no operator '%s' for types '%s' and '%s'" elog(ERROR, "Unable to identify an operator '%s' for types '%s' and '%s'"
"\n\tYou will either have to retype this query using an explicit cast," "\n\tYou will have to retype this query using an explicit cast",
"\n\tor you will have to define the operator using CREATE OPERATOR",
op, typeTypeName(tp1), typeTypeName(tp2)); op, typeTypeName(tp1), typeTypeName(tp2));
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: parse_node.h,v 1.15 1999/07/19 00:26:17 tgl Exp $ * $Id: parse_node.h,v 1.16 1999/08/23 23:48:37 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,6 +33,8 @@ typedef struct ParseState ...@@ -33,6 +33,8 @@ typedef struct ParseState
extern ParseState *make_parsestate(ParseState *parentParseState); extern ParseState *make_parsestate(ParseState *parentParseState);
extern Expr *make_op(char *opname, Node *ltree, Node *rtree); extern Expr *make_op(char *opname, Node *ltree, Node *rtree);
extern Node *make_operand(char *opname, Node *tree,
Oid orig_typeId, Oid target_typeId);
extern Var *make_var(ParseState *pstate, Oid relid, char *refname, extern Var *make_var(ParseState *pstate, Oid relid, char *refname,
char *attrname); char *attrname);
extern ArrayRef *transformArraySubscripts(ParseState *pstate, extern ArrayRef *transformArraySubscripts(ParseState *pstate,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: parse_oper.h,v 1.8 1999/07/15 15:21:27 momjian Exp $ * $Id: parse_oper.h,v 1.9 1999/08/23 23:48:38 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,7 +23,4 @@ extern Operator oper(char *op, Oid arg1, Oid arg2, bool noWarnings); ...@@ -23,7 +23,4 @@ extern Operator oper(char *op, Oid arg1, Oid arg2, bool noWarnings);
extern Operator right_oper(char *op, Oid arg); extern Operator right_oper(char *op, Oid arg);
extern Operator left_oper(char *op, Oid arg); extern Operator left_oper(char *op, Oid arg);
extern Operator oper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings);
extern Operator oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings);
#endif /* PARSE_OPER_H */ #endif /* PARSE_OPER_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment