Skip to content

[Coral-Trino] Fix translation of IN predicate inside JOIN clause - #614

Open
findinpath wants to merge 1 commit into
linkedin:masterfrom
findinpath:findinpath/join-with-in-condition
Open

[Coral-Trino] Fix translation of IN predicate inside JOIN clause#614
findinpath wants to merge 1 commit into
linkedin:masterfrom
findinpath:findinpath/join-with-in-condition

Conversation

@findinpath

@findinpath findinpath commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Reproduction of the issue

CREATE TABLE party (
  party_id   INT,
  party_name STRING
)
STORED AS ORC;

CREATE TABLE party_identification (
  party_id                       INT,
  party_identification_type_code STRING,   -- e.g. 'TIN', 'GIIN', 'SSN'
  party_identification_number    STRING
)
STORED AS ORC;

CREATE VIEW view_repro_in_join AS
SELECT
  p.party_id,
  p.party_name,
  pi1.party_identification_number
FROM party p
INNER JOIN party_identification pi1
  ON  p.party_id = pi1.party_id
  AND pi1.party_identification_type_code IN ('TIN', 'GIIN');

Stacktrace when querying through Trino

Caused by: java.lang.AssertionError: IN($3, 'TIN', 'GIIN')
	at org.apache.calcite.rel.rel2sql.SqlImplementor.convertConditionToSqlNode(SqlImplementor.java:285)
	at org.apache.calcite.rel.rel2sql.SqlImplementor.convertConditionToSqlNode(SqlImplementor.java:222)
	at com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.visit(RelToTrinoConverter.java:311)
Full stacktrace
io.trino.spi.TrinoException: Failed to translate Hive view 'hive_view_repro.view_repro_in_join': While invoking method 'public org.apache.calcite.rel.rel2sql.SqlImplementor$Result com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.visit(org.apache.calcite.rel.core.Project)'
	at io.trino.plugin.hive.ViewReaderUtil$HiveViewReader.decodeViewData(ViewReaderUtil.java:269)
	at io.trino.plugin.hive.HiveMetadata.lambda$toConnectorViewDefinition$0(HiveMetadata.java:3022)
	at java.base/java.util.Optional.flatMap(Optional.java:289)
	at io.trino.plugin.hive.HiveMetadata.toConnectorViewDefinition(HiveMetadata.java:3006)
	at io.trino.plugin.hive.HiveMetadata.getView(HiveMetadata.java:3000)
	at io.trino.plugin.base.classloader.ClassLoaderSafeConnectorMetadata.getView(ClassLoaderSafeConnectorMetadata.java:742)
	at io.trino.tracing.TracingConnectorMetadata.getView(TracingConnectorMetadata.java:875)
	at io.trino.metadata.MetadataManager.getViewInternal(MetadataManager.java:1700)
	at io.trino.metadata.MetadataManager.getView(MetadataManager.java:1638)
	at io.trino.tracing.TracingMetadata.getView(TracingMetadata.java:983)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitTable(StatementAnalyzer.java:2416)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitTable(StatementAnalyzer.java:540)
	at io.trino.sql.tree.Table.accept(Table.java:70)
	at io.trino.sql.tree.AstVisitor.process(AstVisitor.java:27)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.process(StatementAnalyzer.java:559)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.analyzeFrom(StatementAnalyzer.java:5295)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitQuerySpecification(StatementAnalyzer.java:3281)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitQuerySpecification(StatementAnalyzer.java:540)
	at io.trino.sql.tree.QuerySpecification.accept(QuerySpecification.java:155)
	at io.trino.sql.tree.AstVisitor.process(AstVisitor.java:27)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.process(StatementAnalyzer.java:559)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.process(StatementAnalyzer.java:567)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitQuery(StatementAnalyzer.java:1640)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitQuery(StatementAnalyzer.java:540)
	at io.trino.sql.tree.Query.accept(Query.java:130)
	at io.trino.sql.tree.AstVisitor.process(AstVisitor.java:27)
	at io.trino.sql.analyzer.StatementAnalyzer$Visitor.process(StatementAnalyzer.java:559)
	at io.trino.sql.analyzer.StatementAnalyzer.analyze(StatementAnalyzer.java:519)
	at io.trino.sql.analyzer.StatementAnalyzer.analyze(StatementAnalyzer.java:508)
	at io.trino.sql.analyzer.Analyzer.analyze(Analyzer.java:98)
	at io.trino.sql.analyzer.Analyzer.analyze(Analyzer.java:87)
	at io.trino.execution.SqlQueryExecution.analyze(SqlQueryExecution.java:339)
	at io.trino.execution.SqlQueryExecution.<init>(SqlQueryExecution.java:247)
	at io.trino.execution.SqlQueryExecution$SqlQueryExecutionFactory.createQueryExecution(SqlQueryExecution.java:999)
	at io.trino.dispatcher.LocalDispatchQueryFactory.lambda$createDispatchQuery$0(LocalDispatchQueryFactory.java:165)
	at io.trino.$gen.Trino_480_e_1____20260602_153151_2.call(Unknown Source)
	at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:128)
	at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:74)
	at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:80)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
	at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: java.lang.RuntimeException: While invoking method 'public org.apache.calcite.rel.rel2sql.SqlImplementor$Result com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.visit(org.apache.calcite.rel.core.Project)'
	at org.apache.calcite.util.ReflectUtil$2.invoke(ReflectUtil.java:527)
	at org.apache.calcite.rel.rel2sql.RelToSqlConverter.dispatch(RelToSqlConverter.java:122)
	at org.apache.calcite.rel.rel2sql.RelToSqlConverter.visitChild(RelToSqlConverter.java:128)
	at com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.convertToSqlNode(RelToTrinoConverter.java:103)
	at com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.convert(RelToTrinoConverter.java:86)
	at io.trino.plugin.hive.ViewReaderUtil$HiveViewReader.decodeViewData(ViewReaderUtil.java:244)
	... 41 more
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.apache.calcite.util.ReflectUtil$2.invoke(ReflectUtil.java:524)
	... 46 more
