Thread: RfD: more powerful "any" types

RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Hi,

I'm seeking more powerful "any" pseudotypes.  In particular, consider a
function

foo(type1, type2) returns type3

where type1 and type2 can be both any element type, but not necessarily
both of the same type.  Currently this cannot be made to work: you could
try to write the function this way:

foo(anyelement, anyelement) returns anyelement

but this will force them to be both of the same type, which is not what
we want.  In my opinion this is a missing feature of our type system.

One seemingly trivial idea would be to have anyelement2, anyelement3,
and so on.  This is not a very good solution, because we'd have to fill
the catalogs with a large bunch of new pseudotypes, and the code with a
bunch of hardcoded tests -- and there are already 27 cases of
ANYELEMENTOID in our code.


For a practical example, I am trying to write a function that returns
how many NULL arguments it has (this is useful in table CHECK
constraints).  One simple idea is to use type "unknown":

CREATE FUNCTION a (unknown, unknown, unknown) RETURNS INT LANGUAGE plpgsql AS $$
DECLARE  count int = 0;
BEGIN  IF $1 IS NULL THEN count = count + 1; END IF;  IF $2 IS NULL THEN count = count + 1; END IF;  if $3 IS NULL THEN
count= count + 1; END IF;  RETURN count;
 
END $$;

The problem is that it doesn't work.  This trivial query does:

alvherre=# select a(null, '2', null);a 
---2
(1 fila)

But this one does not:

alvherre=# select a(null, 2, null);
ERROR:  function a(unknown, integer, unknown) does not exist

and you cannot cast the integer:
alvherre=# select a(null, 2::unknown, null);
ERROR:  cannot cast type integer to unknown


Before I spend time trying to figure out how this works,
1. is there agreement that this is a problem and needs fixed, and
2. does anybody have an idea how to attack it?

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 8, 2009, at 9:12 AM, Alvaro Herrera wrote:

> foo(anyelement, anyelement) returns anyelement
>
> but this will force them to be both of the same type, which is not  
> what
> we want.  In my opinion this is a missing feature of our type system.

Oh yes, agreed. I've run into this with pgTAP many times.

> One seemingly trivial idea would be to have anyelement2, anyelement3,
> and so on.  This is not a very good solution, because we'd have to  
> fill
> the catalogs with a large bunch of new pseudotypes, and the code  
> with a
> bunch of hardcoded tests -- and there are already 27 cases of
> ANYELEMENTOID in our code.

Yes, and foo() might be called with two different data types, or two  
of the same, and both should work.

<snip what="other useful information" />

> Before I spend time trying to figure out how this works,
> 1. is there agreement that this is a problem and needs fixed, and

+1

> 2. does anybody have an idea how to attack it?

Why can't anyelement be freed from this constraint?

Best,

David



Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
David E. Wheeler wrote:
> On Sep 8, 2009, at 9:12 AM, Alvaro Herrera wrote:

> >2. does anybody have an idea how to attack it?
> 
> Why can't anyelement be freed from this constraint?

Because it would break other uses of it, I think.  IIRC the original use
of anyelement was that it would resolve to the element type of an
anyarray argument-or-return type.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> I'm seeking more powerful "any" pseudotypes.

