88 *
99 *
1010 * 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 $
1212 *
1313 * HISTORY
1414 * AUTHORDATEMAJOR EVENT
@@ -98,7 +98,8 @@ static Expr *simplify_function(Oid funcid,
9898bool allow_inline ,
9999eval_const_expressions_context * context );
100100static List * add_function_defaults (List * args ,Oid result_type ,
101- HeapTuple func_tuple );
101+ HeapTuple func_tuple ,
102+ eval_const_expressions_context * context );
102103static Expr * evaluate_function (Oid funcid ,
103104Oid result_type ,int32 result_typmod ,List * args ,
104105HeapTuple func_tuple ,
@@ -3279,7 +3280,7 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
32793280
32803281/* While we have the tuple, check if we need to add defaults */
32813282if (((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 );
32833284
32843285newexpr = evaluate_function (funcid ,result_type ,result_typmod ,* args ,
32853286func_tuple ,context );
@@ -3302,9 +3303,11 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
33023303 * just like the parser did.
33033304 */
33043305static 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 )
33063308{
33073309Form_pg_proc funcform = (Form_pg_proc )GETSTRUCT (func_tuple );
3310+ int nargsprovided = list_length (args );
33083311Datum proargdefaults ;
33093312bool isnull ;
33103313char * str ;
@@ -3327,7 +3330,7 @@ add_function_defaults(List *args, Oid result_type, HeapTuple func_tuple)
33273330Assert (IsA (defaults ,List ));
33283331pfree (str );
33293332/* 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 ;
33313334if (ndelete < 0 )
33323335elog (ERROR ,"not enough default arguments" );
33333336while (ndelete -- > 0 )
@@ -3337,8 +3340,8 @@ add_function_defaults(List *args, Oid result_type, HeapTuple func_tuple)
33373340Assert (list_length (args )== funcform -> pronargs );
33383341
33393342/*
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.
33423345 */
33433346if (list_length (args )> FUNC_MAX_ARGS )
33443347elog (ERROR ,"too many function arguments" );
@@ -3361,6 +3364,20 @@ add_function_defaults(List *args, Oid result_type, HeapTuple func_tuple)
33613364/* perform any necessary typecasting of arguments */
33623365make_fn_arguments (NULL ,args ,actual_arg_types ,declared_arg_types );
33633366
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+
33643381return args ;
33653382}
33663383