Thread: Proposal: new function array_init

Proposal: new function array_init

From
"Pavel Stehule"
Date:
Hello

There was more time questions about array's initialisation. I propose
function array_init.

CREATE OR REPLACE FUNCTION array_init(sizes int[], v anyelement)
RETURNS anyarray;

First parameter is array of dimension's sizes. Second argument is
value that will be used for initialisation.

Because pg array's indexes must not start from 1 we can allow specify it.

CREATE OR REPLACE FUNCTION array_init(sizes int[], lowers int[], v
anyelement) RETURNS anyarray;



select array_init(array[2],0);    array
---------------    {0,0}
(1 row)


select array_init(array[1,2], 0);    array
---------------{{0,0},{0,0}}
(1 row)

Any comments?

Regards
Pavel Stehule


Re: Proposal: new function array_init

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> There was more time questions about array's initialisation. I propose
> function array_init.

> CREATE OR REPLACE FUNCTION array_init(sizes int[], v anyelement)
> RETURNS anyarray;

I think this is basically a good idea, but maybe the API needs a bit of
adjustment --- providing the sizes as an array doesn't seem especially
convenient.  Since we only allow up to 6 dimensions (IIRC), what about
six functions with different numbers of parameters:
array_int(int, anyelement)array_int(int, int, anyelement)...array_int(int, int, int, int, int, int, anyelement)

I don't object to having the array-input version too, but seems like in
most cases this way would be easier to use.  It wouldn't work well
for providing lower bounds too, but maybe the array-input case is
sufficient for that.

Other thoughts:

* Should the fill value be the first parameter instead of the last?
I'm not sure either way.

* I have a mild preference for "array_fill" instead of "array_init".

* We can handle a null fill value now, but what about nulls in the
dimensions?  The alternatives seem to be to return a null array
(not an array of nulls) or throw error.
        regards, tom lane


Re: Proposal: new function array_init

From
"Webb Sprague"
Date:
On Mon, Jun 2, 2008 at 9:46 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> There was more time questions about array's initialisation. I propose
>> function array_init.

As one of the questioners, I will give some short thoughts below.

>> CREATE OR REPLACE FUNCTION array_init(sizes int[], v anyelement)
>> RETURNS anyarray;

+1.  +0 for Pavel's proposed syntax, because it feels better, but also
it scales to N dimensions (we should throw an error obviously if the
input is too big, but we can probably source that size through an
include), I hate functions with more than four arguments, and having
six slightly overloaded functions in the system catalogs seems
annoying.

> * We can handle a null fill value now, but what about nulls in the
> dimensions?  The alternatives seem to be to return a null array
> (not an array of nulls) or throw error.

I would throw an error, unless there is something that one can do with
a null array (perhaps there is?).

We also might want to consider a resize function, and some other
utilities as long as we are bothering with this.

I am sorry that I can't offer to write these, but I don't have the
time to learn the Postgresql infrastructure to do it.

Thanks for the attention Pavel!


Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/2 Tom Lane <tgl@sss.pgh.pa.us>:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> There was more time questions about array's initialisation. I propose
>> function array_init.
>
>> CREATE OR REPLACE FUNCTION array_init(sizes int[], v anyelement)
>> RETURNS anyarray;
>
> I think this is basically a good idea, but maybe the API needs a bit of
> adjustment --- providing the sizes as an array doesn't seem especially
> convenient.  Since we only allow up to 6 dimensions (IIRC), what about
> six functions with different numbers of parameters:
>
>        array_int(int, anyelement)
>        array_int(int, int, anyelement)
>        ...
>        array_int(int, int, int, int, int, int, anyelement)
>
> I don't object to having the array-input version too, but seems like in
> most cases this way would be easier to use.  It wouldn't work well
> for providing lower bounds too, but maybe the array-input case is
> sufficient for that.

Your proposal is maybe little bit readable with lower bounds, and when
initial value is integer. But it's easy do wrap SQL functions .

