Skip to content

Commit 2f0410b

Browse files
committed
Add Synonyms to SqlServerConnector
Adds a configuration option to allow users to opt-in to having Trino be able to interact with SQL Server Synonym table types. This closes #24206
1 parent 33cbda6 commit 2f0410b

File tree

7 files changed

+88
-0
lines changed

7 files changed

+88
-0
lines changed

docs/src/main/sphinx/connector/sqlserver.md

+4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ behavior of the connector and the issues queries to the database.
106106
- Control the automatic use of snapshot isolation for transactions issued by
107107
Trino in SQL Server. Defaults to `false`, which means that snapshot
108108
isolation is enabled.
109+
* - `sqlserver.synonyms.enabled=true`
110+
- Include [synonyms](https://learn.microsoft.com/en-us/sql/relational-databases/synonyms/synonyms-database-engine?view=sql-server-ver16)
111+
as queryable entities. Defaults to `false`, which means synonyms are not
112+
included by default.
109113
:::
110114

111115
```{include} jdbc-case-insensitive-matching.fragment

plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java

+12
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,12 @@ public class SqlServerClient
287287

288288
return FULL_PUSHDOWN.apply(session, domain);
289289
};
290+
private final boolean synonymsEnabled;
290291

291292
@Inject
292293
public SqlServerClient(
293294
BaseJdbcConfig config,
295+
SqlServerConfig sqlServerConfig,
294296
JdbcStatisticsConfig statisticsConfig,
295297
ConnectionFactory connectionFactory,
296298
QueryBuilder queryBuilder,
@@ -300,6 +302,7 @@ public SqlServerClient(
300302
super("\"", connectionFactory, queryBuilder, config.getJdbcTypesMappedToVarchar(), identifierMapping, queryModifier, true);
301303

302304
this.statisticsEnabled = statisticsConfig.isEnabled();
305+
this.synonymsEnabled = sqlServerConfig.isSynonymsEnabled();
303306

304307
this.connectorExpressionRewriter = JdbcConnectorExpressionRewriterBuilder.newBuilder()
305308
.addStandardRules(this::quoted)
@@ -345,6 +348,15 @@ public SqlServerClient(
345348
.build());
346349
}
347350

351+
@Override
352+
protected Optional<List<String>> getTableTypes()
353+
{
354+
if (synonymsEnabled) {
355+
return Optional.of(ImmutableList.of("TABLE", "VIEW", "SYNONYM"));
356+
}
357+
return Optional.of(ImmutableList.of("TABLE", "VIEW"));
358+
}
359+
348360
@Override
349361
protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade)
350362
throws SQLException

plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerConfig.java

+14
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class SqlServerConfig
2323
private boolean bulkCopyForWrite;
2424
private boolean bulkCopyForWriteLockDestinationTable;
2525
private boolean storedProcedureTableFunctionEnabled;
26+
private boolean synonymsEnabled;
2627

2728
public boolean isBulkCopyForWrite()
2829
{
@@ -76,4 +77,17 @@ public SqlServerConfig setStoredProcedureTableFunctionEnabled(boolean storedProc
7677
this.storedProcedureTableFunctionEnabled = storedProcedureTableFunctionEnabled;
7778
return this;
7879
}
80+
81+
@Config("sqlserver.synonyms.enabled")
82+
@ConfigDescription("Allows SQL Server Synonym manipulation")
83+
public SqlServerConfig setSynonymsEnabled(boolean enabled)
84+
{
85+
this.synonymsEnabled = enabled;
86+
return this;
87+
}
88+
89+
public boolean isSynonymsEnabled()
90+
{
91+
return synonymsEnabled;
92+
}
7993
}

plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/BaseSqlServerConnectorTest.java

+8
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ public void testReadFromView()
120120
}
121121
}
122122

123+
@Test
124+
public void testSynonyms()
125+
{
126+
try (TestSynonym synonym = new TestSynonym(onRemoteDatabase(), "test_synonym", "FOR ORDERS")) {
127+
assertQueryFails("SELECT orderkey FROM " + synonym.getName(), "line 1:22: Table 'sqlserver.*' does not exist");
128+
}
129+
}
130+
123131
@Override
124132
protected void verifyAddNotNullColumnToNonEmptyTableFailurePermissible(Throwable e)
125133
{

plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/TestSqlServerClient.java

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public class TestSqlServerClient
5858

5959
private static final JdbcClient JDBC_CLIENT = new SqlServerClient(
6060
new BaseJdbcConfig(),
61+
new SqlServerConfig(),
6162
new JdbcStatisticsConfig(),
6263
session -> {
6364
throw new UnsupportedOperationException();

plugin/trino-sqlserver/src/test/java/io/trino/plugin/sqlserver/TestSqlServerConfig.java

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class TestSqlServerConfig
2828
public void testDefaults()
2929
{
3030
assertRecordedDefaults(recordDefaults(SqlServerConfig.class)
31+
.setSynonymsEnabled(false)
3132
.setBulkCopyForWrite(false)
3233
.setBulkCopyForWriteLockDestinationTable(false)
3334
.setSnapshotIsolationDisabled(false)
@@ -38,13 +39,15 @@ public void testDefaults()
3839
public void testExplicitPropertyMappings()
3940
{
4041
Map<String, String> properties = ImmutableMap.<String, String>builder()
42+
.put("sqlserver.synonyms.enabled", "true")
4143
.put("sqlserver.bulk-copy-for-write.enabled", "true")
4244
.put("sqlserver.bulk-copy-for-write.lock-destination-table", "true")
4345
.put("sqlserver.snapshot-isolation.disabled", "true")
4446
.put("sqlserver.stored-procedure-table-function-enabled", "true")
4547
.buildOrThrow();
4648

4749
SqlServerConfig expected = new SqlServerConfig()
50+
.setSynonymsEnabled(true)
4851
.setBulkCopyForWrite(true)
4952
.setBulkCopyForWriteLockDestinationTable(true)
5053
.setStoredProcedureTableFunctionEnabled(true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.trino.plugin.sqlserver;
15+
16+
import io.trino.testing.sql.SqlExecutor;
17+
18+
import java.io.Closeable;
19+
20+
import static io.trino.testing.TestingNames.randomNameSuffix;
21+
import static java.lang.String.format;
22+
23+
public class TestSynonym
24+
implements Closeable
25+
{
26+
private final SqlExecutor sqlExecutor;
27+
private final String name;
28+
29+
public TestSynonym(SqlExecutor sqlExecutor, String namePrefix, String definition)
30+
{
31+
this.sqlExecutor = sqlExecutor;
32+
this.name = namePrefix + "_" + randomNameSuffix();
33+
sqlExecutor.execute(format("CREATE SYNONYM %s %s", name, definition));
34+
}
35+
36+
public String getName()
37+
{
38+
return name;
39+
}
40+
41+
@Override
42+
public void close()
43+
{
44+
sqlExecutor.execute("DROP SYNONYM " + name);
45+
}
46+
}

0 commit comments

Comments
 (0)