Thread: How hard would it be to support LIKE in return declaration of generic record function calls ?
How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Hannu Krosing
Date:
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/
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Peter Eisentraut
Date:
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 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); 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.)
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Merlin Moncure
Date:
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 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); > > 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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Hannu Krosing
Date:
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 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); > > > > 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/
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Pavel Stehule
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Merlin Moncure
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Pavel Stehule
Date:
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 > > merlin
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Andrew Dunstan
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Merlin Moncure
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Tom Lane
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Pavel Stehule
Date:
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 > regards, tom lane
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Andrew Dunstan
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Tom Lane
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Merlin Moncure
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Pavel Stehule
Date:
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 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. 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 > > regards, tom lane
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Tom Lane
Date:
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
Re: How hard would it be to support LIKE in return declaration of generic record function calls ?
From
Merlin Moncure
Date:
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