@@ -396,8 +396,9 @@ static Node *processIndirection(Node *node, deparse_context *context,
396
396
static void printSubscripts (ArrayRef * aref , deparse_context * context );
397
397
static char * get_relation_name (Oid relid );
398
398
static char * generate_relation_name (Oid relid , List * namespaces );
399
- static char * generate_function_name (Oid funcid , int nargs , List * argnames ,
400
- Oid * argtypes , bool * is_variadic );
399
+ static char * generate_function_name (Oid funcid , int nargs ,
400
+ List * argnames , Oid * argtypes ,
401
+ bool was_variadic , bool * use_variadic_p );
401
402
static char * generate_operator_name (Oid operid , Oid arg1 , Oid arg2 );
402
403
static text * string_to_text (char * str );
403
404
static char * flatten_reloptions (Oid relid );
@@ -858,7 +859,8 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
858
859
859
860
appendStringInfo (& buf , "EXECUTE PROCEDURE %s(" ,
860
861
generate_function_name (trigrec -> tgfoid , 0 ,
861
- NIL , NULL , NULL ));
862
+ NIL , NULL ,
863
+ false, NULL ));
862
864
863
865
if (trigrec -> tgnargs > 0 )
864
866
{
@@ -7269,7 +7271,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
7269
7271
Oid argtypes [FUNC_MAX_ARGS ];
7270
7272
int nargs ;
7271
7273
List * argnames ;
7272
- bool is_variadic ;
7274
+ bool use_variadic ;
7273
7275
ListCell * l ;
7274
7276
7275
7277
/*
@@ -7327,13 +7329,14 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
7327
7329
appendStringInfo (buf , "%s(" ,
7328
7330
generate_function_name (funcoid , nargs ,
7329
7331
argnames , argtypes ,
7330
- & is_variadic ));
7332
+ expr -> funcvariadic ,
7333
+ & use_variadic ));
7331
7334
nargs = 0 ;
7332
7335
foreach (l , expr -> args )
7333
7336
{
7334
7337
if (nargs ++ > 0 )
7335
7338
appendStringInfoString (buf , ", " );
7336
- if (is_variadic && lnext (l ) == NULL )
7339
+ if (use_variadic && lnext (l ) == NULL )
7337
7340
appendStringInfoString (buf , "VARIADIC " );
7338
7341
get_rule_expr ((Node * ) lfirst (l ), context , true);
7339
7342
}
@@ -7374,7 +7377,8 @@ get_agg_expr(Aggref *aggref, deparse_context *context)
7374
7377
7375
7378
appendStringInfo (buf , "%s(%s" ,
7376
7379
generate_function_name (aggref -> aggfnoid , nargs ,
7377
- NIL , argtypes , NULL ),
7380
+ NIL , argtypes ,
7381
+ false, NULL ),
7378
7382
(aggref -> aggdistinct != NIL ) ? "DISTINCT " : "" );
7379
7383
/* aggstar can be set only in zero-argument aggregates */
7380
7384
if (aggref -> aggstar )
@@ -7416,7 +7420,8 @@ get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context)
7416
7420
7417
7421
appendStringInfo (buf , "%s(" ,
7418
7422
generate_function_name (wfunc -> winfnoid , nargs ,
7419
- NIL , argtypes , NULL ));
7423
+ NIL , argtypes ,
7424
+ false, NULL ));
7420
7425
/* winstar can be set only in zero-argument aggregates */
7421
7426
if (wfunc -> winstar )
7422
7427
appendStringInfoChar (buf , '*' );
@@ -8507,18 +8512,25 @@ generate_relation_name(Oid relid, List *namespaces)
8507
8512
* given that it is being called with the specified actual arg names and
8508
8513
* types. (Those matter because of ambiguous-function resolution rules.)
8509
8514
*
8510
- * The result includes all necessary quoting and schema-prefixing. We can
8511
- * also pass back an indication of whether the function is variadic.
8515
+ * If we're dealing with a potentially variadic function (in practice, this
8516
+ * means a FuncExpr and not some other way of calling the function), then
8517
+ * was_variadic must specify whether VARIADIC appeared in the original call,
8518
+ * and *use_variadic_p will be set to indicate whether to print VARIADIC in
8519
+ * the output. For non-FuncExpr cases, was_variadic should be FALSE and
8520
+ * use_variadic_p can be NULL.
8521
+ *
8522
+ * The result includes all necessary quoting and schema-prefixing.
8512
8523
*/
8513
8524
static char *
8514
- generate_function_name (Oid funcid , int nargs , List * argnames ,
8515
- Oid * argtypes , bool * is_variadic )
8525
+ generate_function_name (Oid funcid , int nargs , List * argnames , Oid * argtypes ,
8526
+ bool was_variadic , bool * use_variadic_p )
8516
8527
{
8528
+ char * result ;
8517
8529
HeapTuple proctup ;
8518
8530
Form_pg_proc procform ;
8519
8531
char * proname ;
8532
+ bool use_variadic ;
8520
8533
char * nspname ;
8521
- char * result ;
8522
8534
FuncDetailCode p_result ;
8523
8535
Oid p_funcid ;
8524
8536
Oid p_rettype ;
@@ -8532,15 +8544,47 @@ generate_function_name(Oid funcid, int nargs, List *argnames,
8532
8544
procform = (Form_pg_proc ) GETSTRUCT (proctup );
8533
8545
proname = NameStr (procform -> proname );
8534
8546
8547
+ /*
8548
+ * Determine whether VARIADIC should be printed. We must do this first
8549
+ * since it affects the lookup rules in func_get_detail().
8550
+ *
8551
+ * Currently, we always print VARIADIC if the function is variadic and
8552
+ * takes a variadic type other than ANY. (In principle, if VARIADIC
8553
+ * wasn't originally specified and the array actual argument is
8554
+ * deconstructable, we could print the array elements separately and not
8555
+ * print VARIADIC, thus more nearly reproducing the original input. For
8556
+ * the moment that seems like too much complication for the benefit.)
8557
+ * However, if the function takes VARIADIC ANY, then the parser didn't
8558
+ * fold the arguments together into an array, so we must print VARIADIC if
8559
+ * and only if it was used originally.
8560
+ */
8561
+ if (use_variadic_p )
8562
+ {
8563
+ if (OidIsValid (procform -> provariadic ))
8564
+ {
8565
+ if (procform -> provariadic != ANYOID )
8566
+ use_variadic = true;
8567
+ else
8568
+ use_variadic = was_variadic ;
8569
+ }
8570
+ else
8571
+ use_variadic = false;
8572
+ * use_variadic_p = use_variadic ;
8573
+ }
8574
+ else
8575
+ {
8576
+ Assert (!was_variadic );
8577
+ use_variadic = false;
8578
+ }
8579
+
8535
8580
/*
8536
8581
* The idea here is to schema-qualify only if the parser would fail to
8537
8582
* resolve the correct function given the unqualified func name with the
8538
- * specified argtypes. If the function is variadic, we should presume
8539
- * that VARIADIC will be included in the call.
8583
+ * specified argtypes and VARIADIC flag.
8540
8584
*/
8541
8585
p_result = func_get_detail (list_make1 (makeString (proname )),
8542
8586
NIL , argnames , nargs , argtypes ,
8543
- !OidIsValid ( procform -> provariadic ) , true,
8587
+ !use_variadic , true,
8544
8588
& p_funcid , & p_rettype ,
8545
8589
& p_retset , & p_nvargs , & p_true_typeids , NULL );
8546
8590
if ((p_result == FUNCDETAIL_NORMAL ||
@@ -8553,17 +8597,6 @@ generate_function_name(Oid funcid, int nargs, List *argnames,
8553
8597
8554
8598
result = quote_qualified_identifier (nspname , proname );
8555
8599
8556
- /* Check variadic-ness if caller cares */
8557
- if (is_variadic )
8558
- {
8559
- /* "any" variadics are not treated as variadics for listing */
8560
- if (OidIsValid (procform -> provariadic ) &&
8561
- procform -> provariadic != ANYOID )
8562
- * is_variadic = true;
8563
- else
8564
- * is_variadic = false;
8565
- }
8566
-
8567
8600
ReleaseSysCache (proctup );
8568
8601
8569
8602
return result ;
0 commit comments