If you don't want any constraints at all on the argument types, you
can use "any" (with the quotes, because it's a reserved word :-().
If you want some constraints but not "anyelement", please be more
specific about what you want.
        regards, tom lane


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 8, 2009, at 9:23 AM, Alvaro Herrera wrote:

>>> 2. does anybody have an idea how to attack it?
>>
>> Why can't anyelement be freed from this constraint?
>
> Because it would break other uses of it, I think.  IIRC the original  
> use
> of anyelement was that it would resolve to the element type of an
> anyarray argument-or-return type.

Does it still? Need it?

David


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 8, 2009, at 9:25 AM, Tom Lane wrote:

> If you don't want any constraints at all on the argument types, you
> can use "any" (with the quotes, because it's a reserved word :-().
> If you want some constraints but not "anyelement", please be more
> specific about what you want.

Oooh, I need to try that. How far back does that behavior go,  
compatibility-wise?

Best,

David



Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Tom Lane wrote:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
> > I'm seeking more powerful "any" pseudotypes.
> 
> If you don't want any constraints at all on the argument types, you
> can use "any" (with the quotes, because it's a reserved word :-().
> If you want some constraints but not "anyelement", please be more
> specific about what you want.

That would work, except that plpgsql and SQL don't like it:

ERROR:  PL/pgSQL functions cannot accept type "any"
ERROR:  SQL functions cannot have arguments of type "any"

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 8, 2009, at 9:32 AM, Alvaro Herrera wrote:

> That would work, except that plpgsql and SQL don't like it:
>
> ERROR:  PL/pgSQL functions cannot accept type "any"
> ERROR:  SQL functions cannot have arguments of type "any"

Seems to go for other PLs, as well:

ERROR:  PL/Perl functions cannot accept type "any"

Perhaps that could be changed?

Best,

David


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> Tom Lane wrote:
>> If you don't want any constraints at all on the argument types, you
>> can use "any" (with the quotes, because it's a reserved word :-().

> That would work, except that plpgsql and SQL don't like it:

Intentionally so, because there's not a whole lot you can *do* with an
ANY parameter, other than checking it for null.  Perhaps the real
question is about what semantics you're expecting for these
unconstrained parameters.
        regards, tom lane


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 8, 2009, at 9:57 AM, Tom Lane wrote:

> Intentionally so, because there's not a whole lot you can *do* with an
> ANY parameter, other than checking it for null.  Perhaps the real
> question is about what semantics you're expecting for these
> unconstrained parameters.

For my purposes, I guess implicit casting for comparing values, as in
    arg_a IS DISTINCT FROM arg_b

and
    arg_a = arg_b

or
    arg_a <> arg_b

It'd work if there was a way to cast one to the type of the other,
such as comparing a TEXT to a VARCHAR. But maybe that'd be too magical…

Best,

David

Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Sep 8, 2009, at 9:57 AM, Tom Lane wrote:
>> Intentionally so, because there's not a whole lot you can *do* with an
>> ANY parameter, other than checking it for null.  Perhaps the real
>> question is about what semantics you're expecting for these
>> unconstrained parameters.

> For my purposes, I guess implicit casting for comparing values, as in

>      arg_a IS DISTINCT FROM arg_b

Surely you'd want arg_a and arg_b constrained to the same type,
otherwise there is no certainty that that means anything at all.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Merlin Moncure
Date:
On Tue, Sep 8, 2009 at 12:12 PM, Alvaro
Herrera<alvherre@commandprompt.com> wrote:
> Hi,
>
> I'm seeking more powerful "any" pseudotypes.  In particular, consider a
> function
>
> foo(type1, type2) returns type3
>
> where type1 and type2 can be both any element type, but not necessarily
> both of the same type.  Currently this cannot be made to work: you could
> try to write the function this way:
>
> foo(anyelement, anyelement) returns anyelement
>
> but this will force them to be both of the same type, which is not what
> we want.  In my opinion this is a missing feature of our type system.
>
> One seemingly trivial idea would be to have anyelement2, anyelement3,
> and so on.  This is not a very good solution, because we'd have to fill
> the catalogs with a large bunch of new pseudotypes, and the code with a
> bunch of hardcoded tests -- and there are already 27 cases of
> ANYELEMENTOID in our code.
>
>
> For a practical example, I am trying to write a function that returns
> how many NULL arguments it has (this is useful in table CHECK
> constraints).  One simple idea is to use type "unknown":
>
> CREATE FUNCTION a (unknown, unknown, unknown) RETURNS INT LANGUAGE plpgsql AS $$
> DECLARE
>   count int = 0;
> BEGIN
>   IF $1 IS NULL THEN count = count + 1; END IF;
>   IF $2 IS NULL THEN count = count + 1; END IF;
>   if $3 IS NULL THEN count = count + 1; END IF;
>   RETURN count;
> END $$;
>
> The problem is that it doesn't work.  This trivial query does:
>
> alvherre=# select a(null, '2', null);
>  a
> ---
>  2
> (1 fila)
>
> But this one does not:
>
> alvherre=# select a(null, 2, null);
> ERROR:  function a(unknown, integer, unknown) does not exist
>
> and you cannot cast the integer:
> alvherre=# select a(null, 2::unknown, null);
> ERROR:  cannot cast type integer to unknown
>
>
> Before I spend time trying to figure out how this works,
> 1. is there agreement that this is a problem and needs fixed, and
> 2. does anybody have an idea how to attack it?

Since you can do all these things and more in C functions, this
becomes a right tool/wrong tool problem?  plpgsql would be fairly
hopeless without some reflection capabilities that we don't currently
have...especially if you consider variadic functions which would be
hard to reconcile with any behavior changes.

I think if you continue going down this road you would end up with a
type system along the lines with c++ templates...so you could do:
DECLARE foo  arg1%type;
etc

And maybe have unique generated plans for each unique set of supplied
input types.

merlin


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 8, 2009, at 10:15 AM, Tom Lane wrote:

>>     arg_a IS DISTINCT FROM arg_b
>
> Surely you'd want arg_a and arg_b constrained to the same type,
> otherwise there is no certainty that that means anything at all.

Yes, for the purposes of pgTAP perhaps so. Then it's on the user to do  
the cast, because she decides that the cast is appropriate. Otherwise,  
as I said, perhaps it'd be too magical.

Best,

David


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> David E. Wheeler wrote:
>> Why can't anyelement be freed from this constraint?

> Because it would break other uses of it, I think.

Specifically, what are you going to do with something like
make_array(anyelement, anyelement) returns anyarray

There's no principled way to determine what anyarray means if the
arguments are not the same type.

I have no objection to adding some other pseudotype with different
behavior, but breaking anyelement is not the path.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Sep 8, 2009, at 9:25 AM, Tom Lane wrote:
>> If you don't want any constraints at all on the argument types, you
>> can use "any" (with the quotes, because it's a reserved word :-().

> Oooh, I need to try that. How far back does that behavior go,  
> compatibility-wise?

Further than "anyelement", I think, or at least the same distance.
IIRC it was one of the types we split up "opaque" into.
        regards, tom lane


Re: RfD: more powerful "any" types

From
David Fetter
Date:
On Tue, Sep 08, 2009 at 12:12:10PM -0400, Alvaro Herrera wrote:
> Hi,
> 
> I'm seeking more powerful "any" pseudotypes.  In particular,
> consider a function
> 
> foo(type1, type2) returns type3
> 
> where type1 and type2 can be both any element type, but not
> necessarily both of the same type.  Currently this cannot be made to
> work: you could try to write the function this way:
> 
> foo(anyelement, anyelement) returns anyelement

I'd like to see pseudo-types like ANYNUMERIC, and allow it to take an
array decorator, which would really help for math-ish functions.  Not
sure where that fits in this discussion.

Cheers,
David.
-- 
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter      XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate


Re: RfD: more powerful "any" types

From
Peter Eisentraut
Date:
On Tue, 2009-09-08 at 10:23 -0700, David E. Wheeler wrote:
> On Sep 8, 2009, at 10:15 AM, Tom Lane wrote:
> 
> >>     arg_a IS DISTINCT FROM arg_b
> >
> > Surely you'd want arg_a and arg_b constrained to the same type,
> > otherwise there is no certainty that that means anything at all.
> 
> Yes, for the purposes of pgTAP perhaps so. Then it's on the user to do  
> the cast, because she decides that the cast is appropriate. Otherwise,  
> as I said, perhaps it'd be too magical.

That's beginning to sound a bit like a generics feature.  E.g.,

CREATE FUNCTION the_same<T>(arg_a T, arg_b T) RETURNS bool AS $$
SELECT arg_a IS DISTINCT FROM arg_b;
$$;



Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Peter Eisentraut wrote:
> On Tue, 2009-09-08 at 10:23 -0700, David E. Wheeler wrote:
> > On Sep 8, 2009, at 10:15 AM, Tom Lane wrote:
> > 
> > >>     arg_a IS DISTINCT FROM arg_b
> > >
> > > Surely you'd want arg_a and arg_b constrained to the same type,
> > > otherwise there is no certainty that that means anything at all.
> > 
> > Yes, for the purposes of pgTAP perhaps so. Then it's on the user to do  
> > the cast, because she decides that the cast is appropriate. Otherwise,  
> > as I said, perhaps it'd be too magical.
> 
> That's beginning to sound a bit like a generics feature.  E.g.,
> 
> CREATE FUNCTION the_same<T>(arg_a T, arg_b T) RETURNS bool AS $$
> SELECT arg_a IS DISTINCT FROM arg_b;
> $$;

Well, you can write that one with anyelement already.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
Peter Eisentraut
Date:
On Wed, 2009-09-09 at 07:47 -0400, Alvaro Herrera wrote:
> Peter Eisentraut wrote:
> > On Tue, 2009-09-08 at 10:23 -0700, David E. Wheeler wrote:
> > > On Sep 8, 2009, at 10:15 AM, Tom Lane wrote:
> > > 
> > > >>     arg_a IS DISTINCT FROM arg_b
> > > >
> > > > Surely you'd want arg_a and arg_b constrained to the same type,
> > > > otherwise there is no certainty that that means anything at all.
> > > 
> > > Yes, for the purposes of pgTAP perhaps so. Then it's on the user to do  
> > > the cast, because she decides that the cast is appropriate. Otherwise,  
> > > as I said, perhaps it'd be too magical.
> > 
> > That's beginning to sound a bit like a generics feature.  E.g.,
> > 
> > CREATE FUNCTION the_same<T>(arg_a T, arg_b T) RETURNS bool AS $$
> > SELECT arg_a IS DISTINCT FROM arg_b;
> > $$;
> 
> Well, you can write that one with anyelement already.

Well, so far we've only seen use cases in this thread that either
already work or that are not well-defined. ;-)



Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> Well, so far we've only seen use cases in this thread that either
> already work or that are not well-defined. ;-)

Well, yeah, the question is can we extract a clear TODO item here.

I think there are two somewhat orthogonal issues:

1. Is a completely unconstrained argument type (ie "any") of any real
use to PL functions, and if so how can we expose that usefulness?
The only clear thing to do with such an argument is IS NULL/IS NOT NULL
tests, which might or might not be worth the trouble.

2. Is there any use for arguments with type constraints not covered
by the existing ANYFOO rules, and if so what do we add for that?

One comment on point 2 is that it was foreseen from the beginning
that there would be need for ANYELEMENT2 etc, and I'm actually rather
surprised that we've gone this long without adding them.  Alvaro made
a good point about not wanting to multiply the various hard-wired
OID references, but perhaps some judicious code refactoring could
prevent a notational disaster.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Tom Lane <tgl@sss.pgh.pa.us>:
> Peter Eisentraut <peter_e@gmx.net> writes:
>> Well, so far we've only seen use cases in this thread that either
>> already work or that are not well-defined. ;-)
>
> Well, yeah, the question is can we extract a clear TODO item here.
>
> I think there are two somewhat orthogonal issues:
>
> 1. Is a completely unconstrained argument type (ie "any") of any real
> use to PL functions, and if so how can we expose that usefulness?
> The only clear thing to do with such an argument is IS NULL/IS NOT NULL
> tests, which might or might not be worth the trouble.
>
> 2. Is there any use for arguments with type constraints not covered
> by the existing ANYFOO rules, and if so what do we add for that?
>
> One comment on point 2 is that it was foreseen from the beginning
> that there would be need for ANYELEMENT2 etc, and I'm actually rather
> surprised that we've gone this long without adding them.  Alvaro made
> a good point about not wanting to multiply the various hard-wired
> OID references, but perhaps some judicious code refactoring could
> prevent a notational disaster.

I hope so 2 independent polymorphic types are enough. The bigger
problem is coexistence 'unknown' type and anyelement type. Simply we
cannot to write equivalent coalesce, nullif functions vith only
polymorphic types, because we cannot to force implicit casting
unknown->text.

maybe we could to add new function hint "unknown to some"

CREATE OR REPLACE FUNCTION coalesce(VARIADIC anyelement[])
RETURNS anyelement AS $$
SELECT $1[i]  FROM generate_subscripts($1) g(i) WHERE $1[i] IS NOT NULL
$$ LANGUAGE sql UNKNOWN IS text;

???
Regards
Pavel Stehule


>
>                        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
>


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 9, 2009, at 6:39 AM, Tom Lane wrote:

> 1. Is a completely unconstrained argument type (ie "any") of any real
> use to PL functions, and if so how can we expose that usefulness?
> The only clear thing to do with such an argument is IS NULL/IS NOT  
> NULL
> tests, which might or might not be worth the trouble.

If you can pass an "any" to pg_typeof(), it's possible for functions  
to determine the types of arguments themselves and then to decide what  
to do with them (cast, etc.). I can see no reason not to give this  
ability to function authors, can you?

> 2. Is there any use for arguments with type constraints not covered
> by the existing ANYFOO rules, and if so what do we add for that?
>
> One comment on point 2 is that it was foreseen from the beginning
> that there would be need for ANYELEMENT2 etc, and I'm actually rather
> surprised that we've gone this long without adding them.  Alvaro made
> a good point about not wanting to multiply the various hard-wired
> OID references, but perhaps some judicious code refactoring could
> prevent a notational disaster.

The difference between allowing ANYELEMENT2, ANYELEMENT3, ANYELEMENT .  
++$i and allowing "any" escapes me.

Best,

David



Re: RfD: more powerful "any" types

From
decibel
Date:
On Sep 9, 2009, at 8:39 AM, Tom Lane wrote:
> Peter Eisentraut <peter_e@gmx.net> writes:
>> Well, so far we've only seen use cases in this thread that either
>> already work or that are not well-defined. ;-)
>
> Well, yeah, the question is can we extract a clear TODO item here.
>
> I think there are two somewhat orthogonal issues:
>
> 1. Is a completely unconstrained argument type (ie "any") of any real
> use to PL functions, and if so how can we expose that usefulness?
> The only clear thing to do with such an argument is IS NULL/IS NOT  
> NULL
> tests, which might or might not be worth the trouble.


Part of that should be providing a means to determine what the  
underlying type of an "any" is. Having that would allow functions to  
take actions appropriate to different types.
-- 
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828




Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Sep 9, 2009, at 6:39 AM, Tom Lane wrote:
>> 1. Is a completely unconstrained argument type (ie "any") of any real
>> use to PL functions, and if so how can we expose that usefulness?
>> The only clear thing to do with such an argument is IS NULL/IS NOT  
>> NULL tests, which might or might not be worth the trouble.

> If you can pass an "any" to pg_typeof(), it's possible for functions  
> to determine the types of arguments themselves and then to decide what  
> to do with them (cast, etc.). I can see no reason not to give this  
> ability to function authors, can you?

Well, yeah: it looks like a fertile source of security holes, not to
mention implementation difficulties (plpgsql really wants well-typed
expressions...).  What you can do at the C level is not necessarily
sane to give to PL authors.  I'm willing to consider a carefully spec'd
out proposal in this area, but "open the floodgates" ain't it.

> The difference between allowing ANYELEMENT2, ANYELEMENT3, ANYELEMENT .  
> ++$i and allowing "any" escapes me.

In an example like
create function foo (anyelement, anyelement2, anyelement2)returns anyarray2

the second and third arguments would be tied to be of the same type,
and the result would be an array of that type; whereas the first
argument's type is unrelated.  "any" doesn't give you any inter-argument
constraints nor any way to define the result type in terms of the
argument types.  For a possibly realistic example, consider a function
defined as "locate the element of an array that equals the search
argument, and return the corresponding element of a second array, which
is possibly of a different type".  This could be defined as
create function search_array (val anyelement,                              search_array anyarray,
      result_array anyarray2)returns anyelement2
 

but "any" isn't nearly expressive enough.
        regards, tom lane


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 9, 2009, at 10:04 AM, Tom Lane wrote:

> Well, yeah: it looks like a fertile source of security holes, not to
> mention implementation difficulties (plpgsql really wants well-typed
> expressions...).  What you can do at the C level is not necessarily
> sane to give to PL authors.  I'm willing to consider a carefully  
> spec'd
> out proposal in this area, but "open the floodgates" ain't it.

Security holes? Huh? What security holes would there be that you don't  
already have with anyelement?

>> The difference between allowing ANYELEMENT2, ANYELEMENT3,  
>> ANYELEMENT .
>> ++$i and allowing "any" escapes me.
>
> In an example like
>
>     create function foo (anyelement, anyelement2, anyelement2)
>     returns anyarray2
>
> the second and third arguments would be tied to be of the same type,
> and the result would be an array of that type; whereas the first
> argument's type is unrelated.  "any" doesn't give you any inter- 
> argument
> constraints nor any way to define the result type in terms of the
> argument types.  For a possibly realistic example, consider a function
> defined as "locate the element of an array that equals the search
> argument, and return the corresponding element of a second array,  
> which
> is possibly of a different type".  This could be defined as
>
>     create function search_array (val anyelement,
>                                   search_array anyarray,
>                                   result_array anyarray2)
>     returns anyelement2
>
> but "any" isn't nearly expressive enough.

I see. Yes, that is nice. Thanks for the examples.

Best,

David



Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Tom Lane wrote:

> In an example like
> 
>     create function foo (anyelement, anyelement2, anyelement2)
>     returns anyarray2
> 
> the second and third arguments would be tied to be of the same type,
> and the result would be an array of that type; whereas the first
> argument's type is unrelated.

Another possible example is sprintf:

create function sprintf(text, anyelement, anyelement2, anyelement3, ...)
returns text

In order for this to work in general, we'd need FUNC_MAX_ARGS different
types, which is currently defined as 100 in our code.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> Another possible example is sprintf:

> create function sprintf(text, anyelement, anyelement2, anyelement3, ...)
> returns text

> In order for this to work in general, we'd need FUNC_MAX_ARGS different
> types, which is currently defined as 100 in our code.

But here, "any" would work perfectly fine, since there's no need for
any two arguments to be tied to each other or the result.

Given that we've got away so far with only 1 instance of anyelement,
I'm not really convinced that there's a market for more than anyelement2
(and anyarray2, etc).
        regards, tom lane


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 9, 2009, at 10:15 AM, Tom Lane wrote:

>> In order for this to work in general, we'd need FUNC_MAX_ARGS  
>> different
>> types, which is currently defined as 100 in our code.
>
> But here, "any" would work perfectly fine, since there's no need for
> any two arguments to be tied to each other or the result.

Well, only if you write your functions in C. I'd like to be able to  
write sprintf() in PL/pgSQL. Or PL/Perl, for that matter.

Best,

David


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Sep 9, 2009, at 10:04 AM, Tom Lane wrote:
>> Well, yeah: it looks like a fertile source of security holes, not to
>> mention implementation difficulties (plpgsql really wants well-typed
>> expressions...).  What you can do at the C level is not necessarily
>> sane to give to PL authors.  I'm willing to consider a carefully  
>> spec'd out proposal in this area, but "open the floodgates" ain't it.

> Security holes? Huh? What security holes would there be that you don't  
> already have with anyelement?

Well, none, *if* it's defined to have exactly the same runtime behavior
as anyelement does.  It sounded like you were arguing for something
looser.  We could certainly define it as being just like anyelement
but not constrained to match any other argument or result (and, hence,
not usable as a result type).
        regards, tom lane


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Sep 9, 2009, at 10:15 AM, Tom Lane wrote:
>> But here, "any" would work perfectly fine, since there's no need for
>> any two arguments to be tied to each other or the result.

> Well, only if you write your functions in C. I'd like to be able to  
> write sprintf() in PL/pgSQL. Or PL/Perl, for that matter.

I think you're confusing the point with a secondary issue, which is what
access we provide to these pseudotypes in PLs.  To write sprintf in a
PL, you'd at least need the ability to cast "any" to text.  I guess you
can do that with anyelement, though, so maybe there is nothing much here
except an overly restrictive safety check.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Tom Lane wrote:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
> > Another possible example is sprintf:
> 
> > create function sprintf(text, anyelement, anyelement2, anyelement3, ...)
> > returns text
> 
> > In order for this to work in general, we'd need FUNC_MAX_ARGS different
> > types, which is currently defined as 100 in our code.
> 
> But here, "any" would work perfectly fine, since there's no need for
> any two arguments to be tied to each other or the result.

Yup.

BTW does "any" match other pseudotypes?  Would I be able to pass a
cstring into "any"?  That would create a large security hole I think.

> Given that we've got away so far with only 1 instance of anyelement,
> I'm not really convinced that there's a market for more than anyelement2
> (and anyarray2, etc).

Well, if we have something general like a constrained "any", then I
agree.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 9, 2009, at 10:17 AM, Tom Lane wrote:

> Well, none, *if* it's defined to have exactly the same runtime  
> behavior
> as anyelement does.  It sounded like you were arguing for something
> looser.  We could certainly define it as being just like anyelement
> but not constrained to match any other argument or result (and, hence,
> not usable as a result type).

Yes, that sounds about right. Is that not basically what Alvaro was  
looking for to start with? And is there an "any" array that could work  
for variadic functions like sprintf(), as well?

Best,

David


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 9, 2009, at 10:22 AM, Tom Lane wrote:

>> Well, only if you write your functions in C. I'd like to be able to
>> write sprintf() in PL/pgSQL. Or PL/Perl, for that matter.
>
> I think you're confusing the point with a secondary issue, which is  
> what
> access we provide to these pseudotypes in PLs.  To write sprintf in a
> PL, you'd at least need the ability to cast "any" to text.  I guess  
> you
> can do that with anyelement, though, so maybe there is nothing much  
> here
> except an overly restrictive safety check.


Yes, exactly.

Best,

David


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> BTW does "any" match other pseudotypes?  Would I be able to pass a
> cstring into "any"?  That would create a large security hole I think.

How so?  'Cause you can do that now with anyelement.

cstring is only a pseudotype for historical reasons, anyway --- there's
nothing about it now that's not a real type.  I think we just have it
that way to discourage people from storing it in tables.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> Yes, that sounds about right. Is that not basically what Alvaro was  
> looking for to start with? And is there an "any" array that could work  
> for variadic functions like sprintf(), as well?

Well, no, because arrays are inherently all the same element type.
You could try to do sprintf as
sprintf(text, variadic anyarray) returns text

but this constrains all the arguments to be the same type, which is
not what you want.  The variadic mechanism doesn't have the ability
to deal with what you're suggesting, and I'm not sure we want to try
to make it do that.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 David E. Wheeler <david@kineticode.com>:
> On Sep 9, 2009, at 10:17 AM, Tom Lane wrote:
>
>> Well, none, *if* it's defined to have exactly the same runtime behavior
>> as anyelement does.  It sounded like you were arguing for something
>> looser.  We could certainly define it as being just like anyelement
>> but not constrained to match any other argument or result (and, hence,
>> not usable as a result type).
>
> Yes, that sounds about right. Is that not basically what Alvaro was looking
> for to start with? And is there an "any" array that could work for variadic
> functions like sprintf(), as well?

no - because PostgreSQL doesn't support multitype array. So VARIADIC
"any" isn't transformed to array and arguments are accessable via
FunctionCallInfo structure. I thing, so this functionality is out of
plpgsql or sql language, but when we are able to transform
FunctionCallInfo to some perl or python structures, this can be
accessed from plperl or plpythonu.

Regards
Pavel Stehule


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


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Tom Lane <tgl@sss.pgh.pa.us>:
> "David E. Wheeler" <david@kineticode.com> writes:
>> Yes, that sounds about right. Is that not basically what Alvaro was
>> looking for to start with? And is there an "any" array that could work
>> for variadic functions like sprintf(), as well?
>
> Well, no, because arrays are inherently all the same element type.
> You could try to do sprintf as
>
>        sprintf(text, variadic anyarray) returns text
>
> but this constrains all the arguments to be the same type, which is
> not what you want.  The variadic mechanism doesn't have the ability
> to deal with what you're suggesting, and I'm not sure we want to try
> to make it do that.

variadic "any" isn't transformed to array.

we are able to write sprintf(text, variadic "any") returns text, but only in C

regards
Pavel Stehule

>
>                        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
>


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Pavel Stehule escribió:

> we are able to write sprintf(text, variadic "any") returns text, but only in C

Hmm, should we provide that function in core?

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
> Pavel Stehule escribió:
>
>> we are able to write sprintf(text, variadic "any") returns text, but only in C
>
> Hmm, should we provide that function in core?

We should it, but I prefer some pgfoundry or contrib package. sprintf
is really far to SQL. What more, we knows types, so some format tags
are useless. Using original sprintf function is possible, but needs
lot of code, because you need to transform PostgreSQL types to C
types, and we have not any helping function for this task.

Some similar to plpgsql's RAISE statement is some +/- 20 rows

regards
Pavel Stehule


>
> --
> Alvaro Herrera                                http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom Development, 24x7 support
>


Re: RfD: more powerful "any" types

From
James Pye
Date:
On Sep 9, 2009, at 4:44 AM, Peter Eisentraut wrote:
> That's beginning to sound a bit like a generics feature.  E.g.,
>
> CREATE FUNCTION the_same<T>(arg_a T, arg_b T) RETURNS bool AS $$
> SELECT arg_a IS DISTINCT FROM arg_b;
> $$;

mmm, yeah... ISTM that expansion in this area should probably head  
toward generics..

Does SQL spec such a thing?


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Pavel Stehule escribió:
> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
> > Pavel Stehule escribió:
> >
> >> we are able to write sprintf(text, variadic "any") returns text, but only in C
> >
> > Hmm, should we provide that function in core?
> 
> We should it, but I prefer some pgfoundry or contrib package. sprintf
> is really far to SQL. What more, we knows types, so some format tags
> are useless. Using original sprintf function is possible, but needs
> lot of code, because you need to transform PostgreSQL types to C
> types, and we have not any helping function for this task.
> 
> Some similar to plpgsql's RAISE statement is some +/- 20 rows

I already published a pseudo-sprintf function in the wiki here:
http://wiki.postgresql.org/wiki/Sprintf  I'm looking for something
better, not just the same hacks.

I don't see any good reason that the function needs to be far from core.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
James Pye
Date:
On Sep 8, 2009, at 10:48 AM, David Fetter wrote:
> I'd like to see pseudo-types like ANYNUMERIC, and allow it to take an
> array decorator, which would really help for math-ish functions.  Not
> sure where that fits in this discussion.

Perhaps typcategory could be leveraged here?


..Tho, if I understand the general direction, I think it would be  
along the lines of type classes/interfaces..


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Tom Lane wrote:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
> > BTW does "any" match other pseudotypes?  Would I be able to pass a
> > cstring into "any"?  That would create a large security hole I think.
> 
> How so?  'Cause you can do that now with anyelement.

Hmm, it doesn't seem to be allowed?

alvherre=# create function anyelem2 (anyelement) returns int language plpgsql as $$ begin return 1; end $$;
CREATE FUNCTION
alvherre=# select anyelem2(textout('oh'));
ERROR:  PL/pgSQL functions cannot accept type cstring
CONTEXTO:  compilation of PL/pgSQL function "anyelem2" near line 0


(BTW I find it a bit funny that lines are counted from 0.  I never
noticed that before).


> cstring is only a pseudotype for historical reasons, anyway --- there's
> nothing about it now that's not a real type.  I think we just have it
> that way to discourage people from storing it in tables.

Wow, it has I/O functions and all.  Amazing, I wasn't aware of that.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Wed, Sep 9, 2009 at 1:15 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
>> Another possible example is sprintf:
>
>> create function sprintf(text, anyelement, anyelement2, anyelement3, ...)
>> returns text
>
>> In order for this to work in general, we'd need FUNC_MAX_ARGS different
>> types, which is currently defined as 100 in our code.
>
> But here, "any" would work perfectly fine, since there's no need for
> any two arguments to be tied to each other or the result.
>
> Given that we've got away so far with only 1 instance of anyelement,
> I'm not really convinced that there's a market for more than anyelement2
> (and anyarray2, etc).

I'm going to go out on a limb and say that if we're going to bother
changing the status quo, we ought to create a reasonable number of
these - maybe, say, four.  I can't see needing a hundred of these, but
I don't think that we should assume that our inability to think of a
use for more than two at the moment implies that there can never be
one.

Really, I think we need a type system that doesn't try to represent
every type as a 32-bit integer.  Right now, for example, there's no
reasonable way to write a function that takes another function as an
argument.  What we need is a system where base types are represented
by an OID, but derived types (list and functional types) are built up
using type constructors that take other types as arguments.  So you
could have a types like list(integer) or list(anyelement) or
function(integer,bool) [meaning either taking an integer and returning
a bool, or the other way around, depending on your notational
preference].  Then you can have functions with complex types like:

maplist : function(anyelement,anyelement2,function(list(anyelement),list(anyelement2)))

This would have the fringe benefit of eliminating types like anyarray
(which is just list(anyelement)) and the need to list every type twice
in pg_type, once for the base type and once for the derived array
type.

</handwaving>

...Robert


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> What we need is a system where base types are represented
> by an OID, but derived types (list and functional types) are built up
> using type constructors that take other types as arguments.

This is SQL, not Haskell.  What you suggest seems about two orders of
magnitude more complex than real-world applications could justify.

(so where is pl/haskell, anyway?)
        regards, tom lane


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Robert Haas escribió:

> Really, I think we need a type system that doesn't try to represent
> every type as a 32-bit integer.  Right now, for example, there's no
> reasonable way to write a function that takes another function as an
> argument.

Function references would be neat -- I remember wanting to use these a
couple of times (map/reduce?)

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
> Pavel Stehule escribió:
>> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
>> > Pavel Stehule escribió:
>> >
>> >> we are able to write sprintf(text, variadic "any") returns text, but only in C
>> >
>> > Hmm, should we provide that function in core?
>>
>> We should it, but I prefer some pgfoundry or contrib package. sprintf
>> is really far to SQL. What more, we knows types, so some format tags
>> are useless. Using original sprintf function is possible, but needs
>> lot of code, because you need to transform PostgreSQL types to C
>> types, and we have not any helping function for this task.
>>
>> Some similar to plpgsql's RAISE statement is some +/- 20 rows
>
> I already published a pseudo-sprintf function in the wiki here:
> http://wiki.postgresql.org/wiki/Sprintf  I'm looking for something
> better, not just the same hacks.
>
> I don't see any good reason that the function needs to be far from core.

what is use case? Why you need sprintf function, when you have ||
operator. This functionality is redundant and out of standard. What I
know, only MySQL has similar function.

Please, try to compile and run sprintf function from attachment

postgres=# select sprintf('1:% 2:% 3:%', 10,null, 'kuku');
      sprintf
--------------------
 1:10 2:NULL 3:kuku
(1 row)

postgres=# select sprintf('Today is %, I am %.', current_date, current_user);
             sprintf
----------------------------------
 Today is 2009-09-09, I am pavel.
(1 row)

Regards
Pavel

>
> --
> Alvaro Herrera                                http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom Development, 24x7 support
>

Attachment

Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Robert Haas <robertmhaas@gmail.com>:
> On Wed, Sep 9, 2009 at 1:15 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:
>> Alvaro Herrera <alvherre@commandprompt.com> writes:
>>> Another possible example is sprintf:
>>
>>> create function sprintf(text, anyelement, anyelement2, anyelement3, ...)
>>> returns text
>>
>>> In order for this to work in general, we'd need FUNC_MAX_ARGS different
>>> types, which is currently defined as 100 in our code.
>>
>> But here, "any" would work perfectly fine, since there's no need for
>> any two arguments to be tied to each other or the result.
>>
>> Given that we've got away so far with only 1 instance of anyelement,
>> I'm not really convinced that there's a market for more than anyelement2
>> (and anyarray2, etc).
>
> I'm going to go out on a limb and say that if we're going to bother
> changing the status quo, we ought to create a reasonable number of
> these - maybe, say, four.  I can't see needing a hundred of these, but
> I don't think that we should assume that our inability to think of a
> use for more than two at the moment implies that there can never be
> one.
>
> Really, I think we need a type system that doesn't try to represent
> every type as a 32-bit integer.  Right now, for example, there's no
> reasonable way to write a function that takes another function as an
> argument.  What we need is a system where base types are represented
> by an OID, but derived types (list and functional types) are built up
> using type constructors that take other types as arguments.  So you
> could have a types like list(integer) or list(anyelement) or
> function(integer,bool) [meaning either taking an integer and returning
> a bool, or the other way around, depending on your notational
> preference].  Then you can have functions with complex types like:
>
> maplist : function(anyelement,anyelement2,function(list(anyelement),list(anyelement2)))
>
> This would have the fringe benefit of eliminating types like anyarray
> (which is just list(anyelement)) and the need to list every type twice
> in pg_type, once for the base type and once for the derived array
> type.

it would be nice, but probably it could significant increase parsing
query time. And this is +/- equal to what my transformationHook does.

regards
Pavel Stehule

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


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Pavel Stehule escribió:
> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:

> > I already published a pseudo-sprintf function in the wiki here:
> > http://wiki.postgresql.org/wiki/Sprintf  I'm looking for something
> > better, not just the same hacks.
> >
> > I don't see any good reason that the function needs to be far from core.
> 
> what is use case? Why you need sprintf function, when you have ||
> operator. This functionality is redundant and out of standard. What I
> know, only MySQL has similar function.

Extensive use of || turns into horrible messes quickly.  sprintf() makes
this kind of thing much cleaner.  You could use strcat/strcpy in C too,
but do you?  You could argue that sprintf is redundant in C, yet it
turns out to be extremely useful.

One use case is using it for error messages in RAISE/USING.  Yes, I am
aware you can use concatenation there.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
> Pavel Stehule escribió:
>> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
>
>> > I already published a pseudo-sprintf function in the wiki here:
>> > http://wiki.postgresql.org/wiki/Sprintf  I'm looking for something
>> > better, not just the same hacks.
>> >
>> > I don't see any good reason that the function needs to be far from core.
>>
>> what is use case? Why you need sprintf function, when you have ||
>> operator. This functionality is redundant and out of standard. What I
>> know, only MySQL has similar function.
>
> Extensive use of || turns into horrible messes quickly.  sprintf() makes
> this kind of thing much cleaner.  You could use strcat/strcpy in C too,
> but do you?  You could argue that sprintf is redundant in C, yet it
> turns out to be extremely useful.
>

Yes, I agree. But this functionality you will use only in plpgsql
language. I thing, so there could be some library that should be
separated from standard functions. It would be nice, when people
clearly understand if use some enhancing functionality or some base
sql functionality.

we could to have schema plpgsql. And there could be function subst,

then in your plpgsql proc you can call

if (...) then message := plpgsql.subst('some message:% ...', some value, ...); ....

if you would, then you can add plpgsql schema to search path.

I dislike to use name sprintf, because this or similar function isn't
real sprintf function - it doesn't use compatible format string with
sprintf function.

regards
Pavel Stehule

> One use case is using it for error messages in RAISE/USING.  Yes, I am
> aware you can use concatenation there.
>
> --
> Alvaro Herrera                                http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom Development, 24x7 support
>


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Wed, 2009-09-09 at 09:39 -0400, Tom Lane wrote:
> Peter Eisentraut <peter_e@gmx.net> writes:
> > Well, so far we've only seen use cases in this thread that either
> > already work or that are not well-defined. ;-)
> 
> Well, yeah, the question is can we extract a clear TODO item here.
> 
> I think there are two somewhat orthogonal issues:
> 
> 1. Is a completely unconstrained argument type (ie "any") of any real
> use to PL functions, and if so how can we expose that usefulness?
> The only clear thing to do with such an argument is IS NULL/IS NOT NULL
> tests, which might or might not be worth the trouble.
> 
> 2. Is there any use for arguments with type constraints not covered
> by the existing ANYFOO rules, and if so what do we add for that?
> 
> One comment on point 2 is that it was foreseen from the beginning
> that there would be need for ANYELEMENT2 etc, and I'm actually rather
> surprised that we've gone this long without adding them. 