>
> Other thoughts:
>
> * Should the fill value be the first parameter instead of the last?
> I'm not sure either way.

I am not sure too. I have not any original - the nearest function is memset?

>
> * I have a mild preference for "array_fill" instead of "array_init".

maybe, maybe array_set. Any ideas are welcome

>
> * We can handle a null fill value now, but what about nulls in the
> dimensions?  The alternatives seem to be to return a null array
> (not an array of nulls) or throw error.

I am afraid so null array can be changed with null value - so I prefer
in this case raise exception.

Regards
Pavel Stehule
>
>                        regards, tom lane
>


Re: Proposal: new function array_init

From
James William Pye
Date:
On Mon, Jun 02, 2008 at 08:10:19PM +0200, Pavel Stehule wrote:
> > * I have a mild preference for "array_fill" instead of "array_init".
> 
> maybe, maybe array_set. Any ideas are welcome

array_create?


Re: Proposal: new function array_init

From
Decibel!
Date:
On Jun 2, 2008, at 11:46 AM, Tom Lane wrote:
> * Should the fill value be the first parameter instead of the last?


+1. The other way just seems weird, at least to me.
-- 
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828



Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/4 Decibel! <decibel@decibel.org>:
> On Jun 2, 2008, at 11:46 AM, Tom Lane wrote:
>>
>> * Should the fill value be the first parameter instead of the last?
>
>
> +1. The other way just seems weird, at least to me.

can you write reason?

I put fill value on end, because it is like default value:

array_set(array[2,2]);
array_set(array[2,2], 0);
array_set(array[2,2],array[1,1]);
array_set(array[2,2],array[1,1], 0); - and it's analogy to memset fce
etc set(where, value);

Pavel

> --
> Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
> Give your computer some brain candy! www.distributed.net Team #1828
>
>
>


Re: Proposal: new function array_init

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> I put fill value on end, because it is like default value:

> array_set(array[2,2]);
> array_set(array[2,2], 0);

Huh?  That's completely nonsensical ... where will you determine the
type of the array, if you don't have a sample element?

The fact that the fill value is determining the array type is why
it seems important enough to put first.
        regards, tom lane


Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> I put fill value on end, because it is like default value:
>
>> array_set(array[2,2]);
>> array_set(array[2,2], 0);
>
> Huh?  That's completely nonsensical ... where will you determine the
> type of the array, if you don't have a sample element?

it is nonsens in current postgres. But null array is castable to anyarray no?

>
> The fact that the fill value is determining the array type is why
> it seems important enough to put first.
>
I agree - first is most important parameter. But I am not sure, that
is it. size or value. An I am strong fixed on C, Intel notation where
destination is first and  value is second.

>                        regards, tom lane
>


Re: Proposal: new function array_init

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> 2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
>> Huh?  That's completely nonsensical ... where will you determine the
>> type of the array, if you don't have a sample element?

> it is nonsens in current postgres. But null array is castable to anyarray no?

If you mean an array of nulls, it still has to have an element type.
        regards, tom lane


Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> 2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
>>> Huh?  That's completely nonsensical ... where will you determine the
>>> type of the array, if you don't have a sample element?
>
>> it is nonsens in current postgres. But null array is castable to anyarray no?
>
> If you mean an array of nulls, it still has to have an element type.

I know it -  but there was discus about untyped array for empty arrays
like ARRAY[]it is little bit similar
>
>                        regards, tom lane
>


Re: Proposal: new function array_init

From
Andrew Dunstan
Date:

Tom Lane wrote:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>   
>> 2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
>>     
>>> Huh?  That's completely nonsensical ... where will you determine the
>>> type of the array, if you don't have a sample element?
>>>       
>
>   
>> it is nonsens in current postgres. But null array is castable to anyarray no?
>>     
>
> If you mean an array of nulls, it still has to have an element type.
>
>             
>   

Right, and since the fill element is thus not optional it should be in a 
fixed position in the argument list, ISTM, which can only mean it would 
come first.

