Обсуждение: pgsql: Declare assorted array functions using anycompatible not anyelem

Поиск
Список
Период
Сортировка

pgsql: Declare assorted array functions using anycompatible not anyelem

От
Tom Lane
Дата:
Declare assorted array functions using anycompatible not anyelement.

Convert array_append, array_prepend, array_cat, array_position,
array_positions, array_remove, array_replace, and width_bucket
to use anycompatiblearray.  This is a simple extension of commit
5c292e6b9 to hit some other places where there's a pretty obvious
gain in usability from doing so.

Ideally we'd also modify other functions taking multiple old-style
polymorphic arguments.  But most of the remainder are tied into one
or more operator classes, making any such change a much larger can of
worms than I desire to open right now.

Discussion: https://postgr.es/m/77675130-89da-dab1-51dd-492c93dcf5d1@postgresfriends.org

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/9e38c2bb5093ceb0c04d6315ccd8975bd17add66

Modified Files
--------------
doc/src/sgml/func.sgml                     | 50 ++++++++++++++++--------------
doc/src/sgml/xaggr.sgml                    |  4 +--
src/include/catalog/catversion.h           |  2 +-
src/include/catalog/pg_operator.dat        | 13 ++++----
src/include/catalog/pg_proc.dat            | 40 +++++++++++++++---------
src/test/regress/expected/arrays.out       | 12 +++++++
src/test/regress/expected/polymorphism.out | 10 +++---
src/test/regress/sql/arrays.sql            |  2 ++
src/test/regress/sql/polymorphism.sql      | 10 +++---
9 files changed, 86 insertions(+), 57 deletions(-)


Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Andrew Dunstan
Дата:
On 11/4/20 4:10 PM, Tom Lane wrote:
> Declare assorted array functions using anycompatible not anyelement.
>
> Convert array_append, array_prepend, array_cat, array_position,
> array_positions, array_remove, array_replace, and width_bucket
> to use anycompatiblearray.  This is a simple extension of commit
> 5c292e6b9 to hit some other places where there's a pretty obvious
> gain in usability from doing so.
>
> Ideally we'd also modify other functions taking multiple old-style
> polymorphic arguments.  But most of the remainder are tied into one
> or more operator classes, making any such change a much larger can of
> worms than I desire to open right now.
>
> Discussion: https://postgr.es/m/77675130-89da-dab1-51dd-492c93dcf5d1@postgresfriends.org
>


This patch broke cross-version pg_upgrade testing. I have cured crake
for the moment by having it execute this in the source database:

    drop aggregate if exists public.array_cat_accum(anyarray);
    drop aggregate if exists public.first_el_agg_any(anyelement);

But I wonder if we really want to make it impossible to upgrade
databases with aggregates that contain these functions?


cheers


andrew




Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Tom Lane
Дата:
Andrew Dunstan <andrew@dunslane.net> writes:
> On 11/4/20 4:10 PM, Tom Lane wrote:
>> Declare assorted array functions using anycompatible not anyelement.

> This patch broke cross-version pg_upgrade testing.

Uh, yeah ... didn't you get my two prior messages about that?

> I have cured crake
> for the moment by having it execute this in the source database:

I think probably the right fix is just to change that test case to
use a different implementation function, per [1].  I'm holding off
pushing the fix till after this week's wraps, though.

> But I wonder if we really want to make it impossible to upgrade
> databases with aggregates that contain these functions?

If I thought that user-defined aggregates relying on array_cat were
really a thing (and not just a test case), I'd be more concerned about
this.  But it's hard to see why users shouldn't use array_agg() instead
of rolling their own.

            regards, tom lane

[1] https://www.postgresql.org/message-id/1915573.1604879242%40sss.pgh.pa.us



Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Andrew Dunstan
Дата:
On 11/9/20 4:29 PM, Tom Lane wrote:
> Andrew Dunstan <andrew@dunslane.net> writes:
>> On 11/4/20 4:10 PM, Tom Lane wrote:
>>> Declare assorted array functions using anycompatible not anyelement.
>> This patch broke cross-version pg_upgrade testing.
> Uh, yeah ... didn't you get my two prior messages about that?



Yes, I did, although by the time you sent them out I'd already modified
crake.



