proposal: fix corner use case of variadic fuctions usage

Started by Pavel Stehuleover 13 years ago48 messageshackersgeneral
Jump to latest
#1Pavel Stehule
pavel.stehule@gmail.com
hackersgeneral

Hello

here is patch, that enables using a variadic parameter modifier for
variadic "any" function.

Motivation for this patch is consistent behave of "format" function,
but it fixes behave of all this class variadic functions.

postgres=> -- check pass variadic argument
postgres=> select format('%s, %s', variadic array['Hello','World']);
format
──────────────
Hello, World
(1 row)

postgres=> -- multidimensional array is supported
postgres=> select format('%s, %s', variadic
array[['Nazdar','Svete'],['Hello','World']]);
format
───────────────────────────────
{Nazdar,Svete}, {Hello,World}
(1 row)

It respect Tom's comments - it is based on short-lived FmgrInfo
structures, that are created immediately before function invocation.

Note: there is unsolved issue - reusing transformed arguments - so it
is little bit suboptimal for VARIADIC RETURNING MultiFuncCall
functions, where we don't need to repeat a unpacking of array value.

Regards

Pavel

Attachments:

variadic_argument_for_variadic_any_function.diffapplication/octet-stream; name=variadic_argument_for_variadic_any_function.diffDownload+209-17
#2Vik Fearing
vik@postgresfriends.org
In reply to: Pavel Stehule (#1)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On Sun, Nov 4, 2012 at 12:49 PM, Pavel Stehule <pavel.stehule@gmail.com>wrote:

Hello

here is patch, that enables using a variadic parameter modifier for
variadic "any" function.

Motivation for this patch is consistent behave of "format" function,
but it fixes behave of all this class variadic functions.

postgres=> -- check pass variadic argument
postgres=> select format('%s, %s', variadic array['Hello','World']);
format
──────────────
Hello, World
(1 row)

postgres=> -- multidimensional array is supported
postgres=> select format('%s, %s', variadic
array[['Nazdar','Svete'],['Hello','World']]);
format
───────────────────────────────
{Nazdar,Svete}, {Hello,World}
(1 row)

It respect Tom's comments - it is based on short-lived FmgrInfo
structures, that are created immediately before function invocation.

Note: there is unsolved issue - reusing transformed arguments - so it
is little bit suboptimal for VARIADIC RETURNING MultiFuncCall
functions, where we don't need to repeat a unpacking of array value.

Regards

Pavel

Hi Pavel.

I am trying to review this patch and on my work computer everything
compiles and tests perfectly. However, on my laptop, the regression tests
don't pass with "cache lookup failed for type XYZ" where XYZ is some number
that does not appear to be any type oid.

I don't really know where to go from here. I am asking that other people
try this patch to see if they get errors as well.

Vik

PS: I won't be able to answer this thread until Tuesday.

#3Pavel Stehule
pavel.stehule@gmail.com
In reply to: Vik Fearing (#2)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Hello

Hi Pavel.

I am trying to review this patch and on my work computer everything compiles
and tests perfectly. However, on my laptop, the regression tests don't pass
with "cache lookup failed for type XYZ" where XYZ is some number that does
not appear to be any type oid.

I don't really know where to go from here. I am asking that other people try
this patch to see if they get errors as well.

yes, I checked it on .x86_64 and I had a same problems

probably there was more than one issue - I had to fix a creating a
unpacked params and I had a issue with gcc optimalization when I used
a stack variable for fcinfo.

Now I fixed these issues and I hope so it will work on all platforms

Regards

Pavel Stehule

Show quoted text

Vik

PS: I won't be able to answer this thread until Tuesday.

Attachments:

variadic_argument_for_variadic_any_function_20121201.diffapplication/octet-stream; name=variadic_argument_for_variadic_any_function_20121201.diffDownload+213-17
#4Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Vik Fearing (#2)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On 30.11.2012 12:18, Vik Reykja wrote:

I am trying to review this patch and on my work computer everything
compiles and tests perfectly. However, on my laptop, the regression tests
don't pass with "cache lookup failed for type XYZ" where XYZ is some number
that does not appear to be any type oid.

I don't really know where to go from here. I am asking that other people
try this patch to see if they get errors as well.

I get the same error. I'll mark this as "waiting on author" in the
commitfest.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Pavel Stehule
pavel.stehule@gmail.com
In reply to: Heikki Linnakangas (#4)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

2012/12/5 Heikki Linnakangas <hlinnakangas@vmware.com>:

On 30.11.2012 12:18, Vik Reykja wrote:

I am trying to review this patch and on my work computer everything
compiles and tests perfectly. However, on my laptop, the regression tests
don't pass with "cache lookup failed for type XYZ" where XYZ is some
number
that does not appear to be any type oid.

I don't really know where to go from here. I am asking that other people
try this patch to see if they get errors as well.

I get the same error. I'll mark this as "waiting on author" in the
commitfest.

it was with new patch?

http://archives.postgresql.org/message-id/CAFj8pRDyXfXZcL2FRESLU-dPqaOKOu-ekKY12tBzdO559PW5uQ@mail.gmail.com

Regards

Pavel

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Pavel Stehule (#5)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On 05.12.2012 10:38, Pavel Stehule wrote:

2012/12/5 Heikki Linnakangas<hlinnakangas@vmware.com>:

I get the same error. I'll mark this as "waiting on author" in the
commitfest.

it was with new patch?

http://archives.postgresql.org/message-id/CAFj8pRDyXfXZcL2FRESLU-dPqaOKOu-ekKY12tBzdO559PW5uQ@mail.gmail.com

Ah, no, sorry. The new patch passes regressions just fine. Never mind..

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Pavel Stehule
pavel.stehule@gmail.com
In reply to: Heikki Linnakangas (#6)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

2012/12/5 Heikki Linnakangas <hlinnakangas@vmware.com>:

On 05.12.2012 10:38, Pavel Stehule wrote:

2012/12/5 Heikki Linnakangas<hlinnakangas@vmware.com>:

I get the same error. I'll mark this as "waiting on author" in the
commitfest.

it was with new patch?

http://archives.postgresql.org/message-id/CAFj8pRDyXfXZcL2FRESLU-dPqaOKOu-ekKY12tBzdO559PW5uQ@mail.gmail.com

Ah, no, sorry. The new patch passes regressions just fine. Never mind..

:)

Pavel

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Vik Fearing
vik@postgresfriends.org
In reply to: Pavel Stehule (#3)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On Sat, Dec 1, 2012 at 1:14 PM, Pavel Stehule <pavel.stehule@gmail.com>wrote:

Hello

Hi Pavel.

I am trying to review this patch and on my work computer everything

compiles

and tests perfectly. However, on my laptop, the regression tests don't

pass

with "cache lookup failed for type XYZ" where XYZ is some number that

does

not appear to be any type oid.

I don't really know where to go from here. I am asking that other people

try

this patch to see if they get errors as well.

yes, I checked it on .x86_64 and I had a same problems

probably there was more than one issue - I had to fix a creating a
unpacked params and I had a issue with gcc optimalization when I used
a stack variable for fcinfo.

Now I fixed these issues and I hope so it will work on all platforms

It appears to work a lot better, yes. I played around with it a little bit
and wasn't able to break it, so I'm marking it as ready for committer.
Some wordsmithing will need to be done on the code comments.

#9Stephen Frost
sfrost@snowman.net
In reply to: Pavel Stehule (#3)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Pavel,

* Pavel Stehule (pavel.stehule@gmail.com) wrote:

Now I fixed these issues and I hope so it will work on all platforms

As mentioned on the commitfest application, this needs documentation.
That is not the responsibility of the committer; if you need help, then
please ask for it.

I've also done a quick review of it.

The massive if() block being added to execQual.c:ExecMakeFunctionResult
really looks like it might be better pulled out into a function of its
own.

What does "use element_type depends for dimensions" mean and why is it
a ToDo? When will it be done?

Overall, the comments really need to be better. Things like this:

+       /* create short lived copies of fmgr data */
+       fmgr_info_copy(&sfinfo, fcinfo->flinfo, fcinfo->flinfo->fn_mcxt);
+       memcpy(scinfo, fcinfo, sizeof(FunctionCallInfoData));
+       scinfo->flinfo = &sfinfo;

Really don't cut it, imv. *Why* are we creating a copy of the fmgr
data? Why does it need to be short lived? And what is going to happen
later when you do this?:

fcinfo = scinfo;
MemoryContextSwitchTo(oldContext);

Is there any reason to worry about the fact that fcache->fcinfo_data no
longer matches the fcinfo that we're working on? What if there are
other references made to it in the future? These memcpy's and pointer
foolishness really don't strike me as being a well thought out approach.

There are other similar comments throughout which really need to be
rewritten to address why we're doing something, not what is being done-
you can read the code for that.

Marking this Waiting on Author.

Thanks,

Stephen

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Stephen Frost (#9)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Stephen Frost <sfrost@snowman.net> writes:

[ quick review of patch ]

On reflection it seems to me that this is probably not a very good
approach overall. Our general theory for functions taking ANY has
been that the core system just computes the arguments and leaves it
to the function to make sense of them. Why should this be different
in the one specific case of VARIADIC ANY with a variadic array?

The approach is also inherently seriously inefficient. Not only
does ExecMakeFunctionResult have to build a separate phony Const
node for each array element, but the variadic function itself can
have no idea that those Consts are all the same type, which means
it's going to do datatype lookup over again for each array element.
(format(), for instance, would have to look up the same type output
function over and over again.) This might not be noticeable on toy
examples with a couple of array entries, but it'll be a large
performance problem on large arrays.

The patch also breaks any attempt that a variadic function might be
making to cache info about its argument types across calls. I suppose
that the copying of the FmgrInfo is a hack to avoid crashes due to
called functions supposing that their flinfo->fn_extra data is still
valid for the new argument set. Of course that's another pretty
significant performance hit, compounding the per-element hit. Whereas
an ordinary variadic function that is given N arguments in a particular
query will probably do N datatype lookups and cache the info for the
life of the query, a variadic function called with this approach will
do one datatype lookup for each array element in each row of the query;
and there is no way to optimize that.

But large arrays have a worse problem: the approach flat out does
not work for arrays of more than FUNC_MAX_ARGS elements, because
there's no place to put their values in the FunctionCallInfo struct.
(As submitted, if the array is too big the patch will blithely stomp
all over memory with user-supplied data, making it not merely a crash
risk but probably an exploitable security hole.)

This last problem is, so far as I can see, unfixable within this
approach; surely we are not going to accept a feature that only works
for small arrays. So I am going to mark the CF item rejected not just
RWF.

I believe that a workable approach would require having the function
itself act differently when the VARIADIC flag is set. Currently there
is no way for ANY-taking functions to do this because we don't record
the use of the VARIADIC flag in FuncExpr, but it'd be reasonable to
change that, and probably then add a function similar to
get_fn_expr_rettype to dig it out of the FmgrInfo. I don't know if
we could usefully provide any infrastructure beyond that for the case,
but it'd be worth thinking about whether there's any common behavior
for such functions.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Pavel Stehule
pavel.stehule@gmail.com
In reply to: Stephen Frost (#9)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Hello

I try to recapitulate our design of variadic functions (sorry for my
English - really I have plan to learn this language better - missing
time).

We have two kinds of VARG functions: VARIADIC "any" and VARIADIC
anyarray. These kinds are really different although it is transparent
for final user.

Our low level design supports variadic functions - it based on
FunctionCallInfoData structure. But SQL functions are designed as
nonvariadic overloaded functions - described by pg_proc tuple and
later FmgrInfo structure. This structure contains fn_nargs and fn_expr
(pointer to related parser node) and others, but fn_nargs and fn_epxr
are important for this moment. When we would to get parameter of any
function parameter, we have to use a get_fn_expr_argtype, that is
based on some magic over parser nodes. This expect static number of
parameters of any function during query execution - FmgrInfo is
significantly reused.

So variadic SQL function break some old expectation - but only
partially - with using some trick we are able use variadic function
inside SQL space without significant changes.

1) CALL of variadic functions are transformed to CALL of function with
fixed number of parameters - variadic parameters are transformed to
array
2) if you call variadic function in non variadic manner, then its
calling function with fixed number of parameters and then there
transformation are not necessary.

Points @1 and @2 are valid for VARIADIC anyarray functions.

We introduced VARIADIC "any" function. Motivation for this kind of
function was bypassing postgresql's coerce rules - and own rules
implementation for requested functionality. Some builtins function
does it internally - but it is not possible for custom functions or it
is not possible without some change in parser. Same motivation is
reason why "format" function is VARIADIC "any" function.

Internal implementation of this function is very simple - just enhance
internal checks for mutable number of parameters - and doesn't do
anything more - parameters are passed with FunctionCallInfoData,
necessary expression nodes are created natively. There is important
fact - number of parameters are immutable per one usage - so we can
reuse FmgrInfo. Current limit of VARIADIC "any" function is support
for call in non variadic manner - originally I didn't propose call in
non variadic manner and later we missed support for this use case.
What is worse, we don't handle this use case corectly now - call in
non variadic manner is quietly and buggy forwarded to variadic call
(keyword VARIADIC is ignored)

so we can

SELECT myleast(10,20,40);
SELECT myleast(VARIADIC array[10,20,40]);

SELECT format("%d %d", 10, 20);
but SELECT format("%d %d", VARIADIC array[10, 20]) returns wrong
result because it is not implemented

I proposed more solutions

a) disabling nob variadic call for VARIADIC "any" function and using
overloading as solution for this use case. It was rejected - it has
some issues due possible signature ambiguity.

b) enhancing FunctionCallInfoData about manner of call - variadic, or
non variadic. It was rejected - it needs fixing of all current
VARIADIC "any" functions and probably duplicate some work that can be
handled generic routine.

I don't defend these proposals too much - a issues are clear.

c) enhancing executor, so it can transform non variadic call to
variadic call - just quietly unpack array with parameters and stores
values to FunctionCallInfoData structure. There is new issue - we
cannot reuse parser's nodes and fn_expr and FmgrInfo structure -
because with this transformation these data are mutable.

some example

CREATE TABLE test(format_str text, params text[]);
INSERT INTO test VALUES('%s', ARRAY['Hello']);
INSERT INTO test VALUES('%s %s', ARRAY['Hello','World']);

SELECT format(format_str, VARIADIC params) FROM test;

now I have to support two instances of function - format('%s',
'Hello') and format('%s %s', 'Hello','World') with two different
FmgrInfo - mainly with two different fake parser nodes.

any call needs different FmgrInfo - and I am creating it in short
context due safe design - any forgotten pointer to this mutable
FmgrInfo or more precisely flinfo->fn_expr returns cleaned memory
(with enabled asserts) .

2013/1/18 Stephen Frost <sfrost@snowman.net>:

Pavel,

* Pavel Stehule (pavel.stehule@gmail.com) wrote:

Now I fixed these issues and I hope so it will work on all platforms

As mentioned on the commitfest application, this needs documentation.
That is not the responsibility of the committer; if you need help, then
please ask for it.

I've also done a quick review of it.

The massive if() block being added to execQual.c:ExecMakeFunctionResult
really looks like it might be better pulled out into a function of its
own.

good idea

What does "use element_type depends for dimensions" mean and why is it
a ToDo? When will it be done?

I had to thinking some time :( - forgotten note - should be removed

Actually it should to support multidimensional array as parameter's
array - and it does one dimensional slicing - so passing arrays to
variadic "any" function in non variadic manner is possible.

-- multidimensional array is supported
select format('%s, %s', variadic array[['Nazdar','Svete'],['Hello','World']]);
format
-------------------------------
{Nazdar,Svete}, {Hello,World}
(1 row)

Overall, the comments really need to be better. Things like this:

+       /* create short lived copies of fmgr data */
+       fmgr_info_copy(&sfinfo, fcinfo->flinfo, fcinfo->flinfo->fn_mcxt);
+       memcpy(scinfo, fcinfo, sizeof(FunctionCallInfoData));
+       scinfo->flinfo = &sfinfo;

Really don't cut it, imv. *Why* are we creating a copy of the fmgr
data? Why does it need to be short lived? And what is going to happen
later when you do this?:

pls, see my introduction - in this case FmgrInfo is not immutable (in
this use case), so it is reason for short living copy and then I using
this copied structure instead repeated modification original
structure.

fcinfo = scinfo;
MemoryContextSwitchTo(oldContext);

Is there any reason to worry about the fact that fcache->fcinfo_data no
longer matches the fcinfo that we're working on? What if there are
other references made to it in the future? These memcpy's and pointer
foolishness really don't strike me as being a well thought out approach.

fcinfo_data is used for some purposes now - and it can be accessed
from function. Changes that I do are transparent for variadic function
- so I cannot use this.

There are other similar comments throughout which really need to be
rewritten to address why we're doing something, not what is being done-
you can read the code for that.

Thanks for review

Regards

Pavel

Marking this Waiting on Author.

Thanks,

Stephen

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#10)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Hello

2013/1/18 Tom Lane <tgl@sss.pgh.pa.us>:

Stephen Frost <sfrost@snowman.net> writes:

[ quick review of patch ]

On reflection it seems to me that this is probably not a very good
approach overall. Our general theory for functions taking ANY has
been that the core system just computes the arguments and leaves it
to the function to make sense of them. Why should this be different
in the one specific case of VARIADIC ANY with a variadic array?

I am not sure if I understand well to question?

Reason why VARIADIC "any" is different than VARIADIC anyarray is
simple - we have only single type arrays - there are no "any"[] - and
we use combination FunctionCallInfoData structure for data and parser
expression nodes for type specification. And why we use VARIADIC "any"
function? Due our coerce rules - that try to find common coerce type
for any unknown (polymorphic) parameters. This coercion can be
acceptable - and then people can use VARIADIC "anyarray" or
unacceptable - and then people should to use VARIADIC "any" - for
example we would not lost type info for boolean types. Next motivation
for VARIADIC "any" - implementation is very simple and fast - nobody
have to do packing and unpacking array - just push values to narg, arg
and argnull fields of FunctionCallInfoData structure. There are no
necessary any operations with data. There are only one issue - this
corner case.

The approach is also inherently seriously inefficient. Not only
does ExecMakeFunctionResult have to build a separate phony Const
node for each array element, but the variadic function itself can
have no idea that those Consts are all the same type, which means
it's going to do datatype lookup over again for each array element.
(format(), for instance, would have to look up the same type output
function over and over again.) This might not be noticeable on toy
examples with a couple of array entries, but it'll be a large
performance problem on large arrays.

yes, "format()" it actually does it - in all cases. And it is not best
- but almost of overhead is masked by using sys caches.

What is important - for this use case - there is simple and perfect
possible optimization - in this case "non variadic manner call of
variadic "any" function" all variadic parameters will share same type.
Inside variadic function I have not information so this situation is
in this moment, but just I can remember last used type - and I can
reuse it, when parameter type is same like previous parameter.

So there no performance problem.

The patch also breaks any attempt that a variadic function might be
making to cache info about its argument types across calls. I suppose
that the copying of the FmgrInfo is a hack to avoid crashes due to
called functions supposing that their flinfo->fn_extra data is still
valid for the new argument set. Of course that's another pretty
significant performance hit, compounding the per-element hit. Whereas
an ordinary variadic function that is given N arguments in a particular
query will probably do N datatype lookups and cache the info for the
life of the query, a variadic function called with this approach will
do one datatype lookup for each array element in each row of the query;
and there is no way to optimize that.

I believe so cache of last used datatype and related function can be
very effective and enough for this possible performance issues.

But large arrays have a worse problem: the approach flat out does
not work for arrays of more than FUNC_MAX_ARGS elements, because
there's no place to put their values in the FunctionCallInfo struct.
(As submitted, if the array is too big the patch will blithely stomp
all over memory with user-supplied data, making it not merely a crash
risk but probably an exploitable security hole.)

agree - FUNC_MAX_ARGS should be tested - it is significant security
bug and should be fixed.

This last problem is, so far as I can see, unfixable within this
approach; surely we are not going to accept a feature that only works
for small arrays. So I am going to mark the CF item rejected not just
RWF.

disagree - non variadic manner call should not be used for walk around
FUNC_MAX_ARGS limit. So there should not be passed big array.

If somebody need to pass big array to function, then he should to use
usual non variadic function with usual array type parameter. He should
not use a VARIADIC parameter. We didn't design variadic function to
exceeding FUNC_MAX_ARGS limit.

So I strongly disagree with rejection for this argument. By contrast -
a fact so we don't check array size when variadic function is not
called as variadic function is bug.

Any function - varidic or not varidic in any use case have to have max
FUNC_MAX_ARGS arguments. Our internal variadic functions - that are
+/- VARIADIC "any" functions has FUNC_MAX_ARGS limit.

I believe that a workable approach would require having the function
itself act differently when the VARIADIC flag is set. Currently there
is no way for ANY-taking functions to do this because we don't record
the use of the VARIADIC flag in FuncExpr, but it'd be reasonable to
change that, and probably then add a function similar to
get_fn_expr_rettype to dig it out of the FmgrInfo. I don't know if
we could usefully provide any infrastructure beyond that for the case,
but it'd be worth thinking about whether there's any common behavior
for such functions.

You propose now something, what you rejected four months ago.

your proposal is +/- same like my second proposal and implementation
that I sent some time ago. I have not a problem with it - and I'll
rewrite it, just I recapitulate your objection

a) anybody should to fix any existent variadic "any" function
separately - this fix is not general
b) it increase complexity (little bit) for this kind of variadic functions.

please, can we define agreement on strategy how to fix this issue?

I see two important questions?

a) what limits are valid for variadic functions? Now FUNC_MAX_ARGS
limit is ignored sometime - is it ok?
b) where array of variadic parameters for variadic "any" function
should be unnested? two possibilities - executor (increase complexity
of executor) or inside variadic function - (increase complexity of
variadic function).

