|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.179 2005/05/12 20:41:56 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.180 2005/06/26 22:05:36 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -105,6 +105,9 @@ static Datum ExecEvalRow(RowExprState *rstate,
|
105 | 105 | staticDatumExecEvalCoalesce(CoalesceExprState*coalesceExpr,
|
106 | 106 | ExprContext*econtext,
|
107 | 107 | bool*isNull,ExprDoneCond*isDone);
|
| 108 | +staticDatumExecEvalMinMax(MinMaxExprState*minmaxExpr, |
| 109 | +ExprContext*econtext, |
| 110 | +bool*isNull,ExprDoneCond*isDone); |
108 | 111 | staticDatumExecEvalNullIf(FuncExprState*nullIfExpr,
|
109 | 112 | ExprContext*econtext,
|
110 | 113 | bool*isNull,ExprDoneCond*isDone);
|
@@ -2247,6 +2250,63 @@ ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
|
2247 | 2250 | return (Datum)0;
|
2248 | 2251 | }
|
2249 | 2252 |
|
| 2253 | +/* ---------------------------------------------------------------- |
| 2254 | + *ExecEvalMinMax |
| 2255 | + * ---------------------------------------------------------------- |
| 2256 | + */ |
| 2257 | +staticDatum |
| 2258 | +ExecEvalMinMax(MinMaxExprState*minmaxExpr,ExprContext*econtext, |
| 2259 | +bool*isNull,ExprDoneCond*isDone) |
| 2260 | +{ |
| 2261 | +Datumresult= (Datum)0; |
| 2262 | +MinMaxOpop= ((MinMaxExpr*)minmaxExpr->xprstate.expr)->op; |
| 2263 | +FunctionCallInfoDatalocfcinfo; |
| 2264 | +ListCell*arg; |
| 2265 | + |
| 2266 | +if (isDone) |
| 2267 | +*isDone=ExprSingleResult; |
| 2268 | +*isNull= true;/* until we get a result */ |
| 2269 | + |
| 2270 | +InitFunctionCallInfoData(locfcinfo,&minmaxExpr->cfunc,2,NULL,NULL); |
| 2271 | +locfcinfo.argnull[0]= false; |
| 2272 | +locfcinfo.argnull[1]= false; |
| 2273 | + |
| 2274 | +foreach(arg,minmaxExpr->args) |
| 2275 | +{ |
| 2276 | +ExprState*e= (ExprState*)lfirst(arg); |
| 2277 | +Datumvalue; |
| 2278 | +boolvalueIsNull; |
| 2279 | +int32cmpresult; |
| 2280 | + |
| 2281 | +value=ExecEvalExpr(e,econtext,&valueIsNull,NULL); |
| 2282 | +if (valueIsNull) |
| 2283 | +continue;/* ignore NULL inputs */ |
| 2284 | + |
| 2285 | +if (*isNull) |
| 2286 | +{ |
| 2287 | +/* first nonnull input, adopt value */ |
| 2288 | +result=value; |
| 2289 | +*isNull= false; |
| 2290 | +} |
| 2291 | +else |
| 2292 | +{ |
| 2293 | +/* apply comparison function */ |
| 2294 | +locfcinfo.arg[0]=result; |
| 2295 | +locfcinfo.arg[1]=value; |
| 2296 | +locfcinfo.isnull= false; |
| 2297 | +cmpresult=DatumGetInt32(FunctionCallInvoke(&locfcinfo)); |
| 2298 | +if (locfcinfo.isnull)/* probably should not happen */ |
| 2299 | +continue; |
| 2300 | +if (cmpresult>0&&op==IS_LEAST) |
| 2301 | +result=value; |
| 2302 | +elseif (cmpresult<0&&op==IS_GREATEST) |
| 2303 | +result=value; |
| 2304 | +} |
| 2305 | +} |
| 2306 | + |
| 2307 | +returnresult; |
| 2308 | +} |
| 2309 | + |
2250 | 2310 | /* ----------------------------------------------------------------
|
2251 | 2311 | *ExecEvalNullIf
|
2252 | 2312 | *
|
@@ -3206,6 +3266,36 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
3206 | 3266 | state= (ExprState*)cstate;
|
3207 | 3267 | }
|
3208 | 3268 | break;
|
| 3269 | +caseT_MinMaxExpr: |
| 3270 | +{ |
| 3271 | +MinMaxExpr*minmaxexpr= (MinMaxExpr*)node; |
| 3272 | +MinMaxExprState*mstate=makeNode(MinMaxExprState); |
| 3273 | +List*outlist=NIL; |
| 3274 | +ListCell*l; |
| 3275 | +TypeCacheEntry*typentry; |
| 3276 | + |
| 3277 | +mstate->xprstate.evalfunc= (ExprStateEvalFunc)ExecEvalMinMax; |
| 3278 | +foreach(l,minmaxexpr->args) |
| 3279 | +{ |
| 3280 | +Expr*e= (Expr*)lfirst(l); |
| 3281 | +ExprState*estate; |
| 3282 | + |
| 3283 | +estate=ExecInitExpr(e,parent); |
| 3284 | +outlist=lappend(outlist,estate); |
| 3285 | +} |
| 3286 | +mstate->args=outlist; |
| 3287 | +/* Look up the btree comparison function for the datatype */ |
| 3288 | +typentry=lookup_type_cache(minmaxexpr->minmaxtype, |
| 3289 | +TYPECACHE_CMP_PROC); |
| 3290 | +if (!OidIsValid(typentry->cmp_proc)) |
| 3291 | +ereport(ERROR, |
| 3292 | +(errcode(ERRCODE_UNDEFINED_FUNCTION), |
| 3293 | +errmsg("could not identify a comparison function for type %s", |
| 3294 | +format_type_be(minmaxexpr->minmaxtype)))); |
| 3295 | +fmgr_info(typentry->cmp_proc,&(mstate->cfunc)); |
| 3296 | +state= (ExprState*)mstate; |
| 3297 | +} |
| 3298 | +break; |
3209 | 3299 | caseT_NullIfExpr:
|
3210 | 3300 | {
|
3211 | 3301 | NullIfExpr*nullifexpr= (NullIfExpr*)node;
|
|