Where we could need anyelement2 and enyelement3 is if we need the
sameness of any 2 parameters or OUT parameter types

maybe we could (re/ab)use parametrized types and define

anyelement(1), anyelement(2), ..., anyelement(N) and then match them by
the number in parentheses

>  Alvaro made
> a good point about not wanting to multiply the various hard-wired
> OID references, but perhaps some judicious code refactoring could
> prevent a notational disaster.
> 
>             regards, tom lane

-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Wed, 2009-09-09 at 15:10 -0400, Robert Haas wrote:
> On Wed, Sep 9, 2009 at 1:15 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:
> > Alvaro Herrera <alvherre@commandprompt.com> writes:
> >> Another possible example is sprintf:
> >
> >> create function sprintf(text, anyelement, anyelement2, anyelement3, ...)
> >> returns text
> >
> >> In order for this to work in general, we'd need FUNC_MAX_ARGS different
> >> types, which is currently defined as 100 in our code.
> >
> > But here, "any" would work perfectly fine, since there's no need for
> > any two arguments to be tied to each other or the result.
> >
> > Given that we've got away so far with only 1 instance of anyelement,
> > I'm not really convinced that there's a market for more than anyelement2
> > (and anyarray2, etc).
> 
> I'm going to go out on a limb and say that if we're going to bother
> changing the status quo, we ought to create a reasonable number of
> these - maybe, say, four.  I can't see needing a hundred of these, but
> I don't think that we should assume that our inability to think of a
> use for more than two at the moment implies that there can never be
> one.
> 
> Really, I think we need a type system that doesn't try to represent
> every type as a 32-bit integer.  Right now, for example, there's no
> reasonable way to write a function that takes another function as an
> argument.  What we need is a system where base types are represented
> by an OID, but derived types (list and functional types) are built up
> using type constructors that take other types as arguments.

There is nothing that prevents us from representing those by an OID as
well.

Though how to define and store those in pg_type is another issue. 

>   So you
> could have a types like list(integer) or list(anyelement) or
> function(integer,bool) [meaning either taking an integer and returning
> a bool, or the other way around, depending on your notational
> preference].  Then you can have functions with complex types like:
> 
> maplist : function(anyelement,anyelement2,function(list(anyelement),list(anyelement2)))
> 
> This would have the fringe benefit of eliminating types like anyarray
> (which is just list(anyelement)) and the need to list every type twice
> in pg_type, once for the base type and once for the derived array
> type.
> 
> </handwaving>
> 
> ...Robert

-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Hannu Krosing <hannu@2ndQuadrant.com> writes:
> maybe we could (re/ab)use parametrized types and define

> anyelement(1), anyelement(2), ..., anyelement(N) and then match them by
> the number in parentheses

Yeah, that idea occurred to me too.  The immediate practical problem is
that we don't store a typmod for function argument/result types.
I guess we could look into doing that ...
        regards, tom lane


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/9 Hannu Krosing <hannu@krosing.net>:
> On Wed, 2009-09-09 at 21:57 +0200, Pavel Stehule wrote:
>> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
>> > Pavel Stehule escribió:
>> >> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
>> >
>> >> > I already published a pseudo-sprintf function in the wiki here:
>> >> > http://wiki.postgresql.org/wiki/Sprintf  I'm looking for something
>> >> > better, not just the same hacks.
>> >> >
>> >> > I don't see any good reason that the function needs to be far from core.
>> >>
>> >> what is use case? Why you need sprintf function, when you have ||
>> >> operator. This functionality is redundant and out of standard. What I
>> >> know, only MySQL has similar function.
>> >
>> > Extensive use of || turns into horrible messes quickly.  sprintf() makes
>> > this kind of thing much cleaner.  You could use strcat/strcpy in C too,
>> > but do you?  You could argue that sprintf is redundant in C, yet it
>> > turns out to be extremely useful.
>> >
>>
>> Yes, I agree. But this functionality you will use only in plpgsql
>> language. I thing, so there could be some library that should be
>> separated from standard functions. It would be nice, when people
>> clearly understand if use some enhancing functionality or some base
>> sql functionality.
>
> There is lots of stuff in postgreSQL, especially functions, that is not
> "some base sql functionality", yet is in core.
>
>>
>> we could to have schema plpgsql. And there could be function subst,
>>
>> then in your plpgsql proc you can call
>>
>> if (...) then
>>   message := plpgsql.subst('some message:% ...', some value, ...);
>>   ....
>>
>> if you would, then you can add plpgsql schema to search path.
>>
>> I dislike to use name sprintf, because this or similar function isn't
>> real sprintf function - it doesn't use compatible format string with
>> sprintf function.
>
> call it format(txt, variadic "any") - that's what it does

why not?

this function should be in contrib - as variadic function sample.

Pavel

>
>> regards
>> Pavel Stehule
>>
>> > One use case is using it for error messages in RAISE/USING.  Yes, I am
>> > aware you can use concatenation there.
>> >
>> > --
>> > Alvaro Herrera                                http://www.CommandPrompt.com/
>> > PostgreSQL Replication, Consulting, Custom Development, 24x7 support
>> >
>>
>
>


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Wed, 2009-09-09 at 21:57 +0200, Pavel Stehule wrote:
> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
> > Pavel Stehule escribió:
> >> 2009/9/9 Alvaro Herrera <alvherre@commandprompt.com>:
> >
> >> > I already published a pseudo-sprintf function in the wiki here:
> >> > http://wiki.postgresql.org/wiki/Sprintf  I'm looking for something
> >> > better, not just the same hacks.
> >> >
> >> > I don't see any good reason that the function needs to be far from core.
> >>
> >> what is use case? Why you need sprintf function, when you have ||
> >> operator. This functionality is redundant and out of standard. What I
> >> know, only MySQL has similar function.
> >
> > Extensive use of || turns into horrible messes quickly.  sprintf() makes
> > this kind of thing much cleaner.  You could use strcat/strcpy in C too,
> > but do you?  You could argue that sprintf is redundant in C, yet it
> > turns out to be extremely useful.
> >
> 
> Yes, I agree. But this functionality you will use only in plpgsql
> language. I thing, so there could be some library that should be
> separated from standard functions. It would be nice, when people
> clearly understand if use some enhancing functionality or some base
> sql functionality.

There is lots of stuff in postgreSQL, especially functions, that is not
"some base sql functionality", yet is in core.

> 
> we could to have schema plpgsql. And there could be function subst,
> 
> then in your plpgsql proc you can call
> 
> if (...) then
>   message := plpgsql.subst('some message:% ...', some value, ...);
>   ....
> 
> if you would, then you can add plpgsql schema to search path.
> 
> I dislike to use name sprintf, because this or similar function isn't
> real sprintf function - it doesn't use compatible format string with
> sprintf function.

call it format(txt, variadic "any") - that's what it does

> regards
> Pavel Stehule
> 
> > One use case is using it for error messages in RAISE/USING.  Yes, I am
> > aware you can use concatenation there.
> >
> > --
> > Alvaro Herrera                                http://www.CommandPrompt.com/
> > PostgreSQL Replication, Consulting, Custom Development, 24x7 support
> >
> 



Re: RfD: more powerful "any" types

From
Sam Mason
Date:
On Wed, Sep 09, 2009 at 03:23:52PM -0400, Tom Lane wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
> > What we need is a system where base types are represented
> > by an OID, but derived types (list and functional types) are built up
> > using type constructors that take other types as arguments.
> 
> This is SQL, not Haskell.  What you suggest seems about two orders of
> magnitude more complex than real-world applications could justify.

Parametric polymorphism seems to have made it well into the mainstream
now, Java, C# and many other "mainstream" languages have got it, it's
not just ML and Haskell any more.  Excuses of it being of esoteric
academic interest alone seem a little misplaced.

It would also tidy up a lot of the features that already exist in PG.
Arrays in PG already effectively have a type parameter, why not extend
this to normal user's code?  Even staying within the types in PG,
I've wanted to use the geometric functions parametrized over integer
and numeric types before, fixing them to double precision types seems
unfortunate.

--  Sam  http://samason.me.uk/


Re: RfD: more powerful "any" types

From
decibel
Date:
On Sep 9, 2009, at 2:36 PM, Alvaro Herrera wrote:
> Robert Haas escribió:
>
>> Really, I think we need a type system that doesn't try to represent
>> every type as a 32-bit integer.  Right now, for example, there's no
>> reasonable way to write a function that takes another function as an
>> argument.
>
> Function references would be neat -- I remember wanting to use these a
> couple of times (map/reduce?)


Yeah, I recall having a want for that as well, though I can't
remember what the use case was now. :/

Though that kind of flexibility is probably the most complete
solution, going with the idea of anyelement(N) might be a lot more
practical...
--
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828




Re: RfD: more powerful "any" types

From
Dimitri Fontaine
Date:
Hi,

Tom Lane <tgl@sss.pgh.pa.us> writes:
> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>> anyelement(1), anyelement(2), ..., anyelement(N) and then match them by
>> the number in parentheses
>
> Yeah, that idea occurred to me too.  The immediate practical problem is
> that we don't store a typmod for function argument/result types.
> I guess we could look into doing that ...

But still, it looks terrible...

On Sep 9, 2009, at 4:44 AM, Peter Eisentraut wrote:
> That's beginning to sound a bit like a generics feature.  E.g.,
>
> CREATE FUNCTION the_same<T>(arg_a T, arg_b T) RETURNS bool AS $$
> SELECT arg_a IS DISTINCT FROM arg_b;
> $$;

And even if we don't want to go this far (I'd be in favor of going there
FWIW), we could maybe have a syntax allowing the users to name or
declare the any types he'll need?

CREATE FUNCTION foo(a anyelement x, b anyelement x, c anyelement y)RETURNS anyelement y[]
AS $$
... 
$$;

Now we have anyelement and anyelement2, but without the ugly names or
the typmod feature stretching, and we can even have any number of user
defined anyelement types. That behave just like anyelement.

Then, maybe we need VARIADIC anyelement any[] to declare the function as able
to cope with a variable length list of all different kinds of elements?

Regards,
-- 
dim


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Wed, Sep 9, 2009 at 3:23 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
>> What we need is a system where base types are represented
>> by an OID, but derived types (list and functional types) are built up
>> using type constructors that take other types as arguments.
>
> This is SQL, not Haskell.  What you suggest seems about two orders of
> magnitude more complex than real-world applications could justify.
>
> (so where is pl/haskell, anyway?)

There are languages much less obscure than Haskell that support
passing functions as arguments to other functions, such as C.   While
C doesn't support user-defined type constructors, it does support one
built-in type constructor - you can declare a function argument as
taking arbitrary argument types and returning an arbitrary type.  C++
supports user-defined type constructors via the template mechanism.

The scripting languages generally do not guarantee type-safety for
functions passed as arguments, but they do let you pass them.
However, I can't really imagine how we could get away with such a
system in SQL, due to security concerns.

...Robert


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 00:31 +0200, Dimitri Fontaine wrote:
> Hi,
> 
> Tom Lane <tgl@sss.pgh.pa.us> writes:
> > Hannu Krosing <hannu@2ndQuadrant.com> writes:
> >> anyelement(1), anyelement(2), ..., anyelement(N) and then match them by
> >> the number in parentheses
> >
> > Yeah, that idea occurred to me too.  The immediate practical problem is
> > that we don't store a typmod for function argument/result types.
> > I guess we could look into doing that ...
> 
> But still, it looks terrible...
> 
> On Sep 9, 2009, at 4:44 AM, Peter Eisentraut wrote:
> > That's beginning to sound a bit like a generics feature.  E.g.,
> >
> > CREATE FUNCTION the_same<T>(arg_a T, arg_b T) RETURNS bool AS $$
> > SELECT arg_a IS DISTINCT FROM arg_b;
> > $$;
> 
> And even if we don't want to go this far (I'd be in favor of going there
> FWIW), we could maybe have a syntax allowing the users to name or
> declare the any types he'll need?
> 
> CREATE FUNCTION foo(a anyelement x, b anyelement x, c anyelement y)
>  RETURNS anyelement y[]
> AS $$
> ... 
> $$;
> 
> Now we have anyelement and anyelement2, but without the ugly names or
> the typmod feature stretching, and we can even have any number of user
> defined anyelement types. That behave just like anyelement.
> 
> Then, maybe we need VARIADIC anyelement any[] to declare the function as able
> to cope with a variable length list of all different kinds of elements?

maybe just let users say what they mean, so first time we have "any" and
if we need more then we say "same_as(...)"

so your example becomes

CREATE FUNCTION foo(a any, b same_type_as(a), c any) RETURNS same_type_as(c)[]AS $$... $$;

or the same using positional arguments

CREATE FUNCTION foo(a any, b same_type_as(1), c any) RETURNS same_type_as(3)[]AS $$... $$;

this then gets transformed at parse time to whatever internal
representation of type sameness we use.

-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 08:44 +0300, Hannu Krosing wrote:

> maybe just let users say what they mean, so first time we have "any" and
> if we need more then we say "same_as(...)"

Acutually we could be even more SQL-y and have a more verbose syntax for
pseudotypes by extending the grammar 

CREATE FUNCTION foo(  a ANY TYPE,  b SAME TYPE AS a,  c ANY TYPE
OUT d ARRAY OF SAME TYPE AS c
) ....

TYPE could probably be optional 


> so your example becomes
> 
>  
> CREATE FUNCTION foo(a any, b same_type_as(a), c any)
>   RETURNS same_type_as(c)[]
>  AS $$
>  ... 
>  $$;
> 
> or the same using positional arguments
> 
> CREATE FUNCTION foo(a any, b same_type_as(1), c any)
>   RETURNS same_type_as(3)[]
>  AS $$
>  ... 
>  $$;
> 
> this then gets transformed at parse time to whatever internal
> representation of type sameness we use.
> 
> -- 
> Hannu Krosing   http://www.2ndQuadrant.com
> PostgreSQL Scalability and Availability 
>    Services, Consulting and Training
> 
> 
> 



Re: RfD: more powerful "any" types

From
Peter Eisentraut
Date:
On Wed, 2009-09-09 at 16:31 -0400, Tom Lane wrote:
> The immediate practical problem is
> that we don't store a typmod for function argument/result types.
> I guess we could look into doing that ...

I think that functionality could also end up being useful for other
types.



Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Hannu Krosing <hannu@krosing.net>:
> On Thu, 2009-09-10 at 08:44 +0300, Hannu Krosing wrote:
>
>> maybe just let users say what they mean, so first time we have "any" and
>> if we need more then we say "same_as(...)"
>
> Acutually we could be even more SQL-y and have a more verbose syntax for
> pseudotypes by extending the grammar
>
> CREATE FUNCTION foo(
>   a ANY TYPE,
>   b SAME TYPE AS a,
>   c ANY TYPE
> OUT d ARRAY OF SAME TYPE AS c
> ) ....
>
> TYPE could probably be optional
>

We could define anything, but we have to implement function searching
algorithm, that understand this new feature, and that is compatible
with current behave. Syntax is some simple, but the core is in
namespace.c.

regards
Pavel


>
>> so your example becomes
>>
>>
>> CREATE FUNCTION foo(a any, b same_type_as(a), c any)
>>   RETURNS same_type_as(c)[]
>>  AS $$
>>  ...
>>  $$;
>>
>> or the same using positional arguments
>>
>> CREATE FUNCTION foo(a any, b same_type_as(1), c any)
>>   RETURNS same_type_as(3)[]
>>  AS $$
>>  ...
>>  $$;
>>
>> this then gets transformed at parse time to whatever internal
>> representation of type sameness we use.
>>
>> --
>> Hannu Krosing   http://www.2ndQuadrant.com
>> PostgreSQL Scalability and Availability
>>    Services, Consulting and Training
>>
>>
>>
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>


Re: RfD: more powerful "any" types

From
"Kevin Grittner"
Date:
Robert Haas <robertmhaas@gmail.com> wrote:
> There are languages much less obscure than Haskell that support
> passing functions as arguments to other functions, such as C.
Or Java, which lets you, for example, pass a Class or Method as an
argument, and includes support for generics.
I see that pgfoundry has pl/Java, which has an activity percentile
of 91.08%.  I'm not sure whether this could address the needs that
started this discussion, since I assume such capabilities would only
be usable when invoking one Java method from another.  I'm just
saying -- these features aren't all that esoteric; we use
introspection and reflection within our Java software.  While we
probably wouldn't use such features in PostgreSQL (if they were
there) because of our portability mandate; I can certainly
understand those who don't mind PostgreSQL-specific code and want to
move more of the business logic to the DBMS wanting such features.
-Kevin


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Pavel Stehule escribió:

> Please, try to compile and run sprintf function from attachment

There's a minor bug in the comparison to PG_NARGS() inside the loop,
fixed in this version.

The one problem I have with this is that if the format string does not
contain any % (and thus there is no extra argument), it errors out:

alvherre=# select text_format('ouch');
ERROR:  function text_format(unknown) does not exist
LÍNEA 1: select text_format('ouch');
                ^
SUGERENCIA:  No function matches the given name and argument types. You might need to add explicit type casts.

AFAICS fixing this would require a second pg_proc entry for this
function.


alvherre=# select text_format('% was % at % and said % % times', 'Pavel'::text, 'here'::unknown, now(),
row('a','b','c'),'{42}'::int[]); 
                                 text_format
-----------------------------------------------------------------------------
 Pavel was here at 2009-09-10 13:12:09.054653-04 and said (a,b,c) {42} times
(1 fila)

--
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

Attachment

Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> alvherre=# select text_format('% was % at % and said % % times', 'Pavel'::text, 'here'::unknown, now(),
row('a','b','c'),'{42}'::int[]);
 
>                                  text_format                                 
> -----------------------------------------------------------------------------
>  Pavel was here at 2009-09-10 13:12:09.054653-04 and said (a,b,c) {42} times
> (1 fila)

Is that what's being proposed?  That pretty much sucks --- it's just
another way of concatenating some strings.  I thought the idea was to
provide the same power as sprintf, eg field width controls, numeric
formatting options, etc.
        regards, tom lane


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 10, 2009, at 10:16 AM, Tom Lane wrote:

> Is that what's being proposed?

I think that's what currently works, given the limitations of arrays  
(variadic arguments) to a single data type.

> That pretty much sucks --- it's just
> another way of concatenating some strings.  I thought the idea was to
> provide the same power as sprintf, eg field width controls, numeric
> formatting options, etc.

That would be the goal, yes.

Best,

David


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Sep 10, 2009, at 10:16 AM, Tom Lane wrote:
>> Is that what's being proposed?

> I think that's what currently works, given the limitations of arrays  
> (variadic arguments) to a single data type.

Well, at the very least the parameter markers should be spelled "%s",
so that there's some hope of upward compatibility with a more complete
implementation.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
>> alvherre=# select text_format('% was % at % and said % % times', 'Pavel'::text, 'here'::unknown, now(),
row('a','b','c'),'{42}'::int[]); 
>>                                  text_format
>> -----------------------------------------------------------------------------
>>  Pavel was here at 2009-09-10 13:12:09.054653-04 and said (a,b,c) {42} times
>> (1 fila)
>
> Is that what's being proposed?  That pretty much sucks --- it's just
> another way of concatenating some strings.  I thought the idea was to
> provide the same power as sprintf, eg field width controls, numeric
> formatting options, etc.
>

I thing so this is enough - we can get simply message text - like
raise notice statement. I thing so simple and clean function has more
usability than heavy real sprintf function. We (c coders) are old
dinosaurs - but  nobody else knows what sprintf function does.

I thing so the name only "format" is good, it's short. If you need
some other formating, just you can use to_char function.

Pavel

>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> "David E. Wheeler" <david@kineticode.com> writes:
>> On Sep 10, 2009, at 10:16 AM, Tom Lane wrote:
>>> Is that what's being proposed?
>
>> I think that's what currently works, given the limitations of arrays
>> (variadic arguments) to a single data type.

no, in my code is nothing transformed to single data type.

>
> Well, at the very least the parameter markers should be spelled "%s",
> so that there's some hope of upward compatibility with a more complete
> implementation.

I thing so people who knows sprintf function could be confused. It's
ok for any text types, but for datetime, numeric types and others?
More natural is using complete sprintf's tags, but it is far to
friendly using. So it is reason why I am against to sprintf
implementation in postgres, and I am for implementation some different
function, that just simplify formatting.

format function should be nice with new raise statement syntax.

regards
Pavel Stehule

>
>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 David E. Wheeler <david@kineticode.com>:
> On Sep 10, 2009, at 10:16 AM, Tom Lane wrote:
>
>> Is that what's being proposed?
>
> I think that's what currently works, given the limitations of arrays
> (variadic arguments) to a single data type.
>
>> That pretty much sucks --- it's just
>> another way of concatenating some strings.  I thought the idea was to
>> provide the same power as sprintf, eg field width controls, numeric
>> formatting options, etc.
>
> That would be the goal, yes.

no - we have to_char function, why we need different formatting system?

Pavel

>
> Best,
>
> David
>


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Pavel Stehule <pavel.stehule@gmail.com> writes:
>> On Sep 10, 2009, at 10:16 AM, Tom Lane wrote:
>>> I thought the idea was to
>>> provide the same power as sprintf, eg field width controls, numeric
>>> formatting options, etc.

> no - we have to_char function, why we need different formatting system?

Why do we need this at all, when we have the concatenation operator?
I think the point of it is that people are used to how sprintf works.
So it should work as nearly like sprintf as possible.
        regards, tom lane


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 10, 2009, at 11:16 AM, Tom Lane wrote:

>> no - we have to_char function, why we need different formatting  
>> system?
>
> Why do we need this at all, when we have the concatenation operator?
> I think the point of it is that people are used to how sprintf works.
> So it should work as nearly like sprintf as possible.

+1

David


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Wed, Sep 9, 2009 at 3:44 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
>> Really, I think we need a type system that doesn't try to represent
>> every type as a 32-bit integer.  Right now, for example, there's no
>> reasonable way to write a function that takes another function as an
>> argument.  What we need is a system where base types are represented
>> by an OID, but derived types (list and functional types) are built up
>> using type constructors that take other types as arguments.  So you
>> could have a types like list(integer) or list(anyelement) or
>> function(integer,bool) [meaning either taking an integer and returning
>> a bool, or the other way around, depending on your notational
>> preference].  Then you can have functions with complex types like:
>>
>> maplist : function(anyelement,anyelement2,function(list(anyelement),list(anyelement2)))
>>
>> This would have the fringe benefit of eliminating types like anyarray
>> (which is just list(anyelement)) and the need to list every type twice
>> in pg_type, once for the base type and once for the derived array
>> type.
>
> it would be nice, but probably it could significant increase parsing
> query time. And this is +/- equal to what my transformationHook does.

I can't believe that this is even close to being correct.
Transformationhook is a cheap syntax hack (sorry, but it is).  It's
not going to solve the problem of people who want anyelement and
anyelement2, nor will it solve the problem of people who want to pass
functions as arguments or treat them as first-class objects.

The major downside of such a system is that every place where we now
count on being able to store a type in a fixed-size field would need
to be touched.  I don't believe that the overall slowdown in parsing
time would be significant, but I do think it would be a massive,
highly invasive, highly destabilizing patch.  For the level of pain
involved, there might be better uses of our time, which is not to say
that I'd be in favor of rejecting such a patch out of hand if someone
felt called to develop it (Tom might, though).

...Robert


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Pavel Stehule <pavel.stehule@gmail.com> writes:
>>> On Sep 10, 2009, at 10:16 AM, Tom Lane wrote:
>>>> I thought the idea was to
>>>> provide the same power as sprintf, eg field width controls, numeric
>>>> formatting options, etc.
>
>> no - we have to_char function, why we need different formatting system?
>
> Why do we need this at all, when we have the concatenation operator?

what is more readable?

select 'i=' || i || ', b=' || b || ', c=' || c ..

or

select format('i=%, b=%, c=%', i, b, c ..)

> I think the point of it is that people are used to how sprintf works.
> So it should work as nearly like sprintf as possible.
>

How sprintf will be print bytea type, or char(n) type values? I can
understand, so people like some what is well known, but sprintf
function is from other domain than databases. There isn't possible
100% compatible implementation - because sprintf desn't knows arrays,
custom types, rows.

>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Robert Haas <robertmhaas@gmail.com>:
> On Wed, Sep 9, 2009 at 3:44 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
>>> Really, I think we need a type system that doesn't try to represent
>>> every type as a 32-bit integer.  Right now, for example, there's no
>>> reasonable way to write a function that takes another function as an
>>> argument.  What we need is a system where base types are represented
>>> by an OID, but derived types (list and functional types) are built up
>>> using type constructors that take other types as arguments.  So you
>>> could have a types like list(integer) or list(anyelement) or
>>> function(integer,bool) [meaning either taking an integer and returning
>>> a bool, or the other way around, depending on your notational
>>> preference].  Then you can have functions with complex types like:
>>>
>>> maplist : function(anyelement,anyelement2,function(list(anyelement),list(anyelement2)))
>>>
>>> This would have the fringe benefit of eliminating types like anyarray
>>> (which is just list(anyelement)) and the need to list every type twice
>>> in pg_type, once for the base type and once for the derived array
>>> type.
>>
>> it would be nice, but probably it could significant increase parsing
>> query time. And this is +/- equal to what my transformationHook does.
>
> I can't believe that this is even close to being correct.
> Transformationhook is a cheap syntax hack (sorry, but it is).  It's
> not going to solve the problem of people who want anyelement and
> anyelement2, nor will it solve the problem of people who want to pass
> functions as arguments or treat them as first-class objects.

nobody written some better code. Just implement some too simple like
Oracle's decode function, and then talk about this topic. I like to
see this discus, but who looked on FuncnameGetCandidates functions,
and who knows, what is really possible.

regards
Pavel

>
> The major downside of such a system is that every place where we now
> count on being able to store a type in a fixed-size field would need
> to be touched.  I don't believe that the overall slowdown in parsing
> time would be significant, but I do think it would be a massive,
> highly invasive, highly destabilizing patch.  For the level of pain
> involved, there might be better uses of our time, which is not to say
> that I'd be in favor of rejecting such a patch out of hand if someone
> felt called to develop it (Tom might, though).
>
> ...Robert
>


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> The major downside of such a system is that every place where we now
> count on being able to store a type in a fixed-size field would need
> to be touched.  I don't believe that the overall slowdown in parsing
> time would be significant, but I do think it would be a massive,
> highly invasive, highly destabilizing patch.  For the level of pain
> involved, there might be better uses of our time,

Yeah, that's exactly the problem.

I am not sure that we really *have to* have a non-OID-based type
representation though.  We have managed to have composite types without
that, and I don't see why something similar would not work for
functional types.

But that's all well beyond the immediate problem, which is whether we
need something more flexible than "anyelement".  ISTM we had these
not-all-mutually-exclusive ideas on the table:

1. Allow the existing "any" pseudotype as an input argument type for PLs.
(AFAICS this is simple and painless; about the only question is whether
we want to keep using the name "any", which because of conflicting with
a reserved word would always need the double quotes.)

2. Come up with some way to do the equivalent of "variadic any[]",
ie, a variable number of not-all-the-same-type arguments.  (This isn't
just a type-system problem, there's also the question of how the type
information would be passed at runtime.  IIRC we have a solution at the
C level but not for PLs.)

3. Add anyelement2/anyarray2, and maybe also -3 and -4 while at it.

4. Instead of #3, allow anyelement(N), which is certainly more flexible
than #3 but would require a much larger investment of work.  (I'm
uncertain whether attaching typmods to function arguments/results could
have any interesting or unpleasant semantic side effects.  It might be
all good, or maybe not.  It would definitely need some thought.)

5. Various syntactic sugar to substitute for anyelement.  (Not in favor
of this myself, it seems to just complicate matters.)

Functional types might be interesting in the long run but I don't see
that they alter the need for one or more of these.
        regards, tom lane


Re: RfD: more powerful "any" types

From
"Kevin Grittner"
Date:
Pavel Stehule <pavel.stehule@gmail.com> wrote:
> what is more readable?
> 
> select 'i=' || i || ', b=' || b || ', c=' || c ..
> 
> or
> 
> select format('i=%, b=%, c=%', i, b, c ..)
Seriously, those are about dead even for me.  The concatenation
might have a slight edge, particularly since I have the option, if
it gets out of hand, to do:
select 'i=' || i || ', b=' || b || ', c=' || c ..
-Kevin


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Pavel Stehule <pavel.stehule@gmail.com> writes:
> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>> I think the point of it is that people are used to how sprintf works.
>> So it should work as nearly like sprintf as possible.

> How sprintf will be print bytea type, or char(n) type values?

Well, that's why it requires some actual thought and agreement on a
specification --- sprintf just crashes on type mismatches, but perhaps
the SQL version should be smarter.  You shouldn't expect that the
easiest thing to throw together is going to be considered the most
desirable solution.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Pavel Stehule <pavel.stehule@gmail.com> writes:
>> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>>> I think the point of it is that people are used to how sprintf works.
>>> So it should work as nearly like sprintf as possible.
>
>> How sprintf will be print bytea type, or char(n) type values?
>
> Well, that's why it requires some actual thought and agreement on a
> specification --- sprintf just crashes on type mismatches, but perhaps
> the SQL version should be smarter.  You shouldn't expect that the
> easiest thing to throw together is going to be considered the most
> desirable solution.

I don't afraid about crashing. Simply I have not idea what sql
sprintf's behave in case:

SELECT sprintf('some %s', 10)

or

SELECT sprintf('some %d', 10::mycustomtype)

???


>
>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Thu, Sep 10, 2009 at 2:42 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
>> The major downside of such a system is that every place where we now
>> count on being able to store a type in a fixed-size field would need
>> to be touched.  I don't believe that the overall slowdown in parsing
>> time would be significant, but I do think it would be a massive,
>> highly invasive, highly destabilizing patch.  For the level of pain
>> involved, there might be better uses of our time,
>
> Yeah, that's exactly the problem.
>
> I am not sure that we really *have to* have a non-OID-based type
> representation though.  We have managed to have composite types without
> that, and I don't see why something similar would not work for
> functional types.

It might be possible to make it work, but it's likely to create a lot
of bloat in pg_type, and will make it very difficult to implement
features such as anonymous functions (i.e. LAMBDA).  I think it's
further embedding a not-particularly-great design decision.  We've
already patched around the insufficiency of representing types as
32-bit integers for types by adding typmods, but that solution is
incompletely implemented (as exemplified by your comments below under
#4, and I don't think that's the only example) and doesn't handle all
the interesting cases.  Maybe we should move in the direction of
having some kind of semi-opaque Type object that for now can contain a
typid and typmod, and always compare types by using some abstract
function that operates on Types.

> But that's all well beyond the immediate problem, which is whether we
> need something more flexible than "anyelement".  ISTM we had these
> not-all-mutually-exclusive ideas on the table:
>
> 1. Allow the existing "any" pseudotype as an input argument type for PLs.
> (AFAICS this is simple and painless; about the only question is whether
> we want to keep using the name "any", which because of conflicting with
> a reserved word would always need the double quotes.)

+1 from me.  I could go either way on changing the name, but if we're
to do it, first we'll have to think of something better than "any",
which might not be so easy.

> 2. Come up with some way to do the equivalent of "variadic any[]",
> ie, a variable number of not-all-the-same-type arguments.  (This isn't
> just a type-system problem, there's also the question of how the type
> information would be passed at runtime.  IIRC we have a solution at the
> C level but not for PLs.)

This also seems like a good idea.  Will pg_typeof() work for PL/pgsql?I think if we can come up with a solution for
PL/pgsql,it would be 
reasonable to commit this, leaving the tidying up for any PLs for
which the right solution is non-obvious to someone who wants the
feature enough to propose an appropriate patch.

> 3. Add anyelement2/anyarray2, and maybe also -3 and -4 while at it.
>
> 4. Instead of #3, allow anyelement(N), which is certainly more flexible
> than #3 but would require a much larger investment of work.  (I'm
> uncertain whether attaching typmods to function arguments/results could
> have any interesting or unpleasant semantic side effects.  It might be
> all good, or maybe not.  It would definitely need some thought.)

Of these two, I prefer #4, but I don't think #3 would be horrible either.

> 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
> of this myself, it seems to just complicate matters.)

I agree; I don't think this solves any real problem.

