Thread: JSON Function Bike Shedding

JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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









Re: JSON Function Bike Shedding

From
Josh Berkus
Date:
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



Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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




Re: JSON Function Bike Shedding

From
Tom Lane
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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





Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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



Re: JSON Function Bike Shedding

From
Tom Lane
Date:
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



Re: JSON Function Bike Shedding

From
David E. Wheeler
Date:
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





Re: JSON Function Bike Shedding

From
Pavel Stehule
Date:
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



Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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



Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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


Re: JSON Function Bike Shedding

From
Alvaro Herrera
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Robert Haas
Date:
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



Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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




Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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





Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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




Re: JSON Function Bike Shedding

From
Andres Freund
Date:
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



Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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




Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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


Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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




Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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


Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Robert Haas
Date:
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



Re: JSON Function Bike Shedding

From
"Petr Jelinek"
Date:
> -----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





Re: JSON Function Bike Shedding

From
Pavel Stehule
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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


Re: JSON Function Bike Shedding

From
Josh Berkus
Date:
>> 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



Re: JSON Function Bike Shedding

From
Pavel Stehule
Date:
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



Re: JSON Function Bike Shedding

From
Robert Haas
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Robert Haas
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Robert Haas
Date:
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



Re: JSON Function Bike Shedding

From
"David E. Wheeler"
Date:
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




Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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



Re: JSON Function Bike Shedding

From
Tom Lane
Date:
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



Re: JSON Function Bike Shedding

From
Josh Berkus
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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



Re: JSON Function Bike Shedding

From
Merlin Moncure
Date:
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



Re: JSON Function Bike Shedding

From
Andrew Dunstan
Date:
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


Attachment