Thread: JSON Function Bike Shedding
Hello Hackers, If you dislike bike-shedding (and who does?), delete this email and the ensuing thread right now. You have been warned! I have been playing with Andrew’s JSON enhancements and really enjoying them. I am already using them in code I’m developingfor production deployment in a month or two. Kudos! However, I am not so keen on the function names. They all start with json_! This mostly feels redundant to me, since thetypes of the parameters are part of the function signature. Therefore, I would like to propose different names: Existing Name Proposed Name -------------------------- ---------------------------------------- json_array_length() array_length() or length() or size() json_each() each_json() json_each_as_text() each_text() json_get() get_json() json_get_as_text() get_text() json_get_path() get_json() json_get_path_as_text() get_text() json_object_keys() get_keys() json_populate_record() record() or row() json_populate_recordset() records() or rows() json_unnest() get_values() json_agg() collect_json() Note that I have given json_get() and json_get_path() the same names, as it seems to me that the former is the same as thelatter, with only one parameter. Same for json_get_as_text() and json_get_path_as_text(). One nice thing about get_values() as opposed to json_unnest(), is that it could be used to fetch the values from a JSON objectas well as an array. (BTW, I think unnest is not a good name at all, since unlike the SQL unnest() function, it doesn'tactually unnest (flatten) the entire array). As for the operators, as previously discussed, I'm happy with either -> or ~> (and ->> or ~>>, of course). But I'm wonderingif the same operator couldn't be used when an array is on the RHS. I mean, having #> to that it doesn't have tobe cast is nice, too, but I think it'd be nice if an array would work with -> and ->>, too. AS for #> and #>>, what about @> and @>> instead? Or am I just too much the Perl hacker for thinking that @ is a nice mnemonicfor "array"? And finally, a couple of feature requests, which can be taken with a shaker of salt -- or as ideas for 9.4 -- and are mostlystolen from hstore: * An exists() function (and ? operator) similar to hstore * A defined() function * A delete() function * A slice() function * A concatenation function and operator * union, intercept, and except operators and/or functions * Perhaps some set-returning functions (select_keys(), select_values()) Even if nothing changes before release, I'm happy with the functionality Andrew has added. As I said, this is pure bike shedding,but I believe naming things is important, so it's a discussion worth having. Best, David
David, > However, I am not so keen on the function names. They all start with > json_! This mostly feels redundant to me, since the types of the > parameters are part of the function signature. I have no opinion about starting the function names with json_ or not. If we decide not, I agree that in general your proposed names are reasonable. Except: > json_populate_record() > record() or row() > json_populate_recordset() records() or > rows() Given that row() is already a type-agnostic function, and RECORD is a stored procedure return meta-type, I think the above names would be a mistake. I'd suggest instead: json_to_record() and json_to_recordset() or: to_record(json) and to_recordset(json) -- Josh Berkus PostgreSQL Experts Inc. http://pgexperts.com
On Feb 12, 2013, at 2:01 PM, Josh Berkus <josh@agliodbs.com> wrote: > Given that row() is already a type-agnostic function, and RECORD is a > stored procedure return meta-type, I think the above names would be a > mistake. I'd suggest instead: > > json_to_record() and json_to_recordset() > or: > > to_record(json) and to_recordset(json) I like these last two a lot, actually. Thanks! David
Josh Berkus <josh@agliodbs.com> writes: > David, >> However, I am not so keen on the function names. They all start with >> json_! This mostly feels redundant to me, since the types of the >> parameters are part of the function signature. > I have no opinion about starting the function names with json_ or not. +1 for removing that where possible. We generally have avoided such names at SQL level. (The C-level function names need such prefixes to be unique, but the SQL names don't.) In the cases where one or more arguments are anyelement, however, we may need to be more specific to avoid ambiguity problems in future. I agree with Josh's objections to record(), row() etc. to_record() and to_recordset() might be OK. regards, tom lane
On Tue, Feb 12, 2013 at 6:15 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Josh Berkus <josh@agliodbs.com> writes: >> David, >>> However, I am not so keen on the function names. They all start with >>> json_! This mostly feels redundant to me, since the types of the >>> parameters are part of the function signature. > >> I have no opinion about starting the function names with json_ or not. > > +1 for removing that where possible. We generally have avoided such > names at SQL level. (The C-level function names need such prefixes to > be unique, but the SQL names don't.) > > In the cases where one or more arguments are anyelement, however, we may > need to be more specific to avoid ambiguity problems in future. I agree > with Josh's objections to record(), row() etc. to_record() and > to_recordset() might be OK. ! merlin
On Feb 12, 2013, at 8:00 PM, Merlin Moncure <mmoncure@gmail.com> wrote: >> +1 for removing that where possible. We generally have avoided such >> names at SQL level. (The C-level function names need such prefixes to >> be unique, but the SQL names don't.) >> >> In the cases where one or more arguments are anyelement, however, we may >> need to be more specific to avoid ambiguity problems in future. I agree >> with Josh's objections to record(), row() etc. to_record() and >> to_recordset() might be OK. Agreed on all counts. (Wow!) > ! Not sure this would make a useful operator. Maybe for exists()? :-O David
On Tue, Feb 12, 2013 at 1:18 PM, David E. Wheeler <david@justatheory.com> wrote: couple other suggestions: > Existing Name Proposed Name > -------------------------- ---------------------------------------- > json_array_length() array_length() or length() or size() very much prefer without 'array_' prefix as this leads to semantic confusion with our (generally badly named) array manipulation API. So, length() -- also I see no reason why this can't be made to run if the outermost container is an object but that's an acceptable implementation detail. > json_each() each_json() why not each(). Assumption to return json is reasonable and doesn't need decoration IMO. > json_each_as_text() each_text() like this > json_get() get_json() prefer get() > json_get_as_text() get_text() like this > json_get_path() get_json() get() please > json_get_path_as_text() get_text() like this > json_object_keys() get_keys() like this > json_populate_record() record() or row() to_record() > json_populate_recordset() records() or rows() to_recordset() > json_unnest() get_values() greatly prefer unwrap() > json_agg() collect_json() perfer to leave as json_agg() -- we have string_agg, array_agg, etc. merlin
On 02/12/2013 02:18 PM, David E. Wheeler wrote: > Hello Hackers, > > If you dislike bike-shedding (and who does?), delete this email and the ensuing thread right now. You have been warned! > > I have been playing with Andrew’s JSON enhancements and really enjoying them. I am already using them in code I’m developingfor production deployment in a month or two. Kudos! > > However, I am not so keen on the function names. They all start with json_! This mostly feels redundant to me, since thetypes of the parameters are part of the function signature. I don't have any problem getting rid of the json_ prefixes, except for json_agg which I think should keep it (c.f. string_agg, array_agg). > Therefore, I would like to propose different names: > > Existing Name Proposed Name > -------------------------- ---------------------------------------- > json_array_length() array_length() or length() or size() > json_each() each_json() > json_each_as_text() each_text() > json_get() get_json() > json_get_as_text() get_text() > json_get_path() get_json() > json_get_path_as_text() get_text() > json_object_keys() get_keys() > json_populate_record() record() or row() > json_populate_recordset() records() or rows() > json_unnest() get_values() > json_agg() collect_json() > > Note that I have given json_get() and json_get_path() the same names, as it seems to me that the former is the same asthe latter, with only one parameter. Same for json_get_as_text() and json_get_path_as_text(). I will take some of this under advisement. Note that json_populate_record's name was taken from hstore's populate_record, so if we're trying to use similar names then it should possibly be just populate_record. Or if that's still a bit long I would accept to_record. > > One nice thing about get_values() as opposed to json_unnest(), is that it could be used to fetch the values from a JSONobject as well as an array. (BTW, I think unnest is not a good name at all, since unlike the SQL unnest() function, itdoesn't actually unnest (flatten) the entire array). I think Merlin's suggestion if unwrap might be good. Or simply "elements()" might work. > > As for the operators, as previously discussed, I'm happy with either -> or ~> (and ->> or ~>>, of course). But I'm wonderingif the same operator couldn't be used when an array is on the RHS. I mean, having #> to that it doesn't have tobe cast is nice, too, but I think it'd be nice if an array would work with -> and ->>, too. The point of using different operator names is that if there's an array literal postgres will convert it to an array. If the operator names are the same it will treat it as a text key instead. Being able to type my_json #>> '{f1,0,f2,3,f3}' is nice. Of course, we could duplicate the operators, but I generally prefer not to do that. > > AS for #> and #>>, what about @> and @>> instead? Or am I just too much the Perl hacker for thinking that @ is a nice mnemonicfor "array"? Probably. I deliberately avoided @> because it's used elsewhere to mean "contains" and using it for something quite different here might be confusing. > > And finally, a couple of feature requests, which can be taken with a shaker of salt -- or as ideas for 9.4 -- and are mostlystolen from hstore: > > * An exists() function (and ? operator) similar to hstore > * A defined() function > * A delete() function > * A slice() function > * A concatenation function and operator > * union, intercept, and except operators and/or functions > * Perhaps some set-returning functions (select_keys(), select_values()) I think this is beyond bikeshedding. Apparently you have missed the existence of json_object_keys(). The new API makes many or all of these things possible to do with relative ease as extensions (See my possibly upcoming talk on the subject.) cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > I will take some of this under advisement. Note that > json_populate_record's name was taken from hstore's populate_record, so > if we're trying to use similar names then it should possibly be just > populate_record. Or if that's still a bit long I would accept to_record. +1 for following precedent whenever there is some --- so let's go with populate_record. regards, tom lane
On Feb 13, 2013, at 8:36 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > I don't have any problem getting rid of the json_ prefixes, except for json_agg which I think should keep it (c.f. string_agg,array_agg). I think that's an unfortunately naming forced on us by the SQL standard, and it doesn't mean we have to use it anyway. > I will take some of this under advisement. Note that json_populate_record's name was taken from hstore's populate_record,so if we're trying to use similar names then it should possibly be just populate_record. Or if that's stilla bit long I would accept to_record. to_record()++ > I think Merlin's suggestion if unwrap might be good. Or simply "elements()" might work. Perhaps unwrap() returns a set and elements() returns an array? >> AS for #> and #>>, what about @> and @>> instead? Or am I just too much the Perl hacker for thinking that @ is a nicemnemonic for "array"? > > Probably. I deliberately avoided @> because it's used elsewhere to mean "contains" and using it for something quite differenthere might be confusing. I can see that, especially if you end up adding exists(): @> could be its operator. > I think this is beyond bikeshedding. Apparently you have missed the existence of json_object_keys(). Oh, I forgot it returned a set rather than an array. So I suggest: values() - Returns an array keys() - Returns an array And: unwrap() - Returns a set skeys() - Returns a set Er, okay, so skeys() sucks alongside the others here. If we were to steal from hstore, these would be: svals() - Returns a set skeys() - Returns a set avals() - Returns an array akeys() - Returns an array I don’t love those, but if we want to follow precedent… > The new API makes many or all of these things possible to do with relative ease as extensions (See my possibly upcomingtalk on the subject.) I’ll be there, yo! David
2013/2/13 David E. Wheeler <david@justatheory.com>: > On Feb 13, 2013, at 8:36 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > >> I don't have any problem getting rid of the json_ prefixes, except for json_agg which I think should keep it (c.f. string_agg,array_agg). > > I think that's an unfortunately naming forced on us by the SQL standard, and it doesn't mean we have to use it anyway. > >> I will take some of this under advisement. Note that json_populate_record's name was taken from hstore's populate_record,so if we're trying to use similar names then it should possibly be just populate_record. Or if that's stilla bit long I would accept to_record. > > to_record()++ > >> I think Merlin's suggestion if unwrap might be good. Or simply "elements()" might work. > > Perhaps unwrap() returns a set and elements() returns an array? > >>> AS for #> and #>>, what about @> and @>> instead? Or am I just too much the Perl hacker for thinking that @ is a nicemnemonic for "array"? >> >> Probably. I deliberately avoided @> because it's used elsewhere to mean "contains" and using it for something quite differenthere might be confusing. > > I can see that, especially if you end up adding exists(): @> could be its operator. > >> I think this is beyond bikeshedding. Apparently you have missed the existence of json_object_keys(). > > Oh, I forgot it returned a set rather than an array. So I suggest: > > values() - Returns an array > keys() - Returns an array "values" is keyword and "keys" is relative high risk too Regards Pavel > > And: > > unwrap() - Returns a set > skeys() - Returns a set > > Er, okay, so skeys() sucks alongside the others here. If we were to steal from hstore, these would be: > > svals() - Returns a set > skeys() - Returns a set > avals() - Returns an array > akeys() - Returns an array > > I don’t love those, but if we want to follow precedent… > >> The new API makes many or all of these things possible to do with relative ease as extensions (See my possibly upcomingtalk on the subject.) > > I’ll be there, yo! > > David > > > > > -- > Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-hackers
On 02/13/2013 12:07 PM, David E. Wheeler wrote: > On Feb 13, 2013, at 8:36 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > >> I don't have any problem getting rid of the json_ prefixes, except for json_agg which I think should keep it (c.f. string_agg,array_agg). > I think that's an unfortunately naming forced on us by the SQL standard, and it doesn't mean we have to use it anyway. Regardless of that, I'd prefer to be consistent. >> I think Merlin's suggestion if unwrap might be good. Or simply "elements()" might work. > Perhaps unwrap() returns a set and elements() returns an array? Now you're adding functionality. Let's just keep this to the question of names. >> I think this is beyond bikeshedding. Apparently you have missed the existence of json_object_keys(). > Oh, I forgot it returned a set rather than an array. So I suggest: > > values() - Returns an array > keys() - Returns an array > > And: > > unwrap() - Returns a set > skeys() - Returns a set > > Er, okay, so skeys() sucks alongside the others here. If we were to steal from hstore, these would be: > > svals() - Returns a set > skeys() - Returns a set > avals() - Returns an array > akeys() - Returns an array > > I don’t love those, but if we want to follow precedent… Ditto. I think we're a bit late to be adding functionality. cheers andrew
On Feb 13, 2013, at 9:31 AM, Andrew Dunstan <andrew@dunslane.net> wrote: >> I don’t love those, but if we want to follow precedent… > > Ditto. I think we're a bit late to be adding functionality. Well, how about having just keys() and vals() return arrays? Then one can just wrap them in unnest() to get sets. Best, David
Andrew Dunstan wrote: > > On 02/13/2013 12:07 PM, David E. Wheeler wrote: > >On Feb 13, 2013, at 8:36 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > >>I think Merlin's suggestion if unwrap might be good. Or simply "elements()" might work. > >Perhaps unwrap() returns a set and elements() returns an array? > > Now you're adding functionality. Let's just keep this to the > question of names. I agree with that, but it seems a good idea to leave names available for future functionality, where reasonable. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
On Wed, Feb 13, 2013 at 11:40 AM, Alvaro Herrera <alvherre@2ndquadrant.com> wrote: > Andrew Dunstan wrote: >> >> On 02/13/2013 12:07 PM, David E. Wheeler wrote: >> >On Feb 13, 2013, at 8:36 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > >> >>I think Merlin's suggestion if unwrap might be good. Or simply "elements()" might work. >> >Perhaps unwrap() returns a set and elements() returns an array? >> >> Now you're adding functionality. Let's just keep this to the >> question of names. > > I agree with that, but it seems a good idea to leave names available for > future functionality, where reasonable. Given all that, is there consensus on the names so that Andrew knows what changes to make? merlin
On Tue, Feb 12, 2013 at 2:18 PM, David E. Wheeler <david@justatheory.com> wrote: > Hello Hackers, > > If you dislike bike-shedding (and who does?), delete this email and the ensuing thread right now. You have been warned! > > I have been playing with Andrew’s JSON enhancements and really enjoying them. I am already using them in code I’m developingfor production deployment in a month or two. Kudos! > > However, I am not so keen on the function names. They all start with json_! This mostly feels redundant to me, since thetypes of the parameters are part of the function signature. > > Therefore, I would like to propose different names: > > Existing Name Proposed Name > -------------------------- ---------------------------------------- > json_array_length() array_length() or length() or size() > json_each() each_json() > json_each_as_text() each_text() > json_get() get_json() > json_get_as_text() get_text() > json_get_path() get_json() > json_get_path_as_text() get_text() > json_object_keys() get_keys() > json_populate_record() record() or row() > json_populate_recordset() records() or rows() > json_unnest() get_values() > json_agg() collect_json() > > Note that I have given json_get() and json_get_path() the same names, as it seems to me that the former is the same asthe latter, with only one parameter. Same for json_get_as_text() and json_get_path_as_text(). I realize I'm in the minority here, but -1 from me on all of this. Should we also rename xml_is_well_formed() to just is_well_formed()? string_agg() to agg()? Eventually we will have more data types, and some of them will have functions that could also be called rows() or get_values(), but it's unlikely that they'll have exactly the same behavior, which will start to make things confusing. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
On Feb 15, 2013, at 9:25 AM, Robert Haas <robertmhaas@gmail.com> wrote: > I realize I'm in the minority here, but -1 from me on all of this. > Should we also rename xml_is_well_formed() to just is_well_formed()? That would be nice, but I think that ship done sunk. > string_agg() to agg()? Would love a different name, but IIRC that followed array_agg(), which was dictated by the SQL standard, in its infinitewisdom. See also =>. > Eventually we will have more data types, and > some of them will have functions that could also be called rows() or > get_values(), but it's unlikely that they'll have exactly the same > behavior, which will start to make things confusing. Well, they will have to take account of *this* precedent and act accordingly. Much easier for them to look back at what hasbeen done here than for us to look forward to something that today exists as no more than a twinkle in your eye. Best, David
On 02/13/2013 11:36 AM, Andrew Dunstan wrote: > >> Therefore, I would like to propose different names: >> >> Existing Name Proposed Name >> -------------------------- ---------------------------------------- >> json_array_length() array_length() or length() or size() >> json_each() each_json() >> json_each_as_text() each_text() >> json_get() get_json() >> json_get_as_text() get_text() >> json_get_path() get_json() >> json_get_path_as_text() get_text() >> json_object_keys() get_keys() >> json_populate_record() record() or row() >> json_populate_recordset() records() or rows() >> json_unnest() get_values() >> json_agg() collect_json() >> >> Note that I have given json_get() and json_get_path() the same names, >> as it seems to me that the former is the same as the latter, with >> only one parameter. Same for json_get_as_text() and >> json_get_path_as_text(). > > I will take some of this under advisement. Note that > json_populate_record's name was taken from hstore's populate_record, > so if we're trying to use similar names then it should possibly be > just populate_record. Or if that's still a bit long I would accept > to_record. I have had a look at doing something like this with the json_get functions. The trouble is that the best way to do it is to have json_get take "variadic any", but then string literals come in as unknown rather than as text, which makes things fairly ugly. If we force people to cast path elements to text then I think the cure is worse than the disease. I think the best we can do here is possibly to provide json_get and json_get_text taking either a single int or variadic text[], and json_get_path and json_get_path_text taking non-variadic text[]. cheers andrew
On Feb 16, 2013, at 8:57 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > I have had a look at doing something like this with the json_get functions. The trouble is that the best way to do it isto have json_get take "variadic any", but then string literals come in as unknown rather than as text, which makes thingsfairly ugly. If we force people to cast path elements to text then I think the cure is worse than the disease. I thinkthe best we can do here is possibly to provide json_get and json_get_text taking either a single int or variadic text[],and json_get_path and json_get_path_text taking non-variadic text[]. Why not also one taking a single text? get(text) get(int) get(variadic text[]) ? David
On 2013-02-16 11:55:26 -0800, David E. Wheeler wrote: > On Feb 16, 2013, at 8:57 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > > > I have had a look at doing something like this with the json_get functions. The trouble is that the best way to do itis to have json_get take "variadic any", but then string literals come in as unknown rather than as text, which makes thingsfairly ugly. If we force people to cast path elements to text then I think the cure is worse than the disease. I thinkthe best we can do here is possibly to provide json_get and json_get_text taking either a single int or variadic text[],and json_get_path and json_get_path_text taking non-variadic text[]. > > Why not also one taking a single text? > > get(text) > get(int) > get(variadic text[]) Those aren't differentiable by their argument types. Why should json be able to claim that namespace and not other datatypes? Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training & Services
On 02/16/2013 03:05 PM, Andres Freund wrote: > On 2013-02-16 11:55:26 -0800, David E. Wheeler wrote: >> On Feb 16, 2013, at 8:57 AM, Andrew Dunstan <andrew@dunslane.net> wrote: >> >>> I have had a look at doing something like this with the json_get functions. The trouble is that the best way to do itis to have json_get take "variadic any", but then string literals come in as unknown rather than as text, which makes thingsfairly ugly. If we force people to cast path elements to text then I think the cure is worse than the disease. I thinkthe best we can do here is possibly to provide json_get and json_get_text taking either a single int or variadic text[],and json_get_path and json_get_path_text taking non-variadic text[]. >> Why not also one taking a single text? >> >> get(text) >> get(int) >> get(variadic text[]) > Those aren't differentiable by their argument types. Why should json be > able to claim that namespace and not other datatypes? > Well, of course the calls would be get(json, ...) although I'm still waiting to see if anyone else agrees with Robert about the naming of the functions. To answer David's point, there is no point in having both get(json,text) get(json, variadic text[]) since the second can encompass the first, and having both would make calls ambiguous. cheers andrew
On Feb 16, 2013, at 12:47 PM, Andrew Dunstan <andrew@dunslane.net> wrote: > To answer David's point, there is no point in having both > > get(json,text) > get(json, variadic text[]) > > since the second can encompass the first, and having both would make calls ambiguous. Oh. Well then how about get(json, int) get(json, text) get(json, text[]) ? David
On 02/16/2013 07:50 PM, David E. Wheeler wrote: > On Feb 16, 2013, at 12:47 PM, Andrew Dunstan <andrew@dunslane.net> wrote: > >> To answer David's point, there is no point in having both >> >> get(json,text) >> get(json, variadic text[]) >> >> since the second can encompass the first, and having both would make calls ambiguous. > Oh. Well then how about > > get(json, int) > get(json, text) > get(json, text[]) > > ? > No, then we don't have a variadic version. You are going to have to accept that we can't make one function name cover all of this. cheers andrew
On Feb 17, 2013, at 6:33 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > No, then we don't have a variadic version. You are going to have to accept that we can't make one function name cover allof this. Well, for me, I would rather specify an array than call a function with a different name. But it’s six of one, half-dozenof another, really, as long as it all works. D
On 02/17/2013 01:19 PM, David E. Wheeler wrote: > On Feb 17, 2013, at 6:33 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > >> No, then we don't have a variadic version. You are going to have to accept that we can't make one function name coverall of this. > Well, for me, I would rather specify an array than call a function with a different name. But it’s six of one, half-dozenof another, really, as long as it all works. > > I am going to go the way that involves the least amount of explicit casting or array construction. So get_path() stays, but becomes non-variadic. get() can take an int or variadic text[], so you can do: get(myjson,0) get(myjson,'f1') get(myjson,'f1','2','f3') get_path(myjson,'{f1,2,f3}') cheers andrew
On Fri, Feb 15, 2013 at 11:25 AM, Robert Haas <robertmhaas@gmail.com> wrote: >> Note that I have given json_get() and json_get_path() the same names, as it seems to me that the former is the same asthe latter, with only one parameter. Same for json_get_as_text() and json_get_path_as_text(). > > I realize I'm in the minority here, but -1 from me on all of this. > Should we also rename xml_is_well_formed() to just is_well_formed()? > string_agg() to agg()? Eventually we will have more data types, and > some of them will have functions that could also be called rows() or > get_values(), but it's unlikely that they'll have exactly the same > behavior, which will start to make things confusing. It's a little late, but I'd like to rebut this point: > string_agg() to agg()? This not germane to the discussion. string_agg means you are aggregating *to* a string, not from one, which is a completely different thing. This also applies to to_char, to_date, etc. If you wanted to do just 'agg()', you'd have to supply output type somehow -- the only way to do that in postgres is to use hstore null::foo trick (which is not an improvement obviously). > xml_is_well_formed() to just is_well_formed()? Again, this is not the same thing. It does not work on the xml type, but text, so you'd have to supply a hint to specific behaviors if you wanted to abstract type out of the function. Because the returned type is unambiguously boolean though, you can get away with: validate(format text, data text); select validate('json', <json string>); select validate('xml', <xml string>); etc. if you wanted to. And yes, I absolutely think this is superior to cluttering the public namespace with xml specific verbage, and could be extended to other formats. Look at the other way: we currently have encode(format text, stuff bytea). Would we be better off with hex_encode(bytea), escape_encode(bytea)... .etc? The argument for removing json_ prefix is that when function behaviors are unambiguously controlled by the arguments, decorating the function name to match the input argument is unnecessary verbosity. merlin
On Mon, Feb 18, 2013 at 10:42 AM, Merlin Moncure <mmoncure@gmail.com> wrote: > if you wanted to. And yes, I absolutely think this is superior to > cluttering the public namespace with xml specific verbage, and could > be extended to other formats. Look at the other way: we currently > have encode(format text, stuff bytea). Would we be better off with > hex_encode(bytea), escape_encode(bytea)... .etc? Probably not, but that's not what I proposed either. > The argument for removing json_ prefix is that when function behaviors > are unambiguously controlled by the arguments, decorating the function > name to match the input argument is unnecessary verbosity. I've come to value greppability of source code pretty highly. I think that some of the points you raise are valid, but in my (minority) opinion overloading creates more problems than it solves. You're not going to convince me that get() is *ever* a good name for a function - you might as well call it thing() or foo() for all the useful information that name conveys. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
> -----Original Message----- > From: pgsql-hackers-owner@postgresql.org [mailto:pgsql-hackers- > owner@postgresql.org] On Behalf Of Robert Haas > Sent: 19 February 2013 15:05 > To: Merlin Moncure > Cc: David E. Wheeler; PostgreSQL-development Hackers > > The argument for removing json_ prefix is that when function behaviors > > are unambiguously controlled by the arguments, decorating the function > > name to match the input argument is unnecessary verbosity. > > I've come to value greppability of source code pretty highly. I think that > some of the points you raise are valid, but in my (minority) opinion > overloading creates more problems than it solves. You're not going to > convince me that get() is *ever* a good name for a function - you might as > well call it thing() or foo() for all the useful information that name conveys. Let me join the minority here, +1 Regards Petr Jelinek
2013/2/19 Petr Jelinek <pjmodos@pjmodos.net>: >> -----Original Message----- >> From: pgsql-hackers-owner@postgresql.org [mailto:pgsql-hackers- >> owner@postgresql.org] On Behalf Of Robert Haas >> Sent: 19 February 2013 15:05 >> To: Merlin Moncure >> Cc: David E. Wheeler; PostgreSQL-development Hackers >> > The argument for removing json_ prefix is that when function behaviors >> > are unambiguously controlled by the arguments, decorating the function >> > name to match the input argument is unnecessary verbosity. >> >> I've come to value greppability of source code pretty highly. I think > that >> some of the points you raise are valid, but in my (minority) opinion >> overloading creates more problems than it solves. You're not going to >> convince me that get() is *ever* a good name for a function - you might as >> well call it thing() or foo() for all the useful information that name > conveys. > > Let me join the minority here, +1 me too +1 Pavel > > Regards > Petr Jelinek > > > > > > -- > Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Feb 19, 2013 at 8:04 AM, Robert Haas <robertmhaas@gmail.com> wrote: >> The argument for removing json_ prefix is that when function behaviors >> are unambiguously controlled by the arguments, decorating the function >> name to match the input argument is unnecessary verbosity. > > I've come to value greppability of source code pretty highly. Hm, good point. Counter argument: use better editing tools. Counter-counter argument: postgresql's fast moving boutique syntax is not well understood by any editor I'm aware of. The editor I use is Source insight, a $$$ windows tool, and I use it because it's basically a source code indexer with a full java and C parser. It can do SQL also, but it's limited to what you can do with regex for non fully parsmed languages so if I have the code: select get(j, '...') from foo; It doesn't know that j is json and as such I can't look for all instances of "get() as pertains to json generally or the json field j" Interesting aside: another language that is essentially immune to good tooling, javascript, is exploding in use -- even on the server side. Anyways, as to overloading in general, well, SQL is heavily overloaded. We don't have int_max, float_max, etc. and it would be usability reduction if we did. But that's not even the point; the driving philosophy of SQL is that your data structures (and types) are to be strongly decoupled from the manipulation you do -- this keeps the language very general. That philosophy, while not perfect, should be adhered to when possible. merlin
On Feb 19, 2013, at 6:11 AM, Petr Jelinek <pjmodos@pjmodos.net> wrote: >> some of the points you raise are valid, but in my (minority) opinion >> overloading creates more problems than it solves. You're not going to >> convince me that get() is *ever* a good name for a function - you might as >> well call it thing() or foo() for all the useful information that name > conveys. > > Let me join the minority here, +1 Well, that's why I called them get_json() and get_text(). Basically, I don't mind that the function name says something aboutthe return type. Best, David
>> I've come to value greppability of source code pretty highly. I think > that >> some of the points you raise are valid, but in my (minority) opinion >> overloading creates more problems than it solves. You're not going to >> convince me that get() is *ever* a good name for a function - you might as >> well call it thing() or foo() for all the useful information that name > conveys. What about extract()? That's consistent with the function we already use for timestamps and intervals, and is more clear than get(). On the other hand, to_string() seems like a GREAT name for an overloaded function. You know that it takes some other type as an argument, possibly several other types, and will always output a string. -- Josh Berkus PostgreSQL Experts Inc. http://pgexperts.com
2013/2/19 Josh Berkus <josh@agliodbs.com>: > >>> I've come to value greppability of source code pretty highly. I think >> that >>> some of the points you raise are valid, but in my (minority) opinion >>> overloading creates more problems than it solves. You're not going to >>> convince me that get() is *ever* a good name for a function - you might as >>> well call it thing() or foo() for all the useful information that name >> conveys. > > What about extract()? That's consistent with the function we already > use for timestamps and intervals, and is more clear than get(). "extract" is not usual function, it is supported by parser, and in this time nobody knows datatypes, so result can be some ugly error messages Regards Pavel > > On the other hand, to_string() seems like a GREAT name for an overloaded > function. You know that it takes some other type as an argument, > possibly several other types, and will always output a string. > > -- > Josh Berkus > PostgreSQL Experts Inc. > http://pgexperts.com > > > -- > Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Feb 19, 2013 at 10:00 AM, Merlin Moncure <mmoncure@gmail.com> wrote: > Anyways, as to overloading in general, well, SQL is heavily > overloaded. We don't have int_max, float_max, etc. and it would be > usability reduction if we did. That's true, but max(int) and max(float) are doing pretty much the same logical operation - they are taking the maximum of a group of numbers. Overloading in cases where the semantics vary - e.g. + for both integer addition and string concatenation - is something else altogether, and I have not generally observed it to be a very good idea. Sometimes it works in cases where it's part of the core language design, but we don't have the luxury of knowing what other data types we'll want to add in the future, and I'm vary wary of allowing JSON to engage in uncontrolled namespace pollution. > But that's not even the point; the > driving philosophy of SQL is that your data structures (and types) are > to be strongly decoupled from the manipulation you do -- this keeps > the language very general. That philosophy, while not perfect, should > be adhered to when possible. Perhaps, but that goal seems unlikely to be met in this case. The JSON functions and operators are being named by one group of people with one set of sensibilities, and the hstore functions and operators were named by a different group of people with a different set of sensibilities (and therefore don't match), and the next type that comes along will be named according to yet another group of people with another set of sensibilities. So we're unlikely to end up with a coherent set of primitives that operate on underlying data of a variety of types; we are instead likely to end up with an incoherent jumble. Although we now have a JSON type in core, we should not pretend that it's in the same league as text or int4. If those data types claim common function names like max and abs and common operator names like + and ||, it can be justified on the grounds that the appeal of those data types is pretty near universal. JSON is a very popular format right now and I completely support adding more support for it, but I cheerfully submit that if you think it falls into the same category as "text" or "int4", you've gotten way too caught up in the hype. It's completely appropriate to apply stricter criteria for namespace pollution to JSON than to a basic data type whose semantics are dictated by the SQL standard, the behavior of other database products, and fourth-grade math class. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
On Wed, Feb 20, 2013 at 9:42 AM, Robert Haas <robertmhaas@gmail.com> wrote: > On Tue, Feb 19, 2013 at 10:00 AM, Merlin Moncure <mmoncure@gmail.com> wrote: >> Anyways, as to overloading in general, well, SQL is heavily >> overloaded. We don't have int_max, float_max, etc. and it would be >> usability reduction if we did. > > That's true, but max(int) and max(float) are doing pretty much the > same logical operation - they are taking the maximum of a group of > numbers. Overloading in cases where the semantics vary - e.g. + for > both integer addition and string concatenation - is something else > altogether, and I have not generally observed it to be a very good > idea. Sometimes it works in cases where it's part of the core > language design, but we don't have the luxury of knowing what other > data types we'll want to add in the future, and I'm vary wary of > allowing JSON to engage in uncontrolled namespace pollution. Sure: but that's another straw man: abuse of + operator is case of combining arbitrarily different behaviors (concatenation and arithmetic aggregation) into uniform syntax. This is bad, but a different thing. The right way to do it is to globally define the behavior and map it to types if and only if it makes sense. Again, you want clean separation of 'what you're doing' vs 'what you're doing it over'. >> But that's not even the point; the >> driving philosophy of SQL is that your data structures (and types) are >> to be strongly decoupled from the manipulation you do -- this keeps >> the language very general. That philosophy, while not perfect, should >> be adhered to when possible. > > Perhaps, but that goal seems unlikely to be met in this case. The > JSON functions and operators are being named by one group of people > with one set of sensibilities, and the hstore functions and operators > were named by a different group of people with a different set of > sensibilities (and therefore don't match), and the next type that > comes along will be named according to yet another group of people > with another set of sensibilities. So we're unlikely to end up with a > coherent set of primitives that operate on underlying data of a > variety of types; we are instead likely to end up with an incoherent > jumble. json and hstore have overlap in the sense that you can use them to define a tuple that is independent from database type system and therefore free from it's restrictions (this is why 9.0+ hstore was a complete game changer for trigger development). Also a json object is for all intents and purposes an hstore++ -- json is more general and if json it gets the ability to be manipulated would probably displace hstore for most usages. So I'm not buying that: if the truly overlapping behaviors were syntactically equivalent then you would be able to swap out the implementation changing only the type without refactoring all your code. C++ STL works this way and that principle, at least, is good despite all the C++ baggage headaches. > Although we now have a JSON type in core, we should not pretend that > it's in the same league as text or int4. If those data types claim > common function names like max and abs and common operator names like > + and ||, it can be justified on the grounds that the appeal of those > data types is pretty near universal. JSON is a very popular format > right now and I completely support adding more support for it, but I > cheerfully submit that if you think it falls into the same category as > "text" or "int4", you've gotten way too caught up in the hype. It's > completely appropriate to apply stricter criteria for namespace > pollution to JSON than to a basic data type whose semantics are > dictated by the SQL standard, the behavior of other database products, > and fourth-grade math class. I'm not buying into the hype at all. I've been arguing (without much success) for years that throwing arcane type specific functions into the public namespace is incoherent, not the other way around. array_upper()? How about length() or count()? Well, we need to to decide what to do here -- I'll call the vote about even, and there plausible arguments to do it either way -- so how do we resolve this? merlin
On Thu, Feb 21, 2013 at 10:51 AM, Merlin Moncure <mmoncure@gmail.com> wrote: > Sure: but that's another straw man: abuse of + operator is case of > combining arbitrarily different behaviors (concatenation and > arithmetic aggregation) into uniform syntax. This is bad, but a > different thing. The right way to do it is to globally define the > behavior and map it to types if and only if it makes sense. Again, > you want clean separation of 'what you're doing' vs 'what you're doing > it over'. I'll buy that. So what's the globally defined behavior of a ~> operator or a function called get() or even vals()? The problem is that I don't know how we can be sure any definition we choose now based on one example will be forward-compatible with things we want to do later, perhaps involving completely unrelated data types with very different semantics. It's not like there are an infinite number of short, high-quality operator/function names. > I'm not buying into the hype at all. I've been arguing (without much > success) for years that throwing arcane type specific functions into > the public namespace is incoherent, not the other way around. > array_upper()? How about length() or count()? Not sure I follow. array_upper() is annoying because its semantics are kinda confusing and idiosyncratic, but that's more the fault of the type itself than the accessor function. length() and count() are admittedly very common English words, but it's hard to imagine what we'd want to use those names for that would be more common/important than what they're used for already. It's not at all hard to imagine that with some of the other names that have been proposed. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
On Thu, Feb 21, 2013 at 11:02 AM, Robert Haas <robertmhaas@gmail.com> wrote: > On Thu, Feb 21, 2013 at 10:51 AM, Merlin Moncure <mmoncure@gmail.com> wrote: >> Sure: but that's another straw man: abuse of + operator is case of >> combining arbitrarily different behaviors (concatenation and >> arithmetic aggregation) into uniform syntax. This is bad, but a >> different thing. The right way to do it is to globally define the >> behavior and map it to types if and only if it makes sense. Again, >> you want clean separation of 'what you're doing' vs 'what you're doing >> it over'. > > I'll buy that. So what's the globally defined behavior of a ~> > operator or a function called get() or even vals()? The problem is > that I don't know how we can be sure any definition we choose now > based on one example will be forward-compatible with things we want to > do later, perhaps involving completely unrelated data types with very > different semantics. It's not like there are an infinite number of > short, high-quality operator/function names. Well, for case the of operator, it means whatever we reserve to mean. Very much agree on limitations of symbolic representation of behaviors (especially since some of the best ones were reserved by SQL or other acctors), so I think there is growing consensus that such things should get moved to functions. But functions are a lot less terse than operators so functions describing clearly defined behaviors are appreciated. So, get() means what *define it to mean*, but the definition should be consistent. If it's shorthand for "get from some multiple key/value container" then fine. If get() is just not specific enough -- let's at least try and go for something behavior specific (such as getMember or some such) before punting and resolving type specific function names. In fact, a an awful lot of $propsal's behaviors are in fact direct proxies for hstore behaviors, and a superficial think is suggesting that around 90% of hstore API would make sense in JSON terms (even though Andrew didn't implement all those behaviors and we're not going to ask him to). That to me is suggesting that tuple manipulation is a pretty general problem (hstore AKA tuple) and json only brings a couple of things to the table that isn't already covered there. Isn't it nice that you can document functions like avals/svals ONCE and not have to rewrite your triggers when you swap out hstore for json to get a couple extra behavior bits? >> I'm not buying into the hype at all. I've been arguing (without much >> success) for years that throwing arcane type specific functions into >> the public namespace is incoherent, not the other way around. >> array_upper()? How about length() or count()? > > Not sure I follow. array_upper() is annoying because its semantics > are kinda confusing and idiosyncratic, but that's more the fault of > the type itself than the accessor function. length() and count() are > admittedly very common English words, but it's hard to imagine what > we'd want to use those names for that would be more common/important > than what they're used for already. It's not at all hard to imagine > that with some of the other names that have been proposed. yeah. merlin
On Thu, Feb 21, 2013 at 1:16 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > Well, for case the of operator, it means whatever we reserve to mean. > Very much agree on limitations of symbolic representation of behaviors > (especially since some of the best ones were reserved by SQL or other > acctors), so I think there is growing consensus that such things > should get moved to functions. But functions are a lot less terse > than operators so functions describing clearly defined behaviors are > appreciated. > > So, get() means what *define it to mean*, but the definition should be > consistent. If it's shorthand for "get from some multiple key/value > container" then fine. If get() is just not specific enough -- let's > at least try and go for something behavior specific (such as getMember > or some such) before punting and resolving type specific function > names. > > In fact, a an awful lot of $propsal's behaviors are in fact direct > proxies for hstore behaviors, and a superficial think is suggesting > that around 90% of hstore API would make sense in JSON terms (even > though Andrew didn't implement all those behaviors and we're not going > to ask him to). That to me is suggesting that tuple manipulation is a > pretty general problem (hstore AKA tuple) and json only brings a > couple of things to the table that isn't already covered there. > Isn't it nice that you can document functions like avals/svals ONCE > and not have to rewrite your triggers when you swap out hstore for > json to get a couple extra behavior bits? Naming the JSON stuff the same way we've already named the hstore stuff is a somewhat promising idea, but it's hard for me to believe we'd truly resist the urge to tinker. avals and svals are completely opaque to me; without reading the manual I have no idea what those things mean. If they had longer, more descriptive names it would be more tempting. Still, if the behaviors line up closely enough for government work and we want to match the names up as well, I think that'd be tolerable. What I think is NOT tolerable is choosing a set of short but arbitrary names which are different from anything that we have now and pretending that we'll want to use those again for the next data type that comes along. That's just wishful thinking. Programmers who believe that their decisions will act as precedent for all future code are almost inevitably disappointed. Precedent grows organically out of what happens; it's very hard to create it ex nihilo, especially since we have no clear idea what future data types we'll likely want to add. Sure, if we add something that's just like JSON but with a few extra features, we'll be able to reuse the names no problem. But that's unlikely, because we typically resist the urge to add things that are too much like what we already have. The main reason we're adding JSON when we already have hstore is because JSON has become something of a standard. We probably WILL add more "container" types in the future, but I'd guess that they are likely to be as different from JSON as JSON is from XML, or from arrays. I'm not convinced we can define a set of semantics that are going to sweep that broadly. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
On Feb 22, 2013, at 9:37 AM, Robert Haas <robertmhaas@gmail.com> wrote: > What I think is NOT tolerable is choosing a set of short but arbitrary > names which are different from anything that we have now and > pretending that we'll want to use those again for the next data type > that comes along. That's just wishful thinking. Programmers who > believe that their decisions will act as precedent for all future code > are almost inevitably disappointed. Precedent grows organically out > of what happens; it's very hard to create it ex nihilo, especially > since we have no clear idea what future data types we'll likely want > to add. Sure, if we add something that's just like JSON but with a > few extra features, we'll be able to reuse the names no problem. But > that's unlikely, because we typically resist the urge to add things > that are too much like what we already have. The main reason we're > adding JSON when we already have hstore is because JSON has become > something of a standard. We probably WILL add more "container" types > in the future, but I'd guess that they are likely to be as different > from JSON as JSON is from XML, or from arrays. I'm not convinced we > can define a set of semantics that are going to sweep that broadly. Maybe. I would argue, however, that a key/value-oriented data type will always call those things "keys" and "values". Sokeys() and vals() (or get_keys() and get_vals()) seems pretty reasonable to me. Anyway, back to practicalities, Andrew last posted: > I am going to go the way that involves the least amount of explicit casting or array construction. So get_path() stays,but becomes non-variadic. get() can take an int or variadic text[], so you can do: > > get(myjson,0) > get(myjson,'f1') > get(myjson,'f1','2','f3') > get_path(myjson,'{f1,2,f3}') I would change these to mention the return types: get_json(myjson,0) get_json(myjson,'f1') get_json(myjson,'f1','2','f3') get_path_json(myjson,'{f1,2,f3}') And then the complementary text-returning versions: get_text(myjson,0) get_text(myjson,'f1') get_text(myjson,'f1','2','f3') get_path_text(myjson,'{f1,2,f3}') I do think that something like length() has pretty good semantics across data types, though. So to update the proposed names,taking in the discussion, I now propose: Existing Name Proposed Name -------------------------- ------------------- json_array_length() length() json_each() each_json() json_each_as_text() each_text() json_get() get_json() json_get_as_text() get_text() json_get_path() get_path_json() json_get_path_as_text() get_path_text() json_object_keys() get_keys() json_populate_record() to_record() json_populate_recordset() to_records() json_unnest() get_values() json_agg() json_agg() I still prefer to_record() and to_records() to populate_record(). It just feels more like a cast to me. I dislike json_agg(),but assume we're stuck with it. But at this point, I’m happy to leave Andrew to it. The functionality is awesome. Best, David
On Fri, Feb 22, 2013 at 11:50 AM, David E. Wheeler <david@justatheory.com> wrote: > On Feb 22, 2013, at 9:37 AM, Robert Haas <robertmhaas@gmail.com> wrote: > >> What I think is NOT tolerable is choosing a set of short but arbitrary >> names which are different from anything that we have now and >> pretending that we'll want to use those again for the next data type >> that comes along. That's just wishful thinking. Programmers who >> believe that their decisions will act as precedent for all future code >> are almost inevitably disappointed. Precedent grows organically out >> of what happens; it's very hard to create it ex nihilo, especially >> since we have no clear idea what future data types we'll likely want >> to add. Sure, if we add something that's just like JSON but with a >> few extra features, we'll be able to reuse the names no problem. But >> that's unlikely, because we typically resist the urge to add things >> that are too much like what we already have. The main reason we're >> adding JSON when we already have hstore is because JSON has become >> something of a standard. We probably WILL add more "container" types >> in the future, but I'd guess that they are likely to be as different >> from JSON as JSON is from XML, or from arrays. I'm not convinced we >> can define a set of semantics that are going to sweep that broadly. > > Maybe. I would argue, however, that a key/value-oriented data type will always call those things "keys" and "values". Sokeys() and vals() (or get_keys() and get_vals()) seems pretty reasonable to me. > > Anyway, back to practicalities, Andrew last posted: > >> I am going to go the way that involves the least amount of explicit casting or array construction. So get_path() stays,but becomes non-variadic. get() can take an int or variadic text[], so you can do: >> >> get(myjson,0) >> get(myjson,'f1') >> get(myjson,'f1','2','f3') >> get_path(myjson,'{f1,2,f3}') > > I would change these to mention the return types: > > get_json(myjson,0) > get_json(myjson,'f1') > get_json(myjson,'f1','2','f3') > get_path_json(myjson,'{f1,2,f3}') > > And then the complementary text-returning versions: > > get_text(myjson,0) > get_text(myjson,'f1') > get_text(myjson,'f1','2','f3') > get_path_text(myjson,'{f1,2,f3}') > > I do think that something like length() has pretty good semantics across data types, though. So to update the proposednames, taking in the discussion, I now propose: > > Existing Name Proposed Name > -------------------------- ------------------- > json_array_length() length() > json_each() each_json() > json_each_as_text() each_text() > json_get() get_json() > json_get_as_text() get_text() > json_get_path() get_path_json() > json_get_path_as_text() get_path_text() > json_object_keys() get_keys() > json_populate_record() to_record() > json_populate_recordset() to_records() > json_unnest() get_values() > json_agg() json_agg() > > I still prefer to_record() and to_records() to populate_record(). It just feels more like a cast to me. I dislike json_agg(),but assume we're stuck with it. > > But at this point, I’m happy to leave Andrew to it. The functionality is awesome. Agreed: +1 to your thoughts here. But also +1 to the originals and +1 to Robert's point of view also. This feature is of huge strategic importance to the project and we need to lock this down and commit it. There is a huge difference between "i slightly prefersome different names" and "the feature has issues". So, i think the various positions are clear: this is one argument i'd be happy to lose (or win). merlin
On 03/01/2013 11:09 AM, Merlin Moncure wrote: > On Fri, Feb 22, 2013 at 11:50 AM, David E. Wheeler > <david@justatheory.com> wrote: >> On Feb 22, 2013, at 9:37 AM, Robert Haas <robertmhaas@gmail.com> wrote: >> >>> What I think is NOT tolerable is choosing a set of short but arbitrary >>> names which are different from anything that we have now and >>> pretending that we'll want to use those again for the next data type >>> that comes along. That's just wishful thinking. Programmers who >>> believe that their decisions will act as precedent for all future code >>> are almost inevitably disappointed. Precedent grows organically out >>> of what happens; it's very hard to create it ex nihilo, especially >>> since we have no clear idea what future data types we'll likely want >>> to add. Sure, if we add something that's just like JSON but with a >>> few extra features, we'll be able to reuse the names no problem. But >>> that's unlikely, because we typically resist the urge to add things >>> that are too much like what we already have. The main reason we're >>> adding JSON when we already have hstore is because JSON has become >>> something of a standard. We probably WILL add more "container" types >>> in the future, but I'd guess that they are likely to be as different >>> from JSON as JSON is from XML, or from arrays. I'm not convinced we >>> can define a set of semantics that are going to sweep that broadly. >> Maybe. I would argue, however, that a key/value-oriented data type will always call those things "keys" and "values".So keys() and vals() (or get_keys() and get_vals()) seems pretty reasonable to me. >> >> Anyway, back to practicalities, Andrew last posted: >> >>> I am going to go the way that involves the least amount of explicit casting or array construction. So get_path() stays,but becomes non-variadic. get() can take an int or variadic text[], so you can do: >>> >>> get(myjson,0) >>> get(myjson,'f1') >>> get(myjson,'f1','2','f3') >>> get_path(myjson,'{f1,2,f3}') >> I would change these to mention the return types: >> >> get_json(myjson,0) >> get_json(myjson,'f1') >> get_json(myjson,'f1','2','f3') >> get_path_json(myjson,'{f1,2,f3}') >> >> And then the complementary text-returning versions: >> >> get_text(myjson,0) >> get_text(myjson,'f1') >> get_text(myjson,'f1','2','f3') >> get_path_text(myjson,'{f1,2,f3}') >> >> I do think that something like length() has pretty good semantics across data types, though. So to update the proposednames, taking in the discussion, I now propose: >> >> Existing Name Proposed Name >> -------------------------- ------------------- >> json_array_length() length() >> json_each() each_json() >> json_each_as_text() each_text() >> json_get() get_json() >> json_get_as_text() get_text() >> json_get_path() get_path_json() >> json_get_path_as_text() get_path_text() >> json_object_keys() get_keys() >> json_populate_record() to_record() >> json_populate_recordset() to_records() >> json_unnest() get_values() >> json_agg() json_agg() >> >> I still prefer to_record() and to_records() to populate_record(). It just feels more like a cast to me. I dislike json_agg(),but assume we're stuck with it. >> >> But at this point, I’m happy to leave Andrew to it. The functionality is awesome. > > Agreed: +1 to your thoughts here. But also +1 to the originals and +1 > to Robert's point of view also. This feature is of huge strategic > importance to the project and we need to lock this down and commit it. > There is a huge difference between "i slightly prefer some different > names" and "the feature has issues". > > So, i think the various positions are clear: this is one argument i'd > be happy to lose (or win). > I've been sitting here for a while mulling none too happily over the debate on the names for the proposed JSON extraction functions. I haven't really been happy with any of the suggestions, much, not least my own original function names which were really only intended as placeholders. Last night in the still watches I decided I just couldn't go with a function name as almost totally content-free as get(), or even get_text(). And I don't think prepending "json_'" to the name helps much either. Just concentrating to start with on those get() functions, in the simple case we really don't need them at all. hstore has the "->" operator without documenting the underlying function ("fetchval"). So maybe we should just do that. We could have documented, simply: myjson -> 'fname' myjson -> 1 myjson ->> 'fname' myjson ->> 1 myjson #> '{fname,1}' myjson #>> '{fname,1}' and leave the underlying functions undocumented. One wrinkle in this picture is the variadic forms of extraction which don't lend themselves nicely to use with an operator. We could decide to do away with those altogether, or come up with a better name. I'm loath to use "json_path" since it's a name used for something similar but different elsewhere. I do think it's valuable to have the variadic form, though, and I'd be sad to see it go. Regarding the remaining functions, * I'd be inclined to stick with json_array_length() and json_object_keys() - I think they describe pretty well what theydo. hstore's skeys() does more or less the same as json_object_keys(), so we could use that if we want to be consistent.I don't think it's a terribly good name though. * json_unnest() should certainly be renamed. Alternatives thatcome to mind are json_unfold() or json_elements() or json_array_elements(). * json_each(), json_each_as_text(), json_populate_record()and json_populate_recordset() - to be consistent with hstore we could remove the "json_". We probablyshould remove the "_as_ from json_each_as_text(). cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > I've been sitting here for a while mulling none too happily over the > debate on the names for the proposed JSON extraction functions. I > haven't really been happy with any of the suggestions, much, not least > my own original function names which were really only intended as > placeholders. Last night in the still watches I decided I just couldn't > go with a function name as almost totally content-free as get(), or even > get_text(). And I don't think prepending "json_'" to the name helps much > either. Agreed. > Just concentrating to start with on those get() functions, in the simple > case we really don't need them at all. hstore has the "->" operator > without documenting the underlying function ("fetchval"). So maybe we > should just do that. Well, not documenting the underlying function does not relieve you from having to name it in a reasonably sane fashion. It still wouldn't do to call it "get()". > * I'd be inclined to stick with json_array_length() and > json_object_keys() - I think they describe pretty well what they do. > hstore's skeys() does more or less the same as json_object_keys(), > so we could use that if we want to be consistent. I don't think it's > a terribly good name though. > * json_unnest() should certainly be renamed. Alternatives that come to > mind are json_unfold() or json_elements() or json_array_elements(). > * json_each(), json_each_as_text(), json_populate_record() and > json_populate_recordset() - to be consistent with hstore we could > remove the "json_". We probably should remove the "_as_ from > json_each_as_text(). I don't particularly have a dog in this fight, but do we really want some of these to have a json_ prefix and others not? regards, tom lane
On 03/18/2013 12:29 PM, Andrew Dunstan wrote: > > One wrinkle in this picture is the variadic forms of extraction which > don't lend themselves nicely to use with an operator. We could decide to > do away with those altogether, or come up with a better name. I'm loath > to use "json_path" since it's a name used for something similar but > different elsewhere. I do think it's valuable to have the variadic form, > though, and I'd be sad to see it go. Given that the variadic form is meant to be the foundation of future tree-based indexing of JSON values, I really don't want to do without it. Plus, I'd be forced to reimplement it in my own code. But the name does need work. json_tree? Hmmm, no good ... -- Josh Berkus PostgreSQL Experts Inc. http://pgexperts.com
On Mon, Mar 18, 2013 at 3:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Andrew Dunstan <andrew@dunslane.net> writes: >> I've been sitting here for a while mulling none too happily over the >> debate on the names for the proposed JSON extraction functions. I >> haven't really been happy with any of the suggestions, much, not least >> my own original function names which were really only intended as >> placeholders. Last night in the still watches I decided I just couldn't >> go with a function name as almost totally content-free as get(), or even >> get_text(). And I don't think prepending "json_'" to the name helps much >> either. > > Agreed. > >> Just concentrating to start with on those get() functions, in the simple >> case we really don't need them at all. hstore has the "->" operator >> without documenting the underlying function ("fetchval"). So maybe we >> should just do that. > > Well, not documenting the underlying function does not relieve you from > having to name it in a reasonably sane fashion. It still wouldn't do > to call it "get()". How about 'fetch'. Or is that just skirting the content free aspect? Agree that 'path' is out (as unnest is out due to unfortunate semantic confusion). At the end of the day, 'get()' is simply referencing an array (either associative or not). Most languages do this with an operator, but I think fetch is pretty solid term. >> * I'd be inclined to stick with json_array_length() and >> json_object_keys() - I think they describe pretty well what they do. >> hstore's skeys() does more or less the same as json_object_keys(), >> so we could use that if we want to be consistent. I don't think it's >> a terribly good name though. >> * json_unnest() should certainly be renamed. Alternatives that come to >> mind are json_unfold() or json_elements() or json_array_elements(). >> * json_each(), json_each_as_text(), json_populate_record() and >> json_populate_recordset() - to be consistent with hstore we could >> remove the "json_". We probably should remove the "_as_ from >> json_each_as_text(). > > I don't particularly have a dog in this fight, but do we really want > some of these to have a json_ prefix and others not? That's already baked in, because 9.2 json functions have prefix. I'm still partial to json_unwrap for unnest, but out of Andrew's suggestions I like json_elements the best. Like removing _as_. merlin
On 03/22/2013 09:29 AM, Merlin Moncure wrote: > On Mon, Mar 18, 2013 at 3:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> Andrew Dunstan <andrew@dunslane.net> writes: >>> I've been sitting here for a while mulling none too happily over the >>> debate on the names for the proposed JSON extraction functions. I >>> haven't really been happy with any of the suggestions, much, not least >>> my own original function names which were really only intended as >>> placeholders. Last night in the still watches I decided I just couldn't >>> go with a function name as almost totally content-free as get(), or even >>> get_text(). And I don't think prepending "json_'" to the name helps much >>> either. >> Agreed. >> >>> Just concentrating to start with on those get() functions, in the simple >>> case we really don't need them at all. hstore has the "->" operator >>> without documenting the underlying function ("fetchval"). So maybe we >>> should just do that. >> Well, not documenting the underlying function does not relieve you from >> having to name it in a reasonably sane fashion. It still wouldn't do >> to call it "get()". > How about 'fetch'. Or is that just skirting the content free aspect? > Agree that 'path' is out (as unnest is out due to unfortunate semantic > confusion). At the end of the day, 'get()' is simply referencing an > array (either associative or not). Most languages do this with an > operator, but I think fetch is pretty solid term. > > >>> * I'd be inclined to stick with json_array_length() and >>> json_object_keys() - I think they describe pretty well what they do. >>> hstore's skeys() does more or less the same as json_object_keys(), >>> so we could use that if we want to be consistent. I don't think it's >>> a terribly good name though. >>> * json_unnest() should certainly be renamed. Alternatives that come to >>> mind are json_unfold() or json_elements() or json_array_elements(). >>> * json_each(), json_each_as_text(), json_populate_record() and >>> json_populate_recordset() - to be consistent with hstore we could >>> remove the "json_". We probably should remove the "_as_ from >>> json_each_as_text(). >> I don't particularly have a dog in this fight, but do we really want >> some of these to have a json_ prefix and others not? > That's already baked in, because 9.2 json functions have prefix. I have finally decided my position on this. I think we have lots of good precedents for using type names in function names: array functions, xml functions and enum functions, for example. I think these are the precedents to follow, rather than hstore. Some people will be unhappy that this means more typing, but SQL is somewhat verbose anyway, and whatever we do will make someone unhappy :-) > I'm > still partial to json_unwrap for unnest, but out of Andrew's > suggestions I like json_elements the best. Like removing _as_. > OK. I can live with that. New version forthcoming soon. cheers andrew
On Fri, Mar 22, 2013 at 8:58 AM, Andrew Dunstan <andrew@dunslane.net> wrote: > > On 03/22/2013 09:29 AM, Merlin Moncure wrote: >> >> On Mon, Mar 18, 2013 at 3:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >>> >>> Andrew Dunstan <andrew@dunslane.net> writes: >>>> >>>> I've been sitting here for a while mulling none too happily over the >>>> debate on the names for the proposed JSON extraction functions. I >>>> haven't really been happy with any of the suggestions, much, not least >>>> my own original function names which were really only intended as >>>> placeholders. Last night in the still watches I decided I just couldn't >>>> go with a function name as almost totally content-free as get(), or even >>>> get_text(). And I don't think prepending "json_'" to the name helps much >>>> either. >>> >>> Agreed. >>> >>>> Just concentrating to start with on those get() functions, in the simple >>>> case we really don't need them at all. hstore has the "->" operator >>>> without documenting the underlying function ("fetchval"). So maybe we >>>> should just do that. >>> >>> Well, not documenting the underlying function does not relieve you from >>> having to name it in a reasonably sane fashion. It still wouldn't do >>> to call it "get()". >> >> How about 'fetch'. Or is that just skirting the content free aspect? >> Agree that 'path' is out (as unnest is out due to unfortunate semantic >> confusion). At the end of the day, 'get()' is simply referencing an >> array (either associative or not). Most languages do this with an >> operator, but I think fetch is pretty solid term. >> >> >>>> * I'd be inclined to stick with json_array_length() and >>>> json_object_keys() - I think they describe pretty well what they >>>> do. >>>> hstore's skeys() does more or less the same as json_object_keys(), >>>> so we could use that if we want to be consistent. I don't think >>>> it's >>>> a terribly good name though. >>>> * json_unnest() should certainly be renamed. Alternatives that come >>>> to >>>> mind are json_unfold() or json_elements() or json_array_elements(). >>>> * json_each(), json_each_as_text(), json_populate_record() and >>>> json_populate_recordset() - to be consistent with hstore we could >>>> remove the "json_". We probably should remove the "_as_ from >>>> json_each_as_text(). >>> >>> I don't particularly have a dog in this fight, but do we really want >>> some of these to have a json_ prefix and others not? >> >> That's already baked in, because 9.2 json functions have prefix. > > > I have finally decided my position on this. I think we have lots of good > precedents for using type names in function names: array functions, xml > functions and enum functions, for example. I think these are the precedents > to follow, rather than hstore. Some people will be unhappy that this means > more typing, but SQL is somewhat verbose anyway, and whatever we do will > make someone unhappy :-) > > >> I'm >> still partial to json_unwrap for unnest, but out of Andrew's >> suggestions I like json_elements the best. Like removing _as_. >> > > OK. I can live with that. > > New version forthcoming soon. Thanks for that! I'm super duper busy lately, but i'd still like to bone up the docs a little bit, so if I can find the time I'd like to squeeze some in before we lock in the beta if that's all right. merlin
On 03/22/2013 09:58 AM, Andrew Dunstan wrote: > > > New version forthcoming soon. > > And here it is. I think this is just about baked now. cheers andrew