From 908c8def063e529ee4f1aa146d43132b9dafd66e Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Wed, 30 Jan 2019 11:34:47 +0200 Subject: [PATCH] SQL: Skip the nested and object field types in case of an ODBC request (#37948) --- .../plan/logical/command/sys/SysColumns.java | 78 ++++++++++--------- .../logical/command/sys/SysColumnsTests.java | 63 +++++++++++++-- 2 files changed, 98 insertions(+), 43 deletions(-) diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java index 76b58babe28..b3730ee3340 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java @@ -15,8 +15,8 @@ import org.elasticsearch.xpack.sql.proto.Mode; import org.elasticsearch.xpack.sql.session.Rows; import org.elasticsearch.xpack.sql.session.SchemaRowSet; import org.elasticsearch.xpack.sql.session.SqlSession; -import org.elasticsearch.xpack.sql.tree.Source; import org.elasticsearch.xpack.sql.tree.NodeInfo; +import org.elasticsearch.xpack.sql.tree.Source; import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataTypes; import org.elasticsearch.xpack.sql.type.EsField; @@ -133,42 +133,46 @@ public class SysColumns extends Command { EsField field = entry.getValue(); DataType type = field.getDataType(); - if (columnMatcher == null || columnMatcher.matcher(name).matches()) { - rows.add(asList(clusterName, - // schema is not supported - null, - indexName, - name, - odbcCompatible(type.sqlType.getVendorTypeNumber(), isOdbcClient), - type.esType.toUpperCase(Locale.ROOT), - type.displaySize, - // TODO: is the buffer_length correct? - type.size, - // no DECIMAL support - null, - odbcCompatible(DataTypes.metaSqlRadix(type), isOdbcClient), - // everything is nullable - odbcCompatible(DatabaseMetaData.columnNullable, isOdbcClient), - // no remarks - null, - // no column def - null, - // SQL_DATA_TYPE apparently needs to be same as DATA_TYPE except for datetime and interval data types - odbcCompatible(DataTypes.metaSqlDataType(type), isOdbcClient), - // SQL_DATETIME_SUB ? - odbcCompatible(DataTypes.metaSqlDateTimeSub(type), isOdbcClient), - // char octet length - type.isString() || type == DataType.BINARY ? type.size : null, - // position - pos, - "YES", - null, - null, - null, - null, - "NO", - "NO" - )); + // skip the nested and object types only for ODBC + // https://github.com/elastic/elasticsearch/issues/35376 + if (type.isPrimitive() || !isOdbcClient) { + if (columnMatcher == null || columnMatcher.matcher(name).matches()) { + rows.add(asList(clusterName, + // schema is not supported + null, + indexName, + name, + odbcCompatible(type.sqlType.getVendorTypeNumber(), isOdbcClient), + type.esType.toUpperCase(Locale.ROOT), + type.displaySize, + // TODO: is the buffer_length correct? + type.size, + // no DECIMAL support + null, + odbcCompatible(DataTypes.metaSqlRadix(type), isOdbcClient), + // everything is nullable + odbcCompatible(DatabaseMetaData.columnNullable, isOdbcClient), + // no remarks + null, + // no column def + null, + // SQL_DATA_TYPE apparently needs to be same as DATA_TYPE except for datetime and interval data types + odbcCompatible(DataTypes.metaSqlDataType(type), isOdbcClient), + // SQL_DATETIME_SUB ? + odbcCompatible(DataTypes.metaSqlDateTimeSub(type), isOdbcClient), + // char octet length + type.isString() || type == DataType.BINARY ? type.size : null, + // position + pos, + "YES", + null, + null, + null, + null, + "NO", + "NO" + )); + } } if (field.getProperties() != null) { fillInRows(clusterName, indexName, field.getProperties(), name, rows, columnMatcher, isOdbcClient); diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java index 6e254eca938..be656411656 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java @@ -61,7 +61,7 @@ public class SysColumnsTests extends ESTestCase { public void testSysColumnsInOdbcMode() { List> rows = new ArrayList<>(); SysColumns.fillInRows("test", "index", TypesTests.loadMapping("mapping-multi-field-variation.json", true), null, rows, null, true); - assertEquals(16, rows.size()); + assertEquals(14, rows.size()); assertEquals(24, rows.get(0).size()); List row = rows.get(0); @@ -90,6 +90,16 @@ public class SysColumnsTests extends ESTestCase { assertEquals(Short.class, sqlDataType(row).getClass()); assertEquals(Short.class, sqlDataTypeSub(row).getClass()); + row = rows.get(3); + assertEquals("keyword", name(row)); + assertEquals((short) Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + assertNull(decimalPrecision(row)); + assertEquals(Short.class, nullable(row).getClass()); + assertEquals(Short.class, sqlDataType(row).getClass()); + assertEquals(Short.class, sqlDataTypeSub(row).getClass()); + row = rows.get(4); assertEquals("date", name(row)); assertEquals((short) Types.TIMESTAMP, sqlType(row)); @@ -101,17 +111,58 @@ public class SysColumnsTests extends ESTestCase { assertEquals(Short.class, sqlDataType(row).getClass()); assertEquals(Short.class, sqlDataTypeSub(row).getClass()); - row = rows.get(7); - assertEquals("some.dotted", name(row)); - assertEquals((short) Types.STRUCT, sqlType(row)); + row = rows.get(5); + assertEquals("unsupported", name(row)); + assertEquals((short) Types.OTHER, sqlType(row)); assertEquals(null, radix(row)); - assertEquals(-1, bufferLength(row)); + assertEquals(0, precision(row)); + assertEquals(0, bufferLength(row)); assertNull(decimalPrecision(row)); assertEquals(Short.class, nullable(row).getClass()); assertEquals(Short.class, sqlDataType(row).getClass()); assertEquals(Short.class, sqlDataTypeSub(row).getClass()); - row = rows.get(15); + row = rows.get(6); + assertEquals("some.dotted.field", name(row)); + assertEquals((short) Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + assertNull(decimalPrecision(row)); + assertEquals(Short.class, nullable(row).getClass()); + assertEquals(Short.class, sqlDataType(row).getClass()); + assertEquals(Short.class, sqlDataTypeSub(row).getClass()); + + row = rows.get(7); + assertEquals("some.string", name(row)); + assertEquals((short) Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + assertNull(decimalPrecision(row)); + assertEquals(Short.class, nullable(row).getClass()); + assertEquals(Short.class, sqlDataType(row).getClass()); + assertEquals(Short.class, sqlDataTypeSub(row).getClass()); + + row = rows.get(8); + assertEquals("some.string.normalized", name(row)); + assertEquals((short) Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + assertNull(decimalPrecision(row)); + assertEquals(Short.class, nullable(row).getClass()); + assertEquals(Short.class, sqlDataType(row).getClass()); + assertEquals(Short.class, sqlDataTypeSub(row).getClass()); + + row = rows.get(9); + assertEquals("some.string.typical", name(row)); + assertEquals((short) Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + assertNull(decimalPrecision(row)); + assertEquals(Short.class, nullable(row).getClass()); + assertEquals(Short.class, sqlDataType(row).getClass()); + assertEquals(Short.class, sqlDataTypeSub(row).getClass()); + + row = rows.get(13); assertEquals("some.ambiguous.normalized", name(row)); assertEquals((short) Types.VARCHAR, sqlType(row)); assertEquals(null, radix(row));