8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
* HISTORY
14
14
* AUTHOR DATE MAJOR EVENT
@@ -98,25 +98,19 @@ make_clause(int type, Node *oper, List *args)
98
98
*
99
99
* Returns t iff the clause is an operator clause:
100
100
* (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.]
105
101
*/
106
102
bool
107
103
is_opclause (Node * clause )
108
104
{
109
105
return (clause != NULL &&
110
106
IsA (clause , Expr ) &&
111
- ((((Expr * ) clause )-> opType == OP_EXPR ) ||
112
- ((Expr * ) clause )-> opType == DISTINCT_EXPR ));
107
+ ((Expr * ) clause )-> opType == OP_EXPR );
113
108
}
114
109
115
110
/*
116
111
* 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).
120
114
*/
121
115
Expr *
122
116
make_opclause (Oper * op , Var * leftop , Var * rightop )
@@ -1191,10 +1185,10 @@ eval_const_expressions_mutator(Node *node, void *context)
1191
1185
bool has_nonconst_input = false;
1192
1186
1193
1187
/*
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.
1196
1191
*/
1197
- Assert (length (args ) == 2 );
1198
1192
foreach (arg , args )
1199
1193
{
1200
1194
if (IsA (lfirst (arg ), Const ))
@@ -1205,82 +1199,28 @@ eval_const_expressions_mutator(Node *node, void *context)
1205
1199
else
1206
1200
has_nonconst_input = true;
1207
1201
}
1208
- /* all nulls? then not distinct */
1209
- if (all_null_input )
1210
- return MAKEBOOLCONST (false, false);
1211
1202
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 */
1217
1204
if (!has_nonconst_input )
1218
1205
{
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 ;
1283
1218
}
1219
+
1220
+ /*
1221
+ * else fall out to build new Expr node with simplified
1222
+ * args
1223
+ */
1284
1224
break ;
1285
1225
}
1286
1226
case OR_EXPR :
@@ -1624,21 +1564,21 @@ simplify_op_or_func(Expr *expr, List *args)
1624
1564
* Note we take the result type from the Oper or Func node, not the
1625
1565
* pg_proc tuple; probably necessary for binary-compatibility cases.
1626
1566
*/
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 */
1628
1575
{
1629
1576
Oper * oper = (Oper * ) expr -> oper ;
1630
1577
1631
1578
replace_opid (oper ); /* OK to scribble on input to this extent */
1632
1579
funcid = oper -> opid ;
1633
1580
result_typeid = oper -> opresulttype ;
1634
1581
}
1635
- else
1636
- {
1637
- Func * func = (Func * ) expr -> oper ;
1638
-
1639
- funcid = func -> funcid ;
1640
- result_typeid = func -> funcresulttype ;
1641
- }
1642
1582
1643
1583
/*
1644
1584
* we could use func_volatile() here, but we need several fields out
@@ -1693,7 +1633,7 @@ simplify_op_or_func(Expr *expr, List *args)
1693
1633
*
1694
1634
* Build a new Expr node containing the already-simplified arguments. The
1695
1635
* 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.
1697
1637
*/
1698
1638
newexpr = makeNode (Expr );
1699
1639
newexpr -> typeOid = expr -> typeOid ;
0 commit comments