-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Array comparisons behavior changed #3476
Comments
From the SQL Standard, part 2, section 4.10.4 Collection comparison and assignment:
H2 doesn't emulate incompatibilities with the Standard in that area in its compatibility modes. Collection data types from PostgreSQL definitely have some and yours at least consistent, with row value data type result of comparison in PostgreSQL depends on source of arguments, they are processed differently in |
For reference, it doesn't seem to matter to PostgreSQL if the array is a literal or comes from a column. The following is Not sure what you mean by "consistent with row value". The following results in a |
I just had a chat with some folks from the PostgreSQL community and they seem to be sure that PostgreSQL is behaving SQL standard compliant. Let me cite from the discussion
So overall, it seems to me this is in fact a bug in H2 |
But
To check array equality we need to check equality of its elements:
So, behavior of H2 seems so be correct, H2 returns Situation with row values in PostgreSQL is even more complicated: CREATE TYPE D AS(A INT, B INT);
CREATE TABLE T(V D);
INSERT INTO T VALUES (ROW(1, NULL));
SELECT V, (1, NULL::INT), V = (1, NULL::INT), (1, NULL::INT) = (1, NULL::INT) FROM T;
v | row | ?column? | ?column?
-----------+-----------+----------+----------
(1, null) | (1, null) | t | null Of course, someone may say that this data type is not a real row value data type (PostgreSQL supports row value literals, but doesn't support standard-compliant row data type definitions) and this vendor-specific syntax may produce a data type with different comparison rules, but it looks weird anyway. H2 handles them in consistent way: CREATE TABLE T(V ROW(A INT, B INT));
INSERT INTO T VALUES ROW(1, NULL);
SELECT V, (1, NULL), V = (1, NULL), (1, NULL) = (1, NULL) FROM T;
> V | ROW (1, NULL) | V = ROW (1, NULL) | UNKNOWN
> --------------+---------------+-------------------+--------
> ROW (1, null) | ROW (1, null) | null | null |
Thanks for the ping, @katzyn. I can't access the linked slack channel by @beikov. Weird, why use a closed (to domains other than the ones listed) slack channel rather than the usual mailing lists? Anyway. ISO/IEC 9075-2:2016(E) 8.2 <comparison predicate> GR 1) b) ii) is quite clear. H2 is right, PostgreSQL and HSQLDB are both wrong. I've posted a message to the pgsql-bugs list: Whether that's worth fixing in PostgreSQL is one thing, but I think H2 is doing it right, and there's no need to take action here. |
For the record, that isn't criticism of you, @beikov, just my surprise that such closed channels even exist. |
It's not closed, but Slack requires that people are invited. You can join here: https://postgres-slack.herokuapp.com/ |
By the way, the null behavior regarding composite types is actually documented: https://www.postgresql.org/docs/current/functions-comparisons.html#COMPOSITE-TYPE-COMPARISON |
Yeah, I guess the array comparison behaviour should be documented there as well |
Thanks. Their explanation of that behavior is the same as for row values. I don't think that ordered index with ordered nulls inside composite values really cannot be used for standard-compliant comparison operator (in H2 it can, both distinct and equality with their very different rules about nulls work with indexes too), but I understand why they don't want to touch that logic. How implementations of JPA or other persistence technologies should deal with these deviations between database systems is an interesting question. But semantics of |
I'm testing with H2 2.1.210
Querying like this
gives no results. Note that the same works on PostgreSQL just fine and in H2 1.4 also when changing from
boolean array
to the untypedarray
.I noticed that switching to the
distinct
operator makes this workSo it seems null semantics are taken into account although they shouldn't.
The text was updated successfully, but these errors were encountered: