88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.66 2000/04/16 01:55:45 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.67 2000/05/28 20:33:28 tgl Exp $
1212 *
1313 * HISTORY
1414 * AUTHORDATEMAJOR EVENT
@@ -1307,7 +1307,7 @@ eval_const_expressions_mutator(Node *node, void *context)
13071307 * the expression here. This would avoid much runtime overhead, and perhaps
13081308 * expose opportunities for constant-folding within the expression even if
13091309 * not all the func's input args are constants. It'd be appropriate to do
1310- * here, and not in the parser, since we wouldn't want it to happen until
1310+ *that here, not in the parser, since we wouldn't want it to happen until
13111311 * after rule substitution/rewriting.
13121312 */
13131313static Expr *
@@ -1321,26 +1321,38 @@ simplify_op_or_func(Expr *expr, List *args)
13211321Type resultType ;
13221322Expr * newexpr ;
13231323Datum const_val ;
1324+ bool has_nonconst_input = false;
1325+ bool has_null_input = false;
13241326bool const_is_null ;
13251327bool isDone ;
13261328
13271329/*
1328- * For an operator or function, we cannot simplify unless all the
1329- * inputs are constants. (XXX possible future improvement: if the
1330- * op/func is strict and at least one input is NULL, we could simplify
1331- * to NULL. But we do not currently have any way to know if the
1332- * op/func is strict or not. For now, a NULL input is treated the
1333- * same as any other constant node.)
1330+ * Check for constant inputs and especially constant-NULL inputs.
13341331 */
13351332foreach (arg ,args )
13361333{
1337- if (!IsA (lfirst (arg ),Const ))
1338- return NULL ;
1334+ if (IsA (lfirst (arg ),Const ))
1335+ has_null_input |= ((Const * )lfirst (arg ))-> constisnull ;
1336+ else
1337+ has_nonconst_input = true;
13391338}
13401339
1340+ /*
1341+ * If the function is strict and has a constant-NULL input, it will
1342+ * never be called at all, so we can replace the call by a NULL
1343+ * constant even if there are other inputs that aren't constant.
1344+ * Otherwise, we can only simplify if all inputs are constants.
1345+ * We can skip the function lookup if neither case applies.
1346+ */
1347+ if (has_nonconst_input && !has_null_input )
1348+ return NULL ;
1349+
13411350/*
13421351 * Get the function procedure's OID and look to see whether it is
13431352 * marked proiscachable.
1353+ *
1354+ * XXX would it be better to take the result type from the pg_proc tuple,
1355+ * rather than the Oper or Func node?
13441356 */
13451357if (expr -> opType == OP_EXPR )
13461358{
@@ -1373,6 +1385,31 @@ simplify_op_or_func(Expr *expr, List *args)
13731385if (funcform -> proretset )
13741386return NULL ;
13751387
1388+ /*
1389+ * Now that we know if the function is strict, we can finish the
1390+ * checks for simplifiable inputs that we started above.
1391+ */
1392+ if (funcform -> proisstrict && has_null_input )
1393+ {
1394+ /*
1395+ * It's strict and has NULL input, so must produce NULL output.
1396+ * Return a NULL constant of the right type.
1397+ */
1398+ resultType = typeidType (result_typeid );
1399+ return (Expr * )makeConst (result_typeid ,typeLen (resultType ),
1400+ (Datum )0 , true,
1401+ typeByVal (resultType ),
1402+ false, false);
1403+ }
1404+
1405+ /*
1406+ * Otherwise, can simplify only if all inputs are constants.
1407+ * (For a non-strict function, constant NULL inputs are treated
1408+ * the same as constant non-NULL inputs.)
1409+ */
1410+ if (has_nonconst_input )
1411+ return NULL ;
1412+
13761413/*
13771414 * OK, looks like we can simplify this operator/function.
13781415 *
@@ -1402,9 +1439,6 @@ simplify_op_or_func(Expr *expr, List *args)
14021439
14031440/*
14041441 * Make the constant result node.
1405- *
1406- * XXX would it be better to take the result type from the pg_proc tuple,
1407- * rather than the Oper or Func node?
14081442 */
14091443resultType = typeidType (result_typeid );
14101444return (Expr * )makeConst (result_typeid ,typeLen (resultType ),