diff --git a/docs/en/sql/endpoints/rest.asciidoc b/docs/en/sql/endpoints/rest.asciidoc index 17d96ad4df0..beb1cd2847a 100644 --- a/docs/en/sql/endpoints/rest.asciidoc +++ b/docs/en/sql/endpoints/rest.asciidoc @@ -183,35 +183,3 @@ or fewer results though. `time_zone` is the time zone to use for date functions and date parsing. `time_zone` defaults to `utc` and can take any values documented http://www.joda.org/joda-time/apidocs/org/joda/time/DateTimeZone.html[here]. - - -[[sql-rest-metadata]] - -To get the list of fields that are supported in SQL execute: - -[source,js] --------------------------------------------------- -POST /_xpack/sql/columns -{ - "table_pattern": "library", - "column_pattern": "" -} --------------------------------------------------- -// CONSOLE -// TEST[continued] - -[source,js] --------------------------------------------------- -{ - "columns": [ - {"table": "library", "name": "author", "type": "text", "position": 1}, - {"table": "library", "name": "name", "type": "text", "position": 2}, - {"table": "library", "name": "page_count", "type": "short", "position": 3}, - {"table": "library", "name": "release_date", "type": "date", "position": 4} - ] -} --------------------------------------------------- -// TESTRESPONSE - -The `position` is the position in the original table and won't match the position in the -array if the `column_pattern` removes any columns. \ No newline at end of file diff --git a/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java b/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java index dbc1b2f017a..9fb6e233f84 100644 --- a/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java +++ b/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java @@ -480,8 +480,7 @@ public class AuthorizationService extends AbstractComponent { action.equals("indices:data/read/search/template") || action.equals("indices:data/write/reindex") || action.equals("indices:data/read/sql") || - action.equals("indices:data/read/sql/translate") || - action.equals("indices:admin/sql/columns") ; + action.equals("indices:data/read/sql/translate"); } private static boolean isTranslatedToBulkAction(String action) { diff --git a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcDatabaseMetaData.java b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcDatabaseMetaData.java index a538ecb5d94..4e5d77e99f9 100644 --- a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcDatabaseMetaData.java +++ b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcDatabaseMetaData.java @@ -10,7 +10,6 @@ import org.elasticsearch.xpack.sql.client.shared.Version; import org.elasticsearch.xpack.sql.jdbc.JdbcSQLException; import org.elasticsearch.xpack.sql.jdbc.net.client.Cursor; import org.elasticsearch.xpack.sql.jdbc.net.protocol.ColumnInfo; -import org.elasticsearch.xpack.sql.plugin.MetaColumnInfo; import java.sql.Connection; import java.sql.DatabaseMetaData; @@ -23,8 +22,6 @@ import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.List; -import static org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcUtils.numericPrecisionRadix; - /** * Implementation of {@link DatabaseMetaData} for Elasticsearch. Draws inspiration * from @@ -742,73 +739,11 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper { @Override public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { - List info = columnInfo("COLUMNS", - "TABLE_CAT", - "TABLE_SCHEM", - "TABLE_NAME", - "COLUMN_NAME", - "DATA_TYPE", int.class, - "TYPE_NAME", - "COLUMN_SIZE", int.class, - "BUFFER_LENGTH", void.class, - "DECIMAL_DIGITS", int.class, - "NUM_PREC_RADIX", int.class, - "NULLABLE", int.class, - "REMARKS", - "COLUMN_DEF", - "SQL_DATA_TYPE", int.class, - "SQL_DATETIME_SUB", int.class, - "CHAR_OCTET_LENGTH", int.class, - "ORDINAL_POSITION", int.class, - "IS_NULLABLE", - "SCOPE_CATALOG", - "SCOPE_SCHEMA", - "SCOPE_TABLE", - "SOURCE_DATA_TYPE", short.class, - "IS_AUTOINCREMENT", - "IS_GENERATEDCOLUMN"); - - // schema and catalogs are not being used, if these are specified return an empty result set - if (!isDefaultCatalog(catalog) || !isDefaultSchema(schemaPattern)) { - return emptySet(con.cfg, info); - } - - String cat = defaultCatalog(); - // escaping is done on the server - List columns = con.client.metaInfoColumns(tableNamePattern, columnNamePattern); - Object[][] data = new Object[columns.size()][]; - for (int i = 0; i < data.length; i++) { - data[i] = new Object[24]; - Object[] row = data[i]; - MetaColumnInfo col = columns.get(i); - - row[ 0] = cat; - row[ 1] = ""; - row[ 2] = col.table(); - row[ 3] = col.name(); - row[ 4] = col.jdbcType().getVendorTypeNumber(); - row[ 5] = col.jdbcType().getName(); - row[ 6] = col.size(); - row[ 7] = null; - row[ 8] = null; - row[ 9] = numericPrecisionRadix(col.jdbcType().getVendorTypeNumber()); - row[10] = columnNullable; - row[11] = null; - row[12] = null; - row[13] = null; - row[14] = null; - row[15] = null; - row[16] = col.position(); - row[17] = "YES"; - row[18] = null; - row[19] = null; - row[20] = null; - row[21] = null; - row[22] = ""; - row[23] = ""; - } - return memorySet(con.cfg, info, data); + PreparedStatement ps = con.prepareStatement("SYS COLUMNS TABLES LIKE ? LIKE ?"); + ps.setString(1, tableNamePattern != null ? tableNamePattern.trim() : "%"); + ps.setString(2, columnNamePattern != null ? columnNamePattern.trim() : "%"); + return ps.executeQuery(); } @Override diff --git a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcResultSet.java b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcResultSet.java index 5cf09ac3ee3..7ef0f333895 100644 --- a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcResultSet.java +++ b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcResultSet.java @@ -354,7 +354,7 @@ class JdbcResultSet implements ResultSet, JdbcWrapper { } Object val = column(columnIndex); - + if (val == null) { return null; } @@ -371,7 +371,7 @@ class JdbcResultSet implements ResultSet, JdbcWrapper { T t = TypeConverter.convert(val, columnType, type); - if (t != null) { + if (t != null || type == null) { return t; } throw new SQLException("Conversion from type [" + columnType + "] to [" + type.getName() + "] not supported"); diff --git a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcUtils.java b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcUtils.java index 522438be5a7..c6e75214525 100644 --- a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcUtils.java +++ b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/JdbcUtils.java @@ -166,22 +166,4 @@ public abstract class JdbcUtils { static JDBCType type(int jdbcType) { return JDBCType.valueOf(jdbcType); } - - static Integer numericPrecisionRadix(int type) { - switch (type) { - case TINYINT: - case SMALLINT: - case INTEGER: - case BIGINT: - return 10; - case REAL: - case DOUBLE: - case FLOAT: - case DECIMAL: - case NUMERIC: - return 2; - default: - return null; - } - } } \ No newline at end of file diff --git a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/PreparedQuery.java b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/PreparedQuery.java index 45e020df6bf..db16ba98a52 100644 --- a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/PreparedQuery.java +++ b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/jdbc/PreparedQuery.java @@ -64,7 +64,7 @@ class PreparedQuery { for (int i = 0; i < fragments.size(); i++) { sb.append(fragments.get(i)); if (i < params.length) { - // TODO: this needs conversion + // TODO: this needs converting sb.append(params[i].value); } } diff --git a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/net/client/JdbcHttpClient.java b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/net/client/JdbcHttpClient.java index 23cf12ad502..30cccd96473 100644 --- a/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/net/client/JdbcHttpClient.java +++ b/plugin/sql/jdbc/src/main/java/org/elasticsearch/xpack/sql/jdbc/net/client/JdbcHttpClient.java @@ -13,8 +13,6 @@ import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration; import org.elasticsearch.xpack.sql.jdbc.net.protocol.ColumnInfo; import org.elasticsearch.xpack.sql.jdbc.net.protocol.InfoResponse; import org.elasticsearch.xpack.sql.plugin.AbstractSqlRequest; -import org.elasticsearch.xpack.sql.plugin.MetaColumnInfo; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsRequest; import org.elasticsearch.xpack.sql.plugin.SqlQueryRequest; import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse; import org.joda.time.DateTimeZone; @@ -77,10 +75,6 @@ public class JdbcHttpClient { return new InfoResponse(mainResponse.getClusterName().value(), mainResponse.getVersion().major, mainResponse.getVersion().minor); } - public List metaInfoColumns(String tablePattern, String columnPattern) throws SQLException { - return httpClient.listColumns(new SqlListColumnsRequest(AbstractSqlRequest.Mode.JDBC, tablePattern, columnPattern)).getColumns(); - } - /** * Converts REST column metadata into JDBC column metadata */ @@ -89,5 +83,4 @@ public class JdbcHttpClient { new ColumnInfo(columnInfo.name(), columnInfo.jdbcType(), EMPTY, EMPTY, EMPTY, EMPTY, columnInfo.displaySize()) ).collect(Collectors.toList()); } - -} +} \ No newline at end of file diff --git a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsAction.java b/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsAction.java deleted file mode 100644 index dfaedfce8e7..00000000000 --- a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsAction.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.action.Action; -import org.elasticsearch.client.ElasticsearchClient; - -public class SqlListColumnsAction extends Action { - - public static final SqlListColumnsAction INSTANCE = new SqlListColumnsAction(); - public static final String NAME = "indices:admin/sql/columns"; - public static final String REST_ENDPOINT = "/_xpack/sql/columns"; - - private SqlListColumnsAction() { - super(NAME); - } - - @Override - public SqlListColumnsRequestBuilder newRequestBuilder(ElasticsearchClient client) { - return new SqlListColumnsRequestBuilder(client, this); - } - - @Override - public SqlListColumnsResponse newResponse() { - return new SqlListColumnsResponse(); - } -} diff --git a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequest.java b/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequest.java deleted file mode 100644 index d8b023979b6..00000000000 --- a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequest.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.CompositeIndicesRequest; -import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.inject.internal.Nullable; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ConstructingObjectParser; -import org.elasticsearch.common.xcontent.ToXContentObject; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentParser; - -import java.io.IOException; -import java.util.Objects; - -import static org.elasticsearch.action.ValidateActions.addValidationError; -import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; -import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; - -/** - * Request to get a list of SQL-supported columns of an index - *

