Skip to content
Snippets Groups Projects
Commit a23faeee authored by Tom Lane's avatar Tom Lane
Browse files

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
No related branches found
No related tags found
No related merge requests found
......@@ -7,7 +7,7 @@
*
*
* 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 @@
#include "utils/syscache.h"
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()
* Allocate and initialize a new ParseState.
......@@ -58,31 +54,31 @@ make_parsestate(ParseState *parentParseState)
/* make_operand()
* Ensure argument type match by forcing conversion of constants.
*/
static Node *
Node *
make_operand(char *opname,
Node *tree,
Oid orig_typeId,
Oid true_typeId)
Oid target_typeId)
{
Node *result;
Type true_type;
Type target_type;
if (tree != NULL)
{
result = tree;
true_type = typeidType(true_typeId);
disallow_setop(opname, true_type, result);
target_type = typeidType(target_typeId);
disallow_setop(opname, target_type, result);
/* must coerce? */
if (true_typeId != orig_typeId)
result = coerce_type(NULL, tree, orig_typeId, true_typeId, -1);
if (target_typeId != orig_typeId)
result = coerce_type(NULL, tree, orig_typeId, target_typeId, -1);
}
/* otherwise, this is a NULL value */
else
{
Const *con = makeNode(Const);
con->consttype = true_typeId;
con->consttype = target_typeId;
con->constlen = 0;
con->constvalue = (Datum) (struct varlena *) NULL;
con->constisnull = true;
......@@ -128,47 +124,31 @@ make_op(char *opname, Node *ltree, Node *rtree)
*right;
Expr *result;
ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
/* right operator? */
if (rtree == NULL)
{
ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
tup = right_oper(opname, ltypeId);
opform = (Form_pg_operator) GETSTRUCT(tup);
left = make_operand(opname, ltree, ltypeId, opform->oprleft);
right = NULL;
}
/* left operator? */
else if (ltree == NULL)
{
rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
tup = left_oper(opname, rtypeId);
opform = (Form_pg_operator) GETSTRUCT(tup);
right = make_operand(opname, rtree, rtypeId, opform->oprright);
left = NULL;
}
/* otherwise, binary operator */
else
{
/* binary operator */
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... */
}
tup = oper(opname, ltypeId, rtypeId, FALSE);
opform = (Form_pg_operator) GETSTRUCT(tup);
left = make_operand(opname, ltree, ltypeId, opform->oprleft);
right = make_operand(opname, rtree, rtypeId, opform->oprright);
......
......@@ -7,7 +7,7 @@
*
*
* 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 @@
static Oid *oper_select_candidate(int nargs, Oid *input_typeids,
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,
Oid leftTypeId,
Oid rightTypeId,
......@@ -376,15 +378,14 @@ oper_select_candidate(int nargs,
/* oper_exact()
* Given operator, and arguments, return oper struct.
* Given operator, and arguments, return oper struct or NULL.
* Inputs:
* arg1, arg2: Type IDs
*/
Operator
oper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings)
static Operator
oper_exact(char *op, Oid arg1, Oid arg2)
{
HeapTuple tup;
Node *tree;
/* Unspecified type for one of the arguments? then use the other */
if ((arg1 == UNKNOWNOID) && (arg2 != InvalidOid))
......@@ -398,51 +399,17 @@ oper_exact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarn
ObjectIdGetDatum(arg2),
CharGetDatum('b'));
/*
* 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;
return (Operator) tup;
} /* oper_exact() */
/* 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:
* arg1, arg2: Type IDs
*/
Operator
oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWarnings)
static Operator
oper_inexact(char *op, Oid arg1, Oid arg2)
{
HeapTuple tup;
CandidateList candidates;
......@@ -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);
/* No operators found? Then throw error or return null... */
/* No operators found? Then return null... */
if (ncandidates == 0)
{
if (!noWarnings)
op_error(op, arg1, arg2);
return NULL;
}
/* Or found exactly one? Then proceed... */
else if (ncandidates == 1)
......@@ -493,18 +456,6 @@ oper_inexact(char *op, Oid arg1, Oid arg2, Node **ltree, Node **rtree, bool noWa
}
else
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;
} /* oper_inexact() */
......@@ -521,17 +472,16 @@ oper(char *opname, Oid ltypeId, Oid rtypeId, bool noWarnings)
HeapTuple tup;
/* 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... */
else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId, NULL, NULL, TRUE)))
else if (HeapTupleIsValid(tup = oper_inexact(opname, ltypeId, rtypeId)))
{
}
else if (!noWarnings)
{
elog(ERROR, "Unable to identify a binary operator '%s' for types %s and %s",
opname, typeTypeName(typeidType(ltypeId)), typeTypeName(typeidType(rtypeId)));
op_error(opname, ltypeId, rtypeId);
}
return (Operator) tup;
......@@ -741,8 +691,7 @@ op_error(char *op, Oid arg1, Oid arg2)
"\n\tProbably a bad attribute name", op);
}
elog(ERROR, "There is no operator '%s' for types '%s' and '%s'"
"\n\tYou will either have to retype this query using an explicit cast,"
"\n\tor you will have to define the operator using CREATE OPERATOR",
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(tp1), typeTypeName(tp2));
}
......@@ -5,7 +5,7 @@
*
* 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
extern ParseState *make_parsestate(ParseState *parentParseState);
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,
char *attrname);
extern ArrayRef *transformArraySubscripts(ParseState *pstate,
......
......@@ -6,7 +6,7 @@
*
* 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);
extern Operator right_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 */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment