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 1cd4a5928763..4d666570add2 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 @@ -69,6 +69,7 @@ import io.trino.spi.connector.JoinCondition; import io.trino.spi.connector.JoinStatistics; import io.trino.spi.connector.JoinType; +import io.trino.spi.connector.TableNotFoundException; import io.trino.spi.expression.ConnectorExpression; import io.trino.spi.predicate.Domain; import io.trino.spi.predicate.ValueSet; @@ -438,7 +439,7 @@ protected Map getCaseSensitivityForColumns(ConnectorSes if (tableHandle.isSynthetic()) { return ImmutableMap.of(); } - PreparedQuery preparedQuery = new PreparedQuery(format("SELECT * from %s", quoted(tableHandle.asPlainTable().getRemoteTableName())), ImmutableList.of()); + PreparedQuery preparedQuery = new PreparedQuery(format("SELECT * FROM %s", quoted(tableHandle.asPlainTable().getRemoteTableName())), ImmutableList.of()); try (PreparedStatement preparedStatement = queryBuilder.prepareStatement(this, session, connection, preparedQuery)) { ResultSetMetaData metadata = preparedStatement.getMetaData(); @@ -450,6 +451,13 @@ protected Map getCaseSensitivityForColumns(ConnectorSes return columns.buildOrThrow(); } catch (SQLException e) { + if (e instanceof SQLServerException sqlServerException && sqlServerException.getSQLServerError().getErrorNumber() == 208) { + // The 208 indicates that the object doesn't exist or lack of permission. + // Throw TableNotFoundException because users shouldn't see such tables if they don't have the permission. + // TableNotFoundException will be suppressed when listing information_schema. + // https://learn.microsoft.com/sql/relational-databases/errors-events/mssqlserver-208-database-engine-error + throw new TableNotFoundException(tableHandle.asPlainTable().getSchemaTableName()); + } throw new TrinoException(JDBC_ERROR, "Failed to get case sensitivity for columns. " + firstNonNull(e.getMessage(), e), e); } } diff --git a/plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/BaseSqlServerConnectorTest.java b/plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/BaseSqlServerConnectorTest.java index 429e14d225d7..df6f1ce1b7c3 100644 --- a/plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/BaseSqlServerConnectorTest.java +++ b/plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/BaseSqlServerConnectorTest.java @@ -161,14 +161,6 @@ public void testReadMetadataWithRelationsConcurrentModifications() } catch (Exception expected) { // The test failure is not guaranteed - // TODO (https://github.com/trinodb/trino/issues/10846): shouldn't fail - if (expected.getMessage().contains("case sensitivity")) { - // this could fail on step before - during read case sensitivity information - assertThat(expected) - // before get columns from database metadata, for SqlServer we first try to get case sensitivity - .hasMessageMatching(".*Failed to get case sensitivity for columns. Invalid object name.*"); - throw new SkipException("to be fixed"); - } assertThat(expected) .hasMessageMatching("(?s).*(" + "No task completed before timeout|" +