SQL: Improve compatibility with MS query (#30516)

Support TABLE as a legacy argument for SYS TABLE commands

Fix #30398
This commit is contained in:
Costin Leau 2018-05-10 20:15:50 +03:00 committed by GitHub
parent 52580b5ca8
commit 293ca92e93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 4 deletions

View File

@ -148,6 +148,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
@Override
public SysTables visitSysTables(SysTablesContext ctx) {
List<IndexType> types = new ArrayList<>();
boolean legacyTableType = false;
for (StringContext string : ctx.string()) {
String value = string(string);
if (value != null) {
@ -156,6 +157,12 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
// since % is the same as not specifying a value, choose
// https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/value-list-arguments?view=ssdt-18vs2017
// that is skip the value
}
// special case for legacy apps (like msquery) that always asks for 'TABLE'
// which we manually map to all concrete tables supported
else if (value.toUpperCase(Locale.ROOT).equals("TABLE")) {
legacyTableType = true;
types.add(IndexType.INDEX);
} else {
IndexType type = IndexType.from(value);
types.add(type);
@ -165,7 +172,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
// if the ODBC enumeration is specified, skip validation
EnumSet<IndexType> set = types.isEmpty() ? null : EnumSet.copyOf(types);
return new SysTables(source(ctx), visitPattern(ctx.clusterPattern), visitPattern(ctx.tablePattern), set);
return new SysTables(source(ctx), visitPattern(ctx.clusterPattern), visitPattern(ctx.tablePattern), set, legacyTableType);
}
@Override

View File

@ -33,17 +33,21 @@ public class SysTables extends Command {
private final LikePattern pattern;
private final LikePattern clusterPattern;
private final EnumSet<IndexType> types;
// flag indicating whether tables are reported as `TABLE` or `BASE TABLE`
private final boolean legacyTableTypes;
public SysTables(Location location, LikePattern clusterPattern, LikePattern pattern, EnumSet<IndexType> types) {
public SysTables(Location location, LikePattern clusterPattern, LikePattern pattern, EnumSet<IndexType> types,
boolean legacyTableTypes) {
super(location);
this.clusterPattern = clusterPattern;
this.pattern = pattern;
this.types = types;
this.legacyTableTypes = legacyTableTypes;
}
@Override
protected NodeInfo<SysTables> info() {
return NodeInfo.create(this, SysTables::new, clusterPattern, pattern, types);
return NodeInfo.create(this, SysTables::new, clusterPattern, pattern, types, legacyTableTypes);
}
@Override
@ -111,7 +115,7 @@ public class SysTables extends Command {
.map(t -> asList(cluster,
EMPTY,
t.name(),
t.type().toSql(),
legacyName(t.type()),
EMPTY,
null,
null,
@ -122,6 +126,10 @@ public class SysTables extends Command {
, listener::onFailure));
}
private String legacyName(IndexType indexType) {
return legacyTableTypes && indexType == IndexType.INDEX ? "TABLE" : indexType.toSql();
}
@Override
public int hashCode() {
return Objects.hash(clusterPattern, pattern, types);

View File

@ -105,6 +105,23 @@ public class SysTablesTests extends ESTestCase {
}, index);
}
public void testSysTablesOnlyIndicesInLegacyMode() throws Exception {
executeCommand("SYS TABLES LIKE 'test' TYPE 'TABLE'", r -> {
assertEquals(1, r.size());
assertEquals("test", r.column(2));
assertEquals("TABLE", r.column(3));
}, index);
}
public void testSysTablesOnlyIndicesLegacyModeParameterized() throws Exception {
executeCommand("SYS TABLES LIKE 'test' TYPE ?", asList(param("TABLE")), r -> {
assertEquals(1, r.size());
assertEquals("test", r.column(2));
assertEquals("TABLE", r.column(3));
}, index);
}
public void testSysTablesOnlyIndicesParameterized() throws Exception {
executeCommand("SYS TABLES LIKE 'test' TYPE ?", asList(param("ALIAS")), r -> {
assertEquals(1, r.size());
@ -131,6 +148,18 @@ public class SysTablesTests extends ESTestCase {
}, index, alias);
}
public void testSysTablesOnlyIndicesLegacyAndAliasesParameterized() throws Exception {
List<SqlTypedParamValue> params = asList(param("ALIAS"), param("TABLE"));
executeCommand("SYS TABLES LIKE 'test' TYPE ?, ?", params, r -> {
assertEquals(2, r.size());
assertEquals("test", r.column(2));
assertEquals("TABLE", r.column(3));
assertTrue(r.advanceRow());
assertEquals("alias", r.column(2));
assertEquals("ALIAS", r.column(3));
}, index, alias);
}
public void testSysTablesWithCatalogOnlyAliases() throws Exception {
executeCommand("SYS TABLES CATALOG LIKE '%' LIKE 'test' TYPE 'ALIAS'", r -> {
assertEquals(1, r.size());