Skip to content

Conversation

@auntyellow
Copy link
Contributor

Mentioned in #2480 .

Convert value = ANY(array) toARRAY_CONTAINS(array, value), and this feature can allow some PostgreSQL clients to get PK/UK from pg_constraint, mentioned in #2450 .

The conversion is in optimize stage, but Select.setGroupQuery is in parse stage. If any ANY function detected, skip setGroupQuery. Then setGroupQuery for real aggregate ANY before execute query.

Copy link
Contributor

@katzyn katzyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL Standard has is a syntax conflict between quantified comparison predicates and aggregate functions. This conflict is resolved in H2 via requirement to add parentheses around these functions.

ANY(array) is not a part of the SQL Standard, I'm not sure that we want to have such feature at all. We can accept this feature, but only with sane and non-intrusive implementation.

First of all, you don't need to touch aggregate functions. They aren't related here, the mentioned syntax conflict is already resolved it H2 and there is nothing to change.

Take a look on ConditionIn, ConditionInQuery, ConditionInConstantSet, and ConditionInParameter. You need to create an additional condition. This condition should work like ConditionInQuery, with its compareType parameter, but shouldn't inherit the PredicateWithSubquery. It should extend Condition instead and use the passed expression with array.

The another possible approach is to use the ConditionInQuery() with UNNEST(array) as a query.

@auntyellow
Copy link
Contributor Author

The ANY function here have different meanings, determined by its argument:

  • [A] a condition if arg is a subquery or a parameter;
  • [B] an aggregate if arg is a bool;
  • [C] comparison/condition if arg is an array.

[A] is clear in H2, but [B] and [C] is hard to distinct in parsing because column type is unknown. In most databases, however, ANY is never recognized as an aggregate. If [C] is only supported in PostgreSQL (I don't know whether Oracle and DB2 also support ANY(array)), things can be simpler: just skip [B] and convert [C] to ARRAY_CONTAINS or new Comparison/ConditionAnyArray.

I may close this and submit another pr.

@katzyn
Copy link
Contributor

katzyn commented May 31, 2020

{<|>|<=|>=|=|<>} ANY(query) is a quantified comparison predicate.
{<|>|<=|>=|=|<>} ANY(non-query expression) is a simple comparison with aggregate function.
{<|>|<=|>=|=|<>} (ANY(anything, including subquery)) is a simple comparison with aggregate function.

if arg is a bool;

In H2 other data types may be used as boolean values.

All other constructions are PostgreSQL-specific. H2 supports only = ANY(?) for some limited compatibility with PostgreSQL, this specific construction is used often and was requested multiple times.

You can add {<|>|<=|>=|=|<>} ANY(array) too, but not in that way.

Actually this problem is really even more complicated than I thought initially, because we can't determine data type of expression early if it is not a constant expression. It looks like {<|>|<=|>=|=|<>} ANY(non-query expression) with non-constant expression should always be parsed not as required by the SQL Standard unconditionally, but I don't like “features” that work like a bugs. We need to design and discuss this feature first.

this can prevent HeidiSQL error on unique or composite keys
@katzyn
Copy link
Contributor

katzyn commented Jun 19, 2023

Superseded by #3822.

@katzyn katzyn closed this Jun 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants