diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java index ea3735df967c..2738606a8aba 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java @@ -27,6 +27,7 @@ import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.connector.FixedSplitSource; +import io.trino.spi.connector.JoinCondition; import io.trino.spi.connector.JoinStatistics; import io.trino.spi.connector.JoinType; import io.trino.spi.connector.SchemaTableName; @@ -412,7 +413,7 @@ public Optional implementJoin( JoinStatistics statistics) { for (JdbcJoinCondition joinCondition : joinConditions) { - if (!isSupportedJoinCondition(joinCondition)) { + if (!isSupportedJoinCondition(session, joinCondition)) { return Optional.empty(); } } @@ -428,7 +429,13 @@ public Optional implementJoin( rightAssignments)); } - protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) + @Override + public String buildJoinColumn(JdbcJoinCondition joinCondition, JdbcColumnHandle column) + { + return quoted(column.getColumnName()); + } + + protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCondition joinCondition) { return false; } diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java index 8b827c2c6692..8c6b3fbb520f 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java @@ -168,6 +168,8 @@ default Optional getSystemTable(ConnectorSession session, SchemaTab return Optional.empty(); } + String buildJoinColumn(JdbcJoinCondition joinCondition, JdbcColumnHandle column); + String quoted(String name); String quoted(RemoteTableName remoteTableName); diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/QueryBuilder.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/QueryBuilder.java index e3a5b4c2afd9..bdbe156c0d78 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/QueryBuilder.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/QueryBuilder.java @@ -125,9 +125,9 @@ public PreparedQuery prepareJoinQuery( joinConditions.stream() .map(condition -> format( "l.%s %s r.%s", - client.quoted(condition.getLeftColumn().getColumnName()), + client.buildJoinColumn(condition, condition.getLeftColumn()), condition.getOperator().getValue(), - client.quoted(condition.getRightColumn().getColumnName()))) + client.buildJoinColumn(condition, condition.getRightColumn()))) .collect(joining(" AND "))); List parameters = ImmutableList.builder() .addAll(leftSource.getParameters()) diff --git a/plugin/trino-memsql/src/main/java/io/trino/plugin/memsql/MemSqlClient.java b/plugin/trino-memsql/src/main/java/io/trino/plugin/memsql/MemSqlClient.java index 6316e5de8a60..a0dadca1aaad 100644 --- a/plugin/trino-memsql/src/main/java/io/trino/plugin/memsql/MemSqlClient.java +++ b/plugin/trino-memsql/src/main/java/io/trino/plugin/memsql/MemSqlClient.java @@ -586,7 +586,7 @@ public Optional implementJoin( } @Override - protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) + protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCondition joinCondition) { if (joinCondition.getOperator() == JoinCondition.Operator.IS_DISTINCT_FROM) { // Not supported in MemSQL diff --git a/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java b/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java index a2aa7322ac72..ff11a6125967 100644 --- a/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java +++ b/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java @@ -620,7 +620,7 @@ public Optional implementJoin( } @Override - protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) + protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCondition joinCondition) { if (joinCondition.getOperator() == JoinCondition.Operator.IS_DISTINCT_FROM) { // Not supported in MySQL diff --git a/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java b/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java index f8683feff133..2bada4cec919 100644 --- a/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java +++ b/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java @@ -352,7 +352,7 @@ else if (precision > Decimals.MAX_PRECISION || actualPrecision <= 0) { } @Override - protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) + protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCondition joinCondition) { return joinCondition.getOperator() != JoinCondition.Operator.IS_DISTINCT_FROM; } diff --git a/plugin/trino-postgresql/src/main/java/io/trino/plugin/postgresql/PostgreSqlClient.java b/plugin/trino-postgresql/src/main/java/io/trino/plugin/postgresql/PostgreSqlClient.java index e3fe3010d17a..437f2c33fd9d 100644 --- a/plugin/trino-postgresql/src/main/java/io/trino/plugin/postgresql/PostgreSqlClient.java +++ b/plugin/trino-postgresql/src/main/java/io/trino/plugin/postgresql/PostgreSqlClient.java @@ -817,7 +817,7 @@ public OptionalLong delete(ConnectorSession session, JdbcTableHandle handle) } @Override - protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) + protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCondition joinCondition) { boolean isVarchar = Stream.of(joinCondition.getLeftColumn(), joinCondition.getRightColumn()) .map(JdbcColumnHandle::getColumnType) @@ -830,7 +830,7 @@ protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) case LESS_THAN_OR_EQUAL: case GREATER_THAN: case GREATER_THAN_OR_EQUAL: - break; + return isEnableStringPushdownWithCollate(session); case EQUAL: case NOT_EQUAL: case IS_DISTINCT_FROM: @@ -842,6 +842,27 @@ protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) return true; } + @Override + public String buildJoinColumn(JdbcJoinCondition joinCondition, JdbcColumnHandle column) + { + boolean isVarchar = Stream.of(joinCondition.getLeftColumn(), joinCondition.getRightColumn()) + .map(JdbcColumnHandle::getColumnType) + .anyMatch(type -> type instanceof CharType || type instanceof VarcharType); + String collation = ""; + if (isVarchar) { + JoinCondition.Operator operator = joinCondition.getOperator(); + switch (operator) { + case LESS_THAN: + case LESS_THAN_OR_EQUAL: + case GREATER_THAN: + case GREATER_THAN_OR_EQUAL: + collation = "COLLATE \"C\""; + } + } + + return String.format("%s %s", quoted(column.getColumnName()), collation); + } + private static ColumnMapping charColumnMapping(int charLength) { if (charLength > CharType.MAX_LENGTH) { diff --git a/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java b/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java index 4f58691d8bbc..cf0fd71a7080 100644 --- a/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java +++ b/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java @@ -613,7 +613,7 @@ public boolean isTopNGuaranteed(ConnectorSession session) } @Override - protected boolean isSupportedJoinCondition(JdbcJoinCondition joinCondition) + protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCondition joinCondition) { if (joinCondition.getOperator() == JoinCondition.Operator.IS_DISTINCT_FROM) { // Not supported in SQL Server