...Robert


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Pavel Stehule <pavel.stehule@gmail.com> writes:
>> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>>> I think the point of it is that people are used to how sprintf works.
>>> So it should work as nearly like sprintf as possible.
>
>> How sprintf will be print bytea type, or char(n) type values?
>
> Well, that's why it requires some actual thought and agreement on a
> specification --- sprintf just crashes on type mismatches, but perhaps
> the SQL version should be smarter.  You shouldn't expect that the
> easiest thing to throw together is going to be considered the most
> desirable solution.

I agree. It's time.

regards
Pavel
>
>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Pavel Stehule <pavel.stehule@gmail.com> writes:
> I don't afraid about crashing. Simply I have not idea what sql
> sprintf's behave in case:

> SELECT sprintf('some %s', 10)

That one I don't think is hard --- coerce the input type to text and
print the string.

> SELECT sprintf('some %d', 10::mycustomtype)

For the formats that presume an integer or float input in C, perhaps
we could coerce to numeric (failing if that fails) and then print
appropriately.  Or maybe int or float8 would be more appropriate
conversion targets.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> On Thu, Sep 10, 2009 at 2:42 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> 2. Come up with some way to do the equivalent of "variadic any[]",
>> ie, a variable number of not-all-the-same-type arguments. �(This isn't
>> just a type-system problem, there's also the question of how the type
>> information would be passed at runtime. �IIRC we have a solution at the
>> C level but not for PLs.)

> This also seems like a good idea.  Will pg_typeof() work for PL/pgsql?

pg_typeof() applied to what?  The existing approach assumes we can make
an array out of the variadic parameters, which isn't going to be the
case here.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
good analyse, thank you

2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Robert Haas <robertmhaas@gmail.com> writes:
>> The major downside of such a system is that every place where we now
>> count on being able to store a type in a fixed-size field would need
>> to be touched.  I don't believe that the overall slowdown in parsing
>> time would be significant, but I do think it would be a massive,
>> highly invasive, highly destabilizing patch.  For the level of pain
>> involved, there might be better uses of our time,
>
> Yeah, that's exactly the problem.
>
> I am not sure that we really *have to* have a non-OID-based type
> representation though.  We have managed to have composite types without
> that, and I don't see why something similar would not work for
> functional types.
>
> But that's all well beyond the immediate problem, which is whether we
> need something more flexible than "anyelement".  ISTM we had these
> not-all-mutually-exclusive ideas on the table:
>
> 1. Allow the existing "any" pseudotype as an input argument type for PLs.
> (AFAICS this is simple and painless; about the only question is whether
> we want to keep using the name "any", which because of conflicting with
> a reserved word would always need the double quotes.)
>

I thing so this is possible - I see only one critical point - you
cannot validate source in validation time. You have to wait for run
time. This is some what we leave in plpgsql. I agree, so this is some
time one possible way for high level programming.

> 2. Come up with some way to do the equivalent of "variadic any[]",
> ie, a variable number of not-all-the-same-type arguments.  (This isn't
> just a type-system problem, there's also the question of how the type
> information would be passed at runtime.  IIRC we have a solution at the
> C level but not for PLs.)

again - this is possible, but there could be some strange cases -
because we have not polymorphic assign statement - and there are not
real some polymorphic variable type like variant or some similar (but
it not big problem to implement it). The bigger problem is cached plan
in assign statement, or other statements - minimally in plpgsql.

>
> 3. Add anyelement2/anyarray2, and maybe also -3 and -4 while at it.
>
> 4. Instead of #3, allow anyelement(N), which is certainly more flexible
> than #3 but would require a much larger investment of work.  (I'm
> uncertain whether attaching typmods to function arguments/results could
> have any interesting or unpleasant semantic side effects.  It might be
> all good, or maybe not.  It would definitely need some thought.)

anyelement(n) looks more general. I am not sure about readability.

>
> 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
> of this myself, it seems to just complicate matters.)
>
> Functional types might be interesting in the long run but I don't see
> that they alter the need for one or more of these.
>

There could be some use cases like work-flow systems or maybe
scheduler event executor.

regards
Pavel Stehule


>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Pavel Stehule <pavel.stehule@gmail.com> writes:
> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>> 1. Allow the existing "any" pseudotype as an input argument type for PLs.
>> (AFAICS this is simple and painless; about the only question is whether
>> we want to keep using the name "any", which because of conflicting with
>> a reserved word would always need the double quotes.)

> I thing so this is possible - I see only one critical point - you
> cannot validate source in validation time.

How's it any different from anyelement?
        regards, tom lane


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Thu, Sep 10, 2009 at 3:15 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Robert Haas <robertmhaas@gmail.com> writes:
>> On Thu, Sep 10, 2009 at 2:42 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>>> 2. Come up with some way to do the equivalent of "variadic any[]",
>>> ie, a variable number of not-all-the-same-type arguments.  (This isn't
>>> just a type-system problem, there's also the question of how the type
>>> information would be passed at runtime.  IIRC we have a solution at the
>>> C level but not for PLs.)
>
>> This also seems like a good idea.  Will pg_typeof() work for PL/pgsql?
>
> pg_typeof() applied to what?  The existing approach assumes we can make
> an array out of the variadic parameters, which isn't going to be the
> case here.

Oh.  For some reason I thought that would still be possible.  I don't
think it's worth designing a whole new PL/pgsql language construct
just to support this feature.  Given that this should be a relatively
unusual type of function, asking people to write them in C doesn't
seem unreasonable.

...Robert


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Pavel Stehule <pavel.stehule@gmail.com> writes:
>> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>>> 1. Allow the existing "any" pseudotype as an input argument type for PLs.
>>> (AFAICS this is simple and painless; about the only question is whether
>>> we want to keep using the name "any", which because of conflicting with
>>> a reserved word would always need the double quotes.)
>
>> I thing so this is possible - I see only one critical point - you
>> cannot validate source in validation time.
>
> How's it any different from anyelement?

true, if I remember well, there is substitution from anyelement to int?

maybe from this perspective can be good to separate polymorphic types
to some kinds:

any - really unknown type - there is possible only check on null or
not null (and maybe some basic operations).
anytext - any value (substituted to text) in validation time
anynumeric - any value (substitued to integer) in validation time.

regards
Pavel Stehule

>
>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> Pavel Stehule <pavel.stehule@gmail.com> writes:
>> I don't afraid about crashing. Simply I have not idea what sql
>> sprintf's behave in case:
>
>> SELECT sprintf('some %s', 10)
>
> That one I don't think is hard --- coerce the input type to text and
> print the string.
>
>> SELECT sprintf('some %d', 10::mycustomtype)
>
> For the formats that presume an integer or float input in C, perhaps
> we could coerce to numeric (failing if that fails) and then print
> appropriately.  Or maybe int or float8 would be more appropriate
> conversion targets.

it's possible - so format tags doesn't mean data type, but it means
"try to drow it as type" - etc invisible explicit casting. It could
work, but it doesn't look like SQL.

regards
Pavel Stehule

>
>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
> On Thu, Sep 10, 2009 at 2:42 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Robert Haas <robertmhaas@gmail.com> writes:
> >> The major downside of such a system is that every place where we now
> >> count on being able to store a type in a fixed-size field would need
> >> to be touched.  I don't believe that the overall slowdown in parsing
> >> time would be significant, but I do think it would be a massive,
> >> highly invasive, highly destabilizing patch.  For the level of pain
> >> involved, there might be better uses of our time,
> >
> > Yeah, that's exactly the problem.
> >
> > I am not sure that we really *have to* have a non-OID-based type
> > representation though.  We have managed to have composite types without
> > that, and I don't see why something similar would not work for
> > functional types.
> 
> It might be possible to make it work, but it's likely to create a lot
> of bloat in pg_type, and will make it very difficult to implement
> features such as anonymous functions (i.e. LAMBDA). 

For functions, anonymous does not mean "impossible to identify" ;)

If it is something (semi)-permanent we should store it in pg_type and id
it by oid, if it is really, really transient (say a closure generated
upper in the function chain) we can probably assign it some kind of
temporary, per-process oid for the duration of its existence

>  I think it's
> further embedding a not-particularly-great design decision.  We've
> already patched around the insufficiency of representing types as
> 32-bit integers for types by adding typmods, but that solution is
> incompletely implemented (as exemplified by your comments below under
> #4, and I don't think that's the only example) and doesn't handle all
> the interesting cases.  Maybe we should move in the direction of
> having some kind of semi-opaque Type object that for now can contain a
> typid and typmod, and always compare types by using some abstract
> function that operates on Types.

here we still could reference this Type object by a 32 bit integer,
which points to either persistent or temporary "pg_type row"

The trick is to look up (typeid,typmod) pairs in some hashtable and not
generate duplicates.

> 
> > But that's all well beyond the immediate problem, which is whether we
> > need something more flexible than "anyelement".  ISTM we had these
> > not-all-mutually-exclusive ideas on the table:
>
> > 1. Allow the existing "any" pseudotype as an input argument type for PLs.
> > (AFAICS this is simple and painless; about the only question is whether
> > we want to keep using the name "any", which because of conflicting with
> > a reserved word would always need the double quotes.)
> 
> +1 from me.  I could go either way on changing the name, but if we're
> to do it, first we'll have to think of something better than "any",
> which might not be so easy.

we could also change parser and translate reserved word ANY to typename
"any" .

> > 2. Come up with some way to do the equivalent of "variadic any[]",
> > ie, a variable number of not-all-the-same-type arguments.  (This isn't
> > just a type-system problem, there's also the question of how the type
> > information would be passed at runtime.  IIRC we have a solution at the
> > C level but not for PLs.)
> 
> This also seems like a good idea.  Will pg_typeof() work for PL/pgsql?
>  I think if we can come up with a solution for PL/pgsql, it would be
> reasonable to commit this, leaving the tidying up for any PLs for
> which the right solution is non-obvious to someone who wants the
> feature enough to propose an appropriate patch.
> 
> > 3. Add anyelement2/anyarray2, and maybe also -3 and -4 while at it.
> >
> > 4. Instead of #3, allow anyelement(N), which is certainly more flexible
> > than #3 but would require a much larger investment of work.  (I'm
> > uncertain whether attaching typmods to function arguments/results could
> > have any interesting or unpleasant semantic side effects.  It might be
> > all good, or maybe not.  It would definitely need some thought.)
> 
> Of these two, I prefer #4, but I don't think #3 would be horrible either.

This will introduce some tricky situations, as we can't always do
function lookups in similar way to what we do now for real types.

An example:

f(a int, b text) and f(a text, b int) 

are two different functions which can be distinguished by their
signature

so are

f(a int, b "any") and f(a "any", b int) and f(a "any", b "any")

but 

f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)

seem to be different but actually are not, so we will need to handle
multiple anyelementN types separately from ordinary types.


> > 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
> > of this myself, it seems to just complicate matters.)
> 
> I agree; I don't think this solves any real problem.

agreed, it does not solve the underlying problem, just may make it
easier to understand and remember for users.

ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
are much more SQL-like than needing to write "any" or anyelement(n) as
argument type or return type


-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Hannu Krosing <hannu@2ndQuadrant.com> writes:
> On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
>> It might be possible to make it work, but it's likely to create a lot
>> of bloat in pg_type, and will make it very difficult to implement
>> features such as anonymous functions (i.e. LAMBDA). 

> For functions, anonymous does not mean "impossible to identify" ;)

> If it is something (semi)-permanent we should store it in pg_type and id
> it by oid, if it is really, really transient (say a closure generated
> upper in the function chain) we can probably assign it some kind of
> temporary, per-process oid for the duration of its existence

Right.  See what we do for anonymous composite types.


> we could also change parser and translate reserved word ANY to typename
> "any" .

ANY is a reserved word for good and sufficient reasons.  "Change the
parser" is not an answer.


> f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)

> seem to be different but actually are not, so we will need to handle
> multiple anyelementN types separately from ordinary types.

Excellent point.  This would be an argument in favor of the typmod
approach (and not counting typmod as something that makes two functions
distinct...)
        regards, tom lane


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 21:30 +0200, Pavel Stehule wrote:
> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> > Pavel Stehule <pavel.stehule@gmail.com> writes:
> >> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> >>> 1. Allow the existing "any" pseudotype as an input argument type for PLs.
> >>> (AFAICS this is simple and painless; about the only question is whether
> >>> we want to keep using the name "any", which because of conflicting with
> >>> a reserved word would always need the double quotes.)
> >
> >> I thing so this is possible - I see only one critical point - you
> >> cannot validate source in validation time.
> >
> > How's it any different from anyelement?
> 
> true, if I remember well, there is substitution from anyelement to int?
> 
> maybe from this perspective can be good to separate polymorphic types
> to some kinds:
> 
> any - really unknown type - there is possible only check on null or
> not null (and maybe some basic operations).
> anytext - any value (substituted to text) in validation time
> anynumeric - any value (substitued to integer) in validation time.

I think that way madness lies.

then we should have anyXXX types for almost any subsets of types

anytime , anygeom, anypointpair, anymorethantwopaintgeom, etc...

better have a (possibility of) validation at compile time and
validation/error-throwing at runtime - the latter is needed anyway.

Unless we are going to implement CHECK constraints for function
arguments and then use constraint exclusion for selecting the correct
function ;)

> regards
> Pavel Stehule
> 
> >
> >                        regards, tom lane
> >
> 



Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 21:35 +0200, Pavel Stehule wrote:
> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> > Pavel Stehule <pavel.stehule@gmail.com> writes:
> >> I don't afraid about crashing. Simply I have not idea what sql
> >> sprintf's behave in case:
> >
> >> SELECT sprintf('some %s', 10)
> >
> > That one I don't think is hard --- coerce the input type to text and
> > print the string.
> >
> >> SELECT sprintf('some %d', 10::mycustomtype)
> >
> > For the formats that presume an integer or float input in C, perhaps
> > we could coerce to numeric (failing if that fails) and then print
> > appropriately.  Or maybe int or float8 would be more appropriate
> > conversion targets.
> 
> it's possible - so format tags doesn't mean data type, but it means
> "try to drow it as type" - etc invisible explicit casting. 


what is the difference between these two ?

> It could work, but it doesn't look like SQL.

but we do it all over the place if another type is needed and CAST
exists for getting it

-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 10, 2009, at 12:10 PM, Tom Lane wrote:

>> SELECT sprintf('some %d', 10::mycustomtype)
>
> For the formats that presume an integer or float input in C, perhaps
> we could coerce to numeric (failing if that fails) and then print
> appropriately.  Or maybe int or float8 would be more appropriate
> conversion targets.

Don't forget type categories, which could dictate useful defaults.

Best,

David


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Hannu Krosing <hannu@krosing.net>:
> On Thu, 2009-09-10 at 21:30 +0200, Pavel Stehule wrote:
>> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>> > Pavel Stehule <pavel.stehule@gmail.com> writes:
>> >> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>> >>> 1. Allow the existing "any" pseudotype as an input argument type for PLs.
>> >>> (AFAICS this is simple and painless; about the only question is whether
>> >>> we want to keep using the name "any", which because of conflicting with
>> >>> a reserved word would always need the double quotes.)
>> >
>> >> I thing so this is possible - I see only one critical point - you
>> >> cannot validate source in validation time.
>> >
>> > How's it any different from anyelement?
>>
>> true, if I remember well, there is substitution from anyelement to int?
>>
>> maybe from this perspective can be good to separate polymorphic types
>> to some kinds:
>>
>> any - really unknown type - there is possible only check on null or
>> not null (and maybe some basic operations).
>> anytext - any value (substituted to text) in validation time
>> anynumeric - any value (substitued to integer) in validation time.
>
> I think that way madness lies.
>
> then we should have anyXXX types for almost any subsets of types
>
> anytime , anygeom, anypointpair, anymorethantwopaintgeom, etc...

true :(
>
> better have a (possibility of) validation at compile time and
> validation/error-throwing at runtime - the latter is needed anyway.
>

I have very bad experience with late validation - like plpgsql did. It
could to throw some exception too late (in production) - so this is
some way, where we have to be carefully. It easy to write dynamic
system - but this system should be dangerous in production. When I
started with PostgreSQL I disliked hard typing system, now I love it -
lot of things are predictable.

> Unless we are going to implement CHECK constraints for function
> arguments and then use constraint exclusion for selecting the correct
> function ;)
>
>> regards
>> Pavel Stehule
>>
>> >
>> >                        regards, tom lane
>> >
>>
>
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Hannu Krosing <hannu@2ndquadrant.com>:
> On Thu, 2009-09-10 at 21:35 +0200, Pavel Stehule wrote:
>> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
>> > Pavel Stehule <pavel.stehule@gmail.com> writes:
>> >> I don't afraid about crashing. Simply I have not idea what sql
>> >> sprintf's behave in case:
>> >
>> >> SELECT sprintf('some %s', 10)
>> >
>> > That one I don't think is hard --- coerce the input type to text and
>> > print the string.
>> >
>> >> SELECT sprintf('some %d', 10::mycustomtype)
>> >
>> > For the formats that presume an integer or float input in C, perhaps
>> > we could coerce to numeric (failing if that fails) and then print
>> > appropriately.  Or maybe int or float8 would be more appropriate
>> > conversion targets.
>>
>> it's possible - so format tags doesn't mean data type, but it means
>> "try to drow it as type" - etc invisible explicit casting.
>
>
> what is the difference between these two ?

first is coming from C and has C semantic - there is only one possible
tag (without binary compatible types) - you cannot use %s for numbers,
and %d for strings is some specific value.

sprintf("%d", "10") - show address of static string "10"

second is Tom's proposal. More dynamic. Tag specify target type.

so sprintf('%d', '10') show 10 with possible width manipulation operations

Pavel

>
>> It could work, but it doesn't look like SQL.
>
> but we do it all over the place if another type is needed and CAST
> exists for getting it
>
> --
> Hannu Krosing   http://www.2ndQuadrant.com
> PostgreSQL Scalability and Availability
>   Services, Consulting and Training
>
>
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
There is actualised version, for people who are interested on it.
Minimally it should be sample of variadic "any" function for playing.
Don't afraid, I don't plan to send it to commit fest.

regards
Pavel