- * It needs to be CompositeIndicesRequest because we resolve wildcards a non-standard SQL - * manner - */ -public class SqlListColumnsRequest extends AbstractSqlRequest implements ToXContentObject, CompositeIndicesRequest { - @SuppressWarnings("unchecked") - private static final ConstructingObjectParser PARSER = - new ConstructingObjectParser<>("sql_list_tables", true, (objects, mode) -> new SqlListColumnsRequest( - mode, - (String) objects[0], - (String) objects[1] - )); - - static { - PARSER.declareString(optionalConstructorArg(), new ParseField("table_pattern")); - PARSER.declareString(optionalConstructorArg(), new ParseField("column_pattern")); - } - - @Nullable - private String tablePattern; - @Nullable - private String columnPattern; - - - public SqlListColumnsRequest() { - } - - public SqlListColumnsRequest(Mode mode, String tablePattern, String columnPattern) { - super(mode); - this.tablePattern = tablePattern; - this.columnPattern = columnPattern; - } - - - public SqlListColumnsRequest(StreamInput in) throws IOException { - super(in); - this.tablePattern = in.readOptionalString(); - this.columnPattern = in.readOptionalString(); - } - - /** - * The index pattern for the results - */ - public String getTablePattern() { - return tablePattern; - } - - public void setTablePattern(String tablePattern) { - this.tablePattern = tablePattern; - } - - /** - * The column pattern for the results - */ - public String getColumnPattern() { - return columnPattern; - } - - public void setColumnPattern(String columnPattern) { - this.columnPattern = columnPattern; - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeOptionalString(tablePattern); - out.writeOptionalString(columnPattern); - } - - @Override - public String getDescription() { - return "SQL List Columns[" + getTablePattern() + ", " + getColumnPattern() + "]"; - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - { - if (tablePattern != null) { - builder.field("table_pattern", tablePattern); - } - if (columnPattern != null) { - builder.field("column_pattern", columnPattern); - } - } - return builder.endObject(); - } - - public static SqlListColumnsRequest fromXContent(XContentParser parser, Mode mode) { - return PARSER.apply(parser, mode); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - SqlListColumnsRequest that = (SqlListColumnsRequest) o; - return Objects.equals(tablePattern, that.tablePattern) && - Objects.equals(columnPattern, that.columnPattern); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), tablePattern, columnPattern); - } -} \ No newline at end of file diff --git a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequestBuilder.java b/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequestBuilder.java deleted file mode 100644 index b172fdfd7fd..00000000000 --- a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequestBuilder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.action.ActionRequestBuilder; -import org.elasticsearch.client.ElasticsearchClient; - -public class SqlListColumnsRequestBuilder extends - ActionRequestBuilder { - - public SqlListColumnsRequestBuilder(ElasticsearchClient client, SqlListColumnsAction action) { - super(client, action, new SqlListColumnsRequest()); - } - - public SqlListColumnsRequestBuilder indexPattern(String indexPattern) { - request.setTablePattern(indexPattern); - return this; - } - - public SqlListColumnsRequestBuilder columnPattern(String columnPattern) { - request.setColumnPattern(columnPattern); - return this; - } - - public SqlListColumnsRequestBuilder mode(String mode) { - request.mode(mode); - return this; - } - - public SqlListColumnsRequestBuilder mode(AbstractSqlRequest.Mode mode) { - request.mode(mode); - return this; - }} diff --git a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsResponse.java b/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsResponse.java deleted file mode 100644 index 99e804606f1..00000000000 --- a/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsResponse.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ConstructingObjectParser; -import org.elasticsearch.common.xcontent.ToXContentObject; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentParser; - -import java.io.IOException; -import java.util.List; -import java.util.Objects; - -import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; - -/** - * Response to perform an sql query - */ -public class SqlListColumnsResponse extends ActionResponse implements ToXContentObject { - @SuppressWarnings("unchecked") - public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("sql", true, - objects -> new SqlListColumnsResponse((List) objects[0])); - - public static final ParseField COLUMNS = new ParseField("columns"); - - static { - PARSER.declareObjectArray(optionalConstructorArg(), (p, c) -> MetaColumnInfo.fromXContent(p), COLUMNS); - } - - private List columns; - - public SqlListColumnsResponse() { - } - - public SqlListColumnsResponse(List columns) { - this.columns = columns; - } - - /** - * The key that must be sent back to SQL to access the next page of - * results. If equal to "" then there is no next page. - */ - public List getColumns() { - return columns; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - columns = in.readList(MetaColumnInfo::new); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeList(columns); - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - { - builder.startArray("columns"); - { - for (MetaColumnInfo column : columns) { - column.toXContent(builder, params); - } - } - builder.endArray(); - } - return builder.endObject(); - } - - public static SqlListColumnsResponse fromXContent(XContentParser parser) { - return PARSER.apply(parser, null); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SqlListColumnsResponse that = (SqlListColumnsResponse) o; - return Objects.equals(columns, that.columns); - } - - @Override - public int hashCode() { - return Objects.hash(columns); - } - - @Override - public String toString() { - return Strings.toString(this); - } - -} diff --git a/plugin/sql/sql-proto/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequestTests.java b/plugin/sql/sql-proto/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequestTests.java deleted file mode 100644 index 3d3e588a9ab..00000000000 --- a/plugin/sql/sql-proto/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsRequestTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.test.AbstractSerializingTestCase; -import org.junit.Before; - -import java.io.IOException; -import java.util.function.Consumer; - -public class SqlListColumnsRequestTests extends AbstractSerializingTestCase { - public AbstractSqlRequest.Mode testMode; - - @Before - public void setup() { - testMode = randomFrom(AbstractSqlRequest.Mode.values()); - } - - @Override - protected SqlListColumnsRequest createTestInstance() { - return new SqlListColumnsRequest(testMode, randomAlphaOfLength(10), randomAlphaOfLength(10)); - } - - @Override - protected Writeable.Reader instanceReader() { - return SqlListColumnsRequest::new; - } - - @Override - protected SqlListColumnsRequest doParseInstance(XContentParser parser) { - return SqlListColumnsRequest.fromXContent(parser, testMode); - } - - @Override - protected SqlListColumnsRequest mutateInstance(SqlListColumnsRequest instance) throws IOException { - @SuppressWarnings("unchecked") - Consumer mutator = randomFrom( - request -> request.mode(randomValueOtherThan(request.mode(), () -> randomFrom(AbstractSqlRequest.Mode.values()))), - request -> request.setColumnPattern(randomValueOtherThan(request.getColumnPattern(), () -> randomAlphaOfLength(10))), - request -> request.setTablePattern(randomValueOtherThan(request.getTablePattern(), () -> randomAlphaOfLength(10))) - ); - SqlListColumnsRequest newRequest = - new SqlListColumnsRequest(instance.mode(), instance.getTablePattern(), instance.getColumnPattern()); - mutator.accept(newRequest); - return newRequest; - } -} diff --git a/plugin/sql/sql-proto/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsResponseTests.java b/plugin/sql/sql-proto/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsResponseTests.java deleted file mode 100644 index 40dd1ddb427..00000000000 --- a/plugin/sql/sql-proto/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlListColumnsResponseTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.test.AbstractStreamableXContentTestCase; - -import java.io.IOException; -import java.sql.JDBCType; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS; -import static org.hamcrest.Matchers.hasSize; - -public class SqlListColumnsResponseTests extends AbstractStreamableXContentTestCase { - - @Override - protected SqlListColumnsResponse createTestInstance() { - int columnCount = between(1, 10); - boolean jdbcMode = randomBoolean(); - List columns = new ArrayList<>(columnCount); - for (int i = 0; i < columnCount; i++) { - if (jdbcMode) { - columns.add(new MetaColumnInfo(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10), - randomFrom(JDBCType.values()), randomInt(25), randomInt(20))); - } else { - columns.add(new MetaColumnInfo(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10), randomInt(20))); - - } - } - return new SqlListColumnsResponse(columns); - } - - @Override - protected SqlListColumnsResponse createBlankInstance() { - return new SqlListColumnsResponse(); - } - - public void testToXContent() throws IOException { - SqlListColumnsResponse testInstance = createTestInstance(); - - XContentBuilder builder = testInstance.toXContent(XContentFactory.jsonBuilder(), EMPTY_PARAMS); - Map rootMap = XContentHelper.convertToMap(builder.bytes(), false, builder.contentType()).v2(); - - logger.info(builder.string()); - - if (testInstance.getColumns() != null) { - List columns = (List) rootMap.get("columns"); - assertThat(columns, hasSize(testInstance.getColumns().size())); - for (int i = 0; i < columns.size(); i++) { - Map columnMap = (Map) columns.get(i); - MetaColumnInfo columnInfo = testInstance.getColumns().get(i); - assertEquals(columnInfo.table(), columnMap.get("table")); - assertEquals(columnInfo.name(), columnMap.get("name")); - assertEquals(columnInfo.esType(), columnMap.get("type")); - if (columnInfo.jdbcType() == null) { - assertNull(columnMap.get("jdbc_type")); - assertNull(columnMap.get("size")); - } else { - assertEquals(columnInfo.jdbcType().getVendorTypeNumber(), columnMap.get("jdbc_type")); - assertEquals(columnInfo.size(), columnMap.get("size")); - } - assertEquals(columnInfo.position(), columnMap.get("position")); - } - } else { - assertNull(rootMap.get("columns")); - } - } - - @Override - protected SqlListColumnsResponse doParseInstance(XContentParser parser) { - return SqlListColumnsResponse.fromXContent(parser); - } -} diff --git a/plugin/sql/sql-shared-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java b/plugin/sql/sql-shared-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java index b6a268f68f8..f72828f520c 100644 --- a/plugin/sql/sql-shared-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java +++ b/plugin/sql/sql-shared-client/src/main/java/org/elasticsearch/xpack/sql/client/HttpClient.java @@ -25,9 +25,6 @@ import org.elasticsearch.xpack.sql.plugin.AbstractSqlRequest; import org.elasticsearch.xpack.sql.plugin.SqlClearCursorAction; import org.elasticsearch.xpack.sql.plugin.SqlClearCursorRequest; import org.elasticsearch.xpack.sql.plugin.SqlClearCursorResponse; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsAction; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsRequest; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsResponse; import org.elasticsearch.xpack.sql.plugin.SqlQueryAction; import org.elasticsearch.xpack.sql.plugin.SqlQueryRequest; import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse; @@ -88,12 +85,8 @@ public class HttpClient { return response.isSucceeded(); } - public SqlListColumnsResponse listColumns(SqlListColumnsRequest request) throws SQLException { - return post(SqlListColumnsAction.REST_ENDPOINT, request, SqlListColumnsResponse::fromXContent); - } - - private Response post(String path, Request request, - CheckedFunction responseParser) + private Response post(String path, Request request, + CheckedFunction responseParser) throws SQLException { BytesReference requestBytes = toXContent(request); String query = "error_trace&mode=" + request.mode(); @@ -167,5 +160,4 @@ public class HttpClient { throw new ClientException("Cannot parse response", ex); } } - -} +} \ No newline at end of file diff --git a/plugin/sql/src/main/antlr/SqlBase.g4 b/plugin/sql/src/main/antlr/SqlBase.g4 index d29c5c3b40c..7298eb7ce23 100644 --- a/plugin/sql/src/main/antlr/SqlBase.g4 +++ b/plugin/sql/src/main/antlr/SqlBase.g4 @@ -2,7 +2,7 @@ * ELASTICSEARCH CONFIDENTIAL * __________________ * - * [2014] Elasticsearch Incorporated. All Rights Reserved. + * [2017] Elasticsearch Incorporated. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of Elasticsearch Incorporated and its suppliers, @@ -56,12 +56,11 @@ statement | (DESCRIBE | DESC) tableIdentifier #showColumns | SHOW FUNCTIONS (LIKE? pattern)? #showFunctions | SHOW SCHEMAS #showSchemas - | SYS TABLES (LIKE? pattern)? #sysTables - | SYS COLUMNS (LIKE? indexPattern=pattern)? (LIKE? columnPattern=pattern)? #sysColumns + | SYS COLUMNS (TABLES LIKE? indexPattern=pattern)? (LIKE? columnPattern=pattern)? #sysColumns | SYS TYPES #sysTypes ; - + query : (WITH namedQuery (',' namedQuery)*)? queryNoWith ; diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/CommandBuilder.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/CommandBuilder.java index bdb1db20766..b7eec686eff 100644 --- a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/CommandBuilder.java +++ b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/CommandBuilder.java @@ -12,6 +12,7 @@ import org.elasticsearch.xpack.sql.parser.SqlBaseParser.ShowColumnsContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.ShowFunctionsContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.ShowSchemasContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.ShowTablesContext; +import org.elasticsearch.xpack.sql.parser.SqlBaseParser.SysColumnsContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.SysTablesContext; import org.elasticsearch.xpack.sql.parser.SqlBaseParser.SysTypesContext; import org.elasticsearch.xpack.sql.plan.TableIdentifier; @@ -22,6 +23,7 @@ import org.elasticsearch.xpack.sql.plan.logical.command.ShowColumns; import org.elasticsearch.xpack.sql.plan.logical.command.ShowFunctions; import org.elasticsearch.xpack.sql.plan.logical.command.ShowSchemas; import org.elasticsearch.xpack.sql.plan.logical.command.ShowTables; +import org.elasticsearch.xpack.sql.plan.logical.command.sys.SysColumns; import org.elasticsearch.xpack.sql.plan.logical.command.sys.SysTables; import org.elasticsearch.xpack.sql.plan.logical.command.sys.SysTypes; import org.elasticsearch.xpack.sql.tree.Location; @@ -125,6 +127,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder { return new ShowColumns(source(ctx), identifier.index()); } + @Override public SysTables visitSysTables(SysTablesContext ctx) { return new SysTables(source(ctx), visitPattern(ctx.pattern())); @@ -134,4 +137,9 @@ abstract class CommandBuilder extends LogicalPlanBuilder { public SysTypes visitSysTypes(SysTypesContext ctx) { return new SysTypes(source(ctx)); } + + @Override + public Object visitSysColumns(SysColumnsContext ctx) { + return new SysColumns(source(ctx), visitPattern(ctx.indexPattern), visitPattern(ctx.columnPattern)); + } } \ No newline at end of file diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java index 4670b16438f..34d10dad2b9 100644 --- a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java +++ b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java @@ -321,6 +321,7 @@ class SqlBaseParser extends Parser { public PatternContext columnPattern; public TerminalNode SYS() { return getToken(SqlBaseParser.SYS, 0); } public TerminalNode COLUMNS() { return getToken(SqlBaseParser.COLUMNS, 0); } + public TerminalNode TABLES() { return getToken(SqlBaseParser.TABLES, 0); } public List pattern() { return getRuleContexts(PatternContext.class); } @@ -544,7 +545,7 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 4, RULE_statement); int _la; try { - setState(163); + setState(164); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { case 1: @@ -829,39 +830,40 @@ class SqlBaseParser extends Parser { match(SYS); setState(148); match(COLUMNS); - setState(153); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { - case 1: + setState(154); + _la = _input.LA(1); + if (_la==TABLES) { { - setState(150); + setState(149); + match(TABLES); + setState(151); _la = _input.LA(1); if (_la==LIKE) { { - setState(149); + setState(150); match(LIKE); } } - setState(152); + setState(153); ((SysColumnsContext)_localctx).indexPattern = pattern(); } - break; } - setState(159); + + setState(160); _la = _input.LA(1); if (_la==LIKE || _la==STRING) { { - setState(156); + setState(157); _la = _input.LA(1); if (_la==LIKE) { { - setState(155); + setState(156); match(LIKE); } } - setState(158); + setState(159); ((SysColumnsContext)_localctx).columnPattern = pattern(); } } @@ -872,9 +874,9 @@ class SqlBaseParser extends Parser { _localctx = new SysTypesContext(_localctx); enterOuterAlt(_localctx, 11); { - setState(161); - match(SYS); setState(162); + match(SYS); + setState(163); match(TYPES); } break; @@ -928,34 +930,34 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(174); + setState(175); _la = _input.LA(1); if (_la==WITH) { { - setState(165); - match(WITH); setState(166); + match(WITH); + setState(167); namedQuery(); - setState(171); + setState(172); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(167); - match(T__2); setState(168); + match(T__2); + setState(169); namedQuery(); } } - setState(173); + setState(174); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(176); + setState(177); queryNoWith(); } } @@ -1012,44 +1014,44 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(178); + setState(179); queryTerm(); - setState(189); + setState(190); _la = _input.LA(1); if (_la==ORDER) { { - setState(179); - match(ORDER); setState(180); - match(BY); + match(ORDER); setState(181); + match(BY); + setState(182); orderBy(); - setState(186); + setState(187); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(182); - match(T__2); setState(183); + match(T__2); + setState(184); orderBy(); } } - setState(188); + setState(189); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(193); + setState(194); _la = _input.LA(1); if (_la==LIMIT) { { - setState(191); - match(LIMIT); setState(192); + match(LIMIT); + setState(193); ((QueryNoWithContext)_localctx).limit = _input.LT(1); _la = _input.LA(1); if ( !(_la==ALL || _la==INTEGER_VALUE) ) { @@ -1127,13 +1129,13 @@ class SqlBaseParser extends Parser { QueryTermContext _localctx = new QueryTermContext(_ctx, getState()); enterRule(_localctx, 10, RULE_queryTerm); try { - setState(200); + setState(201); switch (_input.LA(1)) { case SELECT: _localctx = new QueryPrimaryDefaultContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(195); + setState(196); querySpecification(); } break; @@ -1141,11 +1143,11 @@ class SqlBaseParser extends Parser { _localctx = new SubqueryContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(196); - match(T__0); setState(197); - queryNoWith(); + match(T__0); setState(198); + queryNoWith(); + setState(199); match(T__1); } break; @@ -1197,13 +1199,13 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(202); + setState(203); expression(); - setState(204); + setState(205); _la = _input.LA(1); if (_la==ASC || _la==DESC) { { - setState(203); + setState(204); ((OrderByContext)_localctx).ordering = _input.LT(1); _la = _input.LA(1); if ( !(_la==ASC || _la==DESC) ) { @@ -1282,75 +1284,75 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(206); + setState(207); match(SELECT); - setState(208); + setState(209); _la = _input.LA(1); if (_la==ALL || _la==DISTINCT) { { - setState(207); + setState(208); setQuantifier(); } } - setState(210); + setState(211); selectItem(); - setState(215); + setState(216); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(211); - match(T__2); setState(212); + match(T__2); + setState(213); selectItem(); } } - setState(217); + setState(218); _errHandler.sync(this); _la = _input.LA(1); } - setState(219); + setState(220); _la = _input.LA(1); if (_la==FROM) { { - setState(218); + setState(219); fromClause(); } } - setState(223); + setState(224); _la = _input.LA(1); if (_la==WHERE) { { - setState(221); - match(WHERE); setState(222); + match(WHERE); + setState(223); ((QuerySpecificationContext)_localctx).where = booleanExpression(0); } } - setState(228); + setState(229); _la = _input.LA(1); if (_la==GROUP) { { - setState(225); - match(GROUP); setState(226); - match(BY); + match(GROUP); setState(227); + match(BY); + setState(228); groupBy(); } } - setState(232); + setState(233); _la = _input.LA(1); if (_la==HAVING) { { - setState(230); - match(HAVING); setState(231); + match(HAVING); + setState(232); ((QuerySpecificationContext)_localctx).having = booleanExpression(0); } } @@ -1402,23 +1404,23 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(234); - match(FROM); setState(235); + match(FROM); + setState(236); relation(); - setState(240); + setState(241); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(236); - match(T__2); setState(237); + match(T__2); + setState(238); relation(); } } - setState(242); + setState(243); _errHandler.sync(this); _la = _input.LA(1); } @@ -1471,30 +1473,30 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(244); + setState(245); _la = _input.LA(1); if (_la==ALL || _la==DISTINCT) { { - setState(243); + setState(244); setQuantifier(); } } - setState(246); + setState(247); groupingElement(); - setState(251); + setState(252); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(247); - match(T__2); setState(248); + match(T__2); + setState(249); groupingElement(); } } - setState(253); + setState(254); _errHandler.sync(this); _la = _input.LA(1); } @@ -1549,7 +1551,7 @@ class SqlBaseParser extends Parser { _localctx = new SingleGroupingSetContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(254); + setState(255); groupingExpressions(); } } @@ -1595,47 +1597,47 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 22, RULE_groupingExpressions); int _la; try { - setState(269); + setState(270); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,35,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(256); + setState(257); match(T__0); - setState(265); + setState(266); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << ANALYZE) | (1L << ANALYZED) | (1L << CAST) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXISTS) | (1L << EXPLAIN) | (1L << EXTRACT) | (1L << FALSE) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << MATCH) | (1L << NOT) | (1L << NULL) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TRUE) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (PLUS - 64)) | (1L << (MINUS - 64)) | (1L << (ASTERISK - 64)) | (1L << (STRING - 64)) | (1L << (INTEGER_VALUE - 64)) | (1L << (DECIMAL_VALUE - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << ANALYZE) | (1L << ANALYZED) | (1L << CAST) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXISTS) | (1L << EXPLAIN) | (1L << EXTRACT) | (1L << FALSE) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << MATCH) | (1L << NOT) | (1L << NULL) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TRUE) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (PLUS - 64)) | (1L << (MINUS - 64)) | (1L << (ASTERISK - 64)) | (1L << (STRING - 64)) | (1L << (INTEGER_VALUE - 64)) | (1L << (DECIMAL_VALUE - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(257); + setState(258); expression(); - setState(262); + setState(263); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(258); - match(T__2); setState(259); + match(T__2); + setState(260); expression(); } } - setState(264); + setState(265); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(267); + setState(268); match(T__1); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(268); + setState(269); expression(); } break; @@ -1686,15 +1688,15 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(271); - ((NamedQueryContext)_localctx).name = identifier(); setState(272); - match(AS); + ((NamedQueryContext)_localctx).name = identifier(); setState(273); - match(T__0); + match(AS); setState(274); - queryNoWith(); + match(T__0); setState(275); + queryNoWith(); + setState(276); match(T__1); } } @@ -1738,7 +1740,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(277); + setState(278); _la = _input.LA(1); if ( !(_la==ALL || _la==DISTINCT) ) { _errHandler.recoverInline(this); @@ -1801,22 +1803,22 @@ class SqlBaseParser extends Parser { _localctx = new SelectExpressionContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(279); + setState(280); expression(); - setState(284); + setState(285); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(281); + setState(282); _la = _input.LA(1); if (_la==AS) { { - setState(280); + setState(281); match(AS); } } - setState(283); + setState(284); identifier(); } } @@ -1870,19 +1872,19 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(286); + setState(287); relationPrimary(); - setState(290); + setState(291); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FULL) | (1L << INNER) | (1L << JOIN) | (1L << LEFT) | (1L << NATURAL) | (1L << RIGHT))) != 0)) { { { - setState(287); + setState(288); joinRelation(); } } - setState(292); + setState(293); _errHandler.sync(this); _la = _input.LA(1); } @@ -1936,7 +1938,7 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 32, RULE_joinRelation); int _la; try { - setState(304); + setState(305); switch (_input.LA(1)) { case FULL: case INNER: @@ -1946,18 +1948,18 @@ class SqlBaseParser extends Parser { enterOuterAlt(_localctx, 1); { { - setState(293); + setState(294); joinType(); } - setState(294); - match(JOIN); setState(295); + match(JOIN); + setState(296); ((JoinRelationContext)_localctx).right = relationPrimary(); - setState(297); + setState(298); _la = _input.LA(1); if (_la==ON || _la==USING) { { - setState(296); + setState(297); joinCriteria(); } } @@ -1967,13 +1969,13 @@ class SqlBaseParser extends Parser { case NATURAL: enterOuterAlt(_localctx, 2); { - setState(299); - match(NATURAL); setState(300); - joinType(); + match(NATURAL); setState(301); - match(JOIN); + joinType(); setState(302); + match(JOIN); + setState(303); ((JoinRelationContext)_localctx).right = relationPrimary(); } break; @@ -2022,17 +2024,17 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 34, RULE_joinType); int _la; try { - setState(321); + setState(322); switch (_input.LA(1)) { case INNER: case JOIN: enterOuterAlt(_localctx, 1); { - setState(307); + setState(308); _la = _input.LA(1); if (_la==INNER) { { - setState(306); + setState(307); match(INNER); } } @@ -2042,13 +2044,13 @@ class SqlBaseParser extends Parser { case LEFT: enterOuterAlt(_localctx, 2); { - setState(309); + setState(310); match(LEFT); - setState(311); + setState(312); _la = _input.LA(1); if (_la==OUTER) { { - setState(310); + setState(311); match(OUTER); } } @@ -2058,13 +2060,13 @@ class SqlBaseParser extends Parser { case RIGHT: enterOuterAlt(_localctx, 3); { - setState(313); + setState(314); match(RIGHT); - setState(315); + setState(316); _la = _input.LA(1); if (_la==OUTER) { { - setState(314); + setState(315); match(OUTER); } } @@ -2074,13 +2076,13 @@ class SqlBaseParser extends Parser { case FULL: enterOuterAlt(_localctx, 4); { - setState(317); + setState(318); match(FULL); - setState(319); + setState(320); _la = _input.LA(1); if (_la==OUTER) { { - setState(318); + setState(319); match(OUTER); } } @@ -2138,43 +2140,43 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 36, RULE_joinCriteria); int _la; try { - setState(337); + setState(338); switch (_input.LA(1)) { case ON: enterOuterAlt(_localctx, 1); { - setState(323); - match(ON); setState(324); + match(ON); + setState(325); booleanExpression(0); } break; case USING: enterOuterAlt(_localctx, 2); { - setState(325); - match(USING); setState(326); - match(T__0); + match(USING); setState(327); + match(T__0); + setState(328); identifier(); - setState(332); + setState(333); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(328); - match(T__2); setState(329); + match(T__2); + setState(330); identifier(); } } - setState(334); + setState(335); _errHandler.sync(this); _la = _input.LA(1); } - setState(335); + setState(336); match(T__1); } break; @@ -2279,29 +2281,29 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 38, RULE_relationPrimary); int _la; try { - setState(364); + setState(365); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,54,_ctx) ) { case 1: _localctx = new TableNameContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(339); + setState(340); tableIdentifier(); - setState(344); + setState(345); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(341); + setState(342); _la = _input.LA(1); if (_la==AS) { { - setState(340); + setState(341); match(AS); } } - setState(343); + setState(344); qualifiedName(); } } @@ -2312,26 +2314,26 @@ class SqlBaseParser extends Parser { _localctx = new AliasedQueryContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(346); - match(T__0); setState(347); - queryNoWith(); + match(T__0); setState(348); + queryNoWith(); + setState(349); match(T__1); - setState(353); + setState(354); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(350); + setState(351); _la = _input.LA(1); if (_la==AS) { { - setState(349); + setState(350); match(AS); } } - setState(352); + setState(353); qualifiedName(); } } @@ -2342,26 +2344,26 @@ class SqlBaseParser extends Parser { _localctx = new AliasedRelationContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(355); - match(T__0); setState(356); - relation(); + match(T__0); setState(357); + relation(); + setState(358); match(T__1); - setState(362); + setState(363); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << AS) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(359); + setState(360); _la = _input.LA(1); if (_la==AS) { { - setState(358); + setState(359); match(AS); } } - setState(361); + setState(362); qualifiedName(); } } @@ -2410,7 +2412,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(366); + setState(367); booleanExpression(0); } } @@ -2613,7 +2615,7 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(415); + setState(416); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,58,_ctx) ) { case 1: @@ -2622,9 +2624,9 @@ class SqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(369); - match(NOT); setState(370); + match(NOT); + setState(371); booleanExpression(8); } break; @@ -2633,13 +2635,13 @@ class SqlBaseParser extends Parser { _localctx = new ExistsContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(371); - match(EXISTS); setState(372); - match(T__0); + match(EXISTS); setState(373); - query(); + match(T__0); setState(374); + query(); + setState(375); match(T__1); } break; @@ -2648,29 +2650,29 @@ class SqlBaseParser extends Parser { _localctx = new StringQueryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(376); - match(QUERY); setState(377); - match(T__0); + match(QUERY); setState(378); + match(T__0); + setState(379); ((StringQueryContext)_localctx).queryString = match(STRING); - setState(383); + setState(384); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(379); - match(T__2); setState(380); + match(T__2); + setState(381); ((StringQueryContext)_localctx).options = match(STRING); } } - setState(385); + setState(386); _errHandler.sync(this); _la = _input.LA(1); } - setState(386); + setState(387); match(T__1); } break; @@ -2679,33 +2681,33 @@ class SqlBaseParser extends Parser { _localctx = new MatchQueryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(387); - match(MATCH); setState(388); - match(T__0); + match(MATCH); setState(389); - ((MatchQueryContext)_localctx).singleField = qualifiedName(); + match(T__0); setState(390); - match(T__2); + ((MatchQueryContext)_localctx).singleField = qualifiedName(); setState(391); + match(T__2); + setState(392); ((MatchQueryContext)_localctx).queryString = match(STRING); - setState(396); + setState(397); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(392); - match(T__2); setState(393); + match(T__2); + setState(394); ((MatchQueryContext)_localctx).options = match(STRING); } } - setState(398); + setState(399); _errHandler.sync(this); _la = _input.LA(1); } - setState(399); + setState(400); match(T__1); } break; @@ -2714,33 +2716,33 @@ class SqlBaseParser extends Parser { _localctx = new MultiMatchQueryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(401); - match(MATCH); setState(402); - match(T__0); + match(MATCH); setState(403); - ((MultiMatchQueryContext)_localctx).multiFields = match(STRING); + match(T__0); setState(404); - match(T__2); + ((MultiMatchQueryContext)_localctx).multiFields = match(STRING); setState(405); + match(T__2); + setState(406); ((MultiMatchQueryContext)_localctx).queryString = match(STRING); - setState(410); + setState(411); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(406); - match(T__2); setState(407); + match(T__2); + setState(408); ((MultiMatchQueryContext)_localctx).options = match(STRING); } } - setState(412); + setState(413); _errHandler.sync(this); _la = _input.LA(1); } - setState(413); + setState(414); match(T__1); } break; @@ -2749,13 +2751,13 @@ class SqlBaseParser extends Parser { _localctx = new BooleanDefaultContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(414); + setState(415); predicated(); } break; } _ctx.stop = _input.LT(-1); - setState(425); + setState(426); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,60,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -2763,7 +2765,7 @@ class SqlBaseParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(423); + setState(424); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,59,_ctx) ) { case 1: @@ -2771,11 +2773,11 @@ class SqlBaseParser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(417); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); setState(418); - ((LogicalBinaryContext)_localctx).operator = match(AND); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); setState(419); + ((LogicalBinaryContext)_localctx).operator = match(AND); + setState(420); ((LogicalBinaryContext)_localctx).right = booleanExpression(3); } break; @@ -2784,18 +2786,18 @@ class SqlBaseParser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(420); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(421); - ((LogicalBinaryContext)_localctx).operator = match(OR); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(422); + ((LogicalBinaryContext)_localctx).operator = match(OR); + setState(423); ((LogicalBinaryContext)_localctx).right = booleanExpression(2); } break; } } } - setState(427); + setState(428); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,60,_ctx); } @@ -2844,14 +2846,14 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(428); + setState(429); valueExpression(0); - setState(430); + setState(431); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,61,_ctx) ) { case 1: { - setState(429); + setState(430); predicate(); } break; @@ -2925,142 +2927,142 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 46, RULE_predicate); int _la; try { - setState(478); + setState(479); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,69,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(433); + setState(434); _la = _input.LA(1); if (_la==NOT) { { - setState(432); + setState(433); match(NOT); } } - setState(435); - ((PredicateContext)_localctx).kind = match(BETWEEN); setState(436); - ((PredicateContext)_localctx).lower = valueExpression(0); + ((PredicateContext)_localctx).kind = match(BETWEEN); setState(437); - match(AND); + ((PredicateContext)_localctx).lower = valueExpression(0); setState(438); + match(AND); + setState(439); ((PredicateContext)_localctx).upper = valueExpression(0); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(441); + setState(442); _la = _input.LA(1); if (_la==NOT) { { - setState(440); + setState(441); match(NOT); } } - setState(443); - ((PredicateContext)_localctx).kind = match(IN); setState(444); - match(T__0); + ((PredicateContext)_localctx).kind = match(IN); setState(445); + match(T__0); + setState(446); expression(); - setState(450); + setState(451); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(446); - match(T__2); setState(447); + match(T__2); + setState(448); expression(); } } - setState(452); + setState(453); _errHandler.sync(this); _la = _input.LA(1); } - setState(453); + setState(454); match(T__1); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(456); + setState(457); _la = _input.LA(1); if (_la==NOT) { { - setState(455); + setState(456); match(NOT); } } - setState(458); - ((PredicateContext)_localctx).kind = match(IN); setState(459); - match(T__0); + ((PredicateContext)_localctx).kind = match(IN); setState(460); - query(); + match(T__0); setState(461); + query(); + setState(462); match(T__1); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(464); + setState(465); _la = _input.LA(1); if (_la==NOT) { { - setState(463); + setState(464); match(NOT); } } - setState(466); - ((PredicateContext)_localctx).kind = match(LIKE); setState(467); + ((PredicateContext)_localctx).kind = match(LIKE); + setState(468); pattern(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(469); + setState(470); _la = _input.LA(1); if (_la==NOT) { { - setState(468); + setState(469); match(NOT); } } - setState(471); - ((PredicateContext)_localctx).kind = match(RLIKE); setState(472); + ((PredicateContext)_localctx).kind = match(RLIKE); + setState(473); ((PredicateContext)_localctx).regex = match(STRING); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(473); + setState(474); match(IS); - setState(475); + setState(476); _la = _input.LA(1); if (_la==NOT) { { - setState(474); + setState(475); match(NOT); } } - setState(477); + setState(478); ((PredicateContext)_localctx).kind = match(NULL); } break; @@ -3110,16 +3112,16 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(480); + setState(481); ((PatternContext)_localctx).value = match(STRING); - setState(483); + setState(484); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,70,_ctx) ) { case 1: { - setState(481); - match(ESCAPE); setState(482); + match(ESCAPE); + setState(483); ((PatternContext)_localctx).escape = match(STRING); } break; @@ -3263,7 +3265,7 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(489); + setState(490); switch (_input.LA(1)) { case T__0: case ANALYZE: @@ -3286,9 +3288,6 @@ class SqlBaseParser extends Parser { case PLAN: case RLIKE: case QUERY: - case SCHEMAS: - case SHOW: - case SYS: case TABLES: case TEXT: case TRUE: @@ -3307,7 +3306,7 @@ class SqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(486); + setState(487); primaryExpression(); } break; @@ -3317,7 +3316,7 @@ class SqlBaseParser extends Parser { _localctx = new ArithmeticUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(487); + setState(488); ((ArithmeticUnaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -3325,7 +3324,7 @@ class SqlBaseParser extends Parser { } else { consume(); } - setState(488); + setState(489); valueExpression(4); } break; @@ -3333,7 +3332,7 @@ class SqlBaseParser extends Parser { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(503); + setState(504); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,73,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -3341,7 +3340,7 @@ class SqlBaseParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(501); + setState(502); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,72,_ctx) ) { case 1: @@ -3349,9 +3348,9 @@ class SqlBaseParser extends Parser { _localctx = new ArithmeticBinaryContext(new ValueExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_valueExpression); - setState(491); - if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); setState(492); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(493); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(((((_la - 75)) & ~0x3f) == 0 && ((1L << (_la - 75)) & ((1L << (ASTERISK - 75)) | (1L << (SLASH - 75)) | (1L << (PERCENT - 75)))) != 0)) ) { @@ -3359,7 +3358,7 @@ class SqlBaseParser extends Parser { } else { consume(); } - setState(493); + setState(494); ((ArithmeticBinaryContext)_localctx).right = valueExpression(4); } break; @@ -3368,9 +3367,9 @@ class SqlBaseParser extends Parser { _localctx = new ArithmeticBinaryContext(new ValueExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_valueExpression); - setState(494); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); setState(495); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(496); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -3378,7 +3377,7 @@ class SqlBaseParser extends Parser { } else { consume(); } - setState(496); + setState(497); ((ArithmeticBinaryContext)_localctx).right = valueExpression(3); } break; @@ -3387,18 +3386,18 @@ class SqlBaseParser extends Parser { _localctx = new ComparisonContext(new ValueExpressionContext(_parentctx, _parentState)); ((ComparisonContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_valueExpression); - setState(497); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(498); - comparisonOperator(); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); setState(499); + comparisonOperator(); + setState(500); ((ComparisonContext)_localctx).right = valueExpression(2); } break; } } } - setState(505); + setState(506); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,73,_ctx); } @@ -3625,24 +3624,24 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 52, RULE_primaryExpression); int _la; try { - setState(555); + setState(556); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,78,_ctx) ) { case 1: _localctx = new CastContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(506); - match(CAST); setState(507); - match(T__0); + match(CAST); setState(508); - expression(); + match(T__0); setState(509); - match(AS); + expression(); setState(510); - dataType(); + match(AS); setState(511); + dataType(); + setState(512); match(T__1); } break; @@ -3650,17 +3649,17 @@ class SqlBaseParser extends Parser { _localctx = new ExtractContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(513); - match(EXTRACT); setState(514); - match(T__0); + match(EXTRACT); setState(515); - ((ExtractContext)_localctx).field = identifier(); + match(T__0); setState(516); - match(FROM); + ((ExtractContext)_localctx).field = identifier(); setState(517); - valueExpression(0); + match(FROM); setState(518); + valueExpression(0); + setState(519); match(T__1); } break; @@ -3668,7 +3667,7 @@ class SqlBaseParser extends Parser { _localctx = new ConstantDefaultContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(520); + setState(521); constant(); } break; @@ -3676,7 +3675,7 @@ class SqlBaseParser extends Parser { _localctx = new StarContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(521); + setState(522); match(ASTERISK); } break; @@ -3684,18 +3683,18 @@ class SqlBaseParser extends Parser { _localctx = new StarContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(525); + setState(526); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << COLUMNS) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(522); - qualifiedName(); setState(523); + qualifiedName(); + setState(524); match(DOT); } } - setState(527); + setState(528); match(ASTERISK); } break; @@ -3703,45 +3702,45 @@ class SqlBaseParser extends Parser { _localctx = new FunctionCallContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(528); - identifier(); setState(529); + identifier(); + setState(530); match(T__0); - setState(541); + setState(542); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << ALL) | (1L << ANALYZE) | (1L << ANALYZED) | (1L << CAST) | (1L << COLUMNS) | (1L << DEBUG) | (1L << DISTINCT) | (1L << EXECUTABLE) | (1L << EXISTS) | (1L << EXPLAIN) | (1L << EXTRACT) | (1L << FALSE) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << MATCH) | (1L << NOT) | (1L << NULL) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << SCHEMAS) | (1L << SHOW) | (1L << SYS) | (1L << TABLES) | (1L << TEXT) | (1L << TRUE) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (PLUS - 64)) | (1L << (MINUS - 64)) | (1L << (ASTERISK - 64)) | (1L << (STRING - 64)) | (1L << (INTEGER_VALUE - 64)) | (1L << (DECIMAL_VALUE - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << ALL) | (1L << ANALYZE) | (1L << ANALYZED) | (1L << CAST) | (1L << COLUMNS) | (1L << DEBUG) | (1L << DISTINCT) | (1L << EXECUTABLE) | (1L << EXISTS) | (1L << EXPLAIN) | (1L << EXTRACT) | (1L << FALSE) | (1L << FORMAT) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << MAPPED) | (1L << MATCH) | (1L << NOT) | (1L << NULL) | (1L << OPTIMIZED) | (1L << PARSED) | (1L << PHYSICAL) | (1L << PLAN) | (1L << RLIKE) | (1L << QUERY) | (1L << TABLES) | (1L << TEXT) | (1L << TRUE) | (1L << TYPES))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (VERIFY - 64)) | (1L << (PLUS - 64)) | (1L << (MINUS - 64)) | (1L << (ASTERISK - 64)) | (1L << (STRING - 64)) | (1L << (INTEGER_VALUE - 64)) | (1L << (DECIMAL_VALUE - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { { - setState(531); + setState(532); _la = _input.LA(1); if (_la==ALL || _la==DISTINCT) { { - setState(530); + setState(531); setQuantifier(); } } - setState(533); + setState(534); expression(); - setState(538); + setState(539); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(534); - match(T__2); setState(535); + match(T__2); + setState(536); expression(); } } - setState(540); + setState(541); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(543); + setState(544); match(T__1); } break; @@ -3749,11 +3748,11 @@ class SqlBaseParser extends Parser { _localctx = new SubqueryExpressionContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(545); - match(T__0); setState(546); - query(); + match(T__0); setState(547); + query(); + setState(548); match(T__1); } break; @@ -3761,7 +3760,7 @@ class SqlBaseParser extends Parser { _localctx = new ColumnReferenceContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(549); + setState(550); identifier(); } break; @@ -3769,7 +3768,7 @@ class SqlBaseParser extends Parser { _localctx = new DereferenceContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(550); + setState(551); qualifiedName(); } break; @@ -3777,11 +3776,11 @@ class SqlBaseParser extends Parser { _localctx = new ParenthesizedExpressionContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(551); - match(T__0); setState(552); - expression(); + match(T__0); setState(553); + expression(); + setState(554); match(T__1); } break; @@ -3890,13 +3889,13 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 54, RULE_constant); try { int _alt; - setState(565); + setState(566); switch (_input.LA(1)) { case NULL: _localctx = new NullLiteralContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(557); + setState(558); match(NULL); } break; @@ -3905,7 +3904,7 @@ class SqlBaseParser extends Parser { _localctx = new NumericLiteralContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(558); + setState(559); number(); } break; @@ -3914,7 +3913,7 @@ class SqlBaseParser extends Parser { _localctx = new BooleanLiteralContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(559); + setState(560); booleanValue(); } break; @@ -3922,7 +3921,7 @@ class SqlBaseParser extends Parser { _localctx = new StringLiteralContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(561); + setState(562); _errHandler.sync(this); _alt = 1; do { @@ -3930,7 +3929,7 @@ class SqlBaseParser extends Parser { case 1: { { - setState(560); + setState(561); match(STRING); } } @@ -3938,7 +3937,7 @@ class SqlBaseParser extends Parser { default: throw new NoViableAltException(this); } - setState(563); + setState(564); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,79,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); @@ -3992,7 +3991,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(567); + setState(568); _la = _input.LA(1); if ( !(((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (EQ - 67)) | (1L << (NEQ - 67)) | (1L << (LT - 67)) | (1L << (LTE - 67)) | (1L << (GT - 67)) | (1L << (GTE - 67)))) != 0)) ) { _errHandler.recoverInline(this); @@ -4041,7 +4040,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(569); + setState(570); _la = _input.LA(1); if ( !(_la==FALSE || _la==TRUE) ) { _errHandler.recoverInline(this); @@ -4099,7 +4098,7 @@ class SqlBaseParser extends Parser { _localctx = new PrimitiveDataTypeContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(571); + setState(572); identifier(); } } @@ -4151,25 +4150,25 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(578); + setState(579); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,81,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(573); - identifier(); setState(574); + identifier(); + setState(575); match(DOT); } } } - setState(580); + setState(581); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,81,_ctx); } - setState(581); + setState(582); identifier(); } } @@ -4214,13 +4213,13 @@ class SqlBaseParser extends Parser { IdentifierContext _localctx = new IdentifierContext(_ctx, getState()); enterRule(_localctx, 64, RULE_identifier); try { - setState(585); + setState(586); switch (_input.LA(1)) { case QUOTED_IDENTIFIER: case BACKQUOTED_IDENTIFIER: enterOuterAlt(_localctx, 1); { - setState(583); + setState(584); quoteIdentifier(); } break; @@ -4240,9 +4239,6 @@ class SqlBaseParser extends Parser { case PLAN: case RLIKE: case QUERY: - case SCHEMAS: - case SHOW: - case SYS: case TABLES: case TEXT: case TYPES: @@ -4251,7 +4247,7 @@ class SqlBaseParser extends Parser { case DIGIT_IDENTIFIER: enterOuterAlt(_localctx, 2); { - setState(584); + setState(585); unquoteIdentifier(); } break; @@ -4298,12 +4294,12 @@ class SqlBaseParser extends Parser { TableIdentifierContext _localctx = new TableIdentifierContext(_ctx, getState()); enterRule(_localctx, 66, RULE_tableIdentifier); try { - setState(589); + setState(590); switch (_input.LA(1)) { case TABLE_IDENTIFIER: enterOuterAlt(_localctx, 1); { - setState(587); + setState(588); match(TABLE_IDENTIFIER); } break; @@ -4323,9 +4319,6 @@ class SqlBaseParser extends Parser { case PLAN: case RLIKE: case QUERY: - case SCHEMAS: - case SHOW: - case SYS: case TABLES: case TEXT: case TYPES: @@ -4336,7 +4329,7 @@ class SqlBaseParser extends Parser { case BACKQUOTED_IDENTIFIER: enterOuterAlt(_localctx, 2); { - setState(588); + setState(589); identifier(); } break; @@ -4405,13 +4398,13 @@ class SqlBaseParser extends Parser { QuoteIdentifierContext _localctx = new QuoteIdentifierContext(_ctx, getState()); enterRule(_localctx, 68, RULE_quoteIdentifier); try { - setState(593); + setState(594); switch (_input.LA(1)) { case QUOTED_IDENTIFIER: _localctx = new QuotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(591); + setState(592); match(QUOTED_IDENTIFIER); } break; @@ -4419,7 +4412,7 @@ class SqlBaseParser extends Parser { _localctx = new BackQuotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(592); + setState(593); match(BACKQUOTED_IDENTIFIER); } break; @@ -4491,13 +4484,13 @@ class SqlBaseParser extends Parser { UnquoteIdentifierContext _localctx = new UnquoteIdentifierContext(_ctx, getState()); enterRule(_localctx, 70, RULE_unquoteIdentifier); try { - setState(598); + setState(599); switch (_input.LA(1)) { case IDENTIFIER: _localctx = new UnquotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(595); + setState(596); match(IDENTIFIER); } break; @@ -4517,9 +4510,6 @@ class SqlBaseParser extends Parser { case PLAN: case RLIKE: case QUERY: - case SCHEMAS: - case SHOW: - case SYS: case TABLES: case TEXT: case TYPES: @@ -4527,7 +4517,7 @@ class SqlBaseParser extends Parser { _localctx = new UnquotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(596); + setState(597); nonReserved(); } break; @@ -4535,7 +4525,7 @@ class SqlBaseParser extends Parser { _localctx = new DigitIdentifierContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(597); + setState(598); match(DIGIT_IDENTIFIER); } break; @@ -4604,13 +4594,13 @@ class SqlBaseParser extends Parser { NumberContext _localctx = new NumberContext(_ctx, getState()); enterRule(_localctx, 72, RULE_number); try { - setState(602); + setState(603); switch (_input.LA(1)) { case DECIMAL_VALUE: _localctx = new DecimalLiteralContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(600); + setState(601); match(DECIMAL_VALUE); } break; @@ -4618,7 +4608,7 @@ class SqlBaseParser extends Parser { _localctx = new IntegerLiteralContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(601); + setState(602); match(INTEGER_VALUE); } break; @@ -4654,9 +4644,6 @@ class SqlBaseParser extends Parser { public TerminalNode PLAN() { return getToken(SqlBaseParser.PLAN, 0); } public TerminalNode QUERY() { return getToken(SqlBaseParser.QUERY, 0); } public TerminalNode RLIKE() { return getToken(SqlBaseParser.RLIKE, 0); } - public TerminalNode SCHEMAS() { return getToken(SqlBaseParser.SCHEMAS, 0); } - public TerminalNode SHOW() { return getToken(SqlBaseParser.SHOW, 0); } - public TerminalNode SYS() { return getToken(SqlBaseParser.SYS, 0); } public TerminalNode TABLES() { return getToken(SqlBaseParser.TABLES, 0); } public TerminalNode TEXT() { return getToken(SqlBaseParser.TEXT, 0); } public TerminalNode TYPES() { return getToken(SqlBaseParser.TYPES, 0); } @@ -4687,9 +4674,9 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(604); + setState(605); _la = _input.LA(1); - if ( !(((((_la - 5)) & ~0x3f) == 0 && ((1L << (_la - 5)) & ((1L << (ANALYZE - 5)) | (1L << (ANALYZED - 5)) | (1L << (COLUMNS - 5)) | (1L << (DEBUG - 5)) | (1L << (EXECUTABLE - 5)) | (1L << (EXPLAIN - 5)) | (1L << (FORMAT - 5)) | (1L << (FUNCTIONS - 5)) | (1L << (GRAPHVIZ - 5)) | (1L << (MAPPED - 5)) | (1L << (OPTIMIZED - 5)) | (1L << (PARSED - 5)) | (1L << (PHYSICAL - 5)) | (1L << (PLAN - 5)) | (1L << (RLIKE - 5)) | (1L << (QUERY - 5)) | (1L << (SCHEMAS - 5)) | (1L << (SHOW - 5)) | (1L << (SYS - 5)) | (1L << (TABLES - 5)) | (1L << (TEXT - 5)) | (1L << (TYPES - 5)) | (1L << (VERIFY - 5)))) != 0)) ) { + if ( !(((((_la - 5)) & ~0x3f) == 0 && ((1L << (_la - 5)) & ((1L << (ANALYZE - 5)) | (1L << (ANALYZED - 5)) | (1L << (COLUMNS - 5)) | (1L << (DEBUG - 5)) | (1L << (EXECUTABLE - 5)) | (1L << (EXPLAIN - 5)) | (1L << (FORMAT - 5)) | (1L << (FUNCTIONS - 5)) | (1L << (GRAPHVIZ - 5)) | (1L << (MAPPED - 5)) | (1L << (OPTIMIZED - 5)) | (1L << (PARSED - 5)) | (1L << (PHYSICAL - 5)) | (1L << (PLAN - 5)) | (1L << (RLIKE - 5)) | (1L << (QUERY - 5)) | (1L << (TABLES - 5)) | (1L << (TEXT - 5)) | (1L << (TYPES - 5)) | (1L << (VERIFY - 5)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -4738,7 +4725,7 @@ class SqlBaseParser extends Parser { } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3^\u0261\4\2\t\2\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3^\u0262\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -4748,237 +4735,238 @@ class SqlBaseParser extends Parser { "\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4m\n\4\f\4\16\4p\13\4\3\4\5\4s\n\4\3"+ "\4\3\4\3\4\3\4\5\4y\n\4\3\4\5\4|\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+ "\4\5\4\u0087\n\4\3\4\5\4\u008a\n\4\3\4\3\4\3\4\3\4\3\4\5\4\u0091\n\4\3"+ - "\4\5\4\u0094\n\4\3\4\3\4\3\4\5\4\u0099\n\4\3\4\5\4\u009c\n\4\3\4\5\4\u009f"+ - "\n\4\3\4\5\4\u00a2\n\4\3\4\3\4\5\4\u00a6\n\4\3\5\3\5\3\5\3\5\7\5\u00ac"+ - "\n\5\f\5\16\5\u00af\13\5\5\5\u00b1\n\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6"+ - "\7\6\u00bb\n\6\f\6\16\6\u00be\13\6\5\6\u00c0\n\6\3\6\3\6\5\6\u00c4\n\6"+ - "\3\7\3\7\3\7\3\7\3\7\5\7\u00cb\n\7\3\b\3\b\5\b\u00cf\n\b\3\t\3\t\5\t\u00d3"+ - "\n\t\3\t\3\t\3\t\7\t\u00d8\n\t\f\t\16\t\u00db\13\t\3\t\5\t\u00de\n\t\3"+ - "\t\3\t\5\t\u00e2\n\t\3\t\3\t\3\t\5\t\u00e7\n\t\3\t\3\t\5\t\u00eb\n\t\3"+ - "\n\3\n\3\n\3\n\7\n\u00f1\n\n\f\n\16\n\u00f4\13\n\3\13\5\13\u00f7\n\13"+ - "\3\13\3\13\3\13\7\13\u00fc\n\13\f\13\16\13\u00ff\13\13\3\f\3\f\3\r\3\r"+ - "\3\r\3\r\7\r\u0107\n\r\f\r\16\r\u010a\13\r\5\r\u010c\n\r\3\r\3\r\5\r\u0110"+ - "\n\r\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\20\3\20\5\20\u011c\n\20"+ - "\3\20\5\20\u011f\n\20\3\21\3\21\7\21\u0123\n\21\f\21\16\21\u0126\13\21"+ - "\3\22\3\22\3\22\3\22\5\22\u012c\n\22\3\22\3\22\3\22\3\22\3\22\5\22\u0133"+ - "\n\22\3\23\5\23\u0136\n\23\3\23\3\23\5\23\u013a\n\23\3\23\3\23\5\23\u013e"+ - "\n\23\3\23\3\23\5\23\u0142\n\23\5\23\u0144\n\23\3\24\3\24\3\24\3\24\3"+ - "\24\3\24\3\24\7\24\u014d\n\24\f\24\16\24\u0150\13\24\3\24\3\24\5\24\u0154"+ - "\n\24\3\25\3\25\5\25\u0158\n\25\3\25\5\25\u015b\n\25\3\25\3\25\3\25\3"+ - "\25\5\25\u0161\n\25\3\25\5\25\u0164\n\25\3\25\3\25\3\25\3\25\5\25\u016a"+ - "\n\25\3\25\5\25\u016d\n\25\5\25\u016f\n\25\3\26\3\26\3\27\3\27\3\27\3"+ - "\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\7\27\u0180\n\27\f\27"+ - "\16\27\u0183\13\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\7\27\u018d"+ - "\n\27\f\27\16\27\u0190\13\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3"+ - "\27\7\27\u019b\n\27\f\27\16\27\u019e\13\27\3\27\3\27\5\27\u01a2\n\27\3"+ - "\27\3\27\3\27\3\27\3\27\3\27\7\27\u01aa\n\27\f\27\16\27\u01ad\13\27\3"+ - "\30\3\30\5\30\u01b1\n\30\3\31\5\31\u01b4\n\31\3\31\3\31\3\31\3\31\3\31"+ - "\3\31\5\31\u01bc\n\31\3\31\3\31\3\31\3\31\3\31\7\31\u01c3\n\31\f\31\16"+ - "\31\u01c6\13\31\3\31\3\31\3\31\5\31\u01cb\n\31\3\31\3\31\3\31\3\31\3\31"+ - "\3\31\5\31\u01d3\n\31\3\31\3\31\3\31\5\31\u01d8\n\31\3\31\3\31\3\31\3"+ - "\31\5\31\u01de\n\31\3\31\5\31\u01e1\n\31\3\32\3\32\3\32\5\32\u01e6\n\32"+ - "\3\33\3\33\3\33\3\33\5\33\u01ec\n\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ - "\3\33\3\33\3\33\7\33\u01f8\n\33\f\33\16\33\u01fb\13\33\3\34\3\34\3\34"+ - "\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34"+ - "\3\34\3\34\5\34\u0210\n\34\3\34\3\34\3\34\3\34\5\34\u0216\n\34\3\34\3"+ - "\34\3\34\7\34\u021b\n\34\f\34\16\34\u021e\13\34\5\34\u0220\n\34\3\34\3"+ - "\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u022e\n\34"+ - "\3\35\3\35\3\35\3\35\6\35\u0234\n\35\r\35\16\35\u0235\5\35\u0238\n\35"+ - "\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3!\7!\u0243\n!\f!\16!\u0246\13!\3!\3"+ - "!\3\"\3\"\5\"\u024c\n\"\3#\3#\5#\u0250\n#\3$\3$\5$\u0254\n$\3%\3%\3%\5"+ - "%\u0259\n%\3&\3&\5&\u025d\n&\3\'\3\'\3\'\2\4,\64(\2\4\6\b\n\f\16\20\22"+ - "\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJL\2\17\b\2\6\6\b\b\26"+ - "\26))//\63\63\4\2\37\37>>\4\2\b\b//\4\2\34\34\"\"\3\2\22\23\4\2\6\6SS"+ - "\4\2\f\f\22\22\4\2\6\6\24\24\3\2KL\3\2MO\3\2EJ\4\2\32\32??\17\2\7\b\20"+ - "\21\26\26\30\30\33\33\36\37))//\63\65\679;>@@BB\u02b2\2N\3\2\2\2\4Q\3"+ - "\2\2\2\6\u00a5\3\2\2\2\b\u00b0\3\2\2\2\n\u00b4\3\2\2\2\f\u00ca\3\2\2\2"+ - "\16\u00cc\3\2\2\2\20\u00d0\3\2\2\2\22\u00ec\3\2\2\2\24\u00f6\3\2\2\2\26"+ - "\u0100\3\2\2\2\30\u010f\3\2\2\2\32\u0111\3\2\2\2\34\u0117\3\2\2\2\36\u0119"+ - "\3\2\2\2 \u0120\3\2\2\2\"\u0132\3\2\2\2$\u0143\3\2\2\2&\u0153\3\2\2\2"+ - "(\u016e\3\2\2\2*\u0170\3\2\2\2,\u01a1\3\2\2\2.\u01ae\3\2\2\2\60\u01e0"+ - "\3\2\2\2\62\u01e2\3\2\2\2\64\u01eb\3\2\2\2\66\u022d\3\2\2\28\u0237\3\2"+ - "\2\2:\u0239\3\2\2\2<\u023b\3\2\2\2>\u023d\3\2\2\2@\u0244\3\2\2\2B\u024b"+ - "\3\2\2\2D\u024f\3\2\2\2F\u0253\3\2\2\2H\u0258\3\2\2\2J\u025c\3\2\2\2L"+ - "\u025e\3\2\2\2NO\5\6\4\2OP\7\2\2\3P\3\3\2\2\2QR\5*\26\2RS\7\2\2\3S\5\3"+ - "\2\2\2T\u00a6\5\b\5\2Uc\7\30\2\2V_\7\3\2\2WX\7\65\2\2X^\t\2\2\2YZ\7\33"+ - "\2\2Z^\t\3\2\2[\\\7B\2\2\\^\5<\37\2]W\3\2\2\2]Y\3\2\2\2][\3\2\2\2^a\3"+ - "\2\2\2_]\3\2\2\2_`\3\2\2\2`b\3\2\2\2a_\3\2\2\2bd\7\4\2\2cV\3\2\2\2cd\3"+ - "\2\2\2de\3\2\2\2e\u00a6\5\6\4\2fr\7\21\2\2gn\7\3\2\2hi\7\65\2\2im\t\4"+ - "\2\2jk\7\33\2\2km\t\3\2\2lh\3\2\2\2lj\3\2\2\2mp\3\2\2\2nl\3\2\2\2no\3"+ - "\2\2\2oq\3\2\2\2pn\3\2\2\2qs\7\4\2\2rg\3\2\2\2rs\3\2\2\2st\3\2\2\2t\u00a6"+ - "\5\6\4\2uv\7;\2\2v{\7=\2\2wy\7\'\2\2xw\3\2\2\2xy\3\2\2\2yz\3\2\2\2z|\5"+ - "\62\32\2{x\3\2\2\2{|\3\2\2\2|\u00a6\3\2\2\2}~\7;\2\2~\177\7\20\2\2\177"+ - "\u0080\t\5\2\2\u0080\u00a6\5D#\2\u0081\u0082\t\6\2\2\u0082\u00a6\5D#\2"+ - "\u0083\u0084\7;\2\2\u0084\u0089\7\36\2\2\u0085\u0087\7\'\2\2\u0086\u0085"+ - "\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u008a\5\62\32\2"+ - "\u0089\u0086\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u00a6\3\2\2\2\u008b\u008c"+ - "\7;\2\2\u008c\u00a6\79\2\2\u008d\u008e\7<\2\2\u008e\u0093\7=\2\2\u008f"+ - "\u0091\7\'\2\2\u0090\u008f\3\2\2\2\u0090\u0091\3\2\2\2\u0091\u0092\3\2"+ - "\2\2\u0092\u0094\5\62\32\2\u0093\u0090\3\2\2\2\u0093\u0094\3\2\2\2\u0094"+ - "\u00a6\3\2\2\2\u0095\u0096\7<\2\2\u0096\u009b\7\20\2\2\u0097\u0099\7\'"+ - "\2\2\u0098\u0097\3\2\2\2\u0098\u0099\3\2\2\2\u0099\u009a\3\2\2\2\u009a"+ - "\u009c\5\62\32\2\u009b\u0098\3\2\2\2\u009b\u009c\3\2\2\2\u009c\u00a1\3"+ - "\2\2\2\u009d\u009f\7\'\2\2\u009e\u009d\3\2\2\2\u009e\u009f\3\2\2\2\u009f"+ - "\u00a0\3\2\2\2\u00a0\u00a2\5\62\32\2\u00a1\u009e\3\2\2\2\u00a1\u00a2\3"+ - "\2\2\2\u00a2\u00a6\3\2\2\2\u00a3\u00a4\7<\2\2\u00a4\u00a6\7@\2\2\u00a5"+ - "T\3\2\2\2\u00a5U\3\2\2\2\u00a5f\3\2\2\2\u00a5u\3\2\2\2\u00a5}\3\2\2\2"+ - "\u00a5\u0081\3\2\2\2\u00a5\u0083\3\2\2\2\u00a5\u008b\3\2\2\2\u00a5\u008d"+ - "\3\2\2\2\u00a5\u0095\3\2\2\2\u00a5\u00a3\3\2\2\2\u00a6\7\3\2\2\2\u00a7"+ - "\u00a8\7D\2\2\u00a8\u00ad\5\32\16\2\u00a9\u00aa\7\5\2\2\u00aa\u00ac\5"+ - "\32\16\2\u00ab\u00a9\3\2\2\2\u00ac\u00af\3\2\2\2\u00ad\u00ab\3\2\2\2\u00ad"+ - "\u00ae\3\2\2\2\u00ae\u00b1\3\2\2\2\u00af\u00ad\3\2\2\2\u00b0\u00a7\3\2"+ - "\2\2\u00b0\u00b1\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b3\5\n\6\2\u00b3"+ - "\t\3\2\2\2\u00b4\u00bf\5\f\7\2\u00b5\u00b6\7\61\2\2\u00b6\u00b7\7\16\2"+ - "\2\u00b7\u00bc\5\16\b\2\u00b8\u00b9\7\5\2\2\u00b9\u00bb\5\16\b\2\u00ba"+ - "\u00b8\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc\u00ba\3\2\2\2\u00bc\u00bd\3\2"+ - "\2\2\u00bd\u00c0\3\2\2\2\u00be\u00bc\3\2\2\2\u00bf\u00b5\3\2\2\2\u00bf"+ - "\u00c0\3\2\2\2\u00c0\u00c3\3\2\2\2\u00c1\u00c2\7(\2\2\u00c2\u00c4\t\7"+ - "\2\2\u00c3\u00c1\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4\13\3\2\2\2\u00c5\u00cb"+ - "\5\20\t\2\u00c6\u00c7\7\3\2\2\u00c7\u00c8\5\n\6\2\u00c8\u00c9\7\4\2\2"+ - "\u00c9\u00cb\3\2\2\2\u00ca\u00c5\3\2\2\2\u00ca\u00c6\3\2\2\2\u00cb\r\3"+ - "\2\2\2\u00cc\u00ce\5*\26\2\u00cd\u00cf\t\b\2\2\u00ce\u00cd\3\2\2\2\u00ce"+ - "\u00cf\3\2\2\2\u00cf\17\3\2\2\2\u00d0\u00d2\7:\2\2\u00d1\u00d3\5\34\17"+ - "\2\u00d2\u00d1\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4\u00d9"+ - "\5\36\20\2\u00d5\u00d6\7\5\2\2\u00d6\u00d8\5\36\20\2\u00d7\u00d5\3\2\2"+ - "\2\u00d8\u00db\3\2\2\2\u00d9\u00d7\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u00dd"+ - "\3\2\2\2\u00db\u00d9\3\2\2\2\u00dc\u00de\5\22\n\2\u00dd\u00dc\3\2\2\2"+ - "\u00dd\u00de\3\2\2\2\u00de\u00e1\3\2\2\2\u00df\u00e0\7C\2\2\u00e0\u00e2"+ - "\5,\27\2\u00e1\u00df\3\2\2\2\u00e1\u00e2\3\2\2\2\u00e2\u00e6\3\2\2\2\u00e3"+ - "\u00e4\7 \2\2\u00e4\u00e5\7\16\2\2\u00e5\u00e7\5\24\13\2\u00e6\u00e3\3"+ - "\2\2\2\u00e6\u00e7\3\2\2\2\u00e7\u00ea\3\2\2\2\u00e8\u00e9\7!\2\2\u00e9"+ - "\u00eb\5,\27\2\u00ea\u00e8\3\2\2\2\u00ea\u00eb\3\2\2\2\u00eb\21\3\2\2"+ - "\2\u00ec\u00ed\7\34\2\2\u00ed\u00f2\5 \21\2\u00ee\u00ef\7\5\2\2\u00ef"+ - "\u00f1\5 \21\2\u00f0\u00ee\3\2\2\2\u00f1\u00f4\3\2\2\2\u00f2\u00f0\3\2"+ - "\2\2\u00f2\u00f3\3\2\2\2\u00f3\23\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f5\u00f7"+ - "\5\34\17\2\u00f6\u00f5\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7\u00f8\3\2\2\2"+ - "\u00f8\u00fd\5\26\f\2\u00f9\u00fa\7\5\2\2\u00fa\u00fc\5\26\f\2\u00fb\u00f9"+ - "\3\2\2\2\u00fc\u00ff\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fd\u00fe\3\2\2\2\u00fe"+ - "\25\3\2\2\2\u00ff\u00fd\3\2\2\2\u0100\u0101\5\30\r\2\u0101\27\3\2\2\2"+ - "\u0102\u010b\7\3\2\2\u0103\u0108\5*\26\2\u0104\u0105\7\5\2\2\u0105\u0107"+ - "\5*\26\2\u0106\u0104\3\2\2\2\u0107\u010a\3\2\2\2\u0108\u0106\3\2\2\2\u0108"+ - "\u0109\3\2\2\2\u0109\u010c\3\2\2\2\u010a\u0108\3\2\2\2\u010b\u0103\3\2"+ - "\2\2\u010b\u010c\3\2\2\2\u010c\u010d\3\2\2\2\u010d\u0110\7\4\2\2\u010e"+ - "\u0110\5*\26\2\u010f\u0102\3\2\2\2\u010f\u010e\3\2\2\2\u0110\31\3\2\2"+ - "\2\u0111\u0112\5B\"\2\u0112\u0113\7\13\2\2\u0113\u0114\7\3\2\2\u0114\u0115"+ - "\5\n\6\2\u0115\u0116\7\4\2\2\u0116\33\3\2\2\2\u0117\u0118\t\t\2\2\u0118"+ - "\35\3\2\2\2\u0119\u011e\5*\26\2\u011a\u011c\7\13\2\2\u011b\u011a\3\2\2"+ - "\2\u011b\u011c\3\2\2\2\u011c\u011d\3\2\2\2\u011d\u011f\5B\"\2\u011e\u011b"+ - "\3\2\2\2\u011e\u011f\3\2\2\2\u011f\37\3\2\2\2\u0120\u0124\5(\25\2\u0121"+ - "\u0123\5\"\22\2\u0122\u0121\3\2\2\2\u0123\u0126\3\2\2\2\u0124\u0122\3"+ - "\2\2\2\u0124\u0125\3\2\2\2\u0125!\3\2\2\2\u0126\u0124\3\2\2\2\u0127\u0128"+ - "\5$\23\2\u0128\u0129\7%\2\2\u0129\u012b\5(\25\2\u012a\u012c\5&\24\2\u012b"+ - "\u012a\3\2\2\2\u012b\u012c\3\2\2\2\u012c\u0133\3\2\2\2\u012d\u012e\7+"+ - "\2\2\u012e\u012f\5$\23\2\u012f\u0130\7%\2\2\u0130\u0131\5(\25\2\u0131"+ - "\u0133\3\2\2\2\u0132\u0127\3\2\2\2\u0132\u012d\3\2\2\2\u0133#\3\2\2\2"+ - "\u0134\u0136\7#\2\2\u0135\u0134\3\2\2\2\u0135\u0136\3\2\2\2\u0136\u0144"+ - "\3\2\2\2\u0137\u0139\7&\2\2\u0138\u013a\7\62\2\2\u0139\u0138\3\2\2\2\u0139"+ - "\u013a\3\2\2\2\u013a\u0144\3\2\2\2\u013b\u013d\7\66\2\2\u013c\u013e\7"+ - "\62\2\2\u013d\u013c\3\2\2\2\u013d\u013e\3\2\2\2\u013e\u0144\3\2\2\2\u013f"+ - "\u0141\7\35\2\2\u0140\u0142\7\62\2\2\u0141\u0140\3\2\2\2\u0141\u0142\3"+ - "\2\2\2\u0142\u0144\3\2\2\2\u0143\u0135\3\2\2\2\u0143\u0137\3\2\2\2\u0143"+ - "\u013b\3\2\2\2\u0143\u013f\3\2\2\2\u0144%\3\2\2\2\u0145\u0146\7.\2\2\u0146"+ - "\u0154\5,\27\2\u0147\u0148\7A\2\2\u0148\u0149\7\3\2\2\u0149\u014e\5B\""+ - "\2\u014a\u014b\7\5\2\2\u014b\u014d\5B\"\2\u014c\u014a\3\2\2\2\u014d\u0150"+ - "\3\2\2\2\u014e\u014c\3\2\2\2\u014e\u014f\3\2\2\2\u014f\u0151\3\2\2\2\u0150"+ - "\u014e\3\2\2\2\u0151\u0152\7\4\2\2\u0152\u0154\3\2\2\2\u0153\u0145\3\2"+ - "\2\2\u0153\u0147\3\2\2\2\u0154\'\3\2\2\2\u0155\u015a\5D#\2\u0156\u0158"+ - "\7\13\2\2\u0157\u0156\3\2\2\2\u0157\u0158\3\2\2\2\u0158\u0159\3\2\2\2"+ - "\u0159\u015b\5@!\2\u015a\u0157\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u016f"+ - "\3\2\2\2\u015c\u015d\7\3\2\2\u015d\u015e\5\n\6\2\u015e\u0163\7\4\2\2\u015f"+ - "\u0161\7\13\2\2\u0160\u015f\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u0162\3"+ - "\2\2\2\u0162\u0164\5@!\2\u0163\u0160\3\2\2\2\u0163\u0164\3\2\2\2\u0164"+ - "\u016f\3\2\2\2\u0165\u0166\7\3\2\2\u0166\u0167\5 \21\2\u0167\u016c\7\4"+ - "\2\2\u0168\u016a\7\13\2\2\u0169\u0168\3\2\2\2\u0169\u016a\3\2\2\2\u016a"+ - "\u016b\3\2\2\2\u016b\u016d\5@!\2\u016c\u0169\3\2\2\2\u016c\u016d\3\2\2"+ - "\2\u016d\u016f\3\2\2\2\u016e\u0155\3\2\2\2\u016e\u015c\3\2\2\2\u016e\u0165"+ - "\3\2\2\2\u016f)\3\2\2\2\u0170\u0171\5,\27\2\u0171+\3\2\2\2\u0172\u0173"+ - "\b\27\1\2\u0173\u0174\7,\2\2\u0174\u01a2\5,\27\n\u0175\u0176\7\27\2\2"+ - "\u0176\u0177\7\3\2\2\u0177\u0178\5\b\5\2\u0178\u0179\7\4\2\2\u0179\u01a2"+ - "\3\2\2\2\u017a\u017b\78\2\2\u017b\u017c\7\3\2\2\u017c\u0181\7R\2\2\u017d"+ - "\u017e\7\5\2\2\u017e\u0180\7R\2\2\u017f\u017d\3\2\2\2\u0180\u0183\3\2"+ - "\2\2\u0181\u017f\3\2\2\2\u0181\u0182\3\2\2\2\u0182\u0184\3\2\2\2\u0183"+ - "\u0181\3\2\2\2\u0184\u01a2\7\4\2\2\u0185\u0186\7*\2\2\u0186\u0187\7\3"+ - "\2\2\u0187\u0188\5@!\2\u0188\u0189\7\5\2\2\u0189\u018e\7R\2\2\u018a\u018b"+ - "\7\5\2\2\u018b\u018d\7R\2\2\u018c\u018a\3\2\2\2\u018d\u0190\3\2\2\2\u018e"+ - "\u018c\3\2\2\2\u018e\u018f\3\2\2\2\u018f\u0191\3\2\2\2\u0190\u018e\3\2"+ - "\2\2\u0191\u0192\7\4\2\2\u0192\u01a2\3\2\2\2\u0193\u0194\7*\2\2\u0194"+ - "\u0195\7\3\2\2\u0195\u0196\7R\2\2\u0196\u0197\7\5\2\2\u0197\u019c\7R\2"+ - "\2\u0198\u0199\7\5\2\2\u0199\u019b\7R\2\2\u019a\u0198\3\2\2\2\u019b\u019e"+ - "\3\2\2\2\u019c\u019a\3\2\2\2\u019c\u019d\3\2\2\2\u019d\u019f\3\2\2\2\u019e"+ - "\u019c\3\2\2\2\u019f\u01a2\7\4\2\2\u01a0\u01a2\5.\30\2\u01a1\u0172\3\2"+ - "\2\2\u01a1\u0175\3\2\2\2\u01a1\u017a\3\2\2\2\u01a1\u0185\3\2\2\2\u01a1"+ - "\u0193\3\2\2\2\u01a1\u01a0\3\2\2\2\u01a2\u01ab\3\2\2\2\u01a3\u01a4\f\4"+ - "\2\2\u01a4\u01a5\7\t\2\2\u01a5\u01aa\5,\27\5\u01a6\u01a7\f\3\2\2\u01a7"+ - "\u01a8\7\60\2\2\u01a8\u01aa\5,\27\4\u01a9\u01a3\3\2\2\2\u01a9\u01a6\3"+ - "\2\2\2\u01aa\u01ad\3\2\2\2\u01ab\u01a9\3\2\2\2\u01ab\u01ac\3\2\2\2\u01ac"+ - "-\3\2\2\2\u01ad\u01ab\3\2\2\2\u01ae\u01b0\5\64\33\2\u01af\u01b1\5\60\31"+ - "\2\u01b0\u01af\3\2\2\2\u01b0\u01b1\3\2\2\2\u01b1/\3\2\2\2\u01b2\u01b4"+ - "\7,\2\2\u01b3\u01b2\3\2\2\2\u01b3\u01b4\3\2\2\2\u01b4\u01b5\3\2\2\2\u01b5"+ - "\u01b6\7\r\2\2\u01b6\u01b7\5\64\33\2\u01b7\u01b8\7\t\2\2\u01b8\u01b9\5"+ - "\64\33\2\u01b9\u01e1\3\2\2\2\u01ba\u01bc\7,\2\2\u01bb\u01ba\3\2\2\2\u01bb"+ - "\u01bc\3\2\2\2\u01bc\u01bd\3\2\2\2\u01bd\u01be\7\"\2\2\u01be\u01bf\7\3"+ - "\2\2\u01bf\u01c4\5*\26\2\u01c0\u01c1\7\5\2\2\u01c1\u01c3\5*\26\2\u01c2"+ - "\u01c0\3\2\2\2\u01c3\u01c6\3\2\2\2\u01c4\u01c2\3\2\2\2\u01c4\u01c5\3\2"+ - "\2\2\u01c5\u01c7\3\2\2\2\u01c6\u01c4\3\2\2\2\u01c7\u01c8\7\4\2\2\u01c8"+ - "\u01e1\3\2\2\2\u01c9\u01cb\7,\2\2\u01ca\u01c9\3\2\2\2\u01ca\u01cb\3\2"+ - "\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01cd\7\"\2\2\u01cd\u01ce\7\3\2\2\u01ce"+ - "\u01cf\5\b\5\2\u01cf\u01d0\7\4\2\2\u01d0\u01e1\3\2\2\2\u01d1\u01d3\7,"+ - "\2\2\u01d2\u01d1\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d4\3\2\2\2\u01d4"+ - "\u01d5\7\'\2\2\u01d5\u01e1\5\62\32\2\u01d6\u01d8\7,\2\2\u01d7\u01d6\3"+ - "\2\2\2\u01d7\u01d8\3\2\2\2\u01d8\u01d9\3\2\2\2\u01d9\u01da\7\67\2\2\u01da"+ - "\u01e1\7R\2\2\u01db\u01dd\7$\2\2\u01dc\u01de\7,\2\2\u01dd\u01dc\3\2\2"+ - "\2\u01dd\u01de\3\2\2\2\u01de\u01df\3\2\2\2\u01df\u01e1\7-\2\2\u01e0\u01b3"+ - "\3\2\2\2\u01e0\u01bb\3\2\2\2\u01e0\u01ca\3\2\2\2\u01e0\u01d2\3\2\2\2\u01e0"+ - "\u01d7\3\2\2\2\u01e0\u01db\3\2\2\2\u01e1\61\3\2\2\2\u01e2\u01e5\7R\2\2"+ - "\u01e3\u01e4\7\25\2\2\u01e4\u01e6\7R\2\2\u01e5\u01e3\3\2\2\2\u01e5\u01e6"+ - "\3\2\2\2\u01e6\63\3\2\2\2\u01e7\u01e8\b\33\1\2\u01e8\u01ec\5\66\34\2\u01e9"+ - "\u01ea\t\n\2\2\u01ea\u01ec\5\64\33\6\u01eb\u01e7\3\2\2\2\u01eb\u01e9\3"+ - "\2\2\2\u01ec\u01f9\3\2\2\2\u01ed\u01ee\f\5\2\2\u01ee\u01ef\t\13\2\2\u01ef"+ - "\u01f8\5\64\33\6\u01f0\u01f1\f\4\2\2\u01f1\u01f2\t\n\2\2\u01f2\u01f8\5"+ - "\64\33\5\u01f3\u01f4\f\3\2\2\u01f4\u01f5\5:\36\2\u01f5\u01f6\5\64\33\4"+ - "\u01f6\u01f8\3\2\2\2\u01f7\u01ed\3\2\2\2\u01f7\u01f0\3\2\2\2\u01f7\u01f3"+ - "\3\2\2\2\u01f8\u01fb\3\2\2\2\u01f9\u01f7\3\2\2\2\u01f9\u01fa\3\2\2\2\u01fa"+ - "\65\3\2\2\2\u01fb\u01f9\3\2\2\2\u01fc\u01fd\7\17\2\2\u01fd\u01fe\7\3\2"+ - "\2\u01fe\u01ff\5*\26\2\u01ff\u0200\7\13\2\2\u0200\u0201\5> \2\u0201\u0202"+ - "\7\4\2\2\u0202\u022e\3\2\2\2\u0203\u0204\7\31\2\2\u0204\u0205\7\3\2\2"+ - "\u0205\u0206\5B\"\2\u0206\u0207\7\34\2\2\u0207\u0208\5\64\33\2\u0208\u0209"+ - "\7\4\2\2\u0209\u022e\3\2\2\2\u020a\u022e\58\35\2\u020b\u022e\7M\2\2\u020c"+ - "\u020d\5@!\2\u020d\u020e\7Q\2\2\u020e\u0210\3\2\2\2\u020f\u020c\3\2\2"+ - "\2\u020f\u0210\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u022e\7M\2\2\u0212\u0213"+ - "\5B\"\2\u0213\u021f\7\3\2\2\u0214\u0216\5\34\17\2\u0215\u0214\3\2\2\2"+ - "\u0215\u0216\3\2\2\2\u0216\u0217\3\2\2\2\u0217\u021c\5*\26\2\u0218\u0219"+ - "\7\5\2\2\u0219\u021b\5*\26\2\u021a\u0218\3\2\2\2\u021b\u021e\3\2\2\2\u021c"+ - "\u021a\3\2\2\2\u021c\u021d\3\2\2\2\u021d\u0220\3\2\2\2\u021e\u021c\3\2"+ - "\2\2\u021f\u0215\3\2\2\2\u021f\u0220\3\2\2\2\u0220\u0221\3\2\2\2\u0221"+ - "\u0222\7\4\2\2\u0222\u022e\3\2\2\2\u0223\u0224\7\3\2\2\u0224\u0225\5\b"+ - "\5\2\u0225\u0226\7\4\2\2\u0226\u022e\3\2\2\2\u0227\u022e\5B\"\2\u0228"+ - "\u022e\5@!\2\u0229\u022a\7\3\2\2\u022a\u022b\5*\26\2\u022b\u022c\7\4\2"+ - "\2\u022c\u022e\3\2\2\2\u022d\u01fc\3\2\2\2\u022d\u0203\3\2\2\2\u022d\u020a"+ - "\3\2\2\2\u022d\u020b\3\2\2\2\u022d\u020f\3\2\2\2\u022d\u0212\3\2\2\2\u022d"+ - "\u0223\3\2\2\2\u022d\u0227\3\2\2\2\u022d\u0228\3\2\2\2\u022d\u0229\3\2"+ - "\2\2\u022e\67\3\2\2\2\u022f\u0238\7-\2\2\u0230\u0238\5J&\2\u0231\u0238"+ - "\5<\37\2\u0232\u0234\7R\2\2\u0233\u0232\3\2\2\2\u0234\u0235\3\2\2\2\u0235"+ - "\u0233\3\2\2\2\u0235\u0236\3\2\2\2\u0236\u0238\3\2\2\2\u0237\u022f\3\2"+ - "\2\2\u0237\u0230\3\2\2\2\u0237\u0231\3\2\2\2\u0237\u0233\3\2\2\2\u0238"+ - "9\3\2\2\2\u0239\u023a\t\f\2\2\u023a;\3\2\2\2\u023b\u023c\t\r\2\2\u023c"+ - "=\3\2\2\2\u023d\u023e\5B\"\2\u023e?\3\2\2\2\u023f\u0240\5B\"\2\u0240\u0241"+ - "\7Q\2\2\u0241\u0243\3\2\2\2\u0242\u023f\3\2\2\2\u0243\u0246\3\2\2\2\u0244"+ - "\u0242\3\2\2\2\u0244\u0245\3\2\2\2\u0245\u0247\3\2\2\2\u0246\u0244\3\2"+ - "\2\2\u0247\u0248\5B\"\2\u0248A\3\2\2\2\u0249\u024c\5F$\2\u024a\u024c\5"+ - "H%\2\u024b\u0249\3\2\2\2\u024b\u024a\3\2\2\2\u024cC\3\2\2\2\u024d\u0250"+ - "\7W\2\2\u024e\u0250\5B\"\2\u024f\u024d\3\2\2\2\u024f\u024e\3\2\2\2\u0250"+ - "E\3\2\2\2\u0251\u0254\7X\2\2\u0252\u0254\7Y\2\2\u0253\u0251\3\2\2\2\u0253"+ - "\u0252\3\2\2\2\u0254G\3\2\2\2\u0255\u0259\7U\2\2\u0256\u0259\5L\'\2\u0257"+ - "\u0259\7V\2\2\u0258\u0255\3\2\2\2\u0258\u0256\3\2\2\2\u0258\u0257\3\2"+ - "\2\2\u0259I\3\2\2\2\u025a\u025d\7T\2\2\u025b\u025d\7S\2\2\u025c\u025a"+ - "\3\2\2\2\u025c\u025b\3\2\2\2\u025dK\3\2\2\2\u025e\u025f\t\16\2\2\u025f"+ - "M\3\2\2\2Y]_clnrx{\u0086\u0089\u0090\u0093\u0098\u009b\u009e\u00a1\u00a5"+ - "\u00ad\u00b0\u00bc\u00bf\u00c3\u00ca\u00ce\u00d2\u00d9\u00dd\u00e1\u00e6"+ - "\u00ea\u00f2\u00f6\u00fd\u0108\u010b\u010f\u011b\u011e\u0124\u012b\u0132"+ - "\u0135\u0139\u013d\u0141\u0143\u014e\u0153\u0157\u015a\u0160\u0163\u0169"+ - "\u016c\u016e\u0181\u018e\u019c\u01a1\u01a9\u01ab\u01b0\u01b3\u01bb\u01c4"+ - "\u01ca\u01d2\u01d7\u01dd\u01e0\u01e5\u01eb\u01f7\u01f9\u020f\u0215\u021c"+ - "\u021f\u022d\u0235\u0237\u0244\u024b\u024f\u0253\u0258\u025c"; + "\4\5\4\u0094\n\4\3\4\3\4\3\4\3\4\5\4\u009a\n\4\3\4\5\4\u009d\n\4\3\4\5"+ + "\4\u00a0\n\4\3\4\5\4\u00a3\n\4\3\4\3\4\5\4\u00a7\n\4\3\5\3\5\3\5\3\5\7"+ + "\5\u00ad\n\5\f\5\16\5\u00b0\13\5\5\5\u00b2\n\5\3\5\3\5\3\6\3\6\3\6\3\6"+ + "\3\6\3\6\7\6\u00bc\n\6\f\6\16\6\u00bf\13\6\5\6\u00c1\n\6\3\6\3\6\5\6\u00c5"+ + "\n\6\3\7\3\7\3\7\3\7\3\7\5\7\u00cc\n\7\3\b\3\b\5\b\u00d0\n\b\3\t\3\t\5"+ + "\t\u00d4\n\t\3\t\3\t\3\t\7\t\u00d9\n\t\f\t\16\t\u00dc\13\t\3\t\5\t\u00df"+ + "\n\t\3\t\3\t\5\t\u00e3\n\t\3\t\3\t\3\t\5\t\u00e8\n\t\3\t\3\t\5\t\u00ec"+ + "\n\t\3\n\3\n\3\n\3\n\7\n\u00f2\n\n\f\n\16\n\u00f5\13\n\3\13\5\13\u00f8"+ + "\n\13\3\13\3\13\3\13\7\13\u00fd\n\13\f\13\16\13\u0100\13\13\3\f\3\f\3"+ + "\r\3\r\3\r\3\r\7\r\u0108\n\r\f\r\16\r\u010b\13\r\5\r\u010d\n\r\3\r\3\r"+ + "\5\r\u0111\n\r\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\20\3\20\5\20"+ + "\u011d\n\20\3\20\5\20\u0120\n\20\3\21\3\21\7\21\u0124\n\21\f\21\16\21"+ + "\u0127\13\21\3\22\3\22\3\22\3\22\5\22\u012d\n\22\3\22\3\22\3\22\3\22\3"+ + "\22\5\22\u0134\n\22\3\23\5\23\u0137\n\23\3\23\3\23\5\23\u013b\n\23\3\23"+ + "\3\23\5\23\u013f\n\23\3\23\3\23\5\23\u0143\n\23\5\23\u0145\n\23\3\24\3"+ + "\24\3\24\3\24\3\24\3\24\3\24\7\24\u014e\n\24\f\24\16\24\u0151\13\24\3"+ + "\24\3\24\5\24\u0155\n\24\3\25\3\25\5\25\u0159\n\25\3\25\5\25\u015c\n\25"+ + "\3\25\3\25\3\25\3\25\5\25\u0162\n\25\3\25\5\25\u0165\n\25\3\25\3\25\3"+ + "\25\3\25\5\25\u016b\n\25\3\25\5\25\u016e\n\25\5\25\u0170\n\25\3\26\3\26"+ + "\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\7\27"+ + "\u0181\n\27\f\27\16\27\u0184\13\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\7\27\u018e\n\27\f\27\16\27\u0191\13\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\3\27\3\27\3\27\7\27\u019c\n\27\f\27\16\27\u019f\13\27\3\27\3\27"+ + "\5\27\u01a3\n\27\3\27\3\27\3\27\3\27\3\27\3\27\7\27\u01ab\n\27\f\27\16"+ + "\27\u01ae\13\27\3\30\3\30\5\30\u01b2\n\30\3\31\5\31\u01b5\n\31\3\31\3"+ + "\31\3\31\3\31\3\31\3\31\5\31\u01bd\n\31\3\31\3\31\3\31\3\31\3\31\7\31"+ + "\u01c4\n\31\f\31\16\31\u01c7\13\31\3\31\3\31\3\31\5\31\u01cc\n\31\3\31"+ + "\3\31\3\31\3\31\3\31\3\31\5\31\u01d4\n\31\3\31\3\31\3\31\5\31\u01d9\n"+ + "\31\3\31\3\31\3\31\3\31\5\31\u01df\n\31\3\31\5\31\u01e2\n\31\3\32\3\32"+ + "\3\32\5\32\u01e7\n\32\3\33\3\33\3\33\3\33\5\33\u01ed\n\33\3\33\3\33\3"+ + "\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\7\33\u01f9\n\33\f\33\16\33\u01fc"+ + "\13\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34"+ + "\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u0211\n\34\3\34\3\34\3\34\3\34\5\34"+ + "\u0217\n\34\3\34\3\34\3\34\7\34\u021c\n\34\f\34\16\34\u021f\13\34\5\34"+ + "\u0221\n\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34"+ + "\5\34\u022f\n\34\3\35\3\35\3\35\3\35\6\35\u0235\n\35\r\35\16\35\u0236"+ + "\5\35\u0239\n\35\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3!\7!\u0244\n!\f!\16"+ + "!\u0247\13!\3!\3!\3\"\3\"\5\"\u024d\n\"\3#\3#\5#\u0251\n#\3$\3$\5$\u0255"+ + "\n$\3%\3%\3%\5%\u025a\n%\3&\3&\5&\u025e\n&\3\'\3\'\3\'\2\4,\64(\2\4\6"+ + "\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJL\2\17"+ + "\b\2\6\6\b\b\26\26))//\63\63\4\2\37\37>>\4\2\b\b//\4\2\34\34\"\"\3\2\22"+ + "\23\4\2\6\6SS\4\2\f\f\22\22\4\2\6\6\24\24\3\2KL\3\2MO\3\2EJ\4\2\32\32"+ + "??\17\2\7\b\20\21\26\26\30\30\33\33\36\37))//\63\65\678=>@@BB\u02b3\2"+ + "N\3\2\2\2\4Q\3\2\2\2\6\u00a6\3\2\2\2\b\u00b1\3\2\2\2\n\u00b5\3\2\2\2\f"+ + "\u00cb\3\2\2\2\16\u00cd\3\2\2\2\20\u00d1\3\2\2\2\22\u00ed\3\2\2\2\24\u00f7"+ + "\3\2\2\2\26\u0101\3\2\2\2\30\u0110\3\2\2\2\32\u0112\3\2\2\2\34\u0118\3"+ + "\2\2\2\36\u011a\3\2\2\2 \u0121\3\2\2\2\"\u0133\3\2\2\2$\u0144\3\2\2\2"+ + "&\u0154\3\2\2\2(\u016f\3\2\2\2*\u0171\3\2\2\2,\u01a2\3\2\2\2.\u01af\3"+ + "\2\2\2\60\u01e1\3\2\2\2\62\u01e3\3\2\2\2\64\u01ec\3\2\2\2\66\u022e\3\2"+ + "\2\28\u0238\3\2\2\2:\u023a\3\2\2\2<\u023c\3\2\2\2>\u023e\3\2\2\2@\u0245"+ + "\3\2\2\2B\u024c\3\2\2\2D\u0250\3\2\2\2F\u0254\3\2\2\2H\u0259\3\2\2\2J"+ + "\u025d\3\2\2\2L\u025f\3\2\2\2NO\5\6\4\2OP\7\2\2\3P\3\3\2\2\2QR\5*\26\2"+ + "RS\7\2\2\3S\5\3\2\2\2T\u00a7\5\b\5\2Uc\7\30\2\2V_\7\3\2\2WX\7\65\2\2X"+ + "^\t\2\2\2YZ\7\33\2\2Z^\t\3\2\2[\\\7B\2\2\\^\5<\37\2]W\3\2\2\2]Y\3\2\2"+ + "\2][\3\2\2\2^a\3\2\2\2_]\3\2\2\2_`\3\2\2\2`b\3\2\2\2a_\3\2\2\2bd\7\4\2"+ + "\2cV\3\2\2\2cd\3\2\2\2de\3\2\2\2e\u00a7\5\6\4\2fr\7\21\2\2gn\7\3\2\2h"+ + "i\7\65\2\2im\t\4\2\2jk\7\33\2\2km\t\3\2\2lh\3\2\2\2lj\3\2\2\2mp\3\2\2"+ + "\2nl\3\2\2\2no\3\2\2\2oq\3\2\2\2pn\3\2\2\2qs\7\4\2\2rg\3\2\2\2rs\3\2\2"+ + "\2st\3\2\2\2t\u00a7\5\6\4\2uv\7;\2\2v{\7=\2\2wy\7\'\2\2xw\3\2\2\2xy\3"+ + "\2\2\2yz\3\2\2\2z|\5\62\32\2{x\3\2\2\2{|\3\2\2\2|\u00a7\3\2\2\2}~\7;\2"+ + "\2~\177\7\20\2\2\177\u0080\t\5\2\2\u0080\u00a7\5D#\2\u0081\u0082\t\6\2"+ + "\2\u0082\u00a7\5D#\2\u0083\u0084\7;\2\2\u0084\u0089\7\36\2\2\u0085\u0087"+ + "\7\'\2\2\u0086\u0085\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0088\3\2\2\2\u0088"+ + "\u008a\5\62\32\2\u0089\u0086\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u00a7\3"+ + "\2\2\2\u008b\u008c\7;\2\2\u008c\u00a7\79\2\2\u008d\u008e\7<\2\2\u008e"+ + "\u0093\7=\2\2\u008f\u0091\7\'\2\2\u0090\u008f\3\2\2\2\u0090\u0091\3\2"+ + "\2\2\u0091\u0092\3\2\2\2\u0092\u0094\5\62\32\2\u0093\u0090\3\2\2\2\u0093"+ + "\u0094\3\2\2\2\u0094\u00a7\3\2\2\2\u0095\u0096\7<\2\2\u0096\u009c\7\20"+ + "\2\2\u0097\u0099\7=\2\2\u0098\u009a\7\'\2\2\u0099\u0098\3\2\2\2\u0099"+ + "\u009a\3\2\2\2\u009a\u009b\3\2\2\2\u009b\u009d\5\62\32\2\u009c\u0097\3"+ + "\2\2\2\u009c\u009d\3\2\2\2\u009d\u00a2\3\2\2\2\u009e\u00a0\7\'\2\2\u009f"+ + "\u009e\3\2\2\2\u009f\u00a0\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1\u00a3\5\62"+ + "\32\2\u00a2\u009f\3\2\2\2\u00a2\u00a3\3\2\2\2\u00a3\u00a7\3\2\2\2\u00a4"+ + "\u00a5\7<\2\2\u00a5\u00a7\7@\2\2\u00a6T\3\2\2\2\u00a6U\3\2\2\2\u00a6f"+ + "\3\2\2\2\u00a6u\3\2\2\2\u00a6}\3\2\2\2\u00a6\u0081\3\2\2\2\u00a6\u0083"+ + "\3\2\2\2\u00a6\u008b\3\2\2\2\u00a6\u008d\3\2\2\2\u00a6\u0095\3\2\2\2\u00a6"+ + "\u00a4\3\2\2\2\u00a7\7\3\2\2\2\u00a8\u00a9\7D\2\2\u00a9\u00ae\5\32\16"+ + "\2\u00aa\u00ab\7\5\2\2\u00ab\u00ad\5\32\16\2\u00ac\u00aa\3\2\2\2\u00ad"+ + "\u00b0\3\2\2\2\u00ae\u00ac\3\2\2\2\u00ae\u00af\3\2\2\2\u00af\u00b2\3\2"+ + "\2\2\u00b0\u00ae\3\2\2\2\u00b1\u00a8\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2"+ + "\u00b3\3\2\2\2\u00b3\u00b4\5\n\6\2\u00b4\t\3\2\2\2\u00b5\u00c0\5\f\7\2"+ + "\u00b6\u00b7\7\61\2\2\u00b7\u00b8\7\16\2\2\u00b8\u00bd\5\16\b\2\u00b9"+ + "\u00ba\7\5\2\2\u00ba\u00bc\5\16\b\2\u00bb\u00b9\3\2\2\2\u00bc\u00bf\3"+ + "\2\2\2\u00bd\u00bb\3\2\2\2\u00bd\u00be\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf"+ + "\u00bd\3\2\2\2\u00c0\u00b6\3\2\2\2\u00c0\u00c1\3\2\2\2\u00c1\u00c4\3\2"+ + "\2\2\u00c2\u00c3\7(\2\2\u00c3\u00c5\t\7\2\2\u00c4\u00c2\3\2\2\2\u00c4"+ + "\u00c5\3\2\2\2\u00c5\13\3\2\2\2\u00c6\u00cc\5\20\t\2\u00c7\u00c8\7\3\2"+ + "\2\u00c8\u00c9\5\n\6\2\u00c9\u00ca\7\4\2\2\u00ca\u00cc\3\2\2\2\u00cb\u00c6"+ + "\3\2\2\2\u00cb\u00c7\3\2\2\2\u00cc\r\3\2\2\2\u00cd\u00cf\5*\26\2\u00ce"+ + "\u00d0\t\b\2\2\u00cf\u00ce\3\2\2\2\u00cf\u00d0\3\2\2\2\u00d0\17\3\2\2"+ + "\2\u00d1\u00d3\7:\2\2\u00d2\u00d4\5\34\17\2\u00d3\u00d2\3\2\2\2\u00d3"+ + "\u00d4\3\2\2\2\u00d4\u00d5\3\2\2\2\u00d5\u00da\5\36\20\2\u00d6\u00d7\7"+ + "\5\2\2\u00d7\u00d9\5\36\20\2\u00d8\u00d6\3\2\2\2\u00d9\u00dc\3\2\2\2\u00da"+ + "\u00d8\3\2\2\2\u00da\u00db\3\2\2\2\u00db\u00de\3\2\2\2\u00dc\u00da\3\2"+ + "\2\2\u00dd\u00df\5\22\n\2\u00de\u00dd\3\2\2\2\u00de\u00df\3\2\2\2\u00df"+ + "\u00e2\3\2\2\2\u00e0\u00e1\7C\2\2\u00e1\u00e3\5,\27\2\u00e2\u00e0\3\2"+ + "\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e7\3\2\2\2\u00e4\u00e5\7 \2\2\u00e5"+ + "\u00e6\7\16\2\2\u00e6\u00e8\5\24\13\2\u00e7\u00e4\3\2\2\2\u00e7\u00e8"+ + "\3\2\2\2\u00e8\u00eb\3\2\2\2\u00e9\u00ea\7!\2\2\u00ea\u00ec\5,\27\2\u00eb"+ + "\u00e9\3\2\2\2\u00eb\u00ec\3\2\2\2\u00ec\21\3\2\2\2\u00ed\u00ee\7\34\2"+ + "\2\u00ee\u00f3\5 \21\2\u00ef\u00f0\7\5\2\2\u00f0\u00f2\5 \21\2\u00f1\u00ef"+ + "\3\2\2\2\u00f2\u00f5\3\2\2\2\u00f3\u00f1\3\2\2\2\u00f3\u00f4\3\2\2\2\u00f4"+ + "\23\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f6\u00f8\5\34\17\2\u00f7\u00f6\3\2"+ + "\2\2\u00f7\u00f8\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9\u00fe\5\26\f\2\u00fa"+ + "\u00fb\7\5\2\2\u00fb\u00fd\5\26\f\2\u00fc\u00fa\3\2\2\2\u00fd\u0100\3"+ + "\2\2\2\u00fe\u00fc\3\2\2\2\u00fe\u00ff\3\2\2\2\u00ff\25\3\2\2\2\u0100"+ + "\u00fe\3\2\2\2\u0101\u0102\5\30\r\2\u0102\27\3\2\2\2\u0103\u010c\7\3\2"+ + "\2\u0104\u0109\5*\26\2\u0105\u0106\7\5\2\2\u0106\u0108\5*\26\2\u0107\u0105"+ + "\3\2\2\2\u0108\u010b\3\2\2\2\u0109\u0107\3\2\2\2\u0109\u010a\3\2\2\2\u010a"+ + "\u010d\3\2\2\2\u010b\u0109\3\2\2\2\u010c\u0104\3\2\2\2\u010c\u010d\3\2"+ + "\2\2\u010d\u010e\3\2\2\2\u010e\u0111\7\4\2\2\u010f\u0111\5*\26\2\u0110"+ + "\u0103\3\2\2\2\u0110\u010f\3\2\2\2\u0111\31\3\2\2\2\u0112\u0113\5B\"\2"+ + "\u0113\u0114\7\13\2\2\u0114\u0115\7\3\2\2\u0115\u0116\5\n\6\2\u0116\u0117"+ + "\7\4\2\2\u0117\33\3\2\2\2\u0118\u0119\t\t\2\2\u0119\35\3\2\2\2\u011a\u011f"+ + "\5*\26\2\u011b\u011d\7\13\2\2\u011c\u011b\3\2\2\2\u011c\u011d\3\2\2\2"+ + "\u011d\u011e\3\2\2\2\u011e\u0120\5B\"\2\u011f\u011c\3\2\2\2\u011f\u0120"+ + "\3\2\2\2\u0120\37\3\2\2\2\u0121\u0125\5(\25\2\u0122\u0124\5\"\22\2\u0123"+ + "\u0122\3\2\2\2\u0124\u0127\3\2\2\2\u0125\u0123\3\2\2\2\u0125\u0126\3\2"+ + "\2\2\u0126!\3\2\2\2\u0127\u0125\3\2\2\2\u0128\u0129\5$\23\2\u0129\u012a"+ + "\7%\2\2\u012a\u012c\5(\25\2\u012b\u012d\5&\24\2\u012c\u012b\3\2\2\2\u012c"+ + "\u012d\3\2\2\2\u012d\u0134\3\2\2\2\u012e\u012f\7+\2\2\u012f\u0130\5$\23"+ + "\2\u0130\u0131\7%\2\2\u0131\u0132\5(\25\2\u0132\u0134\3\2\2\2\u0133\u0128"+ + "\3\2\2\2\u0133\u012e\3\2\2\2\u0134#\3\2\2\2\u0135\u0137\7#\2\2\u0136\u0135"+ + "\3\2\2\2\u0136\u0137\3\2\2\2\u0137\u0145\3\2\2\2\u0138\u013a\7&\2\2\u0139"+ + "\u013b\7\62\2\2\u013a\u0139\3\2\2\2\u013a\u013b\3\2\2\2\u013b\u0145\3"+ + "\2\2\2\u013c\u013e\7\66\2\2\u013d\u013f\7\62\2\2\u013e\u013d\3\2\2\2\u013e"+ + "\u013f\3\2\2\2\u013f\u0145\3\2\2\2\u0140\u0142\7\35\2\2\u0141\u0143\7"+ + "\62\2\2\u0142\u0141\3\2\2\2\u0142\u0143\3\2\2\2\u0143\u0145\3\2\2\2\u0144"+ + "\u0136\3\2\2\2\u0144\u0138\3\2\2\2\u0144\u013c\3\2\2\2\u0144\u0140\3\2"+ + "\2\2\u0145%\3\2\2\2\u0146\u0147\7.\2\2\u0147\u0155\5,\27\2\u0148\u0149"+ + "\7A\2\2\u0149\u014a\7\3\2\2\u014a\u014f\5B\"\2\u014b\u014c\7\5\2\2\u014c"+ + "\u014e\5B\"\2\u014d\u014b\3\2\2\2\u014e\u0151\3\2\2\2\u014f\u014d\3\2"+ + "\2\2\u014f\u0150\3\2\2\2\u0150\u0152\3\2\2\2\u0151\u014f\3\2\2\2\u0152"+ + "\u0153\7\4\2\2\u0153\u0155\3\2\2\2\u0154\u0146\3\2\2\2\u0154\u0148\3\2"+ + "\2\2\u0155\'\3\2\2\2\u0156\u015b\5D#\2\u0157\u0159\7\13\2\2\u0158\u0157"+ + "\3\2\2\2\u0158\u0159\3\2\2\2\u0159\u015a\3\2\2\2\u015a\u015c\5@!\2\u015b"+ + "\u0158\3\2\2\2\u015b\u015c\3\2\2\2\u015c\u0170\3\2\2\2\u015d\u015e\7\3"+ + "\2\2\u015e\u015f\5\n\6\2\u015f\u0164\7\4\2\2\u0160\u0162\7\13\2\2\u0161"+ + "\u0160\3\2\2\2\u0161\u0162\3\2\2\2\u0162\u0163\3\2\2\2\u0163\u0165\5@"+ + "!\2\u0164\u0161\3\2\2\2\u0164\u0165\3\2\2\2\u0165\u0170\3\2\2\2\u0166"+ + "\u0167\7\3\2\2\u0167\u0168\5 \21\2\u0168\u016d\7\4\2\2\u0169\u016b\7\13"+ + "\2\2\u016a\u0169\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u016c\3\2\2\2\u016c"+ + "\u016e\5@!\2\u016d\u016a\3\2\2\2\u016d\u016e\3\2\2\2\u016e\u0170\3\2\2"+ + "\2\u016f\u0156\3\2\2\2\u016f\u015d\3\2\2\2\u016f\u0166\3\2\2\2\u0170)"+ + "\3\2\2\2\u0171\u0172\5,\27\2\u0172+\3\2\2\2\u0173\u0174\b\27\1\2\u0174"+ + "\u0175\7,\2\2\u0175\u01a3\5,\27\n\u0176\u0177\7\27\2\2\u0177\u0178\7\3"+ + "\2\2\u0178\u0179\5\b\5\2\u0179\u017a\7\4\2\2\u017a\u01a3\3\2\2\2\u017b"+ + "\u017c\78\2\2\u017c\u017d\7\3\2\2\u017d\u0182\7R\2\2\u017e\u017f\7\5\2"+ + "\2\u017f\u0181\7R\2\2\u0180\u017e\3\2\2\2\u0181\u0184\3\2\2\2\u0182\u0180"+ + "\3\2\2\2\u0182\u0183\3\2\2\2\u0183\u0185\3\2\2\2\u0184\u0182\3\2\2\2\u0185"+ + "\u01a3\7\4\2\2\u0186\u0187\7*\2\2\u0187\u0188\7\3\2\2\u0188\u0189\5@!"+ + "\2\u0189\u018a\7\5\2\2\u018a\u018f\7R\2\2\u018b\u018c\7\5\2\2\u018c\u018e"+ + "\7R\2\2\u018d\u018b\3\2\2\2\u018e\u0191\3\2\2\2\u018f\u018d\3\2\2\2\u018f"+ + "\u0190\3\2\2\2\u0190\u0192\3\2\2\2\u0191\u018f\3\2\2\2\u0192\u0193\7\4"+ + "\2\2\u0193\u01a3\3\2\2\2\u0194\u0195\7*\2\2\u0195\u0196\7\3\2\2\u0196"+ + "\u0197\7R\2\2\u0197\u0198\7\5\2\2\u0198\u019d\7R\2\2\u0199\u019a\7\5\2"+ + "\2\u019a\u019c\7R\2\2\u019b\u0199\3\2\2\2\u019c\u019f\3\2\2\2\u019d\u019b"+ + "\3\2\2\2\u019d\u019e\3\2\2\2\u019e\u01a0\3\2\2\2\u019f\u019d\3\2\2\2\u01a0"+ + "\u01a3\7\4\2\2\u01a1\u01a3\5.\30\2\u01a2\u0173\3\2\2\2\u01a2\u0176\3\2"+ + "\2\2\u01a2\u017b\3\2\2\2\u01a2\u0186\3\2\2\2\u01a2\u0194\3\2\2\2\u01a2"+ + "\u01a1\3\2\2\2\u01a3\u01ac\3\2\2\2\u01a4\u01a5\f\4\2\2\u01a5\u01a6\7\t"+ + "\2\2\u01a6\u01ab\5,\27\5\u01a7\u01a8\f\3\2\2\u01a8\u01a9\7\60\2\2\u01a9"+ + "\u01ab\5,\27\4\u01aa\u01a4\3\2\2\2\u01aa\u01a7\3\2\2\2\u01ab\u01ae\3\2"+ + "\2\2\u01ac\u01aa\3\2\2\2\u01ac\u01ad\3\2\2\2\u01ad-\3\2\2\2\u01ae\u01ac"+ + "\3\2\2\2\u01af\u01b1\5\64\33\2\u01b0\u01b2\5\60\31\2\u01b1\u01b0\3\2\2"+ + "\2\u01b1\u01b2\3\2\2\2\u01b2/\3\2\2\2\u01b3\u01b5\7,\2\2\u01b4\u01b3\3"+ + "\2\2\2\u01b4\u01b5\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6\u01b7\7\r\2\2\u01b7"+ + "\u01b8\5\64\33\2\u01b8\u01b9\7\t\2\2\u01b9\u01ba\5\64\33\2\u01ba\u01e2"+ + "\3\2\2\2\u01bb\u01bd\7,\2\2\u01bc\u01bb\3\2\2\2\u01bc\u01bd\3\2\2\2\u01bd"+ + "\u01be\3\2\2\2\u01be\u01bf\7\"\2\2\u01bf\u01c0\7\3\2\2\u01c0\u01c5\5*"+ + "\26\2\u01c1\u01c2\7\5\2\2\u01c2\u01c4\5*\26\2\u01c3\u01c1\3\2\2\2\u01c4"+ + "\u01c7\3\2\2\2\u01c5\u01c3\3\2\2\2\u01c5\u01c6\3\2\2\2\u01c6\u01c8\3\2"+ + "\2\2\u01c7\u01c5\3\2\2\2\u01c8\u01c9\7\4\2\2\u01c9\u01e2\3\2\2\2\u01ca"+ + "\u01cc\7,\2\2\u01cb\u01ca\3\2\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01cd\3\2"+ + "\2\2\u01cd\u01ce\7\"\2\2\u01ce\u01cf\7\3\2\2\u01cf\u01d0\5\b\5\2\u01d0"+ + "\u01d1\7\4\2\2\u01d1\u01e2\3\2\2\2\u01d2\u01d4\7,\2\2\u01d3\u01d2\3\2"+ + "\2\2\u01d3\u01d4\3\2\2\2\u01d4\u01d5\3\2\2\2\u01d5\u01d6\7\'\2\2\u01d6"+ + "\u01e2\5\62\32\2\u01d7\u01d9\7,\2\2\u01d8\u01d7\3\2\2\2\u01d8\u01d9\3"+ + "\2\2\2\u01d9\u01da\3\2\2\2\u01da\u01db\7\67\2\2\u01db\u01e2\7R\2\2\u01dc"+ + "\u01de\7$\2\2\u01dd\u01df\7,\2\2\u01de\u01dd\3\2\2\2\u01de\u01df\3\2\2"+ + "\2\u01df\u01e0\3\2\2\2\u01e0\u01e2\7-\2\2\u01e1\u01b4\3\2\2\2\u01e1\u01bc"+ + "\3\2\2\2\u01e1\u01cb\3\2\2\2\u01e1\u01d3\3\2\2\2\u01e1\u01d8\3\2\2\2\u01e1"+ + "\u01dc\3\2\2\2\u01e2\61\3\2\2\2\u01e3\u01e6\7R\2\2\u01e4\u01e5\7\25\2"+ + "\2\u01e5\u01e7\7R\2\2\u01e6\u01e4\3\2\2\2\u01e6\u01e7\3\2\2\2\u01e7\63"+ + "\3\2\2\2\u01e8\u01e9\b\33\1\2\u01e9\u01ed\5\66\34\2\u01ea\u01eb\t\n\2"+ + "\2\u01eb\u01ed\5\64\33\6\u01ec\u01e8\3\2\2\2\u01ec\u01ea\3\2\2\2\u01ed"+ + "\u01fa\3\2\2\2\u01ee\u01ef\f\5\2\2\u01ef\u01f0\t\13\2\2\u01f0\u01f9\5"+ + "\64\33\6\u01f1\u01f2\f\4\2\2\u01f2\u01f3\t\n\2\2\u01f3\u01f9\5\64\33\5"+ + "\u01f4\u01f5\f\3\2\2\u01f5\u01f6\5:\36\2\u01f6\u01f7\5\64\33\4\u01f7\u01f9"+ + "\3\2\2\2\u01f8\u01ee\3\2\2\2\u01f8\u01f1\3\2\2\2\u01f8\u01f4\3\2\2\2\u01f9"+ + "\u01fc\3\2\2\2\u01fa\u01f8\3\2\2\2\u01fa\u01fb\3\2\2\2\u01fb\65\3\2\2"+ + "\2\u01fc\u01fa\3\2\2\2\u01fd\u01fe\7\17\2\2\u01fe\u01ff\7\3\2\2\u01ff"+ + "\u0200\5*\26\2\u0200\u0201\7\13\2\2\u0201\u0202\5> \2\u0202\u0203\7\4"+ + "\2\2\u0203\u022f\3\2\2\2\u0204\u0205\7\31\2\2\u0205\u0206\7\3\2\2\u0206"+ + "\u0207\5B\"\2\u0207\u0208\7\34\2\2\u0208\u0209\5\64\33\2\u0209\u020a\7"+ + "\4\2\2\u020a\u022f\3\2\2\2\u020b\u022f\58\35\2\u020c\u022f\7M\2\2\u020d"+ + "\u020e\5@!\2\u020e\u020f\7Q\2\2\u020f\u0211\3\2\2\2\u0210\u020d\3\2\2"+ + "\2\u0210\u0211\3\2\2\2\u0211\u0212\3\2\2\2\u0212\u022f\7M\2\2\u0213\u0214"+ + "\5B\"\2\u0214\u0220\7\3\2\2\u0215\u0217\5\34\17\2\u0216\u0215\3\2\2\2"+ + "\u0216\u0217\3\2\2\2\u0217\u0218\3\2\2\2\u0218\u021d\5*\26\2\u0219\u021a"+ + "\7\5\2\2\u021a\u021c\5*\26\2\u021b\u0219\3\2\2\2\u021c\u021f\3\2\2\2\u021d"+ + "\u021b\3\2\2\2\u021d\u021e\3\2\2\2\u021e\u0221\3\2\2\2\u021f\u021d\3\2"+ + "\2\2\u0220\u0216\3\2\2\2\u0220\u0221\3\2\2\2\u0221\u0222\3\2\2\2\u0222"+ + "\u0223\7\4\2\2\u0223\u022f\3\2\2\2\u0224\u0225\7\3\2\2\u0225\u0226\5\b"+ + "\5\2\u0226\u0227\7\4\2\2\u0227\u022f\3\2\2\2\u0228\u022f\5B\"\2\u0229"+ + "\u022f\5@!\2\u022a\u022b\7\3\2\2\u022b\u022c\5*\26\2\u022c\u022d\7\4\2"+ + "\2\u022d\u022f\3\2\2\2\u022e\u01fd\3\2\2\2\u022e\u0204\3\2\2\2\u022e\u020b"+ + "\3\2\2\2\u022e\u020c\3\2\2\2\u022e\u0210\3\2\2\2\u022e\u0213\3\2\2\2\u022e"+ + "\u0224\3\2\2\2\u022e\u0228\3\2\2\2\u022e\u0229\3\2\2\2\u022e\u022a\3\2"+ + "\2\2\u022f\67\3\2\2\2\u0230\u0239\7-\2\2\u0231\u0239\5J&\2\u0232\u0239"+ + "\5<\37\2\u0233\u0235\7R\2\2\u0234\u0233\3\2\2\2\u0235\u0236\3\2\2\2\u0236"+ + "\u0234\3\2\2\2\u0236\u0237\3\2\2\2\u0237\u0239\3\2\2\2\u0238\u0230\3\2"+ + "\2\2\u0238\u0231\3\2\2\2\u0238\u0232\3\2\2\2\u0238\u0234\3\2\2\2\u0239"+ + "9\3\2\2\2\u023a\u023b\t\f\2\2\u023b;\3\2\2\2\u023c\u023d\t\r\2\2\u023d"+ + "=\3\2\2\2\u023e\u023f\5B\"\2\u023f?\3\2\2\2\u0240\u0241\5B\"\2\u0241\u0242"+ + "\7Q\2\2\u0242\u0244\3\2\2\2\u0243\u0240\3\2\2\2\u0244\u0247\3\2\2\2\u0245"+ + "\u0243\3\2\2\2\u0245\u0246\3\2\2\2\u0246\u0248\3\2\2\2\u0247\u0245\3\2"+ + "\2\2\u0248\u0249\5B\"\2\u0249A\3\2\2\2\u024a\u024d\5F$\2\u024b\u024d\5"+ + "H%\2\u024c\u024a\3\2\2\2\u024c\u024b\3\2\2\2\u024dC\3\2\2\2\u024e\u0251"+ + "\7W\2\2\u024f\u0251\5B\"\2\u0250\u024e\3\2\2\2\u0250\u024f\3\2\2\2\u0251"+ + "E\3\2\2\2\u0252\u0255\7X\2\2\u0253\u0255\7Y\2\2\u0254\u0252\3\2\2\2\u0254"+ + "\u0253\3\2\2\2\u0255G\3\2\2\2\u0256\u025a\7U\2\2\u0257\u025a\5L\'\2\u0258"+ + "\u025a\7V\2\2\u0259\u0256\3\2\2\2\u0259\u0257\3\2\2\2\u0259\u0258\3\2"+ + "\2\2\u025aI\3\2\2\2\u025b\u025e\7T\2\2\u025c\u025e\7S\2\2\u025d\u025b"+ + "\3\2\2\2\u025d\u025c\3\2\2\2\u025eK\3\2\2\2\u025f\u0260\t\16\2\2\u0260"+ + "M\3\2\2\2Y]_clnrx{\u0086\u0089\u0090\u0093\u0099\u009c\u009f\u00a2\u00a6"+ + "\u00ae\u00b1\u00bd\u00c0\u00c4\u00cb\u00cf\u00d3\u00da\u00de\u00e2\u00e7"+ + "\u00eb\u00f3\u00f7\u00fe\u0109\u010c\u0110\u011c\u011f\u0125\u012c\u0133"+ + "\u0136\u013a\u013e\u0142\u0144\u014f\u0154\u0158\u015b\u0161\u0164\u016a"+ + "\u016d\u016f\u0182\u018f\u019d\u01a2\u01aa\u01ac\u01b1\u01b4\u01bc\u01c5"+ + "\u01cb\u01d3\u01d8\u01de\u01e1\u01e6\u01ec\u01f8\u01fa\u0210\u0216\u021d"+ + "\u0220\u022e\u0236\u0238\u0245\u024c\u0250\u0254\u0259\u025d"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java new file mode 100644 index 00000000000..3dd7c055bcc --- /dev/null +++ b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumns.java @@ -0,0 +1,185 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.plan.logical.command.sys; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.xpack.sql.analysis.index.EsIndex; +import org.elasticsearch.xpack.sql.expression.Attribute; +import org.elasticsearch.xpack.sql.expression.regex.LikePattern; +import org.elasticsearch.xpack.sql.plan.logical.command.Command; +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.Location; +import org.elasticsearch.xpack.sql.tree.NodeInfo; +import org.elasticsearch.xpack.sql.type.DataType; +import org.elasticsearch.xpack.sql.type.EsField; + +import java.sql.DatabaseMetaData; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Pattern; + +import static java.util.Arrays.asList; +import static org.elasticsearch.xpack.sql.type.DataType.INTEGER; +import static org.elasticsearch.xpack.sql.type.DataType.NULL; +import static org.elasticsearch.xpack.sql.type.DataType.SHORT; + +/** + * System command designed to be used by JDBC / ODBC for column metadata, such as + * {@link DatabaseMetaData#getColumns(String, String, String, String)}. + */ +public class SysColumns extends Command { + + private final LikePattern indexPattern; + private final LikePattern columnPattern; + + public SysColumns(Location location, LikePattern indexPattern, LikePattern columnPattern) { + super(location); + this.indexPattern = indexPattern; + this.columnPattern = columnPattern; + } + + public LikePattern indexPattern() { + return indexPattern; + } + + public LikePattern columnPattern() { + return columnPattern; + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, SysColumns::new, indexPattern, columnPattern); + } + + @Override + public List output() { + return asList(keyword("TABLE_CAT"), + keyword("TABLE_SCHEM"), + keyword("TABLE_NAME"), + keyword("COLUMN_NAME"), + field("DATA_TYPE", INTEGER), + keyword("TYPE_NAME"), + field("COLUMN_SIZE", INTEGER), + field("BUFFER_LENGTH", NULL), + field("DECIMAL_DIGITS", INTEGER), + field("NUM_PREC_RADIX", INTEGER), + field("NULLABLE", INTEGER), + keyword("REMARKS"), + keyword("COLUMN_DEF"), + field("SQL_DATA_TYPE", INTEGER), + field("SQL_DATETIME_SUB", INTEGER), + field("CHAR_OCTET_LENGTH", INTEGER), + field("ORDINAL_POSITION", INTEGER), + keyword("IS_NULLABLE"), + // JDBC specific + keyword("SCOPE_CATALOG"), + keyword("SCOPE_SCHEMA"), + keyword("SCOPE_TABLE"), + field("SOURCE_DATA_TYPE", SHORT), + keyword("IS_AUTOINCREMENT"), + keyword("IS_GENERATEDCOLUMN") + ); + } + + @Override + public void execute(SqlSession session, ActionListener listener) { + String index = indexPattern != null ? indexPattern.asIndexNameWildcard() : "*"; + String regex = indexPattern != null ? indexPattern.asJavaRegex() : null; + + Pattern columnMatcher = columnPattern != null ? Pattern.compile(columnPattern.asJavaRegex()) : null; + + String cluster = session.indexResolver().clusterName(); + + session.indexResolver().resolveAsSeparateMappings(index, regex, ActionListener.wrap(esIndices -> { + List> rows = new ArrayList<>(); + for (EsIndex esIndex : esIndices) { + fillInRows(cluster, esIndex.name(), esIndex.mapping(), null, rows, columnMatcher); + } + + listener.onResponse(Rows.of(output(), rows)); + }, listener::onFailure)); + } + + static void fillInRows(String clusterName, String indexName, Map mapping, String prefix, List> rows, + Pattern columnMatcher) { + int pos = 0; + for (Map.Entry entry : mapping.entrySet()) { + pos++; // JDBC is 1-based so we start with 1 here + + String name = entry.getKey(); + name = prefix != null ? prefix + "." + name : name; + 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, + type.jdbcType.getVendorTypeNumber(), + type.esType.toUpperCase(Locale.ROOT), + type.displaySize, + // TODO: is the buffer_length correct? + type.size, + // no DECIMAL support + null, + // RADIX + type.isInteger ? Integer.valueOf(10) : type.isRational ? Integer.valueOf(2) : null, + // everything is nullable + DatabaseMetaData.columnNullable, + // 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 + type.jdbcType.getVendorTypeNumber(), + // SQL_DATETIME_SUB ? + null, + // 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); + } + } + } + + @Override + public int hashCode() { + return Objects.hash(indexPattern, columnPattern); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + SysColumns other = (SysColumns) obj; + return Objects.equals(indexPattern, other.indexPattern) + && Objects.equals(columnPattern, other.columnPattern); + } +} \ No newline at end of file diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/RestSqlListColumnsAction.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/RestSqlListColumnsAction.java deleted file mode 100644 index 39fc225dfd3..00000000000 --- a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/RestSqlListColumnsAction.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.client.node.NodeClient; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.rest.BaseRestHandler; -import org.elasticsearch.rest.RestController; -import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.rest.action.RestToXContentListener; - -import java.io.IOException; - -import static org.elasticsearch.rest.RestRequest.Method.POST; - -public class RestSqlListColumnsAction extends BaseRestHandler { - - public RestSqlListColumnsAction(Settings settings, RestController controller) { - super(settings); - controller.registerHandler(POST, SqlListColumnsAction.REST_ENDPOINT, this); - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - SqlListColumnsRequest listColumnsRequest; - try (XContentParser parser = request.contentOrSourceParamParser()) { - listColumnsRequest = SqlListColumnsRequest.fromXContent(parser, AbstractSqlRequest.Mode.fromString(request.param("mode"))); - } - return channel -> client.executeLocally(SqlListColumnsAction.INSTANCE, listColumnsRequest, new RestToXContentListener<>(channel)); - } - - @Override - public String getName() { - return "xpack_sql_list_columns_action"; - } -} - diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java index fdb2f9b4437..dfb0c82bbeb 100644 --- a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java +++ b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java @@ -105,8 +105,7 @@ public class SqlPlugin extends Plugin implements ActionPlugin { return Arrays.asList(new RestSqlQueryAction(settings, restController), new RestSqlTranslateAction(settings, restController), - new RestSqlClearCursorAction(settings, restController), - new RestSqlListColumnsAction(settings, restController)); + new RestSqlClearCursorAction(settings, restController)); } @Override @@ -117,7 +116,6 @@ public class SqlPlugin extends Plugin implements ActionPlugin { return Arrays.asList(new ActionHandler<>(SqlQueryAction.INSTANCE, TransportSqlQueryAction.class), new ActionHandler<>(SqlTranslateAction.INSTANCE, TransportSqlTranslateAction.class), - new ActionHandler<>(SqlClearCursorAction.INSTANCE, TransportSqlClearCursorAction.class), - new ActionHandler<>(SqlListColumnsAction.INSTANCE, TransportSqlListColumnsAction.class)); + new ActionHandler<>(SqlClearCursorAction.INSTANCE, TransportSqlClearCursorAction.class)); } } diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TransportSqlListColumnsAction.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TransportSqlListColumnsAction.java deleted file mode 100644 index 70784471c49..00000000000 --- a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TransportSqlListColumnsAction.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.sql.plugin; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.support.ActionFilters; -import org.elasticsearch.action.support.HandledTransportAction; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.transport.TransportService; -import org.elasticsearch.xpack.sql.analysis.index.EsIndex; -import org.elasticsearch.xpack.sql.analysis.index.IndexResolver; -import org.elasticsearch.xpack.sql.type.EsField; -import org.elasticsearch.xpack.sql.util.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import static org.elasticsearch.common.Strings.hasText; -import static org.elasticsearch.xpack.sql.plugin.AbstractSqlRequest.Mode.JDBC; - -public class TransportSqlListColumnsAction extends HandledTransportAction { - private final SqlLicenseChecker sqlLicenseChecker; - private final IndexResolver indexResolver; - - @Inject - public TransportSqlListColumnsAction(Settings settings, ThreadPool threadPool, - TransportService transportService, ActionFilters actionFilters, - IndexNameExpressionResolver indexNameExpressionResolver, - SqlLicenseChecker sqlLicenseChecker, IndexResolver indexResolver) { - super(settings, SqlListColumnsAction.NAME, threadPool, transportService, actionFilters, SqlListColumnsRequest::new, - indexNameExpressionResolver); - this.sqlLicenseChecker = sqlLicenseChecker; - this.indexResolver = indexResolver; - } - - @Override - protected void doExecute(SqlListColumnsRequest request, ActionListener listener) { - sqlLicenseChecker.checkIfSqlAllowed(request.mode()); - - String indexPattern = hasText(request.getTablePattern()) ? - StringUtils.likeToIndexWildcard(request.getTablePattern(), (char) 0) : "*"; - String regexPattern = hasText(request.getTablePattern()) ? - StringUtils.likeToJavaPattern(request.getTablePattern(), (char) 0) : null; - - Pattern columnMatcher = hasText(request.getColumnPattern()) ? Pattern.compile( - StringUtils.likeToJavaPattern(request.getColumnPattern(), (char) 0)) : null; - - indexResolver.resolveAsSeparateMappings(indexPattern, regexPattern, ActionListener.wrap(esIndices -> { - List columns = new ArrayList<>(); - for (EsIndex esIndex : esIndices) { - int pos = 0; - for (Map.Entry entry : esIndex.mapping().entrySet()) { - String name = entry.getKey(); - pos++; // JDBC is 1-based so we start with 1 here - if (columnMatcher == null || columnMatcher.matcher(name).matches()) { - EsField field = entry.getValue(); - if (request.mode() == JDBC) { - // the column size it's actually its precision (based on the Javadocs) - columns.add(new MetaColumnInfo(esIndex.name(), name, field.getDataType().esType, - field.getDataType().jdbcType, field.getPrecision(), pos)); - } else { - columns.add(new MetaColumnInfo(esIndex.name(), name, field.getDataType().esType, pos)); - } - } - } - } - listener.onResponse(new SqlListColumnsResponse(columns)); - }, listener::onFailure)); - } -} diff --git a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataType.java b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataType.java index ce52d29cc8f..c03ef435ee9 100644 --- a/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataType.java +++ b/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataType.java @@ -123,5 +123,4 @@ public enum DataType { public boolean isPrimitive() { return this != OBJECT && this != NESTED; } - -} +} \ No newline at end of file diff --git a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlActionIT.java b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlActionIT.java index e32f5d15448..b36fa811d3b 100644 --- a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlActionIT.java +++ b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlActionIT.java @@ -7,27 +7,19 @@ package org.elasticsearch.xpack.sql.action; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.WriteRequest; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.xpack.sql.plugin.AbstractSqlRequest.Mode; import org.elasticsearch.xpack.sql.plugin.ColumnInfo; -import org.elasticsearch.xpack.sql.plugin.MetaColumnInfo; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsAction; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsResponse; import org.elasticsearch.xpack.sql.plugin.SqlQueryAction; import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse; -import org.hamcrest.Matchers; -import java.io.IOException; import java.sql.JDBCType; -import java.util.List; -import java.util.stream.Collectors; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; public class SqlActionIT extends AbstractSqlIntegTestCase { + public void testSqlAction() throws Exception { assertAcked(client().admin().indices().prepareCreate("test").get()); client().prepareBulk() @@ -54,56 +46,5 @@ public class SqlActionIT extends AbstractSqlIntegTestCase { assertEquals("baz", response.rows().get(1).get(dataIndex)); assertEquals(43L, response.rows().get(1).get(countIndex)); } - - public void testSqlListColumnsAction() throws Exception { - - createCompatibleIndex("bar"); - createCompatibleIndex("baz"); - createIncompatibleIndex("broken"); - - SqlListColumnsResponse response = client().prepareExecute(SqlListColumnsAction.INSTANCE) - .indexPattern("bar").columnPattern("").mode(Mode.JDBC).get(); - List columns = response.getColumns(); - assertThat(columns, hasSize(2)); - assertThat(columns, Matchers.contains( - new MetaColumnInfo("bar", "int_field", "integer", JDBCType.INTEGER, 10, 1), - new MetaColumnInfo("bar", "str_field", "text", JDBCType.VARCHAR, Integer.MAX_VALUE, 2) - )); - - response = client().prepareExecute(SqlListColumnsAction.INSTANCE) - .indexPattern("bar").columnPattern("").mode(Mode.PLAIN).get(); - columns = response.getColumns(); - assertThat(columns, hasSize(2)); - assertThat(columns, Matchers.contains( - new MetaColumnInfo("bar", "int_field", "integer", null, 0, 1), - new MetaColumnInfo("bar", "str_field", "text", null, 0, 2) - )); - } - - private void createCompatibleIndex(String name) throws IOException { - XContentBuilder mapping = jsonBuilder().startObject(); - { - mapping.startObject("properties"); - { - mapping.startObject("str_field").field("type", "text").endObject(); - mapping.startObject("int_field").field("type", "integer").endObject(); - } - mapping.endObject(); - } - mapping.endObject(); - - assertAcked(client().admin().indices().prepareCreate(name).addMapping("doc", mapping).get()); - } - - private void createIncompatibleIndex(String name) throws IOException { - assertAcked(client().admin().indices().prepareCreate(name).get()); - } - - /** - * Removes list of internal indices to make tests consistent between secure and unsecure environments - */ - private static List removeInternal(List list) { - return list.stream().filter(s -> s.startsWith(".") == false).collect(Collectors.toList()); - } } diff --git a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlLicenseIT.java b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlLicenseIT.java index 336d861b02d..d4d9ab4c3e8 100644 --- a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlLicenseIT.java +++ b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/action/SqlLicenseIT.java @@ -19,8 +19,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; import org.elasticsearch.transport.Netty4Plugin; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsAction; -import org.elasticsearch.xpack.sql.plugin.SqlListColumnsResponse; import org.elasticsearch.xpack.sql.plugin.SqlQueryAction; import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse; import org.elasticsearch.xpack.sql.plugin.SqlTranslateAction; @@ -37,9 +35,6 @@ import static org.elasticsearch.license.XPackLicenseStateTests.randomBasicStanda import static org.elasticsearch.license.XPackLicenseStateTests.randomTrialBasicStandardGoldOrPlatinumMode; import static org.elasticsearch.license.XPackLicenseStateTests.randomTrialOrPlatinumMode; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; public class SqlLicenseIT extends AbstractLicensesIntegrationTestCase { @Override @@ -140,38 +135,6 @@ public class SqlLicenseIT extends AbstractLicensesIntegrationTestCase { assertThat(response.size(), Matchers.equalTo(2L)); } - public void testSqlListColumnsActionLicense() throws Exception { - setupTestIndex(); - disableSqlLicensing(); - - ElasticsearchSecurityException e = expectThrows(ElasticsearchSecurityException.class, - () -> client().prepareExecute(SqlListColumnsAction.INSTANCE).columnPattern("").indexPattern("test").get()); - assertThat(e.getMessage(), equalTo("current license is non-compliant for [sql]")); - enableSqlLicensing(); - - SqlListColumnsResponse response = client().prepareExecute(SqlListColumnsAction.INSTANCE).columnPattern("") - .indexPattern("test").get(); - assertThat(response.getColumns(), hasSize(2)); - assertThat(response.getColumns().get(0).jdbcType(), nullValue()); - } - - - public void testSqlListColumnsJdbcModeLicense() throws Exception { - setupTestIndex(); - disableJdbcLicensing(); - - ElasticsearchSecurityException e = expectThrows(ElasticsearchSecurityException.class, - () -> client().prepareExecute(SqlListColumnsAction.INSTANCE).columnPattern("") - .indexPattern("test").mode("jdbc").get()); - assertThat(e.getMessage(), equalTo("current license is non-compliant for [jdbc]")); - enableJdbcLicensing(); - - SqlListColumnsResponse response = client().prepareExecute(SqlListColumnsAction.INSTANCE).columnPattern("") - .indexPattern("test").mode("jdbc").get(); - assertThat(response.getColumns(), hasSize(2)); - assertThat(response.getColumns().get(0).jdbcType(), notNullValue()); - } - public void testSqlTranslateActionLicense() throws Exception { setupTestIndex(); disableSqlLicensing(); diff --git a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java new file mode 100644 index 00000000000..2866624b07b --- /dev/null +++ b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysColumnsTests.java @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.plan.logical.command.sys; + +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.sql.type.TypesTests; + +import java.sql.Types; +import java.util.ArrayList; +import java.util.List; + +public class SysColumnsTests extends ESTestCase { + + public void testSysColumns() { + List> rows = new ArrayList<>(); + SysColumns.fillInRows("test", "index", TypesTests.loadMapping("mapping-multi-field-variation.json", true), null, rows, null); + assertEquals(15, rows.size()); + assertEquals(24, rows.get(0).size()); + + List row = rows.get(0); + assertEquals("bool", name(row)); + assertEquals(Types.BOOLEAN, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(1, bufferLength(row)); + + row = rows.get(1); + assertEquals("int", name(row)); + assertEquals(Types.INTEGER, sqlType(row)); + assertEquals(10, radix(row)); + assertEquals(4, bufferLength(row)); + + row = rows.get(2); + assertEquals("text", name(row)); + assertEquals(Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + + row = rows.get(6); + assertEquals("some.dotted", name(row)); + assertEquals(Types.STRUCT, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(-1, bufferLength(row)); + + row = rows.get(14); + assertEquals("some.ambiguous.normalized", name(row)); + assertEquals(Types.VARCHAR, sqlType(row)); + assertEquals(null, radix(row)); + assertEquals(Integer.MAX_VALUE, bufferLength(row)); + } + + private static Object name(List list) { + return list.get(3); + } + + private static Object sqlType(List list) { + return list.get(4); + } + + private static Object bufferLength(List list) { + return list.get(7); + } + + private static Object radix(List list) { + return list.get(9); + } +} diff --git a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysParserTests.java b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysParserTests.java index fb70ba73440..530e0d14866 100644 --- a/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysParserTests.java +++ b/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/plan/logical/command/sys/SysParserTests.java @@ -6,13 +6,16 @@ package org.elasticsearch.xpack.sql.plan.logical.command.sys; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.sql.analysis.analyzer.Analyzer; import org.elasticsearch.xpack.sql.analysis.index.EsIndex; import org.elasticsearch.xpack.sql.analysis.index.IndexResolution; +import org.elasticsearch.xpack.sql.analysis.index.IndexResolver; import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry; import org.elasticsearch.xpack.sql.parser.SqlParser; import org.elasticsearch.xpack.sql.plan.logical.command.Command; +import org.elasticsearch.xpack.sql.session.SqlSession; import org.elasticsearch.xpack.sql.type.EsField; import org.elasticsearch.xpack.sql.type.TypesTests; import org.joda.time.DateTimeZone; @@ -21,20 +24,37 @@ import java.util.List; import java.util.Map; import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class SysParserTests extends ESTestCase { private final SqlParser parser = new SqlParser(DateTimeZone.UTC); + private final Map mapping = TypesTests.loadMapping("mapping-multi-field-with-nested.json", true); - private Command sql(String sql) { - Map mapping = TypesTests.loadMapping("mapping-multi-field-with-nested.json"); + @SuppressWarnings({ "rawtypes", "unchecked" }) + private Tuple sql(String sql) { EsIndex test = new EsIndex("test", mapping); Analyzer analyzer = new Analyzer(new FunctionRegistry(), IndexResolution.valid(test), DateTimeZone.UTC); - return (Command) analyzer.analyze(parser.createStatement(sql), true); + Command cmd = (Command) analyzer.analyze(parser.createStatement(sql), true); + + IndexResolver resolver = mock(IndexResolver.class); + when(resolver.clusterName()).thenReturn("cluster"); + + doAnswer(invocation -> { + ((ActionListener) invocation.getArguments()[2]).onResponse(singletonList(test)); + return Void.TYPE; + }).when(resolver).resolveAsSeparateMappings(any(), any(), any()); + + SqlSession session = new SqlSession(null, null, null, resolver, null, null, null); + return new Tuple<>(cmd, session); } public void testSysTypes() throws Exception { - Command cmd = sql("SYS TYPES"); + Command cmd = sql("SYS TYPES").v1(); List names = asList("BYTE", "SHORT", "INTEGER", "LONG", "HALF_FLOAT", "SCALED_FLOAT", "FLOAT", "DOUBLE", "KEYWORD", "TEXT", "DATE", "BINARY", "NULL", "UNSUPPORTED", "OBJECT", "NESTED", "BOOLEAN"); @@ -50,4 +70,60 @@ public class SysParserTests extends ESTestCase { }, ex -> fail(ex.getMessage()))); } -} + + public void testSysColsNoArgs(String commandVariation) throws Exception { + runSysColumns("SYS COLUMNS"); + } + + public void testSysColsTableOnlyPattern(String commandVariation) throws Exception { + runSysColumns("SYS COLUMNS TABLES LIKE 'test'"); + } + + public void testSysColsColOnlyPattern(String commandVariation) throws Exception { + runSysColumns("SYS COLUMNS LIKE '%'"); + } + + public void testSysColsTableAndColsPattern(String commandVariation) throws Exception { + runSysColumns("SYS COLUMNS TABLES LIKE 'test' LIKE '%'"); + } + + + private void runSysColumns(String commandVariation) throws Exception { + Tuple sql = sql(commandVariation); + List names = asList("bool", + "int", + "text", + "keyword", + "unsupported", + "some", + "some.dotted", + "some.dotted.field", + "some.string", + "some.string.normalized", + "some.string.typical", + "some.ambiguous", + "some.ambiguous.one", + "some.ambiguous.two", + "some.ambiguous.normalized", + "dep", + "dep.dep_name", + "dep.dep_id", + "dep.dep_id.keyword", + "dep.end_date", + "dep.start_date"); + + sql.v1().execute(sql.v2(), ActionListener.wrap(r -> { + assertEquals(24, r.columnCount()); + assertEquals(21, r.size()); + + for (int i = 0; i < r.size(); i++) { + assertEquals("cluster", r.column(0)); + assertNull(r.column(1)); + assertEquals("test", r.column(2)); + assertEquals(names.get(i), r.column(3)); + r.advanceRow(); + } + + }, ex -> fail(ex.getMessage()))); + } +} \ No newline at end of file diff --git a/plugin/src/test/resources/rest-api-spec/api/xpack.sql.columns.json b/plugin/src/test/resources/rest-api-spec/api/xpack.sql.columns.json deleted file mode 100644 index fc87b79fe91..00000000000 --- a/plugin/src/test/resources/rest-api-spec/api/xpack.sql.columns.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "xpack.sql.columns": { - "documentation": "Returns a list of columns supported by SQL for the current user", - "methods": [ "POST" ], - "url": { - "path": "/_xpack/sql/columns", - "paths": [ "/_xpack/sql/columns" ], - "parts": {}, - "params": {} - }, - "body": { - "description" : "Specify the table pattern in the `table_pattern` and the column patter in `column_pattern` element.", - "required" : true - } - } - } diff --git a/plugin/src/test/resources/rest-api-spec/test/sql/sql.yml b/plugin/src/test/resources/rest-api-spec/test/sql/sql.yml index 70ee9f68cf9..033d3223002 100644 --- a/plugin/src/test/resources/rest-api-spec/test/sql/sql.yml +++ b/plugin/src/test/resources/rest-api-spec/test/sql/sql.yml @@ -118,14 +118,3 @@ setup: - match: { indices.test.total.search.open_contexts: 0 } ---- -"Check list of columns": - - do: - xpack.sql.columns: - body: - table_pattern: "t%" - column_pattern: "" - - - length: { columns: 2 } - - match: { columns.0.name: 'int' } - - match: { columns.1.name: 'str' } diff --git a/qa/sql/security/roles.yml b/qa/sql/security/roles.yml index 12316c4dfe9..ff7d8f1b035 100644 --- a/qa/sql/security/roles.yml +++ b/qa/sql/security/roles.yml @@ -3,23 +3,23 @@ read_all: - "cluster:monitor/main" # Used by JDBC's MetaData indices: - names: test - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] - names: bort - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] read_something_else: cluster: - "cluster:monitor/main" # Used by JDBC's MetaData indices: - names: something_that_isnt_test - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] read_test_a: cluster: - "cluster:monitor/main" # Used by JDBC's MetaData indices: - names: test - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] field_security: grant: [a] @@ -28,7 +28,7 @@ read_test_a_and_b: - "cluster:monitor/main" # Used by JDBC's MetaData indices: - names: test - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] field_security: grant: ["*"] except: [c] @@ -38,7 +38,7 @@ read_test_without_c_3: - "cluster:monitor/main" # Used by JDBC's MetaData indices: - names: test - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] query: | { "bool": { @@ -57,4 +57,4 @@ read_bort: - "cluster:monitor/main" # Used by JDBC's MetaData indices: - names: bort - privileges: [read, "indices:admin/get", "indices:admin/sql/columns"] + privileges: [read, "indices:admin/get"] diff --git a/qa/sql/security/src/test/java/org/elasticsearch/xpack/qa/sql/security/JdbcSecurityIT.java b/qa/sql/security/src/test/java/org/elasticsearch/xpack/qa/sql/security/JdbcSecurityIT.java index dabc04d3f5a..d1494d5e4a8 100644 --- a/qa/sql/security/src/test/java/org/elasticsearch/xpack/qa/sql/security/JdbcSecurityIT.java +++ b/qa/sql/security/src/test/java/org/elasticsearch/xpack/qa/sql/security/JdbcSecurityIT.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.xpack.qa.sql.security; -import org.elasticsearch.action.admin.indices.get.GetIndexAction; import org.elasticsearch.common.CheckedConsumer; import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.io.PathUtils; @@ -28,7 +27,6 @@ import static org.elasticsearch.xpack.qa.sql.jdbc.JdbcAssert.assertResultSets; import static org.elasticsearch.xpack.qa.sql.jdbc.JdbcIntegrationTestCase.elasticsearchAddress; import static org.elasticsearch.xpack.qa.sql.jdbc.JdbcIntegrationTestCase.randomKnownTimeZone; import static org.elasticsearch.xpack.qa.sql.security.RestSqlIT.SSL_ENABLED; -import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; public class JdbcSecurityIT extends SqlSecurityTestCase { @@ -264,20 +262,12 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { con -> con.getMetaData().getColumns("%", "%", "%t", "%"), "full_access", con -> con.getMetaData().getColumns("%", "%", "%", "%")); - new AuditLogAsserter() - .expect(true, GetIndexAction.NAME, "test_admin", contains("bort", "test")) - .expect(true, GetIndexAction.NAME, "full_access", contains("bort", "test")) - .assertLogs(); } public void testMetaDataGetColumnsWithNoAccess() throws Exception { createUser("no_access", "read_nothing"); expectForbidden("no_access", con -> con.getMetaData().getColumns("%", "%", "%", "%")); - new AuditLogAsserter() - // TODO figure out why this generates *no* logs - // .expect(false, GetIndexAction.NAME, "no_access", contains("bort", "test")) - .assertLogs(); } public void testMetaDataGetColumnsWithWrongAccess() throws Exception { @@ -287,10 +277,6 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { con -> con.getMetaData().getColumns("%", "%", "not_created", "%"), "wrong_access", con -> con.getMetaData().getColumns("%", "%", "test", "%")); - new AuditLogAsserter() - .expect(true, GetIndexAction.NAME, "test_admin", contains("*", "-*")) - .expect(true, GetIndexAction.NAME, "wrong_access", contains("*", "-*")) - .assertLogs(); } public void testMetaDataGetColumnsSingleFieldGranted() throws Exception { @@ -300,10 +286,6 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { con -> con.getMetaData().getColumns("%", "%", "test", "a"), "only_a", con -> con.getMetaData().getColumns("%", "%", "test", "%")); - new AuditLogAsserter() - .expect(true, GetIndexAction.NAME, "test_admin", contains("test")) - .expect(true, GetIndexAction.NAME, "only_a", contains("test")) - .assertLogs(); } public void testMetaDataGetColumnsSingleFieldExcepted() throws Exception { @@ -322,9 +304,6 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { assertEquals("b", columnName); assertFalse(result.next()); } - new AuditLogAsserter() - .expect(true, GetIndexAction.NAME, "not_c", contains("test")) - .assertLogs(); } public void testMetaDataGetColumnsDocumentExcluded() throws Exception { @@ -334,9 +313,5 @@ public class JdbcSecurityIT extends SqlSecurityTestCase { con -> con.getMetaData().getColumns("%", "%", "test", "%"), "no_3s", con -> con.getMetaData().getColumns("%", "%", "test", "%")); - new AuditLogAsserter() - .expect(true, GetIndexAction.NAME, "test_admin", contains("test")) - .expect(true, GetIndexAction.NAME, "no_3s", contains("test")) - .assertLogs(); } -} +} \ No newline at end of file diff --git a/qa/sql/src/main/java/org/elasticsearch/xpack/qa/sql/jdbc/JdbcAssert.java b/qa/sql/src/main/java/org/elasticsearch/xpack/qa/sql/jdbc/JdbcAssert.java index c4c8a6bbfee..3cfed3752e0 100644 --- a/qa/sql/src/main/java/org/elasticsearch/xpack/qa/sql/jdbc/JdbcAssert.java +++ b/qa/sql/src/main/java/org/elasticsearch/xpack/qa/sql/jdbc/JdbcAssert.java @@ -123,16 +123,16 @@ public class JdbcAssert { int type = metaData.getColumnType(column); - String msg = format(Locale.ROOT, "Different result for column [" + metaData.getColumnName(column) + "], entry [" + count - + "]; " + "expected %s but was %s", expectedObject, actualObject); + String msg = format(Locale.ROOT, "Different result for column [" + metaData.getColumnName(column) + "], " + + "entry [" + (count + 1) + "]"); // handle nulls first if (expectedObject == null || actualObject == null) { - assertEquals(expectedObject, actualObject); + assertEquals(msg, expectedObject, actualObject); } // then timestamp else if (type == Types.TIMESTAMP || type == Types.TIMESTAMP_WITH_TIMEZONE) { - assertEquals(getTime(expected, column), getTime(actual, column)); + assertEquals(msg, getTime(expected, column), getTime(actual, column)); } // and floats/doubles else if (type == Types.DOUBLE) { diff --git a/qa/sql/src/main/resources/setup_mock_metadata_get_columns.sql b/qa/sql/src/main/resources/setup_mock_metadata_get_columns.sql index 1d1aef14a80..32a5874e219 100644 --- a/qa/sql/src/main/resources/setup_mock_metadata_get_columns.sql +++ b/qa/sql/src/main/resources/setup_mock_metadata_get_columns.sql @@ -23,23 +23,28 @@ CREATE TABLE mock ( IS_AUTOINCREMENT VARCHAR, IS_GENERATEDCOLUMN VARCHAR ) AS -SELECT '', 'test1', 'name', 12, 'VARCHAR', 2147483647, null, null, null, +SELECT null, 'test1', 'name', 12, 'TEXT', 0, null, null, null, 1, -- columnNullable - null, null, null, null, null, 1, 'YES', null, null, null, null, '', '' + null, null, 12, null, 2147483647, 1, 'YES', null, null, null, null, 'NO', 'NO' FROM DUAL UNION ALL -SELECT '', 'test2', 'date', 93, 'TIMESTAMP', 19, null, null, null, +SELECT null, 'test1', 'name.keyword', 12, 'KEYWORD', 0, null, null, null, 1, -- columnNullable - null, null, null, null, null, 1, 'YES', null, null, null, null, '', '' + null, null, 12, null, 2147483647, 1, 'YES', null, null, null, null, 'NO', 'NO' FROM DUAL UNION ALL -SELECT '', 'test2', 'float', 7, 'REAL', 7, null, null, 2, +SELECT null, 'test2', 'date', 93, 'DATE', 20, null, null, null, 1, -- columnNullable - null, null, null, null, null, 2, 'YES', null, null, null, null, '', '' + null, null, 93, null, null, 1, 'YES', null, null, null, null, 'NO', 'NO' FROM DUAL UNION ALL -SELECT '', 'test2', 'number', -5, 'BIGINT', 19, null, null, 10, +SELECT null, 'test2', 'float', 7, 'FLOAT', 15, null, null, 2, 1, -- columnNullable - null, null, null, null, null, 3, 'YES', null, null, null, null, '', '' + null, null, 7, null, null, 2, 'YES', null, null, null, null, 'NO', 'NO' +FROM DUAL +UNION ALL +SELECT null, 'test2', 'number', -5, 'LONG', 20, null, null, 10, + 1, -- columnNullable + null, null, -5, null, null, 3, 'YES', null, null, null, null, 'NO', 'NO' FROM DUAL ;