Proposal: new function array_init

Started by Pavel Stehuleover 17 years ago18 messages
#1Pavel Stehule
pavel.stehule@gmail.com

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#1)
Re: Proposal: new function array_init

"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

#3Webb Sprague
webb.sprague@gmail.com
In reply to: Tom Lane (#2)
Re: Proposal: new function array_init

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!

#4Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#2)
Re: Proposal: new function array_init

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

Show quoted text

regards, tom lane

#5James William Pye
pgsql@jwp.name
In reply to: Pavel Stehule (#4)
Re: Proposal: new function array_init

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?

#6Decibel!
decibel@decibel.org
In reply to: Tom Lane (#2)
1 attachment(s)
Re: Proposal: new function array_init

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

Attachments:

smime.p7sapplication/pkcs7-signature; name=smime.p7sDownload
#7Pavel Stehule
pavel.stehule@gmail.com
In reply to: Decibel! (#6)
Re: Proposal: new function array_init

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

Show quoted text

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

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#7)
Re: Proposal: new function array_init

"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

#9Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#8)
Re: Proposal: new function array_init

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.

Show quoted text

regards, tom lane

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#9)
Re: Proposal: new function array_init

"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

#11Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#10)
Re: Proposal: new function array_init

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

Show quoted text

regards, tom lane

#12Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#10)
Re: Proposal: new function array_init

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

#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#11)
Re: Proposal: new function array_init

"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

#14Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#13)
Re: Proposal: new function array_init

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

Show quoted text

regards, tom lane

#15Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#14)
Re: Proposal: new function array_init

"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

#16Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#15)
Re: Proposal: new function array_init

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

Show quoted text

regards, tom lane

#17Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#16)
Re: Proposal: new function array_init

"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

#18Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#17)
Re: Proposal: new function array_init

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