8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.273 2009/01/01 17 :23:44 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.274 2009/01/06 01 :23:21 tgl Exp $
12
12
*
13
13
* HISTORY
14
14
* AUTHOR DATE MAJOR EVENT
@@ -98,7 +98,8 @@ static Expr *simplify_function(Oid funcid,
98
98
bool allow_inline ,
99
99
eval_const_expressions_context * context );
100
100
static List * add_function_defaults (List * args , Oid result_type ,
101
- HeapTuple func_tuple );
101
+ HeapTuple func_tuple ,
102
+ eval_const_expressions_context * context );
102
103
static Expr * evaluate_function (Oid funcid ,
103
104
Oid result_type , int32 result_typmod , List * args ,
104
105
HeapTuple func_tuple ,
@@ -3279,7 +3280,7 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
3279
3280
3280
3281
/* While we have the tuple, check if we need to add defaults */
3281
3282
if (((Form_pg_proc ) GETSTRUCT (func_tuple ))-> pronargs > list_length (* args ))
3282
- * args = add_function_defaults (* args , result_type , func_tuple );
3283
+ * args = add_function_defaults (* args , result_type , func_tuple , context );
3283
3284
3284
3285
newexpr = evaluate_function (funcid , result_type , result_typmod , * args ,
3285
3286
func_tuple , context );
@@ -3302,9 +3303,11 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
3302
3303
* just like the parser did.
3303
3304
*/
3304
3305
static List *
3305
- add_function_defaults (List * args , Oid result_type , HeapTuple func_tuple )
3306
+ add_function_defaults (List * args , Oid result_type , HeapTuple func_tuple ,
3307
+ eval_const_expressions_context * context )
3306
3308
{
3307
3309
Form_pg_proc funcform = (Form_pg_proc ) GETSTRUCT (func_tuple );
3310
+ int nargsprovided = list_length (args );
3308
3311
Datum proargdefaults ;
3309
3312
bool isnull ;
3310
3313
char * str ;
@@ -3327,7 +3330,7 @@ add_function_defaults(List *args, Oid result_type, HeapTuple func_tuple)
3327
3330
Assert (IsA (defaults , List ));
3328
3331
pfree (str );
3329
3332
/* Delete any unused defaults from the list */
3330
- ndelete = list_length ( args ) + list_length (defaults ) - funcform -> pronargs ;
3333
+ ndelete = nargsprovided + list_length (defaults ) - funcform -> pronargs ;
3331
3334
if (ndelete < 0 )
3332
3335
elog (ERROR , "not enough default arguments" );
3333
3336
while (ndelete -- > 0 )
@@ -3337,8 +3340,8 @@ add_function_defaults(List *args, Oid result_type, HeapTuple func_tuple)
3337
3340
Assert (list_length (args ) == funcform -> pronargs );
3338
3341
3339
3342
/*
3340
- * The rest of this should be a no-op if there are no polymorphic
3341
- * arguments, but we do it anyway to be sure.
3343
+ * The next part should be a no-op if there are no polymorphic arguments,
3344
+ * but we do it anyway to be sure.
3342
3345
*/
3343
3346
if (list_length (args ) > FUNC_MAX_ARGS )
3344
3347
elog (ERROR , "too many function arguments" );
@@ -3361,6 +3364,20 @@ add_function_defaults(List *args, Oid result_type, HeapTuple func_tuple)
3361
3364
/* perform any necessary typecasting of arguments */
3362
3365
make_fn_arguments (NULL , args , actual_arg_types , declared_arg_types );
3363
3366
3367
+ /*
3368
+ * Lastly, we have to recursively simplify the arguments we just added
3369
+ * (but don't recurse on the ones passed in, as we already did those).
3370
+ * This isn't merely an optimization, it's *necessary* since there could
3371
+ * be functions with defaulted arguments down in there.
3372
+ */
3373
+ foreach (lc , args )
3374
+ {
3375
+ if (nargsprovided -- > 0 )
3376
+ continue ; /* skip original arg positions */
3377
+ lfirst (lc ) = eval_const_expressions_mutator ((Node * ) lfirst (lc ),
3378
+ context );
3379
+ }
3380
+
3364
3381
return args ;
3365
3382
}
3366
3383
0 commit comments