Skip to content

[CALCITE-7749] CONCAT (and other STRING_SAME_SAME-typed operators) gives misleading error message for mixed CHARACTER/BINARY arguments - #5232

Open
Dwrite wants to merge 1 commit into
apache:mainfrom
Dwrite:CALCITE-7749
Open

[CALCITE-7749] CONCAT (and other STRING_SAME_SAME-typed operators) gives misleading error message for mixed CHARACTER/BINARY arguments#5232
Dwrite wants to merge 1 commit into
apache:mainfrom
Dwrite:CALCITE-7749

Conversation

@Dwrite

@Dwrite Dwrite commented Aug 30, 2026

Copy link
Copy Markdown

CONCAT (and other STRING_SAME_SAME-typed operators) gives misleading error message for mixed CHARACTER/BINARY arguments

Jira Link
CALCITE-7749

Changes Proposed

SqlTypeFamily.STRING is an aggregate family covering both CHARACTER and BINARY. Operators such as CONCAT (SqlLibraryOperators.CONCAT2) use OperandTypes.STRING_SAME_SAME, defined as STRING_STRING.and(SAME_SAME). Each operand independently passes STRING_STRING (since both CHAR and BINARY belong to the STRING family), so the constraint that actually rejects mixed CHARACTER/BINARY calls comes from the second, AND-composed rule SAME_SAME.

CompositeOperandTypeChecker#getAllowedSignatures, however, only includes the first sub-rule's signature for AND compositions and drops any subsequent rule's signature. As a result, the error message for e.g. CONCAT('a', x'0a') was:

Cannot apply 'CONCAT' to arguments of type 'CONCAT(<CHAR(1)>, <BINARY(1)>)'.
Supported form(s): 'CONCAT(, )'

which is misleading, since CONCAT does support BINARY arguments (e.g. CONCAT(x'0a', x'0b')); the real constraint is that both operands must belong to the same concrete sub-family.

This change adds a SqlSingleOperandTypeChecker wrapper in OperandTypes that overrides only getAllowedSignatures, delegating all type-checking behavior to the original checker unchanged, and attaches it to STRING_SAME_SAME, STRING_SAME_SAME_SAME, and STRING_SAME_SAME_INTEGER. The generated message now enumerates both concretely valid forms:

Supported form(s): 'CONCAT(, )'
'CONCAT(, )'

CompositeOperandTypeChecker#withGenerator was not used directly, because it always returns a plain CompositeOperandTypeChecker, which is not a SqlSingleOperandTypeChecker — casting the result throws ClassCastException at runtime for these fields.

STRING_SAME_SAME_OR_ARRAY_SAME_SAME requires no separate change, since it composes STRING_SAME_SAME via OR, and OR-composed signatures already aggregate all sub-rule signatures — it picks up the fix automatically.

Operators sharing STRING_SAME_SAME (CONCAT2, ENDS_WITH/ENDSWITH, STARTS_WITH/STARTSWITH) are all affected by this message change; CONCAT_FUNCTION (the MySQL/BigQuery variadic CONCAT, which uses OperandTypes.repeat(..., STRING) without SAME_SAME) is unrelated and unaffected.

Testing

Updated SqlOperatorTest#checkConcat2Func to assert the new two-form error message for CONCAT('a', x'0a').
Added/updated coverage confirming CONCAT('a', 'b') and CONCAT(x'0a', x'0b') still validate successfully (no regression to the underlying type-checking logic).

…ves misleading error message for mixed CHARACTER/BINARY arguments
@sonarqubecloud

Copy link
Copy Markdown

@Dwrite Dwrite changed the title [CALCITE-7749] CONCAT (and other STRING_SAME_SAME-typed operators) gi… [CALCITE-7749] CONCAT (and other STRING_SAME_SAME-typed operators) gives misleading error message for mixed CHARACTER/BINARY arguments Aug 30, 2026
+ "Supported form\\(s\\): "
+ "'<CHARACTER> \\|\\| <CHARACTER>'\\s*"
+ "'<BINARY> \\|\\| <BINARY>'\\s*"
+ "'<EQUIVALENT_TYPE> \\|\\| <EQUIVALENT_TYPE>'.*");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what is EQUIVALENT_TYPE?

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