How hard would it be to support LIKE in return declaration of generic record function calls ?
Hi Hackers
How hard would it be to add support for LIKE syntax, similar to table
def in field list declaration for generic record functions
What I'dd like to be able to do is to have a generic json_to_record
function
CREATE OR REPLACE RECORD json_to_record(json) RETURNS RECORD AS $$
...
$$ LANGUAGE ... ;
and then be able to call it like this
insert into test2
select * from json_to_record(jrec json) as (like test2);
ERROR: syntax error at or near "like"
instead of explicitly spelling out the structure of table test2 in the
AS part.
insert into test2
select * from json_to_record(jrec json)
as (id int, data2 test, tstamp timestamp);
INSERT 0 1
PS.
As a pie-in-the-sky wish I'd prefer of course even simpler syntax of
insert into test2 json_to_record(jrec json);
or at least
insert into test2 json_to_record(jrec json)::test2;
:)
-
-------
Hannu Krosing
PostgreSQL Unlimited Scalability and Performance Consultant
2ndQuadrant Nordic
PG Admin Book: http://www.2ndQuadrant.com/books/
On ons, 2012-05-02 at 13:40 +0200, Hannu Krosing wrote:
How hard would it be to add support for LIKE syntax, similar to table
def in field list declaration for generic record functionsWhat I'dd like to be able to do is to have a generic json_to_record
functionCREATE OR REPLACE RECORD json_to_record(json) RETURNS RECORD AS $$
...
$$ LANGUAGE ... ;and then be able to call it like this
insert into test2
select * from json_to_record(jrec json) as (like test2);
That would be very useful, and shouldn't be too hard to implement. (I
had to look about three times to understand what this was supposed to
achieve, but I think the syntax is the right one after all.)
On Wed, May 2, 2012 at 12:06 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On ons, 2012-05-02 at 13:40 +0200, Hannu Krosing wrote:
How hard would it be to add support for LIKE syntax, similar to table
def in field list declaration for generic record functionsWhat I'dd like to be able to do is to have a generic json_to_record
functionCREATE OR REPLACE RECORD json_to_record(json) RETURNS RECORD AS $$
...
$$ LANGUAGE ... ;and then be able to call it like this
insert into test2
select * from json_to_record(jrec json) as (like test2);That would be very useful, and shouldn't be too hard to implement. (I
had to look about three times to understand what this was supposed to
achieve, but I think the syntax is the right one after all.)
Although I like the functionality, is this better than the trick used
by hstore/populate_record? That approach doesn't require syntax
changes and allows you to execute the function without 'FROM'.
merlin
On Wed, 2012-05-02 at 14:32 -0500, Merlin Moncure wrote:
On Wed, May 2, 2012 at 12:06 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On ons, 2012-05-02 at 13:40 +0200, Hannu Krosing wrote:
How hard would it be to add support for LIKE syntax, similar to table
def in field list declaration for generic record functionsWhat I'dd like to be able to do is to have a generic json_to_record
functionCREATE OR REPLACE RECORD json_to_record(json) RETURNS RECORD AS $$
...
$$ LANGUAGE ... ;and then be able to call it like this
insert into test2
select * from json_to_record(jrec json) as (like test2);That would be very useful, and shouldn't be too hard to implement. (I
had to look about three times to understand what this was supposed to
achieve, but I think the syntax is the right one after all.)Although I like the functionality, is this better than the trick used
by hstore/populate_record? That approach doesn't require syntax
changes and allows you to execute the function without 'FROM'.
You mean the one using a null::returntype for as first argument for
defining a return type of a function:
Convert an hstore to a predefined record type:
CREATE TABLE test (col1 integer, col2 text, col3 text);
SELECT * FROM populate_record(null::test,
'"col1"=>"456", "col2"=>"zzz"');
col1 | col2 | col3
------+------+------
456 | zzz |
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)
hannu=# insert into test
hannu-# SELECT * FROM populate_record(null::test,
'"id"=>"456", "data"=>"zzz"');
INSERT 0 1
putting the same functionality in LIKE at syntax level kind of feels
more orthogonal to table definition:)
select * from to_record(null::mytable, datasource);
vs
select * from to_record(datasource) as (like mytable);
OTOH, we do not support LIKE in type definition either.
If we were to overhaul template-based structure definition, the perhaps
the following syntax woul be better:
create type mytape as mytable; -- exact copy
create type mytape as (like mytable, comment text); -- copy + extra
field
and same for giving type to generic record in function calls.
If it does not mess up the syntax, it would also be good to add simple
casts in record-->table case
select * from to_record(datasource)::mytable;
--
-------
Hannu Krosing
PostgreSQL Unlimited Scalability and Performance Consultant
2ndQuadrant Nordic
PG Admin Book: http://www.2ndQuadrant.com/books/
Hello
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)hannu=# insert into test
hannu-# SELECT * FROM populate_record(null::test,
'"id"=>"456", "data"=>"zzz"');
INSERT 0 1
few years back I proposed "anytypename" type
with this feature, you can has some clean and more readable call
SELECT * FROM populate_record(test, ...)
Regards
Pavel
On Thu, May 3, 2012 at 7:13 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
Hello
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)
Yeah -- the syntax isn't great, but IMO it's more generally usable
than what you're proposing because it's a scalar returning function
not a table expression. Another point is that the proposed 'like'
syntax (which I still think is great, just maybe not for conversions
from json) seems wedded to record types. The hstore trick should be
able to take a foo[], set it all up and return it. How would that
work with like?
few years back I proposed "anytypename" type
with this feature, you can has some clean and more readable call
SELECT * FROM populate_record(test, ...)
that would be great IMO.
merlin
2012/5/3 Merlin Moncure <mmoncure@gmail.com>:
On Thu, May 3, 2012 at 7:13 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:
Hello
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)Yeah -- the syntax isn't great, but IMO it's more generally usable
than what you're proposing because it's a scalar returning function
not a table expression. Another point is that the proposed 'like'
syntax (which I still think is great, just maybe not for conversions
from json) seems wedded to record types. The hstore trick should be
able to take a foo[], set it all up and return it. How would that
work with like?few years back I proposed "anytypename" type
with this feature, you can has some clean and more readable call
SELECT * FROM populate_record(test, ...)
that would be great IMO.
I'll try propose it again - implementation should not be hard
Regards
Pavel
Show quoted text
merlin
On 05/03/2012 09:43 AM, Pavel Stehule wrote:
2012/5/3 Merlin Moncure<mmoncure@gmail.com>:
On Thu, May 3, 2012 at 7:13 AM, Pavel Stehule<pavel.stehule@gmail.com> wrote:
Hello
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)Yeah -- the syntax isn't great, but IMO it's more generally usable
than what you're proposing because it's a scalar returning function
not a table expression. Another point is that the proposed 'like'
syntax (which I still think is great, just maybe not for conversions
from json) seems wedded to record types. The hstore trick should be
able to take a foo[], set it all up and return it. How would that
work with like?few years back I proposed "anytypename" type
with this feature, you can has some clean and more readable call
SELECT * FROM populate_record(test, ...)
that would be great IMO.
I'll try propose it again - implementation should not be hard
You guys seem to be taking the original proposal off into the weeds. I
have often wanted to be able to use LIKE in type expressions, and I'd
like to see exactly that implemented.
cheers
andrew
On Thu, May 3, 2012 at 9:01 AM, Andrew Dunstan <andrew@dunslane.net> wrote:
On 05/03/2012 09:43 AM, Pavel Stehule wrote:
2012/5/3 Merlin Moncure<mmoncure@gmail.com>:
On Thu, May 3, 2012 at 7:13 AM, Pavel Stehule<pavel.stehule@gmail.com>
wrote:Hello
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)Yeah -- the syntax isn't great, but IMO it's more generally usable
than what you're proposing because it's a scalar returning function
not a table expression. Another point is that the proposed 'like'
syntax (which I still think is great, just maybe not for conversions
from json) seems wedded to record types. The hstore trick should be
able to take a foo[], set it all up and return it. How would that
work with like?few years back I proposed "anytypename" type
with this feature, you can has some clean and more readable call
SELECT * FROM populate_record(test, ...)
that would be great IMO.
I'll try propose it again - implementation should not be hard
You guys seem to be taking the original proposal off into the weeds. I have
often wanted to be able to use LIKE in type expressions, and I'd like to see
exactly that implemented.
would it work for array types? can it called without using FROM?
merlin
Andrew Dunstan <andrew@dunslane.net> writes:
You guys seem to be taking the original proposal off into the weeds. I
have often wanted to be able to use LIKE in type expressions, and I'd
like to see exactly that implemented.
This notion of "anytypename" is utterly unworkable anyway; there's no
way for the parser to know soon enough that a given argument position
needs to be read as a type name rather than a normal expression.
You could conceivably make it work with the argument being a regtype
literal (ie, quoted); but that seems at least as klugy as what hstore
is doing.
regards, tom lane
2012/5/3 Tom Lane <tgl@sss.pgh.pa.us>:
Andrew Dunstan <andrew@dunslane.net> writes:
You guys seem to be taking the original proposal off into the weeds. I
have often wanted to be able to use LIKE in type expressions, and I'd
like to see exactly that implemented.This notion of "anytypename" is utterly unworkable anyway; there's no
way for the parser to know soon enough that a given argument position
needs to be read as a type name rather than a normal expression.
You could conceivably make it work with the argument being a regtype
literal (ie, quoted); but that seems at least as klugy as what hstore
is doing.
type identifier is same identifier like other - but I have no
prototype now, so I don't know if there is some trap
I remember so I though about using CAST keyword too
some like SELECT CAST( populate_record(hstore_value) AS type)
Regards
Pavel
Show quoted text
regards, tom lane
On 05/03/2012 10:18 AM, Merlin Moncure wrote:
On Thu, May 3, 2012 at 9:01 AM, Andrew Dunstan<andrew@dunslane.net> wrote:
On 05/03/2012 09:43 AM, Pavel Stehule wrote:
2012/5/3 Merlin Moncure<mmoncure@gmail.com>:
On Thu, May 3, 2012 at 7:13 AM, Pavel Stehule<pavel.stehule@gmail.com>
wrote:Hello
(1 row)
This works the same indeed, just seems to be a hack, though a cool
one :)Yeah -- the syntax isn't great, but IMO it's more generally usable
than what you're proposing because it's a scalar returning function
not a table expression. Another point is that the proposed 'like'
syntax (which I still think is great, just maybe not for conversions
from json) seems wedded to record types. The hstore trick should be
able to take a foo[], set it all up and return it. How would that
work with like?few years back I proposed "anytypename" type
with this feature, you can has some clean and more readable call
SELECT * FROM populate_record(test, ...)
that would be great IMO.
I'll try propose it again - implementation should not be hard
You guys seem to be taking the original proposal off into the weeds. I have
often wanted to be able to use LIKE in type expressions, and I'd like to see
exactly that implemented.would it work for array types? can it called without using FROM?
Why would you always need FROM? I want to be able to do things like:
create type new_type as (like old_type, extra text);
i.e., anywhere we are specifying a type (e.g. as above or for a function
returnign a setof record), we should be able to import an existing one
rather than having to replicate it.
cheers
andrew
Pavel Stehule <pavel.stehule@gmail.com> writes:
2012/5/3 Tom Lane <tgl@sss.pgh.pa.us>:
This notion of "anytypename" is utterly unworkable anyway; there's no
way for the parser to know soon enough that a given argument position
needs to be read as a type name rather than a normal expression.
type identifier is same identifier like other - but I have no
prototype now, so I don't know if there is some trap
No, it isn't, at least not if you have any ambition to support array
types for instance; to say nothing of types whose standard names are
keywords, multiple words, etc. Even if you were willing to restrict the
feature to only work for simple-identifier type names, the parser would
have thrown an error for failing to find a column by that name, or else
would have misinterpreted the type name as a column name, long before
there is any opportunity to recognize that the argument position is
an "anytypename" argument.
regards, tom lane
On Thu, May 3, 2012 at 9:44 AM, Andrew Dunstan <andrew@dunslane.net> wrote:
Why would you always need FROM?
that was coming from Hannu's original example:
insert into test2
select * from json_to_record(jrec json) as (like test2);
how do you work it so you can call:
select json_to_record(jrec json) as (like test2);
select json_to_array(jrec_json) as ??
create type new_type as (like old_type, extra text);
sure, that would be great on it's own merits.
merlin
2012/5/3 Tom Lane <tgl@sss.pgh.pa.us>:
Pavel Stehule <pavel.stehule@gmail.com> writes:
2012/5/3 Tom Lane <tgl@sss.pgh.pa.us>:
This notion of "anytypename" is utterly unworkable anyway; there's no
way for the parser to know soon enough that a given argument position
needs to be read as a type name rather than a normal expression.type identifier is same identifier like other - but I have no
prototype now, so I don't know if there is some trapNo, it isn't, at least not if you have any ambition to support array
types for instance; to say nothing of types whose standard names are
keywords, multiple words, etc. Even if you were willing to restrict the
feature to only work for simple-identifier type names, the parser would
have thrown an error for failing to find a column by that name, or else
would have misinterpreted the type name as a column name, long before
there is any opportunity to recognize that the argument position is
an "anytypename" argument.
we can identify a position "anytypename" before raising error - it can
be similar to current identification of PL/pgSQL variables inside
expression. Probably it is too complex for this issue :(
Maybe some keyword can help to us. What do you think about new
operator TYPE that can returns regtype value and can be used together
with polymorphic functions.
CREATE FUNCTION foo(anyregtype, ....)
RETURNS anyelement AS ..
SELECT foo('mytype', ....)
or
SELECT foo(TYPE mytype, ....)
It is little bit cleaner than NULL::type.
Regards
Pavel
Show quoted text
regards, tom lane
Pavel Stehule <pavel.stehule@gmail.com> writes:
2012/5/3 Tom Lane <tgl@sss.pgh.pa.us>:
No, it isn't, at least not if you have any ambition to support array
types for instance; to say nothing of types whose standard names are
keywords, multiple words, etc.
we can identify a position "anytypename" before raising error - it can
be similar to current identification of PL/pgSQL variables inside
expression. Probably it is too complex for this issue :(
[ shrug ... ] Feel free to spend time that way if you want to, but
I'm entirely confident that you won't come out with anything except
an ugly, unmaintainable, incomplete kluge.
Maybe some keyword can help to us. What do you think about new
operator TYPE that can returns regtype value and can be used together
with polymorphic functions.
Doesn't have any more attraction for me than the proposed LIKE
extension; that will have the same results and it's at least traceable
to SQL-standard notations.
regards, tom lane
On Thu, May 3, 2012 at 10:12 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Maybe some keyword can help to us. What do you think about new
operator TYPE that can returns regtype value and can be used together
with polymorphic functions.Doesn't have any more attraction for me than the proposed LIKE
extension; that will have the same results and it's at least traceable
to SQL-standard notations.
no it won't (unless I'm being completely obtuse in addition to being
repetitive): LIKE only works when you treat your function call as a
table expression: FROM func() AS ...
that's fine, but converting-from-json functions will want to be able
to be called anywhere a single value returning function would be
normally called. hstore/populate_record trick allows this, so it's
not apples to apples.
merlin