ScalarArrayOpExpr and multi-dimensional arrays

Started by Amit Langoteabout 8 years ago3 messages
#1Amit Langote
Amit Langote
Langote_Amit_f8@lab.ntt.co.jp

Hi.

I wonder if ScalarArrayOpExpr is not really meant for multi-dimensional
arrays appearing on the right hand side? Because:

# select array[1] = any (array[array[1], array[2]]);

ERROR: operator does not exist: integer[] = integer
LINE 1: select array[1] = any (array[array[1], array[2]]);
^
HINT: No operator matches the given name and argument types. You might
need to add explicit type casts.

I noticed this when looking at the constraint of a list partitioned table
on a int[] column.

create table p (a int[]) partition by list (a);
create table p1 partition of p for values in ('{1}');

\d+ p1
...
Partition of: p FOR VALUES IN ('{1}')
Partition constraint: ((a IS NOT NULL) AND ((a)::anyarray
OPERATOR(pg_catalog.=) ANY (ARRAY['{1}'::integer[]])))

I got the same error as above when I try to put that ANY expression in a
query:

select (a)::anyarray OPERATOR(pg_catalog.=) ANY (ARRAY['{1}'::integer[]])
from p;
ERROR: operator does not exist: integer[] pg_catalog.= integer

I guess we shouldn't be generating such a constraint expression if backend
is not going to accept the same. Or should ScalarArrayOpExpr be made to
sanely process multi-dimensional arrays appearing on the right hand side?

Thanks,
Amit

#2Tom Lane
Tom Lane
tgl@sss.pgh.pa.us
In reply to: Amit Langote (#1)
Re: ScalarArrayOpExpr and multi-dimensional arrays

Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> writes:

I wonder if ScalarArrayOpExpr is not really meant for multi-dimensional
arrays appearing on the right hand side? Because:
# select array[1] = any (array[array[1], array[2]]);

ERROR: operator does not exist: integer[] = integer

You are falling into the misimpression that a 2-D array is an array of
1-D arrays. It is not, even if the syntax makes it look like that.

ScalarArrayOpExpr just iterates over the array elements without regard
to dimensionality; so the LHS must be of the element type.

regards, tom lane

#3Amit Langote
Amit Langote
Langote_Amit_f8@lab.ntt.co.jp
In reply to: Tom Lane (#2)
1 attachment(s)
Re: ScalarArrayOpExpr and multi-dimensional arrays

On 2017/12/08 23:34, Tom Lane wrote:

Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> writes:

I wonder if ScalarArrayOpExpr is not really meant for multi-dimensional
arrays appearing on the right hand side? Because:
# select array[1] = any (array[array[1], array[2]]);

ERROR: operator does not exist: integer[] = integer

You are falling into the misimpression that a 2-D array is an array of
1-D arrays. It is not, even if the syntax makes it look like that.

ScalarArrayOpExpr just iterates over the array elements without regard
to dimensionality; so the LHS must be of the element type.

Yeah, I can now see that.

Although, I wonder if there is any room for improvement here. Instead of
waiting for make_scalar_array_op() to emit the error as it does today,
would it be better if we error'd out earlier saying "ERROR: ANY/ALL
leftarg must be scalar, not array"? Attached a patch for that, if it's
worth going for at all.

Thanks,
Amit

Attachments:

scalar-array-op-lhs-scalar.patchtext/plain; charset=UTF-8; name=scalar-array-op-lhs-scalar.patch