Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion core/src/main/java/org/apache/calcite/sql/SqlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,12 @@ public static SqlLiteral concatenateLiterals(List<SqlLiteral> lits) {

private static Iterator<SqlOperator> filterOperatorRoutinesByKind(
Iterator<SqlOperator> routines, final SqlKind sqlKind) {
// Mirror getFunctionKind() on both sides, or an operator whose kind maps to
// something else (e.g. POSITION -> OTHER_FUNCTION) can fail to match itself.
final SqlKind sqlFunctionKind = sqlKind.getFunctionKind();
return Iterators.filter(routines,
operator -> requireNonNull(operator, "operator")
.getKind().getFunctionKind() == sqlKind);
.getKind().getFunctionKind() == sqlFunctionKind);
}

/**
Expand Down
24 changes: 24 additions & 0 deletions core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,30 @@ void testDyadicCollateOperator() {
.fails("Parameters must be of the same type");
}

/** Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-7724">

@mihaibudiu mihaibudiu Aug 18, 2026

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.

this comment is too long; please do not submit useless comments, they will take time from reviewers now and forever when they will be read

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ack

* [CALCITE-7724] SqlUtil#lookupSubjectRoutines rejects a valid operator when its
* SqlKind is remapped by SqlKind#getFunctionKind() and two operator-table entries
* resolve to it</a>.
*
* <p>The kind-based fourth pass in {@code filterOperatorRoutinesByKind} maps only

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.

I am not sure how useful this paragraph is.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've tried to keep it short and be clear. Two competing goals. Are you okay with the comments as they are or do you have a preferred change?

* the candidate's kind through {@code getFunctionKind()}, not the call's own kind -
* so an operator whose kind is remapped (e.g. {@link SqlKind#POSITION}) can fail to
* match itself once a second candidate for the same name exists. */
@Test void testFunctionKindMismatchWithDuplicateOperatorTableEntry() {
// Chaining the operator table with itself ensures that each appears twice.
final SqlOperatorTable duplicated =
SqlOperatorTables.chain(SqlStdOperatorTable.instance(), SqlStdOperatorTable.instance());
expr("position('mouse' in 'house')")
.withOperatorTable(duplicated)
.ok();
expr("char_length('string')")
.withOperatorTable(duplicated)
.ok();
expr("character_length('string')")
.withOperatorTable(duplicated)
.ok();
}

@Test void testTrim() {
expr("trim('mustache' FROM 'beard')").ok();
expr("trim(both 'mustache' FROM 'beard')").ok();
Expand Down
Loading