2009/9/10 Alvaro Herrera <alvherre@commandprompt.com>:
> Pavel Stehule escribió:
>
>> Please, try to compile and run sprintf function from attachment
>
> There's a minor bug in the comparison to PG_NARGS() inside the loop,
> fixed in this version.
>
> The one problem I have with this is that if the format string does not
> contain any % (and thus there is no extra argument), it errors out:
>
> alvherre=# select text_format('ouch');
> ERROR:  function text_format(unknown) does not exist
> LÍNEA 1: select text_format('ouch');
>                ^
> SUGERENCIA:  No function matches the given name and argument types. You might need to add explicit type casts.
>
> AFAICS fixing this would require a second pg_proc entry for this
> function.
>
>
> alvherre=# select text_format('% was % at % and said % % times', 'Pavel'::text, 'here'::unknown, now(),
row('a','b','c'),'{42}'::int[]); 
>                                 text_format
> -----------------------------------------------------------------------------
>  Pavel was here at 2009-09-10 13:12:09.054653-04 and said (a,b,c) {42} times
> (1 fila)
>
> --
> Alvaro Herrera                                http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom Development, 24x7 support
>

Attachment

Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 22:15 +0200, Pavel Stehule wrote:
> 2009/9/10 Hannu Krosing <hannu@2ndquadrant.com>:
> > On Thu, 2009-09-10 at 21:35 +0200, Pavel Stehule wrote:
> >> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> >> > Pavel Stehule <pavel.stehule@gmail.com> writes:
> >> >> I don't afraid about crashing. Simply I have not idea what sql
> >> >> sprintf's behave in case:
> >> >
> >> >> SELECT sprintf('some %s', 10)
> >> >
> >> > That one I don't think is hard --- coerce the input type to text and
> >> > print the string.
> >> >
> >> >> SELECT sprintf('some %d', 10::mycustomtype)
> >> >
> >> > For the formats that presume an integer or float input in C, perhaps
> >> > we could coerce to numeric (failing if that fails) and then print
> >> > appropriately.  Or maybe int or float8 would be more appropriate
> >> > conversion targets.
> >>
> >> it's possible - so format tags doesn't mean data type, but it means
> >> "try to drow it as type" - etc invisible explicit casting.
> >
> >
> > what is the difference between these two ?
> 
> first is coming from C and has C semantic - there is only one possible
> tag (without binary compatible types) - you cannot use %s for numbers,
> and %d for strings is some specific value.

Similar functionality in python allows %s for any type (it will just get
string representation of the value), but not vice-versa:

>>> '%s' % 10
'10'
>>> '%d' % 10
'10'
>>> '%d' % '10'
Traceback (most recent call last): File "<stdin>", line 1, in <module>
TypeError: %d format: a number is required, not str

More restrictive than Tom's proposal. 

> sprintf("%d", "10") - show address of static string "10"
> 
> second is Tom's proposal. More dynamic. Tag specify target type.
> 
> so sprintf('%d', '10') show 10 with possible width manipulation operations

this would be interesting for cases like

sprintf('%.2f', '3.1415927')

but I'd frefer here python-like sematics, where you need to make
explicit casts, i.e.

sprintf('%.2f', '3.1415927'::float)


-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Dimitri Fontaine
Date:
Hannu Krosing <hannu@2ndQuadrant.com> writes:
>> > 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
>> > of this myself, it seems to just complicate matters.)
>> 
>> I agree; I don't think this solves any real problem.
>
> agreed, it does not solve the underlying problem, just may make it
> easier to understand and remember for users.

Well, depends. I'm not convinced that abusing typmods for solving this
is a good idea, but it's just feeling. Having the same syntax covers
different semantics depending on the context is like interpreting data
in a column in different ways, and is on Josh's list of things to do if
you wanna wreck your database.

> f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)
> 
> seem to be different but actually are not, so we will need to handle
> multiple anyelementN types separately from ordinary types.

Here for example you see that typmod on anyelement would mean something
entirely different from typmod on, say, numeric.

This looks like a ugly hack.

> ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
> are much more SQL-like than needing to write "any" or anyelement(n) as
> argument type or return type

Not only it looks SQL'ish, but it'll be easier to document and use. And
it won't taint typmods, which still need a refactor to better handle
PostGIS needs, btw...


Now there's still the issue of having first class functions: that means
we'd be able to store them, have anonymous (lambda) functions (see the
DO command discussion), higher order function, and open the road to
generic function support. All that jazz is being pushed back with the
very natural counter argument: what good is there for having this in
your SQL database?

So for people on the list who really want to push towards those things,
I suppose providing realistic use cases (how it would simplify this hack
you're maintaining in production) would allow for better exchanges :)

Regards,
-- 
dim


Re: RfD: more powerful "any" types

From
Aidan Van Dyk
Date:
* Pavel Stehule <pavel.stehule@gmail.com> [090910 16:16]:
> first is coming from C and has C semantic - there is only one possible
> tag (without binary compatible types) - you cannot use %s for numbers,
> and %d for strings is some specific value.
> 
> sprintf("%d", "10") - show address of static string "10"
> 
> second is Tom's proposal. More dynamic. Tag specify target type.
> 
> so sprintf('%d', '10') show 10 with possible width manipulation operations

Just to make the task that much harder, if PostgreSQL is going to have a
sprintf (in core, or contrib), I *really* hope it's a real sprintf,
supporting everything, like:  $m positional notation  * width argument  All the flags [#0- +'] (I as a bonus)  field
width. presision 
 

And you're going to want to make sure you support all the regular
conversion specifiers (d/i/o/u/x/X/e/E/f/F/g/G/p/n/c/s)...

How to deal with types conflicting with the conversion specifier is
going to be something necessary to look at (And just crashing a-la-C
probably isn't nice).

If you're making sprintf, then it's going to need to be C-like, and it's
going to be a lot of tedious conversion/formating...  Of course, I'ld
love to see it, because I can forever then forget about all that tedious
formatting in PosgreSQL...

a.

-- 
Aidan Van Dyk                                             Create like a god,
aidan@highrise.ca                                       command like a king,
http://www.highrise.ca/                                   work like a slave.

Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 15:49 -0400, Tom Lane wrote:
> Hannu Krosing <hannu@2ndQuadrant.com> writes:
> > On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
> >> It might be possible to make it work, but it's likely to create a lot
> >> of bloat in pg_type, and will make it very difficult to implement
> >> features such as anonymous functions (i.e. LAMBDA). 
> 
> > For functions, anonymous does not mean "impossible to identify" ;)
> 
> > If it is something (semi)-permanent we should store it in pg_type and id
> > it by oid, if it is really, really transient (say a closure generated
> > upper in the function chain) we can probably assign it some kind of
> > temporary, per-process oid for the duration of its existence
> 
> Right.  See what we do for anonymous composite types.
> 
> 
> > we could also change parser and translate reserved word ANY to typename
> > "any" .
> 
> ANY is a reserved word for good and sufficient reasons.  "Change the
> parser" is not an answer.

I suspect that alt least in some early SQL parsers all type names were reserved.

Or do you see a possible conflict here ? 

What way can ANY be used in function type definition ?

> > f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)
> 
> > seem to be different but actually are not, so we will need to handle
> > multiple anyelementN types separately from ordinary types.
> 
> Excellent point.  This would be an argument in favor of the typmod
> approach (and not counting typmod as something that makes two functions
> distinct...)

this seems like an elegant solution.

OTOH we still have a more compliacted case of

f(a anyelement1, b anyelement1, c anyelement2) 

and 

f(a anyelement1, b anyelement2, c anyelement2)

which may not be solved by non-differentiating typmod



> 
>             regards, tom lane
-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Dimitri Fontaine <dfontaine@hi-media.com>:
> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>>> > 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
>>> > of this myself, it seems to just complicate matters.)
>>>
>>> I agree; I don't think this solves any real problem.
>>
>> agreed, it does not solve the underlying problem, just may make it
>> easier to understand and remember for users.
>
> Well, depends. I'm not convinced that abusing typmods for solving this
> is a good idea, but it's just feeling. Having the same syntax covers
> different semantics depending on the context is like interpreting data
> in a column in different ways, and is on Josh's list of things to do if
> you wanna wreck your database.
>
>> f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)
>>
>> seem to be different but actually are not, so we will need to handle
>> multiple anyelementN types separately from ordinary types.
>
> Here for example you see that typmod on anyelement would mean something
> entirely different from typmod on, say, numeric.
>
> This looks like a ugly hack.
>
>> ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
>> are much more SQL-like than needing to write "any" or anyelement(n) as
>> argument type or return type
>

it's  less confusing, than abstract types. And really nicer.

SQL have to be readable for non hard developers too. And this is
readable. Much more than anylement(1) or anyelement(n).

> Not only it looks SQL'ish, but it'll be easier to document and use. And
> it won't taint typmods, which still need a refactor to better handle
> PostGIS needs, btw...
>
>
> Now there's still the issue of having first class functions: that means
> we'd be able to store them, have anonymous (lambda) functions (see the
> DO command discussion), higher order function, and open the road to
> generic function support. All that jazz is being pushed back with the
> very natural counter argument: what good is there for having this in
> your SQL database?
>
> So for people on the list who really want to push towards those things,
> I suppose providing realistic use cases (how it would simplify this hack
> you're maintaining in production) would allow for better exchanges :)

I am fully agree

regards
Pavel

>
> Regards,
> --
> dim
>


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Thu, Sep 10, 2009 at 4:38 PM, Hannu Krosing <hannu@2ndquadrant.com> wrote:
> On Thu, 2009-09-10 at 15:49 -0400, Tom Lane wrote:
>> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>> > On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
>> >> It might be possible to make it work, but it's likely to create a lot
>> >> of bloat in pg_type, and will make it very difficult to implement
>> >> features such as anonymous functions (i.e. LAMBDA).
>>
>> > For functions, anonymous does not mean "impossible to identify" ;)
>>
>> > If it is something (semi)-permanent we should store it in pg_type and id
>> > it by oid, if it is really, really transient (say a closure generated
>> > upper in the function chain) we can probably assign it some kind of
>> > temporary, per-process oid for the duration of its existence
>>
>> Right.  See what we do for anonymous composite types.
>>
>>
>> > we could also change parser and translate reserved word ANY to typename
>> > "any" .
>>
>> ANY is a reserved word for good and sufficient reasons.  "Change the
>> parser" is not an answer.
>
> I suspect that alt least in some early SQL parsers all type names were reserved.
>
> Or do you see a possible conflict here ?
>
> What way can ANY be used in function type definition ?

Perhaps you should try changing ANY to a non-reserved word in the
parser and see what happens.  If you come up with a way to resolve the
shift/reduce and/or reduce/reduce conflicts that will probably result,
submit a patch.

...Robert


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Thu, Sep 10, 2009 at 4:43 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
> 2009/9/10 Dimitri Fontaine <dfontaine@hi-media.com>:
>> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>>>> > 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
>>>> > of this myself, it seems to just complicate matters.)
>>>>
>>>> I agree; I don't think this solves any real problem.
>>>
>>> agreed, it does not solve the underlying problem, just may make it
>>> easier to understand and remember for users.
>>
>> Well, depends. I'm not convinced that abusing typmods for solving this
>> is a good idea, but it's just feeling. Having the same syntax covers
>> different semantics depending on the context is like interpreting data
>> in a column in different ways, and is on Josh's list of things to do if
>> you wanna wreck your database.
>>
>>> f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)
>>>
>>> seem to be different but actually are not, so we will need to handle
>>> multiple anyelementN types separately from ordinary types.
>>
>> Here for example you see that typmod on anyelement would mean something
>> entirely different from typmod on, say, numeric.
>>
>> This looks like a ugly hack.
>>
>>> ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
>>> are much more SQL-like than needing to write "any" or anyelement(n) as
>>> argument type or return type
>>
>
> it's  less confusing, than abstract types. And really nicer.
>
> SQL have to be readable for non hard developers too. And this is
> readable. Much more than anylement(1) or anyelement(n).
>
>> Not only it looks SQL'ish, but it'll be easier to document and use. And
>> it won't taint typmods, which still need a refactor to better handle
>> PostGIS needs, btw...
>>
>>
>> Now there's still the issue of having first class functions: that means
>> we'd be able to store them, have anonymous (lambda) functions (see the
>> DO command discussion), higher order function, and open the road to
>> generic function support. All that jazz is being pushed back with the
>> very natural counter argument: what good is there for having this in
>> your SQL database?
>>
>> So for people on the list who really want to push towards those things,
>> I suppose providing realistic use cases (how it would simplify this hack
>> you're maintaining in production) would allow for better exchanges :)
>
> I am fully agree

So submit it as a follow-on patch and it can be discussed.  It still
has to translate into some other construct (like anyelement2 or
anyelement(2)) internally, so we might as well do those first before
worrying about the rest of it.

...Robert


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 16:48 -0400, Robert Haas wrote:
> On Thu, Sep 10, 2009 at 4:38 PM, Hannu Krosing <hannu@2ndquadrant.com> wrote:
> > On Thu, 2009-09-10 at 15:49 -0400, Tom Lane wrote:
> >> Hannu Krosing <hannu@2ndQuadrant.com> writes:
> >> > On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
> >> >> It might be possible to make it work, but it's likely to create a lot
> >> >> of bloat in pg_type, and will make it very difficult to implement
> >> >> features such as anonymous functions (i.e. LAMBDA).
> >>
> >> > For functions, anonymous does not mean "impossible to identify" ;)
> >>
> >> > If it is something (semi)-permanent we should store it in pg_type and id
> >> > it by oid, if it is really, really transient (say a closure generated
> >> > upper in the function chain) we can probably assign it some kind of
> >> > temporary, per-process oid for the duration of its existence
> >>
> >> Right.  See what we do for anonymous composite types.
> >>
> >>
> >> > we could also change parser and translate reserved word ANY to typename
> >> > "any" .
> >>
> >> ANY is a reserved word for good and sufficient reasons.  "Change the
> >> parser" is not an answer.
> >
> > I suspect that alt least in some early SQL parsers all type names were reserved.
> >
> > Or do you see a possible conflict here ?
> >
> > What way can ANY be used in function type definition ?
> 
> Perhaps you should try changing ANY to a non-reserved word in the
> parser and see what happens.  If you come up with a way to resolve the
> shift/reduce and/or reduce/reduce conflicts that will probably result,
> submit a patch.

I don't want it to be a non-reserved word.

What I want is that this reserved word can be used in function argument
and return type definitions with special meaning