>
>> I have cured crake
>> for the moment by having it execute this in the source database:
> I think probably the right fix is just to change that test case to
> use a different implementation function, per [1].  I'm holding off
> pushing the fix till after this week's wraps, though.



I'd be ok with that. Can we devise a fix that will work all the way back
to 9.2, which is where we start upgrade testing?


>
>> But I wonder if we really want to make it impossible to upgrade
>> databases with aggregates that contain these functions?
> If I thought that user-defined aggregates relying on array_cat were
> really a thing (and not just a test case), I'd be more concerned about
> this.  But it's hard to see why users shouldn't use array_agg() instead
> of rolling their own.
>
>     



Possibly something that's been migrated from before we had array_agg.


cheers


andrew






Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Tom Lane
Дата:
Andrew Dunstan <andrew@dunslane.net> writes:
> On 11/9/20 4:29 PM, Tom Lane wrote:
>> I think probably the right fix is just to change that test case to
>> use a different implementation function, per [1].  I'm holding off
>> pushing the fix till after this week's wraps, though.

> I'd be ok with that. Can we devise a fix that will work all the way back
> to 9.2, which is where we start upgrade testing?

Hm.  To fix it this way, we'd have to push the test-script change
into the pre-9.5 branches.  There's no technical reason we can't do
that, I don't think, though it's a bit outside our normal practices.

>> If I thought that user-defined aggregates relying on array_cat were
>> really a thing (and not just a test case), I'd be more concerned about
>> this.  But it's hard to see why users shouldn't use array_agg() instead
>> of rolling their own.

> Possibly something that's been migrated from before we had array_agg.

array_agg goes back to 8.4, and for at least most of that time it's
been very much more efficient than anything based on array_cat.  So I
think it's past time to push any such laggards into the 21st century.

            regards, tom lane



Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Andrew Dunstan
Дата:
On 11/9/20 5:15 PM, Tom Lane wrote:
> Andrew Dunstan <andrew@dunslane.net> writes:
>> On 11/9/20 4:29 PM, Tom Lane wrote:
>>> I think probably the right fix is just to change that test case to
>>> use a different implementation function, per [1].  I'm holding off
>>> pushing the fix till after this week's wraps, though.
>> I'd be ok with that. Can we devise a fix that will work all the way back
>> to 9.2, which is where we start upgrade testing?
> Hm.  To fix it this way, we'd have to push the test-script change
> into the pre-9.5 branches.  There's no technical reason we can't do
> that, I don't think, though it's a bit outside our normal practices.



I doubt it's necessary. We have provision for adjusting the source
database before we try to upgrade it. Let me know exactly what you have
in mind and I'll try to make it work without having to mangle the
supposedly frozen back branches.


We don't actually run the regression suite regularly for non-live
branches, we just try to upgrade a completely static data dir.



>
>>> If I thought that user-defined aggregates relying on array_cat were
>>> really a thing (and not just a test case), I'd be more concerned about
>>> this.  But it's hard to see why users shouldn't use array_agg() instead
>>> of rolling their own.
>> Possibly something that's been migrated from before we had array_agg.
> array_agg goes back to 8.4, and for at least most of that time it's
> been very much more efficient than anything based on array_cat.  So I
> think it's past time to push any such laggards into the 21st century.
>
>             



fair enough


cheers


andrew




Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Tom Lane
Дата:
Andrew Dunstan <andrew@dunslane.net> writes:
> On 11/9/20 5:15 PM, Tom Lane wrote:
>> Hm.  To fix it this way, we'd have to push the test-script change
>> into the pre-9.5 branches.  There's no technical reason we can't do
>> that, I don't think, though it's a bit outside our normal practices.

> I doubt it's necessary. We have provision for adjusting the source
> database before we try to upgrade it. Let me know exactly what you have
> in mind and I'll try to make it work without having to mangle the
> supposedly frozen back branches.

> We don't actually run the regression suite regularly for non-live
> branches, we just try to upgrade a completely static data dir.

What I have in mind to apply to 9.5 through 13 is per attached.
You could either redefine the aggregate similarly in 9.2-9.4,
or just drop it.  I doubt the latter leads to any interesting
loss of coverage for xversion upgrade, as there's plenty of other
user-defined aggregates in the regression database.

            regards, tom lane

diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out
index 1ff40764d9..980e2e861c 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -729,24 +729,24 @@ select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;
 (5 rows)

 -- another sort of polymorphic aggregate
