88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.113 2002/11/26 03:01:58 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.114 2002/11/30 21:25:04 tgl Exp $
1212 *
1313 * HISTORY
1414 * AUTHORDATEMAJOR EVENT
@@ -98,25 +98,19 @@ make_clause(int type, Node *oper, List *args)
9898 *
9999 * Returns t iff the clause is an operator clause:
100100 *(op expr expr) or (op expr).
101- *
102- * [historical note: is_clause has the exact functionality and is used
103- *throughout the code. They're renamed to is_opclause for clarity.
104- *- ay 10/94.]
105101 */
106102bool
107103is_opclause (Node * clause )
108104{
109105return (clause != NULL &&
110106IsA (clause ,Expr )&&
111- ((((Expr * )clause )-> opType == OP_EXPR )||
112- ((Expr * )clause )-> opType == DISTINCT_EXPR ));
107+ ((Expr * )clause )-> opType == OP_EXPR );
113108}
114109
115110/*
116111 * make_opclause
117- * Creates a clause given its operator left operand and right
118- * operand (if it is non-null).
119- *
112+ * Creates a clause given its operator, left operand, and right
113+ * operand (pass NULL to create single-operand clause).
120114 */
121115Expr *
122116make_opclause (Oper * op ,Var * leftop ,Var * rightop )
@@ -1191,10 +1185,10 @@ eval_const_expressions_mutator(Node *node, void *context)
11911185bool has_nonconst_input = false;
11921186
11931187/*
1194- * Check for constant inputs and especially
1195- * constant-NULL inputs.
1188+ * We must do our own check for NULLs because
1189+ * DISTINCT_EXPR has different results for NULL input
1190+ * than the underlying operator does.
11961191 */
1197- Assert (length (args )== 2 );
11981192foreach (arg ,args )
11991193{
12001194if (IsA (lfirst (arg ),Const ))
@@ -1205,82 +1199,28 @@ eval_const_expressions_mutator(Node *node, void *context)
12051199else
12061200has_nonconst_input = true;
12071201}
1208- /* all nulls? then not distinct */
1209- if (all_null_input )
1210- return MAKEBOOLCONST (false, false);
12111202
1212- /* one null? then distinct */
1213- if (has_null_input )
1214- return MAKEBOOLCONST (true, false);
1215-
1216- /* all constants? then optimize this out */
1203+ /* all constants? then can optimize this out */
12171204if (!has_nonconst_input )
12181205{
1219- Oid result_typeid ;
1220- int16 resultTypLen ;
1221- bool resultTypByVal ;
1222- ExprContext * econtext ;
1223- Datum const_val ;
1224- bool const_is_null ;
1225-
1226- Oper * oper = (Oper * )expr -> oper ;
1227-
1228- replace_opid (oper );/* OK to scribble on input
1229- * to this extent */
1230- result_typeid = oper -> opresulttype ;
1231-
1232- /*
1233- * OK, looks like we can simplify this
1234- * operator/function.
1235- *
1236- * We use the executor's routine ExecEvalExpr() to
1237- * avoid duplication of code and ensure we get the
1238- * same result as the executor would get.
1239- *
1240- * Build a new Expr node containing the
1241- * already-simplified arguments. The only other
1242- * setup needed here is the replace_opid() that we
1243- * already did for the OP_EXPR case.
1244- */
1245- newexpr = makeNode (Expr );
1246- newexpr -> typeOid = expr -> typeOid ;
1247- newexpr -> opType = expr -> opType ;
1248- newexpr -> oper = expr -> oper ;
1249- newexpr -> args = args ;
1250-
1251- /* Get info needed about result datatype */
1252- get_typlenbyval (result_typeid ,& resultTypLen ,& resultTypByVal );
1253-
1254- /*
1255- * It is OK to pass a dummy econtext because none
1256- * of the ExecEvalExpr() code used in this
1257- * situation will use econtext. That might seem
1258- * fortuitous, but it's not so unreasonable --- a
1259- * constant expression does not depend on context,
1260- * by definition, n'est ce pas?
1261- */
1262- econtext = MakeExprContext (NULL ,CurrentMemoryContext );
1263-
1264- const_val = ExecEvalExprSwitchContext ((Node * )newexpr ,econtext ,
1265- & const_is_null ,NULL );
1266-
1267- /*
1268- * Must copy result out of sub-context used by
1269- * expression eval
1270- */
1271- if (!const_is_null )
1272- const_val = datumCopy (const_val ,resultTypByVal ,resultTypLen );
1273-
1274- FreeExprContext (econtext );
1275- pfree (newexpr );
1276-
1277- /*
1278- * Make the constant result node.
1279- */
1280- return (Node * )makeConst (result_typeid ,resultTypLen ,
1281- const_val ,const_is_null ,
1282- resultTypByVal );
1206+ /* all nulls? then not distinct */
1207+ if (all_null_input )
1208+ return MAKEBOOLCONST (false, false);
1209+
1210+ /* one null? then distinct */
1211+ if (has_null_input )
1212+ return MAKEBOOLCONST (true, false);
1213+
1214+ /* otherwise try to evaluate the '=' operator */
1215+ newexpr = simplify_op_or_func (expr ,args );
1216+ if (newexpr )/* successfully simplified it */
1217+ return (Node * )newexpr ;
12831218}
1219+
1220+ /*
1221+ * else fall out to build new Expr node with simplified
1222+ * args
1223+ */
12841224break ;
12851225}
12861226case OR_EXPR :
@@ -1624,21 +1564,21 @@ simplify_op_or_func(Expr *expr, List *args)
16241564 * Note we take the result type from the Oper or Func node, not the
16251565 * pg_proc tuple; probably necessary for binary-compatibility cases.
16261566 */
1627- if (expr -> opType == OP_EXPR )
1567+ if (expr -> opType == FUNC_EXPR )
1568+ {
1569+ Func * func = (Func * )expr -> oper ;
1570+
1571+ funcid = func -> funcid ;
1572+ result_typeid = func -> funcresulttype ;
1573+ }
1574+ else /* OP_EXPR or DISTINCT_EXPR */
16281575{
16291576Oper * oper = (Oper * )expr -> oper ;
16301577
16311578replace_opid (oper );/* OK to scribble on input to this extent */
16321579funcid = oper -> opid ;
16331580result_typeid = oper -> opresulttype ;
16341581}
1635- else
1636- {
1637- Func * func = (Func * )expr -> oper ;
1638-
1639- funcid = func -> funcid ;
1640- result_typeid = func -> funcresulttype ;
1641- }
16421582
16431583/*
16441584 * we could use func_volatile() here, but we need several fields out
@@ -1693,7 +1633,7 @@ simplify_op_or_func(Expr *expr, List *args)
16931633 *
16941634 * Build a new Expr node containing the already-simplified arguments. The
16951635 * only other setup needed here is the replace_opid() that we already
1696- * did for the OP_EXPR case.
1636+ * did for the OP_EXPR/DISTINCT_EXPR case.
16971637 */
16981638newexpr = makeNode (Expr );
16991639newexpr -> typeOid = expr -> typeOid ;