This is an automated email from the ASF dual-hosted git repository.

leborchuk pushed a commit to branch REL_2_STABLE
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 940bab513d924495407d476b0031569ba046ee24
Author: Alena Rybakina <[email protected]>
AuthorDate: Wed Aug 26 13:05:23 2026 +0300

    Reject direct calls to the gp_percentile transition functions
    
    gp_percentile_cont_{float8,interval,timestamp,timestamptz}_transition and
    gp_percentile_disc_transition all read five arguments in C: the running
    transition state plus the four arguments of the gp_percentile_cont() and
    gp_percentile_disc() aggregates.  pg_proc.dat, however, declares them with
    four.  As transition functions they are called correctly, since the executor
    supplies state + 4 arguments regardless of the catalog, but a direct SQL 
call
    reaches past the end of the argument array: PG_GETARG_INT64(4) picks up
    garbage, which yields wrong results, an assertion when the bogus peer count
    makes the code pfree() a NULL pointer, or a segfault.
    
    Correcting the declaration would change the catalog and force an initdb, 
which
    is not acceptable on a stable branch, so check the argument count instead 
and
    raise a plain error.  Direct calls were never useful - the functions only 
make
    sense as the transition step of their aggregates - and 'percentile_* WITHIN
    GROUP' queries are unaffected either way.
    
    Co-authored-by: Georgy Shelkovy <[email protected]>
    
    Ported from Greengage/open-gpdb commit 477b04a (ADBDEV-7770)
---
 src/backend/utils/adt/orderedsetaggs.c   | 22 ++++++++++++++++++++++
 src/test/regress/expected/percentile.out | 24 ++++++++++++++++++++++++
 src/test/regress/sql/percentile.sql      | 14 ++++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/src/backend/utils/adt/orderedsetaggs.c 
b/src/backend/utils/adt/orderedsetaggs.c
index 46b2694d89e..efcadadce05 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -1516,6 +1516,17 @@ gp_percentile_cont_transition(FunctionCallInfo fcinfo,
        int64        first_row;
        int64        second_row;
 
+       /*
+        * Note: 'proargtypes' for this function in pg_proc.dat has 4 arguments.
+        * There are actually 5 arguments coming in here - the result of the
+        * previous call and 4 main arguments.
+        */
+       if (PG_NARGS() != 5)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("wrong number of arguments to 
gp_percentile_cont_transition()"),
+                                errhint("expected 5, got %d", PG_NARGS())));
+
        /* Return state for NULL inputs of val*/
        if (PG_ARGISNULL(1) && !PG_ARGISNULL(0))
                PG_RETURN_DATUM(PG_GETARG_DATUM(0));
@@ -1619,6 +1630,17 @@ gp_percentile_disc_transition(PG_FUNCTION_ARGS)
 {
        int64        rownum;
 
+       /*
+        * Note: 'proargtypes' for this function in pg_proc.dat has 4 arguments.
+        * There are actually 5 arguments coming in here - the result of the
+        * previous call and 4 main arguments.
+        */
+       if (PG_NARGS() != 5)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("wrong number of arguments to 
gp_percentile_disc_transition()"),
+                                errhint("expected 5, got %d", PG_NARGS())));
+
        /* Return state for NULL inputs of val*/
        if (PG_ARGISNULL(1) && !PG_ARGISNULL(0))
                PG_RETURN_DATUM(PG_GETARG_DATUM(0));
diff --git a/src/test/regress/expected/percentile.out 
b/src/test/regress/expected/percentile.out
index c1f4ec69da1..1589d50d8b6 100644
--- a/src/test/regress/expected/percentile.out
+++ b/src/test/regress/expected/percentile.out
@@ -876,6 +876,30 @@ group by d1, d2;
      55 |     1
 (1 row)
 
+--
+-- gp_percentile_cont()/gp_percentile_disc() are the split ordered-set
+-- aggregates that ORCA rewrites percentile_cont()/percentile_disc()/median()
+-- into.  Their transition functions carry the running state on top of the
+-- four aggregate arguments, so they read five arguments, while pg_proc.dat
+-- describes four.  That is left alone here so as not to force an initdb on a
+-- stable branch; instead a direct call, which would read past the end of the
+-- argument array, is rejected.
+--
+select gp_percentile_cont_float8_transition(NULL::float8, 1, 1, 1);
+ERROR:  wrong number of arguments to gp_percentile_cont_transition()
+HINT:  expected 5, got 4
+select gp_percentile_cont_interval_transition(NULL::interval, 1, 1, 1);
+ERROR:  wrong number of arguments to gp_percentile_cont_transition()
+HINT:  expected 5, got 4
+select gp_percentile_cont_timestamp_transition(NULL::timestamp, 1, 1, 1);
+ERROR:  wrong number of arguments to gp_percentile_cont_transition()
+HINT:  expected 5, got 4
+select gp_percentile_cont_timestamptz_transition(NULL::timestamptz, 1, 1, 1);
+ERROR:  wrong number of arguments to gp_percentile_cont_transition()
+HINT:  expected 5, got 4
+select gp_percentile_disc_transition(NULL::numeric, 1, 1, 1);
+ERROR:  wrong number of arguments to gp_percentile_disc_transition()
+HINT:  expected 5, got 4
 drop view percv2;
 drop view percv;
 drop table perct;
diff --git a/src/test/regress/sql/percentile.sql 
b/src/test/regress/sql/percentile.sql
index bc7c327e770..b7b622424e7 100644
--- a/src/test/regress/sql/percentile.sql
+++ b/src/test/regress/sql/percentile.sql
@@ -216,6 +216,20 @@ from  mpp_22413
 where d2 ='55'
 group by d1, d2;
 
+--
+-- gp_percentile_cont()/gp_percentile_disc() are the split ordered-set
+-- aggregates that ORCA rewrites percentile_cont()/percentile_disc()/median()
+-- into.  Their transition functions carry the running state on top of the
+-- four aggregate arguments, so they read five arguments, while pg_proc.dat
+-- describes four.  That is left alone here so as not to force an initdb on a
+-- stable branch; instead a direct call, which would read past the end of the
+-- argument array, is rejected.
+--
+select gp_percentile_cont_float8_transition(NULL::float8, 1, 1, 1);
+select gp_percentile_cont_interval_transition(NULL::interval, 1, 1, 1);
+select gp_percentile_cont_timestamp_transition(NULL::timestamp, 1, 1, 1);
+select gp_percentile_cont_timestamptz_transition(NULL::timestamptz, 1, 1, 1);
+select gp_percentile_disc_transition(NULL::numeric, 1, 1, 1);
 drop view percv2;
 drop view percv;
 drop table perct;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to