-CREATE AGGREGATE array_cat_accum (anyarray)
+CREATE AGGREGATE array_larger_accum (anyarray)
 (
-    sfunc = array_cat,
+    sfunc = array_larger,
     stype = anyarray,
     initcond = '{}'
 );
-SELECT array_cat_accum(i)
+SELECT array_larger_accum(i)
 FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i);
- array_cat_accum
------------------
- {1,2,3,4}
+ array_larger_accum
+--------------------
+ {3,4}
 (1 row)

-SELECT array_cat_accum(i)
+SELECT array_larger_accum(i)
 FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i);
-          array_cat_accum
------------------------------------
- {"(1,2)","(3,4)","(5,6)","(7,8)"}
+ array_larger_accum
+--------------------
+ {"(5,6)","(7,8)"}
 (1 row)

 -- another kind of polymorphic aggregate
diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql
index e5222f1f81..15b8dfc6ce 100644
--- a/src/test/regress/sql/polymorphism.sql
+++ b/src/test/regress/sql/polymorphism.sql
@@ -498,17 +498,17 @@ select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;

 -- another sort of polymorphic aggregate

-CREATE AGGREGATE array_cat_accum (anyarray)
+CREATE AGGREGATE array_larger_accum (anyarray)
 (
-    sfunc = array_cat,
+    sfunc = array_larger,
     stype = anyarray,
     initcond = '{}'
 );

-SELECT array_cat_accum(i)
+SELECT array_larger_accum(i)
 FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i);

-SELECT array_cat_accum(i)
+SELECT array_larger_accum(i)
 FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i);

 -- another kind of polymorphic aggregate

Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Andrew Dunstan
Дата:
On 11/9/20 5:41 PM, Tom Lane wrote:
>
> What I have in mind to apply to 9.5 through 13 is per attached.
> You could either redefine the aggregate similarly in 9.2-9.4,
> or just drop it.  I doubt the latter leads to any interesting
> loss of coverage for xversion upgrade, as there's plenty of other
> user-defined aggregates in the regression database.



You also need to modify first_el_agg_any.