cheers

andrew


Re: Proposal: new function array_init

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> 2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
>> If you mean an array of nulls, it still has to have an element type.

> I know it -  but there was discus about untyped array for empty arrays
> like ARRAY[]

What's that have to do with array_init?  It will not (usually) be trying
to create an empty array.
        regards, tom lane


Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> 2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
>>> If you mean an array of nulls, it still has to have an element type.
>
>> I know it -  but there was discus about untyped array for empty arrays
>> like ARRAY[]
>
> What's that have to do with array_init?  It will not (usually) be trying
> to create an empty array.
>

sparse arrays?? Or it emulation in pg

idealized code:

a = array_set(array[10,10]); // untyped null array
a[10,10] = 'text'; -- now array is typed

without
a = array_set(NULL::text, array[10,10]);
a[10,10] = 'text';

this is only some ideas, I don't plan do it

Pavel


>                        regards, tom lane
>


Re: Proposal: new function array_init

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> idealized code:

> a = array_set(array[10,10]); // untyped null array
> a[10,10] = 'text'; -- now array is typed

And how did you declare 'a'?  This seems like a solution in search of a
problem.
        regards, tom lane


Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/4 Tom Lane <tgl@sss.pgh.pa.us>:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> idealized code:
>
>> a = array_set(array[10,10]); // untyped null array
>> a[10,10] = 'text'; -- now array is typed
>
> And how did you declare 'a'?  This seems like a solution in search of a
> problem.
>
you have true - problem is in assignment

next question:

when I declare function only for anyelement, I can't simply create text array

CREATE OR REPLACE FUNCTION array_fill(dv anyelement, dims int[])
RETURNS anyarray
AS 'MODULE_PATHNAME', 'array_fill'
LANGUAGE C IMMUTABLE;

postgres=# select array_fill(1,array[4,4]);               array_fill
-------------------------------------------{{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}}
(1 row)

Time: 1,369 ms
postgres=# select array_fill('p',array[4,4]);
ERROR:  could not determine polymorphic type because input has type "unknown"

I can use hack:
CREATE OR REPLACE FUNCTION array_fill(dv text, dims int[])
RETURNS text[]
AS 'MODULE_PATHNAME', 'array_fill'
LANGUAGE C IMMUTABLE;

postgres=# select array_fill('p',array[4,4]);               array_fill
-------------------------------------------{{p,p,p,p},{p,p,p,p},{p,p,p,p},{p,p,p,p}}
(1 row)


what do you thing about it?

regards
Pavel Stehule

>                        regards, tom lane
>


Re: Proposal: new function array_init

From
Tom Lane
Date:
"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> postgres=# select array_fill('p',array[4,4]);
> ERROR:  could not determine polymorphic type because input has type "unknown"

[ shrug... ]   I don't really see a problem with that.

> I can use hack:
> CREATE OR REPLACE FUNCTION array_fill(dv text, dims int[])
> RETURNS text[]

This would be a bad idea, I think; what will happen with
array_fill(null, array[1,2])

I think we *want* that to throw error rather than defaulting to text.
        regards, tom lane


Re: Proposal: new function array_init

From
"Pavel Stehule"
Date:
2008/6/5 Tom Lane <tgl@sss.pgh.pa.us>:
> "Pavel Stehule" <pavel.stehule@gmail.com> writes:
>> postgres=# select array_fill('p',array[4,4]);
>> ERROR:  could not determine polymorphic type because input has type "unknown"
>
> [ shrug... ]   I don't really see a problem with that.

you have t cast in most common case

>
>> I can use hack:
>> CREATE OR REPLACE FUNCTION array_fill(dv text, dims int[])
>> RETURNS text[]
>
> This would be a bad idea, I think; what will happen with
>
>        array_fill(null, array[1,2])

>
> I think we *want* that to throw error rather than defaulting to text.
>
>                        regards, tom lane
>

ok

Pavel