like reserver word FROM , which can be used in two different meanings
like this
SELECT substring(fielda FROM myregex') FROM mytable;




> ...Robert
-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Robert Haas <robertmhaas@gmail.com>:
> On Thu, Sep 10, 2009 at 4:43 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
>> 2009/9/10 Dimitri Fontaine <dfontaine@hi-media.com>:
>>> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>>>>> > 5. Various syntactic sugar to substitute for anyelement.  (Not in favor
>>>>> > of this myself, it seems to just complicate matters.)
>>>>>
>>>>> I agree; I don't think this solves any real problem.
>>>>
>>>> agreed, it does not solve the underlying problem, just may make it
>>>> easier to understand and remember for users.
>>>
>>> Well, depends. I'm not convinced that abusing typmods for solving this
>>> is a good idea, but it's just feeling. Having the same syntax covers
>>> different semantics depending on the context is like interpreting data
>>> in a column in different ways, and is on Josh's list of things to do if
>>> you wanna wreck your database.
>>>
>>>> f(a anyelement1, b anyelement2) and f(a anyelement2, b anyelement1)
>>>>
>>>> seem to be different but actually are not, so we will need to handle
>>>> multiple anyelementN types separately from ordinary types.
>>>
>>> Here for example you see that typmod on anyelement would mean something
>>> entirely different from typmod on, say, numeric.
>>>
>>> This looks like a ugly hack.
>>>
>>>> ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
>>>> are much more SQL-like than needing to write "any" or anyelement(n) as
>>>> argument type or return type
>>>
>>
>> it's  less confusing, than abstract types. And really nicer.
>>
>> SQL have to be readable for non hard developers too. And this is
>> readable. Much more than anylement(1) or anyelement(n).
>>
>>> Not only it looks SQL'ish, but it'll be easier to document and use. And
>>> it won't taint typmods, which still need a refactor to better handle
>>> PostGIS needs, btw...
>>>
>>>
>>> Now there's still the issue of having first class functions: that means
>>> we'd be able to store them, have anonymous (lambda) functions (see the
>>> DO command discussion), higher order function, and open the road to
>>> generic function support. All that jazz is being pushed back with the
>>> very natural counter argument: what good is there for having this in
>>> your SQL database?
>>>
>>> So for people on the list who really want to push towards those things,
>>> I suppose providing realistic use cases (how it would simplify this hack
>>> you're maintaining in production) would allow for better exchanges :)
>>
>> I am fully agree
>
> So submit it as a follow-on patch and it can be discussed.  It still
> has to translate into some other construct (like anyelement2 or
> anyelement(2)) internally, so we might as well do those first before
> worrying about the rest of it.

I sent more general patch. It's irony.

I thing, so syntax ANY [TYPE] and SAME AS [TYPE OF]  is good, very
good. But it works only for functions with fixed argument numbers, so
real usage isn't big. Minimum we need third kind -
COMMON TYPE OF (variables). This patch will be very large - it needs
big change of pg_proc :(

Regards
Pavel

>
> ...Robert
>


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/10 Hannu Krosing <hannu@2ndquadrant.com>:
> On Thu, 2009-09-10 at 16:48 -0400, Robert Haas wrote:
>> On Thu, Sep 10, 2009 at 4:38 PM, Hannu Krosing <hannu@2ndquadrant.com> wrote:
>> > On Thu, 2009-09-10 at 15:49 -0400, Tom Lane wrote:
>> >> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>> >> > On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
>> >> >> It might be possible to make it work, but it's likely to create a lot
>> >> >> of bloat in pg_type, and will make it very difficult to implement
>> >> >> features such as anonymous functions (i.e. LAMBDA).
>> >>
>> >> > For functions, anonymous does not mean "impossible to identify" ;)
>> >>
>> >> > If it is something (semi)-permanent we should store it in pg_type and id
>> >> > it by oid, if it is really, really transient (say a closure generated
>> >> > upper in the function chain) we can probably assign it some kind of
>> >> > temporary, per-process oid for the duration of its existence
>> >>
>> >> Right.  See what we do for anonymous composite types.
>> >>
>> >>
>> >> > we could also change parser and translate reserved word ANY to typename
>> >> > "any" .
>> >>
>> >> ANY is a reserved word for good and sufficient reasons.  "Change the
>> >> parser" is not an answer.
>> >
>> > I suspect that alt least in some early SQL parsers all type names were reserved.
>> >
>> > Or do you see a possible conflict here ?
>> >
>> > What way can ANY be used in function type definition ?
>>
>> Perhaps you should try changing ANY to a non-reserved word in the
>> parser and see what happens.  If you come up with a way to resolve the
>> shift/reduce and/or reduce/reduce conflicts that will probably result,
>> submit a patch.
>
> I don't want it to be a non-reserved word.
>
> What I want is that this reserved word can be used in function argument
> and return type definitions with special meaning
>
> like reserver word FROM , which can be used in two different meanings
> like this
>
>  SELECT substring(fielda FROM myregex') FROM mytable;
>

I thing, so this is possible - this is some steps from pseudotypes to
some function's descriptors (metadata collections).

regards
Pavel
>
>
>
>> ...Robert
> --
> Hannu Krosing   http://www.2ndQuadrant.com
> PostgreSQL Scalability and Availability
>   Services, Consulting and Training
>
>
>


Re: RfD: more powerful "any" types

From
"David E. Wheeler"
Date:
On Sep 10, 2009, at 2:08 PM, Hannu Krosing wrote:

>> Perhaps you should try changing ANY to a non-reserved word in the
>> parser and see what happens.  If you come up with a way to resolve  
>> the
>> shift/reduce and/or reduce/reduce conflicts that will probably  
>> result,
>> submit a patch.
>
> I don't want it to be a non-reserved word.

I say we use "whatever" (quotes not required).

David


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Thu, Sep 10, 2009 at 5:08 PM, Hannu Krosing <hannu@2ndquadrant.com> wrote:
> On Thu, 2009-09-10 at 16:48 -0400, Robert Haas wrote:
>> On Thu, Sep 10, 2009 at 4:38 PM, Hannu Krosing <hannu@2ndquadrant.com> wrote:
>> > On Thu, 2009-09-10 at 15:49 -0400, Tom Lane wrote:
>> >> Hannu Krosing <hannu@2ndQuadrant.com> writes:
>> >> > On Thu, 2009-09-10 at 15:06 -0400, Robert Haas wrote:
>> >> >> It might be possible to make it work, but it's likely to create a lot
>> >> >> of bloat in pg_type, and will make it very difficult to implement
>> >> >> features such as anonymous functions (i.e. LAMBDA).
>> >>
>> >> > For functions, anonymous does not mean "impossible to identify" ;)
>> >>
>> >> > If it is something (semi)-permanent we should store it in pg_type and id
>> >> > it by oid, if it is really, really transient (say a closure generated
>> >> > upper in the function chain) we can probably assign it some kind of
>> >> > temporary, per-process oid for the duration of its existence
>> >>
>> >> Right.  See what we do for anonymous composite types.
>> >>
>> >>
>> >> > we could also change parser and translate reserved word ANY to typename
>> >> > "any" .
>> >>
>> >> ANY is a reserved word for good and sufficient reasons.  "Change the
>> >> parser" is not an answer.
>> >
>> > I suspect that alt least in some early SQL parsers all type names were reserved.
>> >
>> > Or do you see a possible conflict here ?
>> >
>> > What way can ANY be used in function type definition ?
>>
>> Perhaps you should try changing ANY to a non-reserved word in the
>> parser and see what happens.  If you come up with a way to resolve the
>> shift/reduce and/or reduce/reduce conflicts that will probably result,
>> submit a patch.
>
> I don't want it to be a non-reserved word.
>
> What I want is that this reserved word can be used in function argument
> and return type definitions with special meaning
>
> like reserver word FROM , which can be used in two different meanings
> like this
>
>  SELECT substring(fielda FROM myregex') FROM mytable;

OK so implement it.

...Robert


Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Aidan Van Dyk escribió:

> Just to make the task that much harder, if PostgreSQL is going to have a
> sprintf (in core, or contrib), I *really* hope it's a real sprintf,
> supporting everything, like:
>    $m positional notation
>    * width argument
>    All the flags [#0- +'] (I as a bonus)
>    field width . presision 
> 
> And you're going to want to make sure you support all the regular
> conversion specifiers (d/i/o/u/x/X/e/E/f/F/g/G/p/n/c/s)...

Is this really all that hard?  I'm thinking it could be implemented by
using the real C sprintf underneath, passing one % specifier and its
corresponding parameter at a time, coerced to whatever the conversion
specifier specifies.

The only thing that breaks this idea is the $n positional specifiers, I
think.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/11 Alvaro Herrera <alvherre@commandprompt.com>:
> Aidan Van Dyk escribió:
>
>> Just to make the task that much harder, if PostgreSQL is going to have a
>> sprintf (in core, or contrib), I *really* hope it's a real sprintf,
>> supporting everything, like:
>>    $m positional notation
>>    * width argument
>>    All the flags [#0- +'] (I as a bonus)
>>    field width . presision
>>
>> And you're going to want to make sure you support all the regular
>> conversion specifiers (d/i/o/u/x/X/e/E/f/F/g/G/p/n/c/s)...
>
> Is this really all that hard?  I'm thinking it could be implemented by
> using the real C sprintf underneath, passing one % specifier and its
> corresponding parameter at a time, coerced to whatever the conversion
> specifier specifies.

What conversion between PostgreSQL datatypes and C types? PostgreSQL
missing infrastructure for it.

Pavel
>
> The only thing that breaks this idea is the $n positional specifiers, I
> think.
>
> --
> Alvaro Herrera                                http://www.CommandPrompt.com/
> The PostgreSQL Company - Command Prompt, Inc.
>


Re: RfD: more powerful "any" types

From
Aidan Van Dyk
Date:
* Alvaro Herrera <alvherre@commandprompt.com> [090910 23:32]:
> Is this really all that hard?  I'm thinking it could be implemented by
> using the real C sprintf underneath, passing one % specifier and its
> corresponding parameter at a time, coerced to whatever the conversion
> specifier specifies.

It's not "hard", but please, don't break this, to make it more "not
hard":

> The only thing that breaks this idea is the $n positional specifiers, I
> think.

And also, please work for user-defined types (meaning you need to use
the type and catalog system to lookup coercions, not hard-code
anything...

l-)

It's doable, but it's going got be a lot of explicit casting and
coercion, and going to require a lot of documentation and error
states...

Remember, users using sprintf are really going to want it to act exactly
as it would if they were using C, minus the crash part.

a.
-- 
Aidan Van Dyk                                             Create like a god,
aidan@highrise.ca                                       command like a king,
http://www.highrise.ca/                                   work like a slave.

Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Thu, 2009-09-10 at 19:52 +0200, Pavel Stehule wrote:
> 2009/9/10 Tom Lane <tgl@sss.pgh.pa.us>:
> > Alvaro Herrera <alvherre@commandprompt.com> writes:
> >> alvherre=# select text_format('% was % at % and said % % times', 'Pavel'::text, 'here'::unknown, now(),
row('a','b','c'),'{42}'::int[]);
 
> >>                                  text_format
> >> -----------------------------------------------------------------------------
> >>  Pavel was here at 2009-09-10 13:12:09.054653-04 and said (a,b,c) {42} times
> >> (1 fila)
> >
> > Is that what's being proposed?  That pretty much sucks --- it's just
> > another way of concatenating some strings.  I thought the idea was to
> > provide the same power as sprintf, eg field width controls, numeric
> > formatting options, etc.
> >
> 
> I thing so this is enough - we can get simply message text - like
> raise notice statement. I thing so simple and clean function has more
> usability than heavy real sprintf function. We (c coders) are old
> dinosaurs - but  nobody else knows what sprintf function does.

They probably do, as at least PHP and perl have also (s)printf
functions, probably many others as well. But most likely each of them
has a slightly different syntax.

> I thing so the name only "format" is good, it's short. If you need
> some other formating, just you can use to_char function.

yes, format(...) is  generic enough that people won't expect it to
confirm to their favorite languages version of printf.

> Pavel
> 
> >                        regards, tom lane
> >

-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
Alvaro Herrera
Date:
Kevin Grittner escribió:
> Pavel Stehule <pavel.stehule@gmail.com> wrote:
>  
> > what is more readable?
> > 
> > select 'i=' || i || ', b=' || b || ', c=' || c ..
> > 
> > or
> > 
> > select format('i=%, b=%, c=%', i, b, c ..)
>  
> Seriously, those are about dead even for me.  The concatenation
> might have a slight edge, particularly since I have the option, if
> it gets out of hand, to do:
>  
> select 'i=' || i
>   || ', b=' || b
>   || ', c=' || c
>   ..

That barely works for me, and then only because it's a trivial example.
In real uses it's never that clear-cut, and the format version is a lot
better than the || alternative.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


Re: RfD: more powerful "any" types

From
"Kevin Grittner"
Date:
Alvaro Herrera <alvherre@commandprompt.com> wrote:
> the format version is a lot better than the || alternative.
Well, if you're trying to tell me what is easier for me to read,
you're probably wrong.  I won't presume to try to tell you what you
find easier to read.
I think the main benefit of a sprintf type function for PostgreSQL is
in the formatting (setting length, scale, alignment), not in making
concatenation more pretty.
-Kevin


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
"Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
> I think the main benefit of a sprintf type function for PostgreSQL is
> in the formatting (setting length, scale, alignment), not in making
> concatenation more pretty.

Exactly, which is why I'm so distressed that this proposal not only
hasn't got that, but is designed so that it's impossible to add it
later.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> Is this really all that hard?  I'm thinking it could be implemented by
> using the real C sprintf underneath, passing one % specifier and its
> corresponding parameter at a time, coerced to whatever the conversion
> specifier specifies.

The only disadvantage I can see of that is that it would lose precision
for NUMERIC.  I'd really like to be able to write "%300.100f" and have it
Do The Right Thing with a 300-digit numeric input.

> The only thing that breaks this idea is the $n positional specifiers, I
> think.

Yeah, that's a bit of a pain too.  But we have the logic for that in
src/port/.  It wouldn't be that much work to repurpose it.  Actually,
since a SQL implementation wouldn't be constrained to read the actual
arguments left-to-right, you could probably simplify it a great deal.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Robert Haas
Date:
On Fri, Sep 11, 2009 at 10:30 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> "Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
>> I think the main benefit of a sprintf type function for PostgreSQL is
>> in the formatting (setting length, scale, alignment), not in making
>> concatenation more pretty.
>
> Exactly, which is why I'm so distressed that this proposal not only
> hasn't got that, but is designed so that it's impossible to add it
> later.

I like the idea of making concatenation more pretty, quite frankly.
No one has really responded to Pavel's contention that this is what
to_char() is for.  Twice the code paths = twice the bugs, twice the
places that have to be updated when some new feature is added, etc.
On the other hand I don't really strongly object if someone else wants
to do the work, either.  I do think allowing for upward compatibility
with future extensions is probably smart, regardless of how simple or
complex the first version is.

...Robert


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Robert Haas <robertmhaas@gmail.com> writes:
> I like the idea of making concatenation more pretty, quite frankly.
> No one has really responded to Pavel's contention that this is what
> to_char() is for.

[ shrug... ]  I regard this as a prettier replacement for to_char.
That thing has got nothing whatsoever to recommend it, other than being
bug-compatible with Oracle.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Merlin Moncure
Date:
On Fri, Sep 11, 2009 at 11:19 AM, Robert Haas <robertmhaas@gmail.com> wrote:
> On Fri, Sep 11, 2009 at 10:30 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> "Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
>>> I think the main benefit of a sprintf type function for PostgreSQL is
>>> in the formatting (setting length, scale, alignment), not in making
>>> concatenation more pretty.
>>
>> Exactly, which is why I'm so distressed that this proposal not only
>> hasn't got that, but is designed so that it's impossible to add it
>> later.
>
> I like the idea of making concatenation more pretty, quite frankly.
> No one has really responded to Pavel's contention that this is what
> to_char() is for.  Twice the code paths = twice the bugs, twice the
> places that have to be updated when some new feature is added, etc.

If you are going to use printf format codes, which is good and useful
being something of a standard, I'd call routine printf (not format)
and actually wrap vsnprintf.  The format codes in printf have a very
specific meaning: converting native C types to arrays of characters.
I think that a postgresql implementation should do exactly that:
attempt to convert the passed in datum to the c type in question if
possible (erroring if no cast exists) and then pass it down.  The idea
is we are not adding new formatting routines but using a very high
quality existing one...why reinvent the wheel?

so if you did: select printf('%s %3.1f', foo::box, bar::circle);
the box to char* cast would work (using the text cast) but the second
cast would fail unless the user added a cast to float.  The code in
question is easy to imagine...parse the format string, and loop the
varargs using the appropriate looked up cast one by one...

merlin


Re: RfD: more powerful "any" types

From
Merlin Moncure
Date:
On Fri, Sep 11, 2009 at 10:38 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Alvaro Herrera <alvherre@commandprompt.com> writes:
>> Is this really all that hard?  I'm thinking it could be implemented by
>> using the real C sprintf underneath, passing one % specifier and its
>> corresponding parameter at a time, coerced to whatever the conversion
>> specifier specifies.
>
> The only disadvantage I can see of that is that it would lose precision
> for NUMERIC.  I'd really like to be able to write "%300.100f" and have it
> Do The Right Thing with a 300-digit numeric input.

that could be simply worked around by formatting the  numeric in sql
and passing it to printf as %s.

merlin


Re: RfD: more powerful "any" types

From
Tom Lane
Date:
Merlin Moncure <mmoncure@gmail.com> writes:
> If you are going to use printf format codes, which is good and useful
> being something of a standard, I'd call routine printf (not format)
> and actually wrap vsnprintf.  The format codes in printf have a very
> specific meaning: converting native C types to arrays of characters.
> I think that a postgresql implementation should do exactly that:
> attempt to convert the passed in datum to the c type in question if
> possible (erroring if no cast exists) and then pass it down.

I think this is a bit too restrictive.  Aside from the issue of loss of
precision for NUMERIC, do we really want users to have to deal with the
fact that "long" doesn't mean the same thing on every platform?  I don't
want the same SQL to work on some platforms and fail on others because
a particular datatype has a cast to int4 and not to int8, for instance.

We should certainly leverage the C library as much as we can for this,
but exposing users to every single idiosyncrasy of C is not quite the
right thing IMHO.
        regards, tom lane


Re: RfD: more powerful "any" types

From
Merlin Moncure
Date:
On Fri, Sep 11, 2009 at 12:11 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Merlin Moncure <mmoncure@gmail.com> writes:
>> If you are going to use printf format codes, which is good and useful
>> being something of a standard, I'd call routine printf (not format)
>> and actually wrap vsnprintf.  The format codes in printf have a very
>> specific meaning: converting native C types to arrays of characters.
>> I think that a postgresql implementation should do exactly that:
>> attempt to convert the passed in datum to the c type in question if
>> possible (erroring if no cast exists) and then pass it down.
>
> I think this is a bit too restrictive.  Aside from the issue of loss of
> precision for NUMERIC, do we really want users to have to deal with the
> fact that "long" doesn't mean the same thing on every platform?  I don't
> want the same SQL to work on some platforms and fail on others because
> a particular datatype has a cast to int4 and not to int8, for instance.
>
> We should certainly leverage the C library as much as we can for this,
> but exposing users to every single idiosyncrasy of C is not quite the
> right thing IMHO.

hmm. how about leaving the existing format codes alone and making some
safer additional ones that we advice the user to use?   It could
probably be all fixed up in the vsnprintf layer.

merlin


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/11 Tom Lane <tgl@sss.pgh.pa.us>:
> Merlin Moncure <mmoncure@gmail.com> writes:
>> If you are going to use printf format codes, which is good and useful
>> being something of a standard, I'd call routine printf (not format)
>> and actually wrap vsnprintf.  The format codes in printf have a very
>> specific meaning: converting native C types to arrays of characters.
>> I think that a postgresql implementation should do exactly that:
>> attempt to convert the passed in datum to the c type in question if
>> possible (erroring if no cast exists) and then pass it down.
>
> I think this is a bit too restrictive.  Aside from the issue of loss of
> precision for NUMERIC, do we really want users to have to deal with the
> fact that "long" doesn't mean the same thing on every platform?  I don't
> want the same SQL to work on some platforms and fail on others because
> a particular datatype has a cast to int4 and not to int8, for instance.
>
> We should certainly leverage the C library as much as we can for this,
> but exposing users to every single idiosyncrasy of C is not quite the
> right thing IMHO.
>

I am thinking so PostgreSQL sprintf function that isn't real sprintf
function is really perfect idea. I see messages, sprintf doesn't
support format correctly ... And I will have three sprintf functions,
perl, c and postgres, ... still are you thinking, so this is good
idea?

regards
Pavel Stehule

>                        regards, tom lane
>


Re: RfD: more powerful "any" types

From
decibel
Date:
On Sep 11, 2009, at 10:19 AM, Robert Haas wrote:
> On Fri, Sep 11, 2009 at 10:30 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> "Kevin Grittner" <Kevin.Grittner@wicourts.gov> writes:
>>> I think the main benefit of a sprintf type function for  
>>> PostgreSQL is
>>> in the formatting (setting length, scale, alignment), not in making
>>> concatenation more pretty.
>>
>> Exactly, which is why I'm so distressed that this proposal not only
>> hasn't got that, but is designed so that it's impossible to add it
>> later.
>
> I like the idea of making concatenation more pretty, quite frankly.


Speaking of concatenation...

Something I find sorely missing in plpgsql is the ability to put  
variables inside of a string, ie:

DECLARE
v_table text := ...
v_sql text;
BEGIN
v_sql := "SELECT * FROM $v_table";

Of course, I'm assuming that if it was easy to do that it would be  
done already... but I thought I'd just throw it out there.
-- 
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828




Re: RfD: more powerful "any" types

From
daveg
Date:
On Fri, Sep 11, 2009 at 11:43:32AM -0400, Merlin Moncure wrote:
> 
> If you are going to use printf format codes, which is good and useful
> being something of a standard, I'd call routine printf (not format)
> and actually wrap vsnprintf.  The format codes in printf have a very
> specific meaning: converting native C types to arrays of characters.
> I think that a postgresql implementation should do exactly that:
> attempt to convert the passed in datum to the c type in question if
> possible (erroring if no cast exists) and then pass it down.  The idea
> is we are not adding new formatting routines but using a very high
> quality existing one...why reinvent the wheel?
> 
> so if you did: select printf('%s %3.1f', foo::box, bar::circle);
> the box to char* cast would work (using the text cast) but the second
> cast would fail unless the user added a cast to float.  The code in
> question is easy to imagine...parse the format string, and loop the
> varargs using the appropriate looked up cast one by one...

+1

-dg 

-- 
David Gould       daveg@sonic.net      510 536 1443    510 282 0869
If simplicity worked, the world would be overrun with insects.


Re: RfD: more powerful "any" types

From
Andrew Dunstan
Date:

decibel wrote:
>
>
> Speaking of concatenation...
>
> Something I find sorely missing in plpgsql is the ability to put 
> variables inside of a string, ie:
>
> DECLARE
> v_table text := ...
> v_sql text;
> BEGIN
> v_sql := "SELECT * FROM $v_table";
>
> Of course, I'm assuming that if it was easy to do that it would be 
> done already... but I thought I'd just throw it out there.
>

Then use a language that supports variable interpolation in strings, 
like plperl, plpythonu, plruby .... instead of plpgsql.

cheers

andrew


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
Hello

>
> ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
> are much more SQL-like than needing to write "any" or anyelement(n) as
> argument type or return type
>

I looked on possibilities in gram.y and I thing, type identifiers

"ANY TYPE" is possible without any problems (this should be synonym for "any"),
"SAME AS" needs add "same" keyword to col_name_keywords , i.e. "same"
is prohibited for function names - it should be a problem

regards
Pavel Stehule

I found so pgparser provide some ref type syntax via % symbol. So we
can use following syntax:

CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b a%TYPE)
RETURNS a%TYPE ...

It is not pretty like SAME AS, but I am sure, so this is doable
(parser knows it now)

any other ideas?

regards
Pavel Stehule


Re: RfD: more powerful "any" types

From
Hannu Krosing
Date:
On Sun, 2009-09-13 at 21:50 +0200, Pavel Stehule wrote:
> Hello
> 
> >
> > ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
> > are much more SQL-like than needing to write "any" or anyelement(n) as
> > argument type or return type
> >
> 
> I looked on possibilities in gram.y and I thing, type identifiers
> 
> "ANY TYPE" is possible without any problems (this should be synonym for "any"),
> "SAME AS" needs add "same" keyword to col_name_keywords , i.e. "same"
> is prohibited for function names - it should be a problem
> 
> regards
> Pavel Stehule
> 
> I found so pgparser provide some ref type syntax via % symbol. So we
> can use following syntax:
> 
> CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b a%TYPE)
> RETURNS a%TYPE ...
> 
> It is not pretty like SAME AS, but I am sure, so this is doable
> (parser knows it now)
> 
> any other ideas?

Hmm, maybe try to make lexer recognize "SAME AS" as one token and then
deal with other cases of 'name AS' ?

Or make the syntax a little uglier, 

CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b TYPE OF a)

