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
* AUTHORDATEMAJOR 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
- * Therest of this should be a no-op if there are no polymorphic
3341
- *arguments, but we do it anyway to be sure.
3343
+ * Thenext 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