Caused by: java.lang.RuntimeException: While invoking method 'public org.apache.calcite.rel.rel2sql.SqlImplementor$Result com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.visit(org.apache.calcite.rel.core.Join)'
	at org.apache.calcite.util.ReflectUtil$2.invoke(ReflectUtil.java:527)
	at org.apache.calcite.rel.rel2sql.RelToSqlConverter.dispatch(RelToSqlConverter.java:122)
	at org.apache.calcite.rel.rel2sql.RelToSqlConverter.visitChild(RelToSqlConverter.java:128)
	at com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.visit(RelToTrinoConverter.java:130)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	... 48 more
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.apache.calcite.util.ReflectUtil$2.invoke(ReflectUtil.java:524)
	... 52 more
Caused by: java.lang.AssertionError: IN($3, 'TIN', 'GIIN')
	at org.apache.calcite.rel.rel2sql.SqlImplementor.convertConditionToSqlNode(SqlImplementor.java:285)
	at org.apache.calcite.rel.rel2sql.SqlImplementor.convertConditionToSqlNode(SqlImplementor.java:222)
	at com.linkedin.coral.trino.rel2trino.RelToTrinoConverter.visit(RelToTrinoConverter.java:311)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	... 54 more

What changes are proposed in this pull request, and why are they necessary?

Calcite's SqlImplementor.convertConditionToSqlNode only handles equality/comparison/null operators in join conditions. CoralINOperator uses SqlKind.OTHER (not SqlKind.IN), so it fell through to the default case and threw AssertionError.

Override convertConditionToSqlNode in RelToTrinoConverter to intercept CoralINOperator nodes and delegate to a join-scoped Context.toSql call, which correctly resolves column references from both sides of the join and renders the IN list via CoralINOperator.unparse.

How was this patch tested?

The patch has been tested with unit tests in HiveToTrinoConverterTest.

@findinpath
findinpath force-pushed the findinpath/join-with-in-condition branch 2 times, most recently from d952756 to 4b35994 Compare August 10, 2026 15:13
@findinpath findinpath changed the title [Coral-Trino] Fix Hive-to-Trino translation of IN predicate inside JOIN clause [Coral-Trino] Fix translation of IN predicate inside JOIN clause Aug 10, 2026
@findinpath
findinpath force-pushed the findinpath/join-with-in-condition branch from 4b35994 to 1271c94 Compare August 10, 2026 15:14

@wmoustafa wmoustafa left a comment

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.

Thanks for the PR. An alternate approach is to modify LinkedIn's Calcite fork to support OTHER operator kinds, but we can go with this approach since it is somewhat specific to Coral IN operator.

@wmoustafa

Copy link
Copy Markdown
Contributor

Can we also apply the same change to CoralRelToSqlNodeConverter?

Calcite's SqlImplementor.convertConditionToSqlNode only handles
equality/comparison/null operators in join conditions. CoralINOperator
uses SqlKind.OTHER (not SqlKind.IN), so it fell through to the default
case and threw AssertionError.

Override convertConditionToSqlNode in
RelToTrinoConverter and CoralRelToSqlNodeConverter
to intercept CoralINOperator nodes and delegate to
a join-scoped Context.toSql call, which correctly
resolves column references from both sides of the join
and renders the IN list via CoralINOperator.unparse.
@findinpath
findinpath force-pushed the findinpath/join-with-in-condition branch from 1271c94 to fdedba7 Compare August 13, 2026 13:37
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