I wrote three variants how to fix this issue - all variants has some
advantage and some disadvantage - and I believe so fourth and fifth
variant will be same - but all advantage and disadvantage are relative
well defined now - so we should to decide for one way.

No offensive Tom :), sincerely thank you for review

Best regards

Pavel

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Stephen Frost
sfrost@snowman.net
In reply to: Pavel Stehule (#12)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Pavel,

While I certainly appreciate your enthusiasm, I don't think this is
going to make it into 9.3, which is what we're currently focused on.

I'd suggest that you put together a wiki page or similar which
outlines how this is going to work and be implemented and it can be
discussed for 9.4 in a couple months. I don't think writing any more
code is going to be helpful for this right now.

Thanks,

Stephen

#14Pavel Stehule
pavel.stehule@gmail.com
In reply to: Stephen Frost (#13)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

2013/1/19 Stephen Frost <sfrost@snowman.net>:

Pavel,

While I certainly appreciate your enthusiasm, I don't think this is
going to make it into 9.3, which is what we're currently focused on.

I'd suggest that you put together a wiki page or similar which
outlines how this is going to work and be implemented and it can be
discussed for 9.4 in a couple months. I don't think writing any more
code is going to be helpful for this right now.

if we don't define solution now, then probably don't will define
solution for 9.4 too. Moving to next release solves nothing.
Personally, I can living with commiting in 9.4 - people, who use it
and need it, can use existing patch, but I would to have a clean
proposition for this issue, because I spent lot of time on this
relative simple issue - and I am not happy with it. So I would to
write some what will be (probably) commited, and I don't would to
return to this open issue again.

Regards

Pavel

Thanks,

Stephen

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#15Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#12)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Pavel Stehule <pavel.stehule@gmail.com> writes:

2013/1/18 Tom Lane <tgl@sss.pgh.pa.us>:

The approach is also inherently seriously inefficient. ...

What is important - for this use case - there is simple and perfect
possible optimization - in this case "non variadic manner call of
variadic "any" function" all variadic parameters will share same type.
Inside variadic function I have not information so this situation is
in this moment, but just I can remember last used type - and I can
reuse it, when parameter type is same like previous parameter.

So there no performance problem.

Well, if we have to hack each variadic function to make it work well in
this scenario, that greatly weakens the major argument for the proposed
patch, namely that it provides a single-point fix for VARIADIC behavior.

BTW, I experimented with lobotomizing array_in's caching of I/O function
lookup behavior, by deleting the if-test at arrayfuncs.c line 184. That
seemed to make it about 30% slower for a simple test involving
converting two-element float8 arrays. So while failing to cache this
stuff isn't the end of the world, arguing that it's not worth worrying
about is simply wrong.

But large arrays have a worse problem: the approach flat out does
not work for arrays of more than FUNC_MAX_ARGS elements, because
there's no place to put their values in the FunctionCallInfo struct.
This last problem is, so far as I can see, unfixable within this
approach; surely we are not going to accept a feature that only works
for small arrays. So I am going to mark the CF item rejected not just
RWF.

disagree - non variadic manner call should not be used for walk around
FUNC_MAX_ARGS limit. So there should not be passed big array.

That's utter nonsense. Why wouldn't people expect concat(), for
example, to work for large (or even just moderate-sized) arrays?

This problem *is* a show stopper for this patch. I suggested a way you
can fix it without having such a limitation. If you don't want to go
that way, well, it's not going to happen.

I agree the prospect that each variadic-ANY function would have to deal
with this case for itself is a tad annoying. But there are only two of
them in the existing system, and it's not like a variadic-ANY function
isn't a pretty complicated beast anyway.

You propose now something, what you rejected four months ago.

Well, at the time it wasn't apparent that this approach wouldn't work.
It is now, though.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#15)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

2013/1/19 Tom Lane <tgl@sss.pgh.pa.us>:

Pavel Stehule <pavel.stehule@gmail.com> writes:

2013/1/18 Tom Lane <tgl@sss.pgh.pa.us>:

The approach is also inherently seriously inefficient. ...

What is important - for this use case - there is simple and perfect
possible optimization - in this case "non variadic manner call of
variadic "any" function" all variadic parameters will share same type.
Inside variadic function I have not information so this situation is
in this moment, but just I can remember last used type - and I can
reuse it, when parameter type is same like previous parameter.

So there no performance problem.

Well, if we have to hack each variadic function to make it work well in
this scenario, that greatly weakens the major argument for the proposed
patch, namely that it provides a single-point fix for VARIADIC behavior.

BTW, I experimented with lobotomizing array_in's caching of I/O function
lookup behavior, by deleting the if-test at arrayfuncs.c line 184. That
seemed to make it about 30% slower for a simple test involving
converting two-element float8 arrays. So while failing to cache this
stuff isn't the end of the world, arguing that it's not worth worrying
about is simply wrong.

But large arrays have a worse problem: the approach flat out does
not work for arrays of more than FUNC_MAX_ARGS elements, because
there's no place to put their values in the FunctionCallInfo struct.
This last problem is, so far as I can see, unfixable within this
approach; surely we are not going to accept a feature that only works
for small arrays. So I am going to mark the CF item rejected not just
RWF.

disagree - non variadic manner call should not be used for walk around
FUNC_MAX_ARGS limit. So there should not be passed big array.

That's utter nonsense. Why wouldn't people expect concat(), for
example, to work for large (or even just moderate-sized) arrays?

This problem *is* a show stopper for this patch. I suggested a way you
can fix it without having such a limitation. If you don't want to go
that way, well, it's not going to happen.

I agree the prospect that each variadic-ANY function would have to deal
with this case for itself is a tad annoying. But there are only two of
them in the existing system, and it's not like a variadic-ANY function
isn't a pretty complicated beast anyway.

You propose now something, what you rejected four months ago.

Well, at the time it wasn't apparent that this approach wouldn't work.
It is now, though.

I have no problem rewrite patch, I'll send new version early.

Regards

Pavel

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#17Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#11)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On Sat, Jan 19, 2013 at 11:58 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

We introduced VARIADIC "any" function. Motivation for this kind of
function was bypassing postgresql's coerce rules - and own rules
implementation for requested functionality. Some builtins function
does it internally - but it is not possible for custom functions or it
is not possible without some change in parser. Same motivation is
reason why "format" function is VARIADIC "any" function.

I'd just like to draw the attention of all assembled to the fact that
this is another example of the cottage industry we've created in
avoiding our own burdensome typecasting rules. I not long ago
proposed a patch that went nowhere which would have obviated the need
for this sort of nonsense in a much more principled way, which of
course went nowhere, despite the design being one which Tom himself
proposed. Is there any amount of this which will sway popular opinion
to the point of view that the problem is not with the individual
cases, but the rules themselves?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#15)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On Sat, Jan 19, 2013 at 3:27 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

disagree - non variadic manner call should not be used for walk around
FUNC_MAX_ARGS limit. So there should not be passed big array.

That's utter nonsense. Why wouldn't people expect concat(), for
example, to work for large (or even just moderate-sized) arrays?

/me blinks.

What does that have to do with anything? IIUC, the question isn't
whether CONCAT() would work for large arrays, but rather for very
large numbers of arrays written out as CONCAT(a1, ..., a10000000).

I don't understand why an appropriately-placed check against
FUNC_MAX_ARGS does anything other than enforce a limit we already
have. Or are we currently not consistently enforcing that limit?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#18)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

Robert Haas <robertmhaas@gmail.com> writes:

On Sat, Jan 19, 2013 at 3:27 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

That's utter nonsense. Why wouldn't people expect concat(), for
example, to work for large (or even just moderate-sized) arrays?

/me blinks.

What does that have to do with anything? IIUC, the question isn't
whether CONCAT() would work for large arrays, but rather for very
large numbers of arrays written out as CONCAT(a1, ..., a10000000).

No, the question is what happens with CONCAT(VARIADIC some-array-here),
which currently just returns the array as-is, but which really ought
to concat all the array elements as if they'd been separate arguments.

Pavel is claiming it's okay for that to fall over if the array has
more than 100 elements. I disagree, not only for the specific case of
CONCAT(), but with the more general implication that such a limitation
is going to be okay for any VARIADIC ANY function that anyone will ever
write.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#20Andrew Dunstan
andrew@dunslane.net
In reply to: Robert Haas (#17)
hackersgeneral
Re: proposal: fix corner use case of variadic fuctions usage

On 01/20/2013 01:37 PM, Robert Haas wrote:

On Sat, Jan 19, 2013 at 11:58 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

We introduced VARIADIC "any" function. Motivation for this kind of
function was bypassing postgresql's coerce rules - and own rules
implementation for requested functionality. Some builtins function
does it internally - but it is not possible for custom functions or it
is not possible without some change in parser. Same motivation is
reason why "format" function is VARIADIC "any" function.

I'd just like to draw the attention of all assembled to the fact that
this is another example of the cottage industry we've created in
avoiding our own burdensome typecasting rules. I not long ago
proposed a patch that went nowhere which would have obviated the need
for this sort of nonsense in a much more principled way, which of
course went nowhere, despite the design being one which Tom himself
proposed. Is there any amount of this which will sway popular opinion
to the point of view that the problem is not with the individual
cases, but the rules themselves?

Uh, reference please? This doesn't jog my memory despite it being
something that's obviously interesting in light of my recent work. (That
could be a a case of dying synapses too.)

cheers

andrew

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#19)
hackersgeneral
#22Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#17)
hackersgeneral
#23Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#19)
hackersgeneral
#24Robert Haas
robertmhaas@gmail.com
In reply to: Andrew Dunstan (#20)
hackersgeneral
#25Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#22)
hackersgeneral
#26Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#23)
hackersgeneral
#27Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#25)
hackersgeneral
#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#23)
hackersgeneral
#29Craig Ringer
craig@2ndquadrant.com
In reply to: Robert Haas (#17)
hackersgeneral
#30Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#28)
hackersgeneral
#31Chris Travers
chris.travers@gmail.com
In reply to: Craig Ringer (#29)
hackersgeneral
#32Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#30)
hackersgeneral
#33Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#15)
hackersgeneral
#34Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#33)
hackersgeneral
#35Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#34)
hackersgeneral
#36Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#34)
hackersgeneral
#37Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#36)
hackersgeneral
#38Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#34)
hackersgeneral
#39Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#38)
hackersgeneral
#40Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#39)
hackersgeneral
#41Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#40)
hackersgeneral
#42Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#39)
hackersgeneral
#43Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#41)
hackersgeneral
#44Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#43)
hackersgeneral
#45Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#44)
hackersgeneral
#46Craig Ringer
craig@2ndquadrant.com
In reply to: Pavel Stehule (#45)
hackersgeneral
#47Tom Lane
tgl@sss.pgh.pa.us
In reply to: Craig Ringer (#46)
hackersgeneral
#48Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#47)
hackersgeneral