Here's what I have working on crake::


        if ($oversion le 'REL9_4_STABLE')
        {
            # this is to be fixed in 9.5 and later
            $prstmt = join(';',
                           'drop aggregate if exists
public.array_cat_accum(anyarray)',
                           'CREATE AGGREGATE array_larger_accum
(anyarray) ' .
                           ' ( ' .
                           '   sfunc = array_larger, ' .
                           '   stype = anyarray, ' .
                           '   initcond = $${}$$ ' .
                           '  ) ' );
            system( "$other_branch/inst/bin/psql -X -e "
                      . " -c '" . $prstmt . "' "
                      . "regression "
                      . ">> '$upgrade_loc/$oversion-copy.log' 2>&1");
            return if $?;
        }
        # drop this branch when upstream is renovated
        else
        {
            $prstmt = join(';',
                          'drop aggregate if exists
public.array_cat_accum(anyarray)',
                          'drop aggregate if exists
public.first_el_agg_any(anyelement)');
            system( "$other_branch/inst/bin/psql -X -e "
                      . " -c '$prstmt' "
                      . "regression "
                      . ">> '$upgrade_loc/$oversion-copy.log' 2>&1");
            return if $?;
        }


When you fix the live branches I'll delete the "else" branch and push
the change to the git repo.


cheers


andrew








Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Tom Lane
Дата:
Andrew Dunstan <andrew@dunslane.net> writes:
> On 11/9/20 5:41 PM, Tom Lane wrote:
>> What I have in mind to apply to 9.5 through 13 is per attached.

> You also need to modify first_el_agg_any.

... doh.  That one is a little messier because there's no equally useful
substitute function.  What I'm inclined to do for that is to add a
SQL-language wrapper to reproduce the old signature for array_append.
As attached.  (I'm keeping this separate from the other patch, since
this doesn't go back as far.)

> Here's what I have working on crake::

OK.

            regards, tom lane

diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out
index 2c3bb0a60b..628a39612a 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -786,16 +786,18 @@ create aggregate build_group(int8, integer) (
   STYPE = int8[]
 );
 -- check proper resolution of data types for polymorphic transfn/finalfn
-create function first_el(anycompatiblearray) returns anycompatible as
+create function first_el_transfn(anyarray, anyelement) returns anyarray as
+'select $1 || $2' language sql immutable;
+create function first_el(anyarray) returns anyelement as
 'select $1[1]' language sql strict immutable;
 create aggregate first_el_agg_f8(float8) (
   SFUNC = array_append,
   STYPE = float8[],
   FINALFUNC = first_el
 );
-create aggregate first_el_agg_any(anycompatible) (
-  SFUNC = array_append,
-  STYPE = anycompatiblearray,
+create aggregate first_el_agg_any(anyelement) (
+  SFUNC = first_el_transfn,
+  STYPE = anyarray,
   FINALFUNC = first_el
 );
 select first_el_agg_f8(x::float8) from generate_series(1,10) x;
diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql
index 70a21c8978..d98a74c3f6 100644
--- a/src/test/regress/sql/polymorphism.sql
+++ b/src/test/regress/sql/polymorphism.sql
@@ -549,7 +549,10 @@ create aggregate build_group(int8, integer) (

 -- check proper resolution of data types for polymorphic transfn/finalfn

-create function first_el(anycompatiblearray) returns anycompatible as
+create function first_el_transfn(anyarray, anyelement) returns anyarray as
+'select $1 || $2' language sql immutable;
+
+create function first_el(anyarray) returns anyelement as
 'select $1[1]' language sql strict immutable;

 create aggregate first_el_agg_f8(float8) (
@@ -558,9 +561,9 @@ create aggregate first_el_agg_f8(float8) (
   FINALFUNC = first_el
 );

-create aggregate first_el_agg_any(anycompatible) (
-  SFUNC = array_append,
-  STYPE = anycompatiblearray,
+create aggregate first_el_agg_any(anyelement) (
+  SFUNC = first_el_transfn,
+  STYPE = anyarray,
   FINALFUNC = first_el
 );

diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out
index 1ff40764d9..236b2532b3 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -786,6 +786,8 @@ create aggregate build_group(int8, integer) (
   STYPE = int8[]
 );
 -- check proper resolution of data types for polymorphic transfn/finalfn
+create function first_el_transfn(anyarray, anyelement) returns anyarray as
+'select $1 || $2' language sql immutable;
 create function first_el(anyarray) returns anyelement as
 'select $1[1]' language sql strict immutable;
 create aggregate first_el_agg_f8(float8) (
@@ -794,7 +796,7 @@ create aggregate first_el_agg_f8(float8) (
   FINALFUNC = first_el
 );
 create aggregate first_el_agg_any(anyelement) (
-  SFUNC = array_append,
+  SFUNC = first_el_transfn,
   STYPE = anyarray,
   FINALFUNC = first_el
 );
diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql
index e5222f1f81..d2e302c330 100644
--- a/src/test/regress/sql/polymorphism.sql
+++ b/src/test/regress/sql/polymorphism.sql
@@ -549,6 +549,9 @@ create aggregate build_group(int8, integer) (

 -- check proper resolution of data types for polymorphic transfn/finalfn

+create function first_el_transfn(anyarray, anyelement) returns anyarray as
+'select $1 || $2' language sql immutable;
+
 create function first_el(anyarray) returns anyelement as
 'select $1[1]' language sql strict immutable;

@@ -559,7 +562,7 @@ create aggregate first_el_agg_f8(float8) (
 );

 create aggregate first_el_agg_any(anyelement) (
-  SFUNC = array_append,
+  SFUNC = first_el_transfn,
   STYPE = anyarray,
   FINALFUNC = first_el
 );

Re: pgsql: Declare assorted array functions using anycompatible not anyelem

От
Andrew Dunstan
Дата:
On 11/10/20 3:31 PM, Tom Lane wrote:
> Andrew Dunstan <andrew@dunslane.net> writes:
>> On 11/9/20 5:41 PM, Tom Lane wrote:
>>> What I have in mind to apply to 9.5 through 13 is per attached.
>> You also need to modify first_el_agg_any.
> ... doh.  That one is a little messier because there's no equally useful
> substitute function.  What I'm inclined to do for that is to add a
> SQL-language wrapper to reproduce the old signature for array_append.
> As attached.  (I'm keeping this separate from the other patch, since
> this doesn't go back as far.)
>
>

Seems reasonable.


cheers


andrew