CREATE OR REPLACE FUNCTION foo(ANY TYPE, TYPE OF $1)


and maybe try

CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b TYPE OF a) 
RETURNS ARRAY OF TYPE OF a

instead of

CREATE OR REPLACE FUNCTION foo(a anyelement, b anyelement) 
RETURNS anyarray

> 
> regards
> Pavel Stehule


-- 
Hannu Krosing   http://www.2ndQuadrant.com
PostgreSQL Scalability and Availability   Services, Consulting and Training




Re: RfD: more powerful "any" types

From
decibel
Date:
On Sep 12, 2009, at 5:54 PM, Andrew Dunstan wrote:
> decibel wrote:
>> Speaking of concatenation...
>>
>> Something I find sorely missing in plpgsql is the ability to put  
>> variables inside of a string, ie:
>>
>> DECLARE
>> v_table text := ...
>> v_sql text;
>> BEGIN
>> v_sql := "SELECT * FROM $v_table";
>>
>> Of course, I'm assuming that if it was easy to do that it would be  
>> done already... but I thought I'd just throw it out there.
>>
>
> Then use a language that supports variable interpolation in  
> strings, like plperl, plpythonu, plruby .... instead of plpgsql.


Which makes executing SQL much, much harder.

At least if we get sprintf dealing with strings might become a bit  
easier...
-- 
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828




Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/13 decibel <decibel@decibel.org>:
> On Sep 12, 2009, at 5:54 PM, Andrew Dunstan wrote:
>>
>> decibel wrote:
>>>
>>> Speaking of concatenation...
>>>
>>> Something I find sorely missing in plpgsql is the ability to put
>>> variables inside of a string, ie:
>>>
>>> DECLARE
>>> v_table text := ...
>>> v_sql text;
>>> BEGIN
>>> v_sql := "SELECT * FROM $v_table";
>>>
>>> Of course, I'm assuming that if it was easy to do that it would be done
>>> already... but I thought I'd just throw it out there.
>>>
>>
>> Then use a language that supports variable interpolation in strings, like
>> plperl, plpythonu, plruby .... instead of plpgsql.
>
>
> Which makes executing SQL much, much harder.
>
> At least if we get sprintf dealing with strings might become a bit easier...

This feature is nice - but very dangerous - it the most easy way how
do vulnerable (on SQL injection) application!

regards
Pavel Stehule

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


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/13 Hannu Krosing <hannu@2ndquadrant.com>:
> On Sun, 2009-09-13 at 21:50 +0200, Pavel Stehule wrote:
>> Hello
>>
>> >
>> > ANY [TYPE] and SAME AS [TYPE OF] are syntactic sugar indeed, but they
>> > are much more SQL-like than needing to write "any" or anyelement(n) as
>> > argument type or return type
>> >
>>
>> I looked on possibilities in gram.y and I thing, type identifiers
>>
>> "ANY TYPE" is possible without any problems (this should be synonym for "any"),
>> "SAME AS" needs add "same" keyword to col_name_keywords , i.e. "same"
>> is prohibited for function names - it should be a problem

I afraid so this technique isn't allowed in SQL parser, or is i

>>
>> regards
>> Pavel Stehule
>>
>> I found so pgparser provide some ref type syntax via % symbol. So we
>> can use following syntax:
>>
>> CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b a%TYPE)
>> RETURNS a%TYPE ...
>>
>> It is not pretty like SAME AS, but I am sure, so this is doable
>> (parser knows it now)
>>
>> any other ideas?
>
> Hmm, maybe try to make lexer recognize "SAME AS" as one token and then
> deal with other cases of 'name AS' ?

I afraid so this technique isn't allowed in SQL parser, or is it?

>
> Or make the syntax a little uglier,
>
> CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b TYPE OF a)
>
> CREATE OR REPLACE FUNCTION foo(ANY TYPE, TYPE OF $1)

TYPE OF generate shift/reduce too :(

Pavel

>
>
> and maybe try
>
> CREATE OR REPLACE FUNCTION foo(a ANY TYPE, b TYPE OF a)
> RETURNS ARRAY OF TYPE OF a
>
> instead of
>
> CREATE OR REPLACE FUNCTION foo(a anyelement, b anyelement)
> RETURNS anyarray
>
>>
>> regards
>> Pavel Stehule
>
>
> --
> Hannu Krosing   http://www.2ndQuadrant.com
> PostgreSQL Scalability and Availability
>   Services, Consulting and Training
>
>
>


Re: RfD: more powerful "any" types

From
decibel
Date:
On Sep 14, 2009, at 12:13 AM, Pavel Stehule wrote:
> 2009/9/13 decibel <decibel@decibel.org>:
>> On Sep 12, 2009, at 5:54 PM, Andrew Dunstan wrote:
>>>
>>> decibel wrote:
>>>>
>>>> Speaking of concatenation...
>>>>
>>>> Something I find sorely missing in plpgsql is the ability to put
>>>> variables inside of a string, ie:
>>>>
>>>> DECLARE
>>>> v_table text := ...
>>>> v_sql text;
>>>> BEGIN
>>>> v_sql := "SELECT * FROM $v_table";
>>>>
>>>> Of course, I'm assuming that if it was easy to do that it would  
>>>> be done
>>>> already... but I thought I'd just throw it out there.
>>>>
>>>
>>> Then use a language that supports variable interpolation in  
>>> strings, like
>>> plperl, plpythonu, plruby .... instead of plpgsql.
>>
>>
>> Which makes executing SQL much, much harder.
>>
>> At least if we get sprintf dealing with strings might become a bit  
>> easier...
>
> This feature is nice - but very dangerous - it the most easy way how
> do vulnerable (on SQL injection) application!


How is it any worse than what people can already do? Anyone who isn't  
aware of the dangers of SQL injection has already screwed themselves.  
You're basically arguing that they would put a variable inside of  
quotes, but they would never use ||.
-- 
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828




Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/14 decibel <decibel@decibel.org>:
> On Sep 14, 2009, at 12:13 AM, Pavel Stehule wrote:
>>
>> 2009/9/13 decibel <decibel@decibel.org>:
>>>
>>> On Sep 12, 2009, at 5:54 PM, Andrew Dunstan wrote:
>>>>
>>>> decibel wrote:
>>>>>
>>>>> Speaking of concatenation...
>>>>>
>>>>> Something I find sorely missing in plpgsql is the ability to put
>>>>> variables inside of a string, ie:
>>>>>
>>>>> DECLARE
>>>>> v_table text := ...
>>>>> v_sql text;
>>>>> BEGIN
>>>>> v_sql := "SELECT * FROM $v_table";
>>>>>
>>>>> Of course, I'm assuming that if it was easy to do that it would be done
>>>>> already... but I thought I'd just throw it out there.
>>>>>
>>>>
>>>> Then use a language that supports variable interpolation in strings,
>>>> like
>>>> plperl, plpythonu, plruby .... instead of plpgsql.
>>>
>>>
>>> Which makes executing SQL much, much harder.
>>>
>>> At least if we get sprintf dealing with strings might become a bit
>>> easier...
>>
>> This feature is nice - but very dangerous - it the most easy way how
>> do vulnerable (on SQL injection) application!
>
>
> How is it any worse than what people can already do? Anyone who isn't aware
> of the dangers of SQL injection has already screwed themselves. You're
> basically arguing that they would put a variable inside of quotes, but they
> would never use ||.

simply - people use functions quote_literal or quote_ident.

regards
Pavel Stehule

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


Re: RfD: more powerful "any" types

From
Merlin Moncure
Date:
On Mon, Sep 14, 2009 at 1:42 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
>> How is it any worse than what people can already do? Anyone who isn't aware
>> of the dangers of SQL injection has already screwed themselves. You're
>> basically arguing that they would put a variable inside of quotes, but they
>> would never use ||.
>
> simply - people use functions quote_literal or quote_ident.

you still have use of those functions:
execute sprintf('select * from %s', quote_ident($1));

sprintf is no more or less dangerous than || operator.

merlin


Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/14 Merlin Moncure <mmoncure@gmail.com>:
> On Mon, Sep 14, 2009 at 1:42 PM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
>>> How is it any worse than what people can already do? Anyone who isn't aware
>>> of the dangers of SQL injection has already screwed themselves. You're
>>> basically arguing that they would put a variable inside of quotes, but they
>>> would never use ||.
>>
>> simply - people use functions quote_literal or quote_ident.
>
> you still have use of those functions:
> execute sprintf('select * from %s', quote_ident($1));
>
> sprintf is no more or less dangerous than || operator.

sure. I commented different feature

some := 'select * from $1'

regards
Pavel

p.s. In this case, I am not sure what is more readable:

execute 'select * from ' || quote_ident($1)

is readable well too.




>
> merlin
>


Re: RfD: more powerful "any" types

From
decibel
Date:
On Sep 14, 2009, at 1:02 PM, Pavel Stehule wrote:

> 2009/9/14 Merlin Moncure <mmoncure@gmail.com>:
>> On Mon, Sep 14, 2009 at 1:42 PM, Pavel Stehule  
>> <pavel.stehule@gmail.com> wrote:
>>>> How is it any worse than what people can already do? Anyone who  
>>>> isn't aware
>>>> of the dangers of SQL injection has already screwed themselves.  
>>>> You're
>>>> basically arguing that they would put a variable inside of  
>>>> quotes, but they
>>>> would never use ||.
>>>
>>> simply - people use functions quote_literal or quote_ident.
>>
>> you still have use of those functions:
>> execute sprintf('select * from %s', quote_ident($1));
>>
>> sprintf is no more or less dangerous than || operator.
>
> sure. I commented different feature
>
> some := 'select * from $1'
>
> regards
> Pavel
>
> p.s. In this case, I am not sure what is more readable:
>
> execute 'select * from ' || quote_ident($1)
>
> is readable well too.


Ahh... the problem is one of fixating on an example instead of the  
overall use case.

More examples...

RETURN 'Your account is now $days_overdue days overdue. Please  
contact your account manager ($manager_name) to ...';

And an example of how readability would certainly be improved...

sql := $$INSERT INTO cnu_stats.$$ || v_field_name || $$( $$ ||  
v_field_name || $$ )    SELECT DISTINCT $$ || v_field_name || $$        FROM chunk t        WHERE NOT EXISTS( SELECT *
FROMcnu_stats.$$ || v_field_name  
 
|| $$ s WHERE s.$$            || v_field_name || $$ = t.$$ || v_field_name || $$ )$$

becomes

sql := $$INSERT INTO cnu_stats.${v_field_name} ( ${v_field_name} )    SELECT DISTINCT $v_field_name        FROM chunk t
      WHERE NOT EXISTS( SELECT * FROM cnu_stats.${v_field_name} s                              WHERE s.${v_field_name}
=t.$ 
 
{v_field_name} )$$

Granted, that example wouldn't be too bad with sprintf, but only  
because everything is referencing the same field.
-- 
Decibel!, aka Jim C. Nasby, Database Architect  decibel@decibel.org
Give your computer some brain candy! www.distributed.net Team #1828




Re: RfD: more powerful "any" types

From
Pavel Stehule
Date:
2009/9/15 decibel <decibel@decibel.org>:
>
> On Sep 14, 2009, at 1:02 PM, Pavel Stehule wrote:
>
>> 2009/9/14 Merlin Moncure <mmoncure@gmail.com>:
>>>
>>> On Mon, Sep 14, 2009 at 1:42 PM, Pavel Stehule <pavel.stehule@gmail.com>
>>> wrote:
>>>>>
>>>>> How is it any worse than what people can already do? Anyone who isn't
>>>>> aware
>>>>> of the dangers of SQL injection has already screwed themselves. You're
>>>>> basically arguing that they would put a variable inside of quotes, but
>>>>> they
>>>>> would never use ||.
>>>>
>>>> simply - people use functions quote_literal or quote_ident.
>>>
>>> you still have use of those functions:
>>> execute sprintf('select * from %s', quote_ident($1));
>>>
>>> sprintf is no more or less dangerous than || operator.
>>
>> sure. I commented different feature
>>
>> some := 'select * from $1'
>>
>> regards
>> Pavel
>>
>> p.s. In this case, I am not sure what is more readable:
>>
>> execute 'select * from ' || quote_ident($1)
>>
>> is readable well too.
>
>
> Ahh... the problem is one of fixating on an example instead of the overall
> use case.
>
> More examples...
>
> RETURN 'Your account is now $days_overdue days overdue. Please contact your
> account manager ($manager_name) to ...';
>
> And an example of how readability would certainly be improved...
>
> sql := $$INSERT INTO cnu_stats.$$ || v_field_name || $$( $$ || v_field_name
> || $$ )
>    SELECT DISTINCT $$ || v_field_name || $$
>        FROM chunk t
>        WHERE NOT EXISTS( SELECT * FROM cnu_stats.$$ || v_field_name || $$ s
> WHERE s.$$
>            || v_field_name || $$ = t.$$ || v_field_name || $$ )$$
>

it isn't fair :) why you use $$ without single quote? And still this
case should be vulnerable on SQL injection. Maybe you or me knows,
what SQL injection means, but beginners knows nothing and this people
use following bad code:

sql := $$SELECT * FROM '${table_name}'$$} and are happy. But this code
is wrong!

> becomes
>
> sql := $$INSERT INTO cnu_stats.${v_field_name} ( ${v_field_name} )
>    SELECT DISTINCT $v_field_name
>        FROM chunk t
>        WHERE NOT EXISTS( SELECT * FROM cnu_stats.${v_field_name} s
>                              WHERE s.${v_field_name} = t.${v_field_name} )$$
>
> Granted, that example wouldn't be too bad with sprintf, but only because
> everything is referencing the same field.

Really I dislike bash like syntax in SQL. What I know - SQL is
language for normal people - it is reason why it's verbose and English
like. Bash is sw for UNIX hackers. If we cut some features from others
languages, then bash, c, perl should be last (I knows these languages
well and I using it well). I thing, so there are better languages like
ADA, SQL/PSM, Python.

regards
Pavel Stehule

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


Re: RfD: more powerful "any" types

From
daveg
Date:
On Tue, Sep 15, 2009 at 07:38:18AM +0200, Pavel Stehule wrote:
> it isn't fair :) why you use $$ without single quote? And still this
> case should be vulnerable on SQL injection. Maybe you or me knows,
> what SQL injection means, but beginners knows nothing and this people
> use following bad code:
> 
> sql := $$SELECT * FROM '${table_name}'$$} and are happy. But this code
> is wrong!

I have an idea you will like less: have multiple interpolation codes that
automagically do the right quoting. Perhaps as extra printf like type codes.
The above then becomes:
 sql := pgprintf($$SELECT * FROM %I;$$, table_name )

Where %I evaluates as if it were quote_ident(%s).

This would maybe even encourage users to do the quoting they should by
making it easy.

-dg

-- 
David Gould       daveg@sonic.net      510 536 1443    510 282 0869
If simplicity worked, the world would be overrun with insects.