Thread: BUG #7620: array_to_json doesn't support heterogeneous arrays
The following bug has been logged on the website: Bug reference: 7620 Logged by: Greg Hazel Email address: ghazel@gmail.com PostgreSQL version: 9.2.1 Operating system: Amazon Linux Description: = array_to_json(ARRAY['foo', 100, true]) complains because arrays can't have mixed types, but json arrays can. So, it's not possible to form a heterogeneous json array, when this is often desired.
On Tue, Oct 23, 2012 at 6:32 PM, <ghazel@gmail.com> wrote: > The following bug has been logged on the website: > > Bug reference: 7620 > Logged by: Greg Hazel > Email address: ghazel@gmail.com > PostgreSQL version: 9.2.1 > Operating system: Amazon Linux > Description: > > array_to_json(ARRAY['foo', 100, true]) complains because arrays can't have > mixed types, but json arrays can. > > So, it's not possible to form a heterogeneous json array, when this is often > desired. This is not really a bug because the feature is working as intended. Postgres arrays are homogonous so what you're asking really isn't possible. You can though use row_to_json to work around: select row_to_json(row('foo', 100, true)); merlin
On Tue, Oct 23, 2012 at 8:05 PM, Greg Hazel <ghazel@gmail.com> wrote: > On Oct 23, 2012, at 6:03 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > >> On Tue, Oct 23, 2012 at 6:32 PM, <ghazel@gmail.com> wrote: >>> The following bug has been logged on the website: >>> >>> Bug reference: 7620 >>> Logged by: Greg Hazel >>> Email address: ghazel@gmail.com >>> PostgreSQL version: 9.2.1 >>> Operating system: Amazon Linux >>> Description: >>> >>> array_to_json(ARRAY['foo', 100, true]) complains because arrays can't have >>> mixed types, but json arrays can. >>> >>> So, it's not possible to form a heterogeneous json array, when this is often >>> desired. >> >> This is not really a bug because the feature is working as intended. >> Postgres arrays are homogonous so what you're asking really isn't >> possible. You can though use row_to_json to work around: >> >> select row_to_json(row('foo', 100, true)); > > That doesn't produce the same results. > > Call it a feature request or a bug report, the postgres json support fails to make the json I need. I didn't say that it did: what it does is return a javascript object which is only a very little bit different from an array. For example, you can do jquery each() over either. I guess if you had to have an array, you could do it like this: array_to_json(ARRAY['foo'::text, 100::text, true::text]) merlin
On 10/24/2012 07:32 AM, ghazel@gmail.com wrote: > The following bug has been logged on the website: > > Bug reference: 7620 > Logged by: Greg Hazel > Email address: ghazel@gmail.com > PostgreSQL version: 9.2.1 > Operating system: Amazon Linux > Description: > > array_to_json(ARRAY['foo', 100, true]) complains because arrays can't have > mixed types, but json arrays can. The issue here isn't array_to_json, it's PostgreSQL arrays. What you appear to want is a way to call row_to_json so that it produces a json array instead of a json object as it currently does. That way you could pass it a ROW() construct, composite type, or record, and have it output a heterogeneous JSON array. This isn't a bug, but it's a perfectly reasonable feature request if re-interpreted a little. It will never work with PostgreSQL arrays, though, because the arrays themselves cannot contain mixed types: regress=# SELECT ARRAY[1,'test']; ERROR: invalid input syntax for integer: "test" LINE 1: SELECT ARRAY[1,'test']; ^ Instead you want a way to take this: regress=# SELECT ROW(1,'test'); row ---------- (1,test) (1 row) and output the json: [1,"test"] instead of a json object: regress=# SELECT row_to_json(ROW(1,'test')); row_to_json ---------------------- {"f1":1,"f2":"test"} (1 row) Would a version of `row_to_json` that output a json array satisfy your needs? -- Craig Ringer
On Wed, Oct 24, 2012 at 2:21 AM, Craig Ringer <ringerc@ringerc.id.au> wrote: > On 10/24/2012 07:32 AM, ghazel@gmail.com wrote: >> The following bug has been logged on the website: >> >> Bug reference: 7620 >> Logged by: Greg Hazel >> Email address: ghazel@gmail.com >> PostgreSQL version: 9.2.1 >> Operating system: Amazon Linux >> Description: >> >> array_to_json(ARRAY['foo', 100, true]) complains because arrays can't have >> mixed types, but json arrays can. > > The issue here isn't array_to_json, it's PostgreSQL arrays. > > What you appear to want is a way to call row_to_json so that it produces > a json array instead of a json object as it currently does. That way you > could pass it a ROW() construct, composite type, or record, and have it > output a heterogeneous JSON array. > > This isn't a bug, but it's a perfectly reasonable feature request if > re-interpreted a little. It will never work with PostgreSQL arrays, > though, because the arrays themselves cannot contain mixed types: > > regress=# SELECT ARRAY[1,'test']; > ERROR: invalid input syntax for integer: "test" > LINE 1: SELECT ARRAY[1,'test']; > ^ > Instead you want a way to take this: > > regress=# SELECT ROW(1,'test'); > row > ---------- > (1,test) > (1 row) > > and output the json: > > [1,"test"] > > instead of a json object: > > regress=# SELECT row_to_json(ROW(1,'test')); > row_to_json > ---------------------- > {"f1":1,"f2":"test"} > (1 row) > > > Would a version of `row_to_json` that output a json array satisfy your > needs? That's an interesting idea, but I'd like to see the OP make a convincing case why the data must be returned as an array. In javascript there isn't much difference...but maybe there's an important point I'm missing. merlin
On Oct 23, 2012, at 6:03 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > On Tue, Oct 23, 2012 at 6:32 PM, <ghazel@gmail.com> wrote: >> The following bug has been logged on the website: >>=20 >> Bug reference: 7620 >> Logged by: Greg Hazel >> Email address: ghazel@gmail.com >> PostgreSQL version: 9.2.1 >> Operating system: Amazon Linux >> Description: >>=20 >> array_to_json(ARRAY['foo', 100, true]) complains because arrays can't = have >> mixed types, but json arrays can. >>=20 >> So, it's not possible to form a heterogeneous json array, when this = is often >> desired. >=20 > This is not really a bug because the feature is working as intended. > Postgres arrays are homogonous so what you're asking really isn't > possible. You can though use row_to_json to work around: >=20 > select row_to_json(row('foo', 100, true)); That doesn't produce the same results. Call it a feature request or a bug report, the postgres json support = fails to make the json I need. -Greg
On Oct 24, 2012, at 12:21 AM, Craig Ringer <ringerc@ringerc.id.au> wrote: > On 10/24/2012 07:32 AM, ghazel@gmail.com wrote: >> The following bug has been logged on the website: >> >> Bug reference: 7620 >> Logged by: Greg Hazel >> Email address: ghazel@gmail.com >> PostgreSQL version: 9.2.1 >> Operating system: Amazon Linux >> Description: >> >> array_to_json(ARRAY['foo', 100, true]) complains because arrays can't have >> mixed types, but json arrays can. > > The issue here isn't array_to_json, it's PostgreSQL arrays. > > What you appear to want is a way to call row_to_json so that it produces > a json array instead of a json object as it currently does. That way you > could pass it a ROW() construct, composite type, or record, and have it > output a heterogeneous JSON array. > > This isn't a bug, but it's a perfectly reasonable feature request if > re-interpreted a little. It will never work with PostgreSQL arrays, > though, because the arrays themselves cannot contain mixed types: > > regress=# SELECT ARRAY[1,'test']; > ERROR: invalid input syntax for integer: "test" > LINE 1: SELECT ARRAY[1,'test']; > ^ > Instead you want a way to take this: > > regress=# SELECT ROW(1,'test'); > row > ---------- > (1,test) > (1 row) > > and output the json: > > [1,"test"] > > instead of a json object: > > regress=# SELECT row_to_json(ROW(1,'test')); > row_to_json > ---------------------- > {"f1":1,"f2":"test"} > (1 row) > > > Would a version of `row_to_json` that output a json array satisfy your > needs? Sure, that would be fine. -Greg
On Oct 23, 2012, at 6:17 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > On Tue, Oct 23, 2012 at 8:05 PM, Greg Hazel <ghazel@gmail.com> wrote: >> On Oct 23, 2012, at 6:03 PM, Merlin Moncure <mmoncure@gmail.com> = wrote: >>=20 >>> On Tue, Oct 23, 2012 at 6:32 PM, <ghazel@gmail.com> wrote: >>>> The following bug has been logged on the website: >>>>=20 >>>> Bug reference: 7620 >>>> Logged by: Greg Hazel >>>> Email address: ghazel@gmail.com >>>> PostgreSQL version: 9.2.1 >>>> Operating system: Amazon Linux >>>> Description: >>>>=20 >>>> array_to_json(ARRAY['foo', 100, true]) complains because arrays = can't have >>>> mixed types, but json arrays can. >>>>=20 >>>> So, it's not possible to form a heterogeneous json array, when this = is often >>>> desired. >>>=20 >>> This is not really a bug because the feature is working as intended. >>> Postgres arrays are homogonous so what you're asking really isn't >>> possible. You can though use row_to_json to work around: >>>=20 >>> select row_to_json(row('foo', 100, true)); >>=20 >> That doesn't produce the same results. >>=20 >> Call it a feature request or a bug report, the postgres json support = fails to make the json I need. >=20 > I didn't say that it did: what it does is return a javascript object > which is only a very little bit different from an array. For example, > you can do jquery each() over either. I guess if you had to have an > array, you could do it like this: >=20 > array_to_json(ARRAY['foo'::text, 100::text, true::text]) Still not exactly the same json, since 100 and true would be quoted = strings. I'm not parsing it with jQuery, it's a client with type = expectations. -Greg
On Oct 24, 2012, at 12:21 AM, Craig Ringer <ringerc@ringerc.id.au> = wrote: > On 10/24/2012 07:32 AM, ghazel@gmail.com wrote: >> The following bug has been logged on the website: >>=20 >> Bug reference: 7620 >> Logged by: Greg Hazel >> Email address: ghazel@gmail.com >> PostgreSQL version: 9.2.1 >> Operating system: Amazon Linux >> Description: =20 >>=20 >> array_to_json(ARRAY['foo', 100, true]) complains because arrays can't = have >> mixed types, but json arrays can. >=20 > The issue here isn't array_to_json, it's PostgreSQL arrays. >=20 > What you appear to want is a way to call row_to_json so that it = produces > a json array instead of a json object as it currently does. That way = you > could pass it a ROW() construct, composite type, or record, and have = it > output a heterogeneous JSON array. >=20 > This isn't a bug, but it's a perfectly reasonable feature request if > re-interpreted a little. It will never work with PostgreSQL arrays, > though, because the arrays themselves cannot contain mixed types: >=20 Another option that just occurred to me is a new function (say, to_json) = that converts the parameter to its json representation, with type json. Then this would be possible: select array_to_json(ARRAY[to_json('foo'), to_json(100), = to_json(true)]); -Greg
On 10/24/2012 11:46 PM, Greg Hazel wrote: > Another option that just occurred to me is a new function (say, to_json) that converts the parameter to its json representation,with type json. > > Then this would be possible: > > select array_to_json(ARRAY[to_json('foo'), to_json(100), to_json(true)]); That's been repeatedly discussed (and requested, and had patches posted) on -hackers. Right now the standing opinion appears to be that "json" represents a whole json document, and json documents must be arrays or JavaScript objects, not scalars, so it is not valid to provide a scalar "to_json". I posted patches to support this functionality - as did several others as it turns out - and they've all been rejected. -- Craig Ringer