SQL: Replace ListTable transport with SQL command (elastic/x-pack-elasticsearch#3675)

Introduce system commands as alternative to meta HTTP endpoints
Pass in cluster name
Use 'BASE TABLE' instead of 'INDEX' when describing a table to stick
with the SQL terminology

Original commit: elastic/x-pack-elasticsearch@600312b8f7
This commit is contained in:
Costin Leau 2018-01-27 11:54:19 +02:00 committed by GitHub
parent dc40562be6
commit e929d16d76
45 changed files with 1665 additions and 1634 deletions

View File

@ -187,30 +187,6 @@ http://www.joda.org/joda-time/apidocs/org/joda/time/DateTimeZone.html[here].
[[sql-rest-metadata]]
SQL can only work with a subset of Elasticsearch indices. To get the list of
indices that are available to the user execute:
[source,js]
--------------------------------------------------
POST /_xpack/sql/tables
{
"table_pattern": "lib%"
}
--------------------------------------------------
// CONSOLE
// TEST[setup:library]
Which returns:
[source,js]
--------------------------------------------------
{
"tables": [ "library" ]
}
--------------------------------------------------
// TESTRESPONSE
To get the list of fields that are supported in SQL execute:
[source,js]

View File

@ -481,7 +481,6 @@ public class AuthorizationService extends AbstractComponent {
action.equals("indices:data/write/reindex") ||
action.equals("indices:data/read/sql") ||
action.equals("indices:data/read/sql/translate") ||
action.equals("indices:admin/sql/tables") ||
action.equals("indices:admin/sql/columns") ;
}

View File

@ -6,15 +6,16 @@
package org.elasticsearch.xpack.sql.jdbc.jdbc;
import org.elasticsearch.xpack.sql.client.shared.ObjectUtils;
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.client.shared.Version;
import org.elasticsearch.xpack.sql.plugin.MetaColumnInfo;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.JDBCType;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
@ -699,42 +700,9 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
@Override
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
List<ColumnInfo> info = columnInfo("TABLES",
"TABLE_CAT", //0
"TABLE_SCHEM", //1
"TABLE_NAME", //2
"TABLE_TYPE", //3
"REMARKS", //4
"TYPE_CAT", //5
"TYPE_SCHEM", //6
"TYPE_NAME", //7
"SELF_REFERENCING_COL_NAME", //8
"REF_GENERATION"); //9
// 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();
List<String> tables = con.client.metaInfoTables(tableNamePattern);
Object[][] data = new Object[tables.size()][];
for (int i = 0; i < data.length; i++) {
data[i] = new Object[10];
Object[] row = data[i];
row[0] = cat;
row[1] = "";
row[2] = tables.get(i);
row[3] = "TABLE";
row[4] = "";
row[5] = null;
row[6] = null;
row[7] = null;
row[8] = null;
row[9] = null;
}
return memorySet(con.cfg, info, data);
PreparedStatement ps = con.prepareStatement("SYS TABLES LIKE ?");
ps.setString(1, tableNamePattern != null ? tableNamePattern.trim() : "%");
return ps.executeQuery();
}
@Override
@ -886,27 +854,7 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
@Override
public ResultSet getTypeInfo() throws SQLException {
return emptySet(con.cfg,
"TYPE_INFO",
"TYPE_NAME",
"DATA_TYPE", int.class,
"PRECISION", int.class,
"LITERAL_PREFIX",
"LITERAL_SUFFIX",
"CREATE_PARAMS",
"NULLABLE", short.class,
"CASE_SENSITIVE", boolean.class,
"SEARCHABLE", short.class,
"UNSIGNED_ATTRIBUTE", boolean.class,
"FIXED_PREC_SCALE", boolean.class,
"AUTO_INCREMENT", boolean.class,
"LOCAL_TYPE_NAME",
"MINIMUM_SCALE", short.class,
"MAXIMUM_SCALE", short.class,
"SQL_DATA_TYPE", int.class,
"SQL_DATETIME_SUB", int.class,
"NUM_PREC_RADIX", int.class
);
return con.createStatement().executeQuery("SYS TYPES");
}
@Override

View File

@ -64,7 +64,8 @@ class PreparedQuery {
for (int i = 0; i < fragments.size(); i++) {
sb.append(fragments.get(i));
if (i < params.length) {
sb.append(params[i]);
// TODO: this needs conversion
sb.append(params[i].value);
}
}

View File

@ -15,7 +15,6 @@ 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.SqlListTablesRequest;
import org.elasticsearch.xpack.sql.plugin.SqlQueryRequest;
import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse;
import org.joda.time.DateTimeZone;
@ -78,10 +77,6 @@ public class JdbcHttpClient {
return new InfoResponse(mainResponse.getClusterName().value(), mainResponse.getVersion().major, mainResponse.getVersion().minor);
}
public List<String> metaInfoTables(String pattern) throws SQLException {
return httpClient.listTables(new SqlListTablesRequest(AbstractSqlRequest.Mode.JDBC, pattern)).getTables();
}
public List<MetaColumnInfo> metaInfoColumns(String tablePattern, String columnPattern) throws SQLException {
return httpClient.listColumns(new SqlListColumnsRequest(AbstractSqlRequest.Mode.JDBC, tablePattern, columnPattern)).getColumns();
}

View File

@ -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 SqlListTablesAction extends Action<SqlListTablesRequest, SqlListTablesResponse, SqlListTablesRequestBuilder> {
public static final SqlListTablesAction INSTANCE = new SqlListTablesAction();
public static final String NAME = "indices:admin/sql/tables";
public static final String REST_ENDPOINT = "/_xpack/sql/tables";
private SqlListTablesAction() {
super(NAME);
}
@Override
public SqlListTablesRequestBuilder newRequestBuilder(ElasticsearchClient client) {
return new SqlListTablesRequestBuilder(client, this);
}
@Override
public SqlListTablesResponse newResponse() {
return new SqlListTablesResponse();
}
}

View File

@ -1,108 +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.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 indices
* <p>
* It needs to be CompositeIndicesRequest because we resolve wildcards a non-standard SQL
* manner
*/
public class SqlListTablesRequest extends AbstractSqlRequest implements ToXContentObject, CompositeIndicesRequest {
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<SqlListTablesRequest, Mode> PARSER = new ConstructingObjectParser<>("sql_list_tables",
true,
(objects, mode) -> new SqlListTablesRequest(
mode,
(String) objects[0]));
static {
PARSER.declareString(optionalConstructorArg(), new ParseField("table_pattern"));
}
private String pattern;
public SqlListTablesRequest() {
}
public SqlListTablesRequest(Mode mode, String pattern) {
super(mode);
this.pattern = pattern;
}
public SqlListTablesRequest(StreamInput in) throws IOException {
super(in);
this.pattern = in.readOptionalString();
}
/**
* The pattern for the results
*/
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeOptionalString(pattern);
}
@Override
public String getDescription() {
return "SQL List Tables[" + getPattern() + "]";
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
{
if (pattern != null) {
builder.field("table_pattern", pattern);
}
}
return builder.endObject();
}
public static SqlListTablesRequest fromXContent(XContentParser parser, Mode mode) {
return PARSER.apply(parser, mode);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!super.equals(o)) return false;
SqlListTablesRequest that = (SqlListTablesRequest) o;
return Objects.equals(pattern, that.pattern);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), pattern);
}
}

View File

@ -1,22 +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 SqlListTablesRequestBuilder extends
ActionRequestBuilder<SqlListTablesRequest, SqlListTablesResponse, SqlListTablesRequestBuilder> {
public SqlListTablesRequestBuilder(ElasticsearchClient client, SqlListTablesAction action) {
super(client, action, new SqlListTablesRequest());
}
public SqlListTablesRequestBuilder pattern(String pattern) {
request.setPattern(pattern);
return this;
}
}

View File

@ -1,105 +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 SqlListTablesResponse extends ActionResponse implements ToXContentObject {
@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<SqlListTablesResponse, Void> PARSER =
new ConstructingObjectParser<>("sql_list_tables", true,
objects -> new SqlListTablesResponse((List<String>) objects[0]));
public static final ParseField TABLES = new ParseField("tables");
static {
PARSER.declareStringArray(optionalConstructorArg(), TABLES);
}
private List<String> tables;
public SqlListTablesResponse() {
}
public SqlListTablesResponse(List<String> tables) {
this.tables = tables;
}
/**
* 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<String> getTables() {
return tables;
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
tables = in.readList(StreamInput::readString);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeStringList(tables);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
{
builder.startArray("tables");
{
for (String table : tables) {
builder.value(table);
}
}
builder.endArray();
}
return builder.endObject();
}
public static SqlListTablesResponse 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;
SqlListTablesResponse that = (SqlListTablesResponse) o;
return Objects.equals(tables, that.tables);
}
@Override
public int hashCode() {
return Objects.hash(tables);
}
@Override
public String toString() {
return Strings.toString(this);
}
}

View File

@ -1,51 +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 SqlListTablesRequestTests extends AbstractSerializingTestCase<SqlListTablesRequest> {
public AbstractSqlRequest.Mode testMode;
@Before
public void setup() {
testMode = randomFrom(AbstractSqlRequest.Mode.values());
}
@Override
protected SqlListTablesRequest createTestInstance() {
return new SqlListTablesRequest(testMode, randomAlphaOfLength(10));
}
@Override
protected Writeable.Reader<SqlListTablesRequest> instanceReader() {
return SqlListTablesRequest::new;
}
@Override
protected SqlListTablesRequest doParseInstance(XContentParser parser) {
return SqlListTablesRequest.fromXContent(parser, testMode);
}
@Override
protected SqlListTablesRequest mutateInstance(SqlListTablesRequest instance) throws IOException {
@SuppressWarnings("unchecked")
Consumer<SqlListTablesRequest> mutator = randomFrom(
request -> request.mode(randomValueOtherThan(request.mode(), () -> randomFrom(AbstractSqlRequest.Mode.values()))),
request -> request.setPattern(randomValueOtherThan(request.getPattern(), () -> randomAlphaOfLength(10)))
);
SqlListTablesRequest newRequest = new SqlListTablesRequest(instance.mode(), instance.getPattern());
mutator.accept(newRequest);
return newRequest;
}
}

View File

@ -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.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
import java.util.ArrayList;
import java.util.List;
public class SqlListTablesResponseTests extends AbstractStreamableXContentTestCase<SqlListTablesResponse> {
@Override
protected SqlListTablesResponse createTestInstance() {
int tableCount = between(1, 10);
List<String> tables = new ArrayList<>(tableCount);
for (int i = 0; i < tableCount; i++) {
tables.add(randomAlphaOfLength(10));
}
return new SqlListTablesResponse(tables);
}
@Override
protected SqlListTablesResponse createBlankInstance() {
return new SqlListTablesResponse();
}
@Override
protected SqlListTablesResponse doParseInstance(XContentParser parser) {
return SqlListTablesResponse.fromXContent(parser);
}
}

View File

@ -28,9 +28,6 @@ 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.SqlListTablesAction;
import org.elasticsearch.xpack.sql.plugin.SqlListTablesRequest;
import org.elasticsearch.xpack.sql.plugin.SqlListTablesResponse;
import org.elasticsearch.xpack.sql.plugin.SqlQueryAction;
import org.elasticsearch.xpack.sql.plugin.SqlQueryRequest;
import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse;
@ -91,10 +88,6 @@ public class HttpClient {
return response.isSucceeded();
}
public SqlListTablesResponse listTables(SqlListTablesRequest request) throws SQLException {
return post(SqlListTablesAction.REST_ENDPOINT, request, SqlListTablesResponse::fromXContent);
}
public SqlListColumnsResponse listColumns(SqlListColumnsRequest request) throws SQLException {
return post(SqlListColumnsAction.REST_ENDPOINT, request, SqlListColumnsResponse::fromXContent);
}

View File

@ -56,6 +56,10 @@ 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 TYPES #sysTypes
;
query
@ -264,8 +268,8 @@ nonReserved
| PARSED | PHYSICAL | PLAN
| QUERY
| RLIKE
| SCHEMAS | SHOW
| TABLES | TEXT
| SCHEMAS | SHOW | SYS
| TABLES | TEXT | TYPES
| VERIFY
;
@ -317,15 +321,17 @@ OUTER: 'OUTER';
PARSED: 'PARSED';
PHYSICAL: 'PHYSICAL';
PLAN: 'PLAN';
QUERY: 'QUERY';
RIGHT: 'RIGHT';
RLIKE: 'RLIKE';
QUERY: 'QUERY';
SCHEMAS: 'SCHEMAS';
SELECT: 'SELECT';
SHOW: 'SHOW';
SYS: 'SYS';
TABLES: 'TABLES';
TEXT: 'TEXT';
TRUE: 'TRUE';
TYPES: 'TYPES';
USING: 'USING';
VERIFY: 'VERIFY';
WHERE: 'WHERE';

View File

@ -49,45 +49,47 @@ OUTER=48
PARSED=49
PHYSICAL=50
PLAN=51
QUERY=52
RIGHT=53
RLIKE=54
RIGHT=52
RLIKE=53
QUERY=54
SCHEMAS=55
SELECT=56
SHOW=57
TABLES=58
TEXT=59
TRUE=60
USING=61
VERIFY=62
WHERE=63
WITH=64
EQ=65
NEQ=66
LT=67
LTE=68
GT=69
GTE=70
PLUS=71
MINUS=72
ASTERISK=73
SLASH=74
PERCENT=75
CONCAT=76
DOT=77
STRING=78
INTEGER_VALUE=79
DECIMAL_VALUE=80
IDENTIFIER=81
DIGIT_IDENTIFIER=82
TABLE_IDENTIFIER=83
QUOTED_IDENTIFIER=84
BACKQUOTED_IDENTIFIER=85
SIMPLE_COMMENT=86
BRACKETED_COMMENT=87
WS=88
UNRECOGNIZED=89
DELIMITER=90
SYS=58
TABLES=59
TEXT=60
TRUE=61
TYPES=62
USING=63
VERIFY=64
WHERE=65
WITH=66
EQ=67
NEQ=68
LT=69
LTE=70
GT=71
GTE=72
PLUS=73
MINUS=74
ASTERISK=75
SLASH=76
PERCENT=77
CONCAT=78
DOT=79
STRING=80
INTEGER_VALUE=81
DECIMAL_VALUE=82
IDENTIFIER=83
DIGIT_IDENTIFIER=84
TABLE_IDENTIFIER=85
QUOTED_IDENTIFIER=86
BACKQUOTED_IDENTIFIER=87
SIMPLE_COMMENT=88
BRACKETED_COMMENT=89
WS=90
UNRECOGNIZED=91
DELIMITER=92
'('=1
')'=2
','=3
@ -139,28 +141,30 @@ DELIMITER=90
'PARSED'=49
'PHYSICAL'=50
'PLAN'=51
'QUERY'=52
'RIGHT'=53
'RLIKE'=54
'RIGHT'=52
'RLIKE'=53
'QUERY'=54
'SCHEMAS'=55
'SELECT'=56
'SHOW'=57
'TABLES'=58
'TEXT'=59
'TRUE'=60
'USING'=61
'VERIFY'=62
'WHERE'=63
'WITH'=64
'='=65
'<'=67
'<='=68
'>'=69
'>='=70
'+'=71
'-'=72
'*'=73
'/'=74
'%'=75
'||'=76
'.'=77
'SYS'=58
'TABLES'=59
'TEXT'=60
'TRUE'=61
'TYPES'=62
'USING'=63
'VERIFY'=64
'WHERE'=65
'WITH'=66
'='=67
'<'=69
'<='=70
'>'=71
'>='=72
'+'=73
'-'=74
'*'=75
'/'=76
'%'=77
'||'=78
'.'=79

View File

@ -49,44 +49,46 @@ OUTER=48
PARSED=49
PHYSICAL=50
PLAN=51
QUERY=52
RIGHT=53
RLIKE=54
RIGHT=52
RLIKE=53
QUERY=54
SCHEMAS=55
SELECT=56
SHOW=57
TABLES=58
TEXT=59
TRUE=60
USING=61
VERIFY=62
WHERE=63
WITH=64
EQ=65
NEQ=66
LT=67
LTE=68
GT=69
GTE=70
PLUS=71
MINUS=72
ASTERISK=73
SLASH=74
PERCENT=75
CONCAT=76
DOT=77
STRING=78
INTEGER_VALUE=79
DECIMAL_VALUE=80
IDENTIFIER=81
DIGIT_IDENTIFIER=82
TABLE_IDENTIFIER=83
QUOTED_IDENTIFIER=84
BACKQUOTED_IDENTIFIER=85
SIMPLE_COMMENT=86
BRACKETED_COMMENT=87
WS=88
UNRECOGNIZED=89
SYS=58
TABLES=59
TEXT=60
TRUE=61
TYPES=62
USING=63
VERIFY=64
WHERE=65
WITH=66
EQ=67
NEQ=68
LT=69
LTE=70
GT=71
GTE=72
PLUS=73
MINUS=74
ASTERISK=75
SLASH=76
PERCENT=77
CONCAT=78
DOT=79
STRING=80
INTEGER_VALUE=81
DECIMAL_VALUE=82
IDENTIFIER=83
DIGIT_IDENTIFIER=84
TABLE_IDENTIFIER=85
QUOTED_IDENTIFIER=86
BACKQUOTED_IDENTIFIER=87
SIMPLE_COMMENT=88
BRACKETED_COMMENT=89
WS=90
UNRECOGNIZED=91
'('=1
')'=2
','=3
@ -138,28 +140,30 @@ UNRECOGNIZED=89
'PARSED'=49
'PHYSICAL'=50
'PLAN'=51
'QUERY'=52
'RIGHT'=53
'RLIKE'=54
'RIGHT'=52
'RLIKE'=53
'QUERY'=54
'SCHEMAS'=55
'SELECT'=56
'SHOW'=57
'TABLES'=58
'TEXT'=59
'TRUE'=60
'USING'=61
'VERIFY'=62
'WHERE'=63
'WITH'=64
'='=65
'<'=67
'<='=68
'>'=69
'>='=70
'+'=71
'-'=72
'*'=73
'/'=74
'%'=75
'||'=76
'.'=77
'SYS'=58
'TABLES'=59
'TEXT'=60
'TRUE'=61
'TYPES'=62
'USING'=63
'VERIFY'=64
'WHERE'=65
'WITH'=66
'='=67
'<'=69
'<='=70
'>'=71
'>='=72
'+'=73
'-'=74
'*'=75
'/'=76
'%'=77
'||'=78
'.'=79

View File

@ -38,7 +38,19 @@ import static java.util.Collections.emptyList;
public class IndexResolver {
public enum IndexType {
INDEX, ALIAS;
INDEX("BASE TABLE"),
ALIAS("ALIAS");
private final String toSql;
IndexType(String sql) {
this.toSql = sql;
}
public String toSql() {
return toSql;
}
}
public static class IndexInfo {
@ -85,9 +97,16 @@ public class IndexResolver {
}
private final Client client;
private final String clusterName;
public IndexResolver(Client client) {
public IndexResolver(Client client, String clusterName) {
this.client = client;
this.clusterName = clusterName;
}
public String clusterName() {
return clusterName;
}
/**
@ -101,7 +120,7 @@ public class IndexResolver {
.aliases(indexWildcard)
.indicesOptions(IndicesOptions.lenientExpandOpen());
client.admin().indices().getAliases(aliasRequest, ActionListener.wrap(aliases ->
client.admin().indices().getAliases(aliasRequest, ActionListener.wrap(aliases ->
resolveIndices(indexWildcard, javaRegex, aliases, listener),
ex -> {
// with security, two exception can be thrown:
@ -117,7 +136,7 @@ public class IndexResolver {
}));
}
private void resolveIndices(String indexWildcard, String javaRegex, GetAliasesResponse aliases,
private void resolveIndices(String indexWildcard, String javaRegex, GetAliasesResponse aliases,
ActionListener<Set<IndexInfo>> listener) {
GetIndexRequest indexRequest = new GetIndexRequest()
.local(true)

View File

@ -12,6 +12,8 @@ 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.SysTablesContext;
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.SysTypesContext;
import org.elasticsearch.xpack.sql.plan.TableIdentifier;
import org.elasticsearch.xpack.sql.plan.logical.command.Command;
import org.elasticsearch.xpack.sql.plan.logical.command.Debug;
@ -20,6 +22,8 @@ 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.SysTables;
import org.elasticsearch.xpack.sql.plan.logical.command.sys.SysTypes;
import org.elasticsearch.xpack.sql.tree.Location;
import org.joda.time.DateTimeZone;
@ -120,4 +124,14 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
TableIdentifier identifier = visitTableIdentifier(ctx.tableIdentifier());
return new ShowColumns(source(ctx), identifier.index());
}
@Override
public SysTables visitSysTables(SysTablesContext ctx) {
return new SysTables(source(ctx), visitPattern(ctx.pattern()));
}
@Override
public SysTypes visitSysTypes(SysTypesContext ctx) {
return new SysTypes(source(ctx));
}
}

View File

@ -124,6 +124,42 @@ class SqlBaseBaseListener implements SqlBaseListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitShowSchemas(SqlBaseParser.ShowSchemasContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterSysTables(SqlBaseParser.SysTablesContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitSysTables(SqlBaseParser.SysTablesContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterSysColumns(SqlBaseParser.SysColumnsContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitSysColumns(SqlBaseParser.SysColumnsContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterSysTypes(SqlBaseParser.SysTypesContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitSysTypes(SqlBaseParser.SysTypesContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -79,6 +79,27 @@ class SqlBaseBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements SqlBa
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitShowSchemas(SqlBaseParser.ShowSchemasContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSysTables(SqlBaseParser.SysTablesContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSysColumns(SqlBaseParser.SysColumnsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSysTypes(SqlBaseParser.SysTypesContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -28,13 +28,14 @@ class SqlBaseLexer extends Lexer {
FALSE=24, FORMAT=25, FROM=26, FULL=27, FUNCTIONS=28, GRAPHVIZ=29, GROUP=30,
HAVING=31, IN=32, INNER=33, IS=34, JOIN=35, LEFT=36, LIKE=37, LIMIT=38,
MAPPED=39, MATCH=40, NATURAL=41, NOT=42, NULL=43, ON=44, OPTIMIZED=45,
OR=46, ORDER=47, OUTER=48, PARSED=49, PHYSICAL=50, PLAN=51, QUERY=52,
RIGHT=53, RLIKE=54, SCHEMAS=55, SELECT=56, SHOW=57, TABLES=58, TEXT=59,
TRUE=60, USING=61, VERIFY=62, WHERE=63, WITH=64, EQ=65, NEQ=66, LT=67,
LTE=68, GT=69, GTE=70, PLUS=71, MINUS=72, ASTERISK=73, SLASH=74, PERCENT=75,
CONCAT=76, DOT=77, STRING=78, INTEGER_VALUE=79, DECIMAL_VALUE=80, IDENTIFIER=81,
DIGIT_IDENTIFIER=82, TABLE_IDENTIFIER=83, QUOTED_IDENTIFIER=84, BACKQUOTED_IDENTIFIER=85,
SIMPLE_COMMENT=86, BRACKETED_COMMENT=87, WS=88, UNRECOGNIZED=89;
OR=46, ORDER=47, OUTER=48, PARSED=49, PHYSICAL=50, PLAN=51, RIGHT=52,
RLIKE=53, QUERY=54, SCHEMAS=55, SELECT=56, SHOW=57, SYS=58, TABLES=59,
TEXT=60, TRUE=61, TYPES=62, USING=63, VERIFY=64, WHERE=65, WITH=66, EQ=67,
NEQ=68, LT=69, LTE=70, GT=71, GTE=72, PLUS=73, MINUS=74, ASTERISK=75,
SLASH=76, PERCENT=77, CONCAT=78, DOT=79, STRING=80, INTEGER_VALUE=81,
DECIMAL_VALUE=82, IDENTIFIER=83, DIGIT_IDENTIFIER=84, TABLE_IDENTIFIER=85,
QUOTED_IDENTIFIER=86, BACKQUOTED_IDENTIFIER=87, SIMPLE_COMMENT=88, BRACKETED_COMMENT=89,
WS=90, UNRECOGNIZED=91;
public static String[] modeNames = {
"DEFAULT_MODE"
};
@ -46,13 +47,13 @@ class SqlBaseLexer extends Lexer {
"FORMAT", "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING",
"IN", "INNER", "IS", "JOIN", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH",
"NATURAL", "NOT", "NULL", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED",
"PHYSICAL", "PLAN", "QUERY", "RIGHT", "RLIKE", "SCHEMAS", "SELECT", "SHOW",
"TABLES", "TEXT", "TRUE", "USING", "VERIFY", "WHERE", "WITH", "EQ", "NEQ",
"LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT",
"CONCAT", "DOT", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "IDENTIFIER",
"DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER",
"EXPONENT", "DIGIT", "LETTER", "SIMPLE_COMMENT", "BRACKETED_COMMENT",
"WS", "UNRECOGNIZED"
"PHYSICAL", "PLAN", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SELECT", "SHOW",
"SYS", "TABLES", "TEXT", "TRUE", "TYPES", "USING", "VERIFY", "WHERE",
"WITH", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK",
"SLASH", "PERCENT", "CONCAT", "DOT", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE",
"IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER",
"BACKQUOTED_IDENTIFIER", "EXPONENT", "DIGIT", "LETTER", "SIMPLE_COMMENT",
"BRACKETED_COMMENT", "WS", "UNRECOGNIZED"
};
private static final String[] _LITERAL_NAMES = {
@ -63,10 +64,11 @@ class SqlBaseLexer extends Lexer {
"'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'", "'GROUP'", "'HAVING'", "'IN'",
"'INNER'", "'IS'", "'JOIN'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'",
"'MATCH'", "'NATURAL'", "'NOT'", "'NULL'", "'ON'", "'OPTIMIZED'", "'OR'",
"'ORDER'", "'OUTER'", "'PARSED'", "'PHYSICAL'", "'PLAN'", "'QUERY'", "'RIGHT'",
"'RLIKE'", "'SCHEMAS'", "'SELECT'", "'SHOW'", "'TABLES'", "'TEXT'", "'TRUE'",
"'USING'", "'VERIFY'", "'WHERE'", "'WITH'", "'='", null, "'<'", "'<='",
"'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", "'||'", "'.'"
"'ORDER'", "'OUTER'", "'PARSED'", "'PHYSICAL'", "'PLAN'", "'RIGHT'", "'RLIKE'",
"'QUERY'", "'SCHEMAS'", "'SELECT'", "'SHOW'", "'SYS'", "'TABLES'", "'TEXT'",
"'TRUE'", "'TYPES'", "'USING'", "'VERIFY'", "'WHERE'", "'WITH'", "'='",
null, "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'",
"'||'", "'.'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, "ALL", "ANALYZE", "ANALYZED", "AND", "ANY", "AS",
@ -75,12 +77,13 @@ class SqlBaseLexer extends Lexer {
"FORMAT", "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING",
"IN", "INNER", "IS", "JOIN", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH",
"NATURAL", "NOT", "NULL", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED",
"PHYSICAL", "PLAN", "QUERY", "RIGHT", "RLIKE", "SCHEMAS", "SELECT", "SHOW",
"TABLES", "TEXT", "TRUE", "USING", "VERIFY", "WHERE", "WITH", "EQ", "NEQ",
"LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT",
"CONCAT", "DOT", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "IDENTIFIER",
"DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER",
"SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS", "UNRECOGNIZED"
"PHYSICAL", "PLAN", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SELECT", "SHOW",
"SYS", "TABLES", "TEXT", "TRUE", "TYPES", "USING", "VERIFY", "WHERE",
"WITH", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK",
"SLASH", "PERCENT", "CONCAT", "DOT", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE",
"IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER",
"BACKQUOTED_IDENTIFIER", "SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS",
"UNRECOGNIZED"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@ -137,7 +140,7 @@ class SqlBaseLexer extends Lexer {
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2[\u0301\b\1\4\2\t"+
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2]\u030f\b\1\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"+
@ -147,258 +150,263 @@ class SqlBaseLexer extends Lexer {
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\3\2\3\2\3\3\3"+
"\3\3\4\3\4\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7"+
"\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3"+
"\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\16\3"+
"\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3"+
"\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3"+
"\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3"+
"\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3"+
"\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3"+
"\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3"+
"\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3"+
"\33\3\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3"+
"\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3"+
"\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3"+
"\"\3#\3#\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3"+
"\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3"+
"*\3*\3+\3+\3+\3+\3,\3,\3,\3,\3,\3-\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3.\3"+
".\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\61\3\61"+
"\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\63\3\63"+
"\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\65\3\65\3\66"+
"\3\66\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\3\67\38\38\38\38\3"+
"8\38\38\38\39\39\39\39\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;\3;\3;\3"+
"<\3<\3<\3<\3<\3=\3=\3=\3=\3=\3>\3>\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3?\3"+
"@\3@\3@\3@\3@\3@\3A\3A\3A\3A\3A\3B\3B\3C\3C\3C\3C\3C\3C\3C\5C\u0243\n"+
"C\3D\3D\3E\3E\3E\3F\3F\3G\3G\3G\3H\3H\3I\3I\3J\3J\3K\3K\3L\3L\3M\3M\3"+
"M\3N\3N\3O\3O\3O\3O\7O\u0262\nO\fO\16O\u0265\13O\3O\3O\3P\6P\u026a\nP"+
"\rP\16P\u026b\3Q\6Q\u026f\nQ\rQ\16Q\u0270\3Q\3Q\7Q\u0275\nQ\fQ\16Q\u0278"+
"\13Q\3Q\3Q\6Q\u027c\nQ\rQ\16Q\u027d\3Q\6Q\u0281\nQ\rQ\16Q\u0282\3Q\3Q"+
"\7Q\u0287\nQ\fQ\16Q\u028a\13Q\5Q\u028c\nQ\3Q\3Q\3Q\3Q\6Q\u0292\nQ\rQ\16"+
"Q\u0293\3Q\3Q\5Q\u0298\nQ\3R\3R\5R\u029c\nR\3R\3R\3R\7R\u02a1\nR\fR\16"+
"R\u02a4\13R\3S\3S\3S\3S\6S\u02aa\nS\rS\16S\u02ab\3T\3T\3T\3T\6T\u02b2"+
"\nT\rT\16T\u02b3\3U\3U\3U\3U\7U\u02ba\nU\fU\16U\u02bd\13U\3U\3U\3V\3V"+
"\3V\3V\7V\u02c5\nV\fV\16V\u02c8\13V\3V\3V\3W\3W\5W\u02ce\nW\3W\6W\u02d1"+
"\nW\rW\16W\u02d2\3X\3X\3Y\3Y\3Z\3Z\3Z\3Z\7Z\u02dd\nZ\fZ\16Z\u02e0\13Z"+
"\3Z\5Z\u02e3\nZ\3Z\5Z\u02e6\nZ\3Z\3Z\3[\3[\3[\3[\3[\7[\u02ef\n[\f[\16"+
"[\u02f2\13[\3[\3[\3[\3[\3[\3\\\6\\\u02fa\n\\\r\\\16\\\u02fb\3\\\3\\\3"+
"]\3]\3\u02f0\2^\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31"+
"\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65"+
"\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64"+
"g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089"+
"F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009d"+
"P\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00ad\2\u00af\2\u00b1"+
"\2\u00b3X\u00b5Y\u00b7Z\u00b9[\3\2\f\3\2))\4\2BBaa\5\2<<BBaa\3\2$$\3\2"+
"bb\4\2--//\3\2\62;\3\2C\\\4\2\f\f\17\17\5\2\13\f\17\17\"\"\u0323\2\3\3"+
"\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2"+
"\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3"+
"\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2"+
"%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61"+
"\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2"+
"\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I"+
"\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2"+
"\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2"+
"\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o"+
"\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2"+
"\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\3"+
"\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+
"\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3"+
"\n\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r"+
"\3\r\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+
"\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22"+
"\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
"\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25"+
"\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27"+
"\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+
"\3\31\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33"+
"\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35"+
"\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36"+
"\3\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3"+
"\"\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3"+
"\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3*\3*\3"+
"*\3*\3*\3*\3*\3*\3+\3+\3+\3+\3,\3,\3,\3,\3,\3-\3-\3-\3.\3.\3.\3.\3.\3"+
".\3.\3.\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3"+
"\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3"+
"\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3"+
"\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\3\67\3"+
"8\38\38\38\38\38\38\38\39\39\39\39\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3"+
";\3<\3<\3<\3<\3<\3<\3<\3=\3=\3=\3=\3=\3>\3>\3>\3>\3>\3?\3?\3?\3?\3?\3"+
"?\3@\3@\3@\3@\3@\3@\3A\3A\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3"+
"C\3C\3D\3D\3E\3E\3E\3E\3E\3E\3E\5E\u0251\nE\3F\3F\3G\3G\3G\3H\3H\3I\3"+
"I\3I\3J\3J\3K\3K\3L\3L\3M\3M\3N\3N\3O\3O\3O\3P\3P\3Q\3Q\3Q\3Q\7Q\u0270"+
"\nQ\fQ\16Q\u0273\13Q\3Q\3Q\3R\6R\u0278\nR\rR\16R\u0279\3S\6S\u027d\nS"+
"\rS\16S\u027e\3S\3S\7S\u0283\nS\fS\16S\u0286\13S\3S\3S\6S\u028a\nS\rS"+
"\16S\u028b\3S\6S\u028f\nS\rS\16S\u0290\3S\3S\7S\u0295\nS\fS\16S\u0298"+
"\13S\5S\u029a\nS\3S\3S\3S\3S\6S\u02a0\nS\rS\16S\u02a1\3S\3S\5S\u02a6\n"+
"S\3T\3T\5T\u02aa\nT\3T\3T\3T\7T\u02af\nT\fT\16T\u02b2\13T\3U\3U\3U\3U"+
"\6U\u02b8\nU\rU\16U\u02b9\3V\3V\3V\3V\6V\u02c0\nV\rV\16V\u02c1\3W\3W\3"+
"W\3W\7W\u02c8\nW\fW\16W\u02cb\13W\3W\3W\3X\3X\3X\3X\7X\u02d3\nX\fX\16"+
"X\u02d6\13X\3X\3X\3Y\3Y\5Y\u02dc\nY\3Y\6Y\u02df\nY\rY\16Y\u02e0\3Z\3Z"+
"\3[\3[\3\\\3\\\3\\\3\\\7\\\u02eb\n\\\f\\\16\\\u02ee\13\\\3\\\5\\\u02f1"+
"\n\\\3\\\5\\\u02f4\n\\\3\\\3\\\3]\3]\3]\3]\3]\7]\u02fd\n]\f]\16]\u0300"+
"\13]\3]\3]\3]\3]\3]\3^\6^\u0308\n^\r^\16^\u0309\3^\3^\3_\3_\3\u02fe\2"+
"`\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20"+
"\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37"+
"= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o"+
"9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH"+
"\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1"+
"R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1\2\u00b3\2\u00b5"+
"\2\u00b7Z\u00b9[\u00bb\\\u00bd]\3\2\f\3\2))\4\2BBaa\5\2<<BBaa\3\2$$\3"+
"\2bb\4\2--//\3\2\62;\3\2C\\\4\2\f\f\17\17\5\2\13\f\17\17\"\"\u0331\2\3"+
"\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2"+
"\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31"+
"\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2"+
"\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2"+
"\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2"+
"\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2"+
"I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3"+
"\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2"+
"\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2"+
"o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3"+
"\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085"+
"\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2"+
"\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097"+
"\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2"+
"\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9"+
"\3\2\2\2\2\u00ab\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2"+
"\2\2\u00b9\3\2\2\2\3\u00bb\3\2\2\2\5\u00bd\3\2\2\2\7\u00bf\3\2\2\2\t\u00c1"+
"\3\2\2\2\13\u00c5\3\2\2\2\r\u00cd\3\2\2\2\17\u00d6\3\2\2\2\21\u00da\3"+
"\2\2\2\23\u00de\3\2\2\2\25\u00e1\3\2\2\2\27\u00e5\3\2\2\2\31\u00ed\3\2"+
"\2\2\33\u00f0\3\2\2\2\35\u00f5\3\2\2\2\37\u00fd\3\2\2\2!\u0103\3\2\2\2"+
"#\u0108\3\2\2\2%\u0111\3\2\2\2\'\u011a\3\2\2\2)\u0121\3\2\2\2+\u012c\3"+
"\2\2\2-\u0133\3\2\2\2/\u013b\3\2\2\2\61\u0143\3\2\2\2\63\u0149\3\2\2\2"+
"\65\u0150\3\2\2\2\67\u0155\3\2\2\29\u015a\3\2\2\2;\u0164\3\2\2\2=\u016d"+
"\3\2\2\2?\u0173\3\2\2\2A\u017a\3\2\2\2C\u017d\3\2\2\2E\u0183\3\2\2\2G"+
"\u0186\3\2\2\2I\u018b\3\2\2\2K\u0190\3\2\2\2M\u0195\3\2\2\2O\u019b\3\2"+
"\2\2Q\u01a2\3\2\2\2S\u01a8\3\2\2\2U\u01b0\3\2\2\2W\u01b4\3\2\2\2Y\u01b9"+
"\3\2\2\2[\u01bc\3\2\2\2]\u01c6\3\2\2\2_\u01c9\3\2\2\2a\u01cf\3\2\2\2c"+
"\u01d5\3\2\2\2e\u01dc\3\2\2\2g\u01e5\3\2\2\2i\u01ea\3\2\2\2k\u01f0\3\2"+
"\2\2m\u01f6\3\2\2\2o\u01fc\3\2\2\2q\u0204\3\2\2\2s\u020b\3\2\2\2u\u0210"+
"\3\2\2\2w\u0217\3\2\2\2y\u021c\3\2\2\2{\u0221\3\2\2\2}\u0227\3\2\2\2\177"+
"\u022e\3\2\2\2\u0081\u0234\3\2\2\2\u0083\u0239\3\2\2\2\u0085\u0242\3\2"+
"\2\2\u0087\u0244\3\2\2\2\u0089\u0246\3\2\2\2\u008b\u0249\3\2\2\2\u008d"+
"\u024b\3\2\2\2\u008f\u024e\3\2\2\2\u0091\u0250\3\2\2\2\u0093\u0252\3\2"+
"\2\2\u0095\u0254\3\2\2\2\u0097\u0256\3\2\2\2\u0099\u0258\3\2\2\2\u009b"+
"\u025b\3\2\2\2\u009d\u025d\3\2\2\2\u009f\u0269\3\2\2\2\u00a1\u0297\3\2"+
"\2\2\u00a3\u029b\3\2\2\2\u00a5\u02a5\3\2\2\2\u00a7\u02b1\3\2\2\2\u00a9"+
"\u02b5\3\2\2\2\u00ab\u02c0\3\2\2\2\u00ad\u02cb\3\2\2\2\u00af\u02d4\3\2"+
"\2\2\u00b1\u02d6\3\2\2\2\u00b3\u02d8\3\2\2\2\u00b5\u02e9\3\2\2\2\u00b7"+
"\u02f9\3\2\2\2\u00b9\u02ff\3\2\2\2\u00bb\u00bc\7*\2\2\u00bc\4\3\2\2\2"+
"\u00bd\u00be\7+\2\2\u00be\6\3\2\2\2\u00bf\u00c0\7.\2\2\u00c0\b\3\2\2\2"+
"\u00c1\u00c2\7C\2\2\u00c2\u00c3\7N\2\2\u00c3\u00c4\7N\2\2\u00c4\n\3\2"+
"\2\2\u00c5\u00c6\7C\2\2\u00c6\u00c7\7P\2\2\u00c7\u00c8\7C\2\2\u00c8\u00c9"+
"\7N\2\2\u00c9\u00ca\7[\2\2\u00ca\u00cb\7\\\2\2\u00cb\u00cc\7G\2\2\u00cc"+
"\f\3\2\2\2\u00cd\u00ce\7C\2\2\u00ce\u00cf\7P\2\2\u00cf\u00d0\7C\2\2\u00d0"+
"\u00d1\7N\2\2\u00d1\u00d2\7[\2\2\u00d2\u00d3\7\\\2\2\u00d3\u00d4\7G\2"+
"\2\u00d4\u00d5\7F\2\2\u00d5\16\3\2\2\2\u00d6\u00d7\7C\2\2\u00d7\u00d8"+
"\7P\2\2\u00d8\u00d9\7F\2\2\u00d9\20\3\2\2\2\u00da\u00db\7C\2\2\u00db\u00dc"+
"\7P\2\2\u00dc\u00dd\7[\2\2\u00dd\22\3\2\2\2\u00de\u00df\7C\2\2\u00df\u00e0"+
"\7U\2\2\u00e0\24\3\2\2\2\u00e1\u00e2\7C\2\2\u00e2\u00e3\7U\2\2\u00e3\u00e4"+
"\7E\2\2\u00e4\26\3\2\2\2\u00e5\u00e6\7D\2\2\u00e6\u00e7\7G\2\2\u00e7\u00e8"+
"\7V\2\2\u00e8\u00e9\7Y\2\2\u00e9\u00ea\7G\2\2\u00ea\u00eb\7G\2\2\u00eb"+
"\u00ec\7P\2\2\u00ec\30\3\2\2\2\u00ed\u00ee\7D\2\2\u00ee\u00ef\7[\2\2\u00ef"+
"\32\3\2\2\2\u00f0\u00f1\7E\2\2\u00f1\u00f2\7C\2\2\u00f2\u00f3\7U\2\2\u00f3"+
"\u00f4\7V\2\2\u00f4\34\3\2\2\2\u00f5\u00f6\7E\2\2\u00f6\u00f7\7Q\2\2\u00f7"+
"\u00f8\7N\2\2\u00f8\u00f9\7W\2\2\u00f9\u00fa\7O\2\2\u00fa\u00fb\7P\2\2"+
"\u00fb\u00fc\7U\2\2\u00fc\36\3\2\2\2\u00fd\u00fe\7F\2\2\u00fe\u00ff\7"+
"G\2\2\u00ff\u0100\7D\2\2\u0100\u0101\7W\2\2\u0101\u0102\7I\2\2\u0102 "+
"\3\2\2\2\u0103\u0104\7F\2\2\u0104\u0105\7G\2\2\u0105\u0106\7U\2\2\u0106"+
"\u0107\7E\2\2\u0107\"\3\2\2\2\u0108\u0109\7F\2\2\u0109\u010a\7G\2\2\u010a"+
"\u010b\7U\2\2\u010b\u010c\7E\2\2\u010c\u010d\7T\2\2\u010d\u010e\7K\2\2"+
"\u010e\u010f\7D\2\2\u010f\u0110\7G\2\2\u0110$\3\2\2\2\u0111\u0112\7F\2"+
"\2\u0112\u0113\7K\2\2\u0113\u0114\7U\2\2\u0114\u0115\7V\2\2\u0115\u0116"+
"\7K\2\2\u0116\u0117\7P\2\2\u0117\u0118\7E\2\2\u0118\u0119\7V\2\2\u0119"+
"&\3\2\2\2\u011a\u011b\7G\2\2\u011b\u011c\7U\2\2\u011c\u011d\7E\2\2\u011d"+
"\u011e\7C\2\2\u011e\u011f\7R\2\2\u011f\u0120\7G\2\2\u0120(\3\2\2\2\u0121"+
"\u0122\7G\2\2\u0122\u0123\7Z\2\2\u0123\u0124\7G\2\2\u0124\u0125\7E\2\2"+
"\u0125\u0126\7W\2\2\u0126\u0127\7V\2\2\u0127\u0128\7C\2\2\u0128\u0129"+
"\7D\2\2\u0129\u012a\7N\2\2\u012a\u012b\7G\2\2\u012b*\3\2\2\2\u012c\u012d"+
"\7G\2\2\u012d\u012e\7Z\2\2\u012e\u012f\7K\2\2\u012f\u0130\7U\2\2\u0130"+
"\u0131\7V\2\2\u0131\u0132\7U\2\2\u0132,\3\2\2\2\u0133\u0134\7G\2\2\u0134"+
"\u0135\7Z\2\2\u0135\u0136\7R\2\2\u0136\u0137\7N\2\2\u0137\u0138\7C\2\2"+
"\u0138\u0139\7K\2\2\u0139\u013a\7P\2\2\u013a.\3\2\2\2\u013b\u013c\7G\2"+
"\2\u013c\u013d\7Z\2\2\u013d\u013e\7V\2\2\u013e\u013f\7T\2\2\u013f\u0140"+
"\7C\2\2\u0140\u0141\7E\2\2\u0141\u0142\7V\2\2\u0142\60\3\2\2\2\u0143\u0144"+
"\7H\2\2\u0144\u0145\7C\2\2\u0145\u0146\7N\2\2\u0146\u0147\7U\2\2\u0147"+
"\u0148\7G\2\2\u0148\62\3\2\2\2\u0149\u014a\7H\2\2\u014a\u014b\7Q\2\2\u014b"+
"\u014c\7T\2\2\u014c\u014d\7O\2\2\u014d\u014e\7C\2\2\u014e\u014f\7V\2\2"+
"\u014f\64\3\2\2\2\u0150\u0151\7H\2\2\u0151\u0152\7T\2\2\u0152\u0153\7"+
"Q\2\2\u0153\u0154\7O\2\2\u0154\66\3\2\2\2\u0155\u0156\7H\2\2\u0156\u0157"+
"\7W\2\2\u0157\u0158\7N\2\2\u0158\u0159\7N\2\2\u01598\3\2\2\2\u015a\u015b"+
"\7H\2\2\u015b\u015c\7W\2\2\u015c\u015d\7P\2\2\u015d\u015e\7E\2\2\u015e"+
"\u015f\7V\2\2\u015f\u0160\7K\2\2\u0160\u0161\7Q\2\2\u0161\u0162\7P\2\2"+
"\u0162\u0163\7U\2\2\u0163:\3\2\2\2\u0164\u0165\7I\2\2\u0165\u0166\7T\2"+
"\2\u0166\u0167\7C\2\2\u0167\u0168\7R\2\2\u0168\u0169\7J\2\2\u0169\u016a"+
"\7X\2\2\u016a\u016b\7K\2\2\u016b\u016c\7\\\2\2\u016c<\3\2\2\2\u016d\u016e"+
"\7I\2\2\u016e\u016f\7T\2\2\u016f\u0170\7Q\2\2\u0170\u0171\7W\2\2\u0171"+
"\u0172\7R\2\2\u0172>\3\2\2\2\u0173\u0174\7J\2\2\u0174\u0175\7C\2\2\u0175"+
"\u0176\7X\2\2\u0176\u0177\7K\2\2\u0177\u0178\7P\2\2\u0178\u0179\7I\2\2"+
"\u0179@\3\2\2\2\u017a\u017b\7K\2\2\u017b\u017c\7P\2\2\u017cB\3\2\2\2\u017d"+
"\u017e\7K\2\2\u017e\u017f\7P\2\2\u017f\u0180\7P\2\2\u0180\u0181\7G\2\2"+
"\u0181\u0182\7T\2\2\u0182D\3\2\2\2\u0183\u0184\7K\2\2\u0184\u0185\7U\2"+
"\2\u0185F\3\2\2\2\u0186\u0187\7L\2\2\u0187\u0188\7Q\2\2\u0188\u0189\7"+
"K\2\2\u0189\u018a\7P\2\2\u018aH\3\2\2\2\u018b\u018c\7N\2\2\u018c\u018d"+
"\7G\2\2\u018d\u018e\7H\2\2\u018e\u018f\7V\2\2\u018fJ\3\2\2\2\u0190\u0191"+
"\7N\2\2\u0191\u0192\7K\2\2\u0192\u0193\7M\2\2\u0193\u0194\7G\2\2\u0194"+
"L\3\2\2\2\u0195\u0196\7N\2\2\u0196\u0197\7K\2\2\u0197\u0198\7O\2\2\u0198"+
"\u0199\7K\2\2\u0199\u019a\7V\2\2\u019aN\3\2\2\2\u019b\u019c\7O\2\2\u019c"+
"\u019d\7C\2\2\u019d\u019e\7R\2\2\u019e\u019f\7R\2\2\u019f\u01a0\7G\2\2"+
"\u01a0\u01a1\7F\2\2\u01a1P\3\2\2\2\u01a2\u01a3\7O\2\2\u01a3\u01a4\7C\2"+
"\2\u01a4\u01a5\7V\2\2\u01a5\u01a6\7E\2\2\u01a6\u01a7\7J\2\2\u01a7R\3\2"+
"\2\2\u01a8\u01a9\7P\2\2\u01a9\u01aa\7C\2\2\u01aa\u01ab\7V\2\2\u01ab\u01ac"+
"\7W\2\2\u01ac\u01ad\7T\2\2\u01ad\u01ae\7C\2\2\u01ae\u01af\7N\2\2\u01af"+
"T\3\2\2\2\u01b0\u01b1\7P\2\2\u01b1\u01b2\7Q\2\2\u01b2\u01b3\7V\2\2\u01b3"+
"V\3\2\2\2\u01b4\u01b5\7P\2\2\u01b5\u01b6\7W\2\2\u01b6\u01b7\7N\2\2\u01b7"+
"\u01b8\7N\2\2\u01b8X\3\2\2\2\u01b9\u01ba\7Q\2\2\u01ba\u01bb\7P\2\2\u01bb"+
"Z\3\2\2\2\u01bc\u01bd\7Q\2\2\u01bd\u01be\7R\2\2\u01be\u01bf\7V\2\2\u01bf"+
"\u01c0\7K\2\2\u01c0\u01c1\7O\2\2\u01c1\u01c2\7K\2\2\u01c2\u01c3\7\\\2"+
"\2\u01c3\u01c4\7G\2\2\u01c4\u01c5\7F\2\2\u01c5\\\3\2\2\2\u01c6\u01c7\7"+
"Q\2\2\u01c7\u01c8\7T\2\2\u01c8^\3\2\2\2\u01c9\u01ca\7Q\2\2\u01ca\u01cb"+
"\7T\2\2\u01cb\u01cc\7F\2\2\u01cc\u01cd\7G\2\2\u01cd\u01ce\7T\2\2\u01ce"+
"`\3\2\2\2\u01cf\u01d0\7Q\2\2\u01d0\u01d1\7W\2\2\u01d1\u01d2\7V\2\2\u01d2"+
"\u01d3\7G\2\2\u01d3\u01d4\7T\2\2\u01d4b\3\2\2\2\u01d5\u01d6\7R\2\2\u01d6"+
"\u01d7\7C\2\2\u01d7\u01d8\7T\2\2\u01d8\u01d9\7U\2\2\u01d9\u01da\7G\2\2"+
"\u01da\u01db\7F\2\2\u01dbd\3\2\2\2\u01dc\u01dd\7R\2\2\u01dd\u01de\7J\2"+
"\2\u01de\u01df\7[\2\2\u01df\u01e0\7U\2\2\u01e0\u01e1\7K\2\2\u01e1\u01e2"+
"\7E\2\2\u01e2\u01e3\7C\2\2\u01e3\u01e4\7N\2\2\u01e4f\3\2\2\2\u01e5\u01e6"+
"\7R\2\2\u01e6\u01e7\7N\2\2\u01e7\u01e8\7C\2\2\u01e8\u01e9\7P\2\2\u01e9"+
"h\3\2\2\2\u01ea\u01eb\7S\2\2\u01eb\u01ec\7W\2\2\u01ec\u01ed\7G\2\2\u01ed"+
"\u01ee\7T\2\2\u01ee\u01ef\7[\2\2\u01efj\3\2\2\2\u01f0\u01f1\7T\2\2\u01f1"+
"\u01f2\7K\2\2\u01f2\u01f3\7I\2\2\u01f3\u01f4\7J\2\2\u01f4\u01f5\7V\2\2"+
"\u01f5l\3\2\2\2\u01f6\u01f7\7T\2\2\u01f7\u01f8\7N\2\2\u01f8\u01f9\7K\2"+
"\2\u01f9\u01fa\7M\2\2\u01fa\u01fb\7G\2\2\u01fbn\3\2\2\2\u01fc\u01fd\7"+
"U\2\2\u01fd\u01fe\7E\2\2\u01fe\u01ff\7J\2\2\u01ff\u0200\7G\2\2\u0200\u0201"+
"\7O\2\2\u0201\u0202\7C\2\2\u0202\u0203\7U\2\2\u0203p\3\2\2\2\u0204\u0205"+
"\7U\2\2\u0205\u0206\7G\2\2\u0206\u0207\7N\2\2\u0207\u0208\7G\2\2\u0208"+
"\u0209\7E\2\2\u0209\u020a\7V\2\2\u020ar\3\2\2\2\u020b\u020c\7U\2\2\u020c"+
"\u020d\7J\2\2\u020d\u020e\7Q\2\2\u020e\u020f\7Y\2\2\u020ft\3\2\2\2\u0210"+
"\u0211\7V\2\2\u0211\u0212\7C\2\2\u0212\u0213\7D\2\2\u0213\u0214\7N\2\2"+
"\u0214\u0215\7G\2\2\u0215\u0216\7U\2\2\u0216v\3\2\2\2\u0217\u0218\7V\2"+
"\2\u0218\u0219\7G\2\2\u0219\u021a\7Z\2\2\u021a\u021b\7V\2\2\u021bx\3\2"+
"\2\2\u021c\u021d\7V\2\2\u021d\u021e\7T\2\2\u021e\u021f\7W\2\2\u021f\u0220"+
"\7G\2\2\u0220z\3\2\2\2\u0221\u0222\7W\2\2\u0222\u0223\7U\2\2\u0223\u0224"+
"\7K\2\2\u0224\u0225\7P\2\2\u0225\u0226\7I\2\2\u0226|\3\2\2\2\u0227\u0228"+
"\7X\2\2\u0228\u0229\7G\2\2\u0229\u022a\7T\2\2\u022a\u022b\7K\2\2\u022b"+
"\u022c\7H\2\2\u022c\u022d\7[\2\2\u022d~\3\2\2\2\u022e\u022f\7Y\2\2\u022f"+
"\u0230\7J\2\2\u0230\u0231\7G\2\2\u0231\u0232\7T\2\2\u0232\u0233\7G\2\2"+
"\u0233\u0080\3\2\2\2\u0234\u0235\7Y\2\2\u0235\u0236\7K\2\2\u0236\u0237"+
"\7V\2\2\u0237\u0238\7J\2\2\u0238\u0082\3\2\2\2\u0239\u023a\7?\2\2\u023a"+
"\u0084\3\2\2\2\u023b\u023c\7>\2\2\u023c\u0243\7@\2\2\u023d\u023e\7#\2"+
"\2\u023e\u0243\7?\2\2\u023f\u0240\7>\2\2\u0240\u0241\7?\2\2\u0241\u0243"+
"\7@\2\2\u0242\u023b\3\2\2\2\u0242\u023d\3\2\2\2\u0242\u023f\3\2\2\2\u0243"+
"\u0086\3\2\2\2\u0244\u0245\7>\2\2\u0245\u0088\3\2\2\2\u0246\u0247\7>\2"+
"\2\u0247\u0248\7?\2\2\u0248\u008a\3\2\2\2\u0249\u024a\7@\2\2\u024a\u008c"+
"\3\2\2\2\u024b\u024c\7@\2\2\u024c\u024d\7?\2\2\u024d\u008e\3\2\2\2\u024e"+
"\u024f\7-\2\2\u024f\u0090\3\2\2\2\u0250\u0251\7/\2\2\u0251\u0092\3\2\2"+
"\2\u0252\u0253\7,\2\2\u0253\u0094\3\2\2\2\u0254\u0255\7\61\2\2\u0255\u0096"+
"\3\2\2\2\u0256\u0257\7\'\2\2\u0257\u0098\3\2\2\2\u0258\u0259\7~\2\2\u0259"+
"\u025a\7~\2\2\u025a\u009a\3\2\2\2\u025b\u025c\7\60\2\2\u025c\u009c\3\2"+
"\2\2\u025d\u0263\7)\2\2\u025e\u0262\n\2\2\2\u025f\u0260\7)\2\2\u0260\u0262"+
"\7)\2\2\u0261\u025e\3\2\2\2\u0261\u025f\3\2\2\2\u0262\u0265\3\2\2\2\u0263"+
"\u0261\3\2\2\2\u0263\u0264\3\2\2\2\u0264\u0266\3\2\2\2\u0265\u0263\3\2"+
"\2\2\u0266\u0267\7)\2\2\u0267\u009e\3\2\2\2\u0268\u026a\5\u00afX\2\u0269"+
"\u0268\3\2\2\2\u026a\u026b\3\2\2\2\u026b\u0269\3\2\2\2\u026b\u026c\3\2"+
"\2\2\u026c\u00a0\3\2\2\2\u026d\u026f\5\u00afX\2\u026e\u026d\3\2\2\2\u026f"+
"\u0270\3\2\2\2\u0270\u026e\3\2\2\2\u0270\u0271\3\2\2\2\u0271\u0272\3\2"+
"\2\2\u0272\u0276\5\u009bN\2\u0273\u0275\5\u00afX\2\u0274\u0273\3\2\2\2"+
"\u0275\u0278\3\2\2\2\u0276\u0274\3\2\2\2\u0276\u0277\3\2\2\2\u0277\u0298"+
"\3\2\2\2\u0278\u0276\3\2\2\2\u0279\u027b\5\u009bN\2\u027a\u027c\5\u00af"+
"X\2\u027b\u027a\3\2\2\2\u027c\u027d\3\2\2\2\u027d\u027b\3\2\2\2\u027d"+
"\u027e\3\2\2\2\u027e\u0298\3\2\2\2\u027f\u0281\5\u00afX\2\u0280\u027f"+
"\3\2\2\2\u0281\u0282\3\2\2\2\u0282\u0280\3\2\2\2\u0282\u0283\3\2\2\2\u0283"+
"\u028b\3\2\2\2\u0284\u0288\5\u009bN\2\u0285\u0287\5\u00afX\2\u0286\u0285"+
"\3\2\2\2\u0287\u028a\3\2\2\2\u0288\u0286\3\2\2\2\u0288\u0289\3\2\2\2\u0289"+
"\u028c\3\2\2\2\u028a\u0288\3\2\2\2\u028b\u0284\3\2\2\2\u028b\u028c\3\2"+
"\2\2\u028c\u028d\3\2\2\2\u028d\u028e\5\u00adW\2\u028e\u0298\3\2\2\2\u028f"+
"\u0291\5\u009bN\2\u0290\u0292\5\u00afX\2\u0291\u0290\3\2\2\2\u0292\u0293"+
"\3\2\2\2\u0293\u0291\3\2\2\2\u0293\u0294\3\2\2\2\u0294\u0295\3\2\2\2\u0295"+
"\u0296\5\u00adW\2\u0296\u0298\3\2\2\2\u0297\u026e\3\2\2\2\u0297\u0279"+
"\3\2\2\2\u0297\u0280\3\2\2\2\u0297\u028f\3\2\2\2\u0298\u00a2\3\2\2\2\u0299"+
"\u029c\5\u00b1Y\2\u029a\u029c\7a\2\2\u029b\u0299\3\2\2\2\u029b\u029a\3"+
"\2\2\2\u029c\u02a2\3\2\2\2\u029d\u02a1\5\u00b1Y\2\u029e\u02a1\5\u00af"+
"X\2\u029f\u02a1\t\3\2\2\u02a0\u029d\3\2\2\2\u02a0\u029e\3\2\2\2\u02a0"+
"\u029f\3\2\2\2\u02a1\u02a4\3\2\2\2\u02a2\u02a0\3\2\2\2\u02a2\u02a3\3\2"+
"\2\2\u02a3\u00a4\3\2\2\2\u02a4\u02a2\3\2\2\2\u02a5\u02a9\5\u00afX\2\u02a6"+
"\u02aa\5\u00b1Y\2\u02a7\u02aa\5\u00afX\2\u02a8\u02aa\t\4\2\2\u02a9\u02a6"+
"\3\2\2\2\u02a9\u02a7\3\2\2\2\u02a9\u02a8\3\2\2\2\u02aa\u02ab\3\2\2\2\u02ab"+
"\u02a9\3\2\2\2\u02ab\u02ac\3\2\2\2\u02ac\u00a6\3\2\2\2\u02ad\u02b2\5\u00b1"+
"Y\2\u02ae\u02b2\5\u00afX\2\u02af\u02b2\t\3\2\2\u02b0\u02b2\5\u0093J\2"+
"\u02b1\u02ad\3\2\2\2\u02b1\u02ae\3\2\2\2\u02b1\u02af\3\2\2\2\u02b1\u02b0"+
"\3\2\2\2\u02b2\u02b3\3\2\2\2\u02b3\u02b1\3\2\2\2\u02b3\u02b4\3\2\2\2\u02b4"+
"\u00a8\3\2\2\2\u02b5\u02bb\7$\2\2\u02b6\u02ba\n\5\2\2\u02b7\u02b8\7$\2"+
"\2\u02b8\u02ba\7$\2\2\u02b9\u02b6\3\2\2\2\u02b9\u02b7\3\2\2\2\u02ba\u02bd"+
"\3\2\2\2\u02bb\u02b9\3\2\2\2\u02bb\u02bc\3\2\2\2\u02bc\u02be\3\2\2\2\u02bd"+
"\u02bb\3\2\2\2\u02be\u02bf\7$\2\2\u02bf\u00aa\3\2\2\2\u02c0\u02c6\7b\2"+
"\2\u02c1\u02c5\n\6\2\2\u02c2\u02c3\7b\2\2\u02c3\u02c5\7b\2\2\u02c4\u02c1"+
"\3\2\2\2\u02c4\u02c2\3\2\2\2\u02c5\u02c8\3\2\2\2\u02c6\u02c4\3\2\2\2\u02c6"+
"\u02c7\3\2\2\2\u02c7\u02c9\3\2\2\2\u02c8\u02c6\3\2\2\2\u02c9\u02ca\7b"+
"\2\2\u02ca\u00ac\3\2\2\2\u02cb\u02cd\7G\2\2\u02cc\u02ce\t\7\2\2\u02cd"+
"\u02cc\3\2\2\2\u02cd\u02ce\3\2\2\2\u02ce\u02d0\3\2\2\2\u02cf\u02d1\5\u00af"+
"X\2\u02d0\u02cf\3\2\2\2\u02d1\u02d2\3\2\2\2\u02d2\u02d0\3\2\2\2\u02d2"+
"\u02d3\3\2\2\2\u02d3\u00ae\3\2\2\2\u02d4\u02d5\t\b\2\2\u02d5\u00b0\3\2"+
"\2\2\u02d6\u02d7\t\t\2\2\u02d7\u00b2\3\2\2\2\u02d8\u02d9\7/\2\2\u02d9"+
"\u02da\7/\2\2\u02da\u02de\3\2\2\2\u02db\u02dd\n\n\2\2\u02dc\u02db\3\2"+
"\2\2\u02dd\u02e0\3\2\2\2\u02de\u02dc\3\2\2\2\u02de\u02df\3\2\2\2\u02df"+
"\u02e2\3\2\2\2\u02e0\u02de\3\2\2\2\u02e1\u02e3\7\17\2\2\u02e2\u02e1\3"+
"\2\2\2\u02e2\u02e3\3\2\2\2\u02e3\u02e5\3\2\2\2\u02e4\u02e6\7\f\2\2\u02e5"+
"\u02e4\3\2\2\2\u02e5\u02e6\3\2\2\2\u02e6\u02e7\3\2\2\2\u02e7\u02e8\bZ"+
"\2\2\u02e8\u00b4\3\2\2\2\u02e9\u02ea\7\61\2\2\u02ea\u02eb\7,\2\2\u02eb"+
"\u02f0\3\2\2\2\u02ec\u02ef\5\u00b5[\2\u02ed\u02ef\13\2\2\2\u02ee\u02ec"+
"\3\2\2\2\u02ee\u02ed\3\2\2\2\u02ef\u02f2\3\2\2\2\u02f0\u02f1\3\2\2\2\u02f0"+
"\u02ee\3\2\2\2\u02f1\u02f3\3\2\2\2\u02f2\u02f0\3\2\2\2\u02f3\u02f4\7,"+
"\2\2\u02f4\u02f5\7\61\2\2\u02f5\u02f6\3\2\2\2\u02f6\u02f7\b[\2\2\u02f7"+
"\u00b6\3\2\2\2\u02f8\u02fa\t\13\2\2\u02f9\u02f8\3\2\2\2\u02fa\u02fb\3"+
"\2\2\2\u02fb\u02f9\3\2\2\2\u02fb\u02fc\3\2\2\2\u02fc\u02fd\3\2\2\2\u02fd"+
"\u02fe\b\\\2\2\u02fe\u00b8\3\2\2\2\u02ff\u0300\13\2\2\2\u0300\u00ba\3"+
"\2\2\2\"\2\u0242\u0261\u0263\u026b\u0270\u0276\u027d\u0282\u0288\u028b"+
"\u0293\u0297\u029b\u02a0\u02a2\u02a9\u02ab\u02b1\u02b3\u02b9\u02bb\u02c4"+
"\u02c6\u02cd\u02d2\u02de\u02e2\u02e5\u02ee\u02f0\u02fb\3\2\3\2";
"\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b7\3\2\2"+
"\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\3\u00bf\3\2\2\2\5\u00c1"+
"\3\2\2\2\7\u00c3\3\2\2\2\t\u00c5\3\2\2\2\13\u00c9\3\2\2\2\r\u00d1\3\2"+
"\2\2\17\u00da\3\2\2\2\21\u00de\3\2\2\2\23\u00e2\3\2\2\2\25\u00e5\3\2\2"+
"\2\27\u00e9\3\2\2\2\31\u00f1\3\2\2\2\33\u00f4\3\2\2\2\35\u00f9\3\2\2\2"+
"\37\u0101\3\2\2\2!\u0107\3\2\2\2#\u010c\3\2\2\2%\u0115\3\2\2\2\'\u011e"+
"\3\2\2\2)\u0125\3\2\2\2+\u0130\3\2\2\2-\u0137\3\2\2\2/\u013f\3\2\2\2\61"+
"\u0147\3\2\2\2\63\u014d\3\2\2\2\65\u0154\3\2\2\2\67\u0159\3\2\2\29\u015e"+
"\3\2\2\2;\u0168\3\2\2\2=\u0171\3\2\2\2?\u0177\3\2\2\2A\u017e\3\2\2\2C"+
"\u0181\3\2\2\2E\u0187\3\2\2\2G\u018a\3\2\2\2I\u018f\3\2\2\2K\u0194\3\2"+
"\2\2M\u0199\3\2\2\2O\u019f\3\2\2\2Q\u01a6\3\2\2\2S\u01ac\3\2\2\2U\u01b4"+
"\3\2\2\2W\u01b8\3\2\2\2Y\u01bd\3\2\2\2[\u01c0\3\2\2\2]\u01ca\3\2\2\2_"+
"\u01cd\3\2\2\2a\u01d3\3\2\2\2c\u01d9\3\2\2\2e\u01e0\3\2\2\2g\u01e9\3\2"+
"\2\2i\u01ee\3\2\2\2k\u01f4\3\2\2\2m\u01fa\3\2\2\2o\u0200\3\2\2\2q\u0208"+
"\3\2\2\2s\u020f\3\2\2\2u\u0214\3\2\2\2w\u0218\3\2\2\2y\u021f\3\2\2\2{"+
"\u0224\3\2\2\2}\u0229\3\2\2\2\177\u022f\3\2\2\2\u0081\u0235\3\2\2\2\u0083"+
"\u023c\3\2\2\2\u0085\u0242\3\2\2\2\u0087\u0247\3\2\2\2\u0089\u0250\3\2"+
"\2\2\u008b\u0252\3\2\2\2\u008d\u0254\3\2\2\2\u008f\u0257\3\2\2\2\u0091"+
"\u0259\3\2\2\2\u0093\u025c\3\2\2\2\u0095\u025e\3\2\2\2\u0097\u0260\3\2"+
"\2\2\u0099\u0262\3\2\2\2\u009b\u0264\3\2\2\2\u009d\u0266\3\2\2\2\u009f"+
"\u0269\3\2\2\2\u00a1\u026b\3\2\2\2\u00a3\u0277\3\2\2\2\u00a5\u02a5\3\2"+
"\2\2\u00a7\u02a9\3\2\2\2\u00a9\u02b3\3\2\2\2\u00ab\u02bf\3\2\2\2\u00ad"+
"\u02c3\3\2\2\2\u00af\u02ce\3\2\2\2\u00b1\u02d9\3\2\2\2\u00b3\u02e2\3\2"+
"\2\2\u00b5\u02e4\3\2\2\2\u00b7\u02e6\3\2\2\2\u00b9\u02f7\3\2\2\2\u00bb"+
"\u0307\3\2\2\2\u00bd\u030d\3\2\2\2\u00bf\u00c0\7*\2\2\u00c0\4\3\2\2\2"+
"\u00c1\u00c2\7+\2\2\u00c2\6\3\2\2\2\u00c3\u00c4\7.\2\2\u00c4\b\3\2\2\2"+
"\u00c5\u00c6\7C\2\2\u00c6\u00c7\7N\2\2\u00c7\u00c8\7N\2\2\u00c8\n\3\2"+
"\2\2\u00c9\u00ca\7C\2\2\u00ca\u00cb\7P\2\2\u00cb\u00cc\7C\2\2\u00cc\u00cd"+
"\7N\2\2\u00cd\u00ce\7[\2\2\u00ce\u00cf\7\\\2\2\u00cf\u00d0\7G\2\2\u00d0"+
"\f\3\2\2\2\u00d1\u00d2\7C\2\2\u00d2\u00d3\7P\2\2\u00d3\u00d4\7C\2\2\u00d4"+
"\u00d5\7N\2\2\u00d5\u00d6\7[\2\2\u00d6\u00d7\7\\\2\2\u00d7\u00d8\7G\2"+
"\2\u00d8\u00d9\7F\2\2\u00d9\16\3\2\2\2\u00da\u00db\7C\2\2\u00db\u00dc"+
"\7P\2\2\u00dc\u00dd\7F\2\2\u00dd\20\3\2\2\2\u00de\u00df\7C\2\2\u00df\u00e0"+
"\7P\2\2\u00e0\u00e1\7[\2\2\u00e1\22\3\2\2\2\u00e2\u00e3\7C\2\2\u00e3\u00e4"+
"\7U\2\2\u00e4\24\3\2\2\2\u00e5\u00e6\7C\2\2\u00e6\u00e7\7U\2\2\u00e7\u00e8"+
"\7E\2\2\u00e8\26\3\2\2\2\u00e9\u00ea\7D\2\2\u00ea\u00eb\7G\2\2\u00eb\u00ec"+
"\7V\2\2\u00ec\u00ed\7Y\2\2\u00ed\u00ee\7G\2\2\u00ee\u00ef\7G\2\2\u00ef"+
"\u00f0\7P\2\2\u00f0\30\3\2\2\2\u00f1\u00f2\7D\2\2\u00f2\u00f3\7[\2\2\u00f3"+
"\32\3\2\2\2\u00f4\u00f5\7E\2\2\u00f5\u00f6\7C\2\2\u00f6\u00f7\7U\2\2\u00f7"+
"\u00f8\7V\2\2\u00f8\34\3\2\2\2\u00f9\u00fa\7E\2\2\u00fa\u00fb\7Q\2\2\u00fb"+
"\u00fc\7N\2\2\u00fc\u00fd\7W\2\2\u00fd\u00fe\7O\2\2\u00fe\u00ff\7P\2\2"+
"\u00ff\u0100\7U\2\2\u0100\36\3\2\2\2\u0101\u0102\7F\2\2\u0102\u0103\7"+
"G\2\2\u0103\u0104\7D\2\2\u0104\u0105\7W\2\2\u0105\u0106\7I\2\2\u0106 "+
"\3\2\2\2\u0107\u0108\7F\2\2\u0108\u0109\7G\2\2\u0109\u010a\7U\2\2\u010a"+
"\u010b\7E\2\2\u010b\"\3\2\2\2\u010c\u010d\7F\2\2\u010d\u010e\7G\2\2\u010e"+
"\u010f\7U\2\2\u010f\u0110\7E\2\2\u0110\u0111\7T\2\2\u0111\u0112\7K\2\2"+
"\u0112\u0113\7D\2\2\u0113\u0114\7G\2\2\u0114$\3\2\2\2\u0115\u0116\7F\2"+
"\2\u0116\u0117\7K\2\2\u0117\u0118\7U\2\2\u0118\u0119\7V\2\2\u0119\u011a"+
"\7K\2\2\u011a\u011b\7P\2\2\u011b\u011c\7E\2\2\u011c\u011d\7V\2\2\u011d"+
"&\3\2\2\2\u011e\u011f\7G\2\2\u011f\u0120\7U\2\2\u0120\u0121\7E\2\2\u0121"+
"\u0122\7C\2\2\u0122\u0123\7R\2\2\u0123\u0124\7G\2\2\u0124(\3\2\2\2\u0125"+
"\u0126\7G\2\2\u0126\u0127\7Z\2\2\u0127\u0128\7G\2\2\u0128\u0129\7E\2\2"+
"\u0129\u012a\7W\2\2\u012a\u012b\7V\2\2\u012b\u012c\7C\2\2\u012c\u012d"+
"\7D\2\2\u012d\u012e\7N\2\2\u012e\u012f\7G\2\2\u012f*\3\2\2\2\u0130\u0131"+
"\7G\2\2\u0131\u0132\7Z\2\2\u0132\u0133\7K\2\2\u0133\u0134\7U\2\2\u0134"+
"\u0135\7V\2\2\u0135\u0136\7U\2\2\u0136,\3\2\2\2\u0137\u0138\7G\2\2\u0138"+
"\u0139\7Z\2\2\u0139\u013a\7R\2\2\u013a\u013b\7N\2\2\u013b\u013c\7C\2\2"+
"\u013c\u013d\7K\2\2\u013d\u013e\7P\2\2\u013e.\3\2\2\2\u013f\u0140\7G\2"+
"\2\u0140\u0141\7Z\2\2\u0141\u0142\7V\2\2\u0142\u0143\7T\2\2\u0143\u0144"+
"\7C\2\2\u0144\u0145\7E\2\2\u0145\u0146\7V\2\2\u0146\60\3\2\2\2\u0147\u0148"+
"\7H\2\2\u0148\u0149\7C\2\2\u0149\u014a\7N\2\2\u014a\u014b\7U\2\2\u014b"+
"\u014c\7G\2\2\u014c\62\3\2\2\2\u014d\u014e\7H\2\2\u014e\u014f\7Q\2\2\u014f"+
"\u0150\7T\2\2\u0150\u0151\7O\2\2\u0151\u0152\7C\2\2\u0152\u0153\7V\2\2"+
"\u0153\64\3\2\2\2\u0154\u0155\7H\2\2\u0155\u0156\7T\2\2\u0156\u0157\7"+
"Q\2\2\u0157\u0158\7O\2\2\u0158\66\3\2\2\2\u0159\u015a\7H\2\2\u015a\u015b"+
"\7W\2\2\u015b\u015c\7N\2\2\u015c\u015d\7N\2\2\u015d8\3\2\2\2\u015e\u015f"+
"\7H\2\2\u015f\u0160\7W\2\2\u0160\u0161\7P\2\2\u0161\u0162\7E\2\2\u0162"+
"\u0163\7V\2\2\u0163\u0164\7K\2\2\u0164\u0165\7Q\2\2\u0165\u0166\7P\2\2"+
"\u0166\u0167\7U\2\2\u0167:\3\2\2\2\u0168\u0169\7I\2\2\u0169\u016a\7T\2"+
"\2\u016a\u016b\7C\2\2\u016b\u016c\7R\2\2\u016c\u016d\7J\2\2\u016d\u016e"+
"\7X\2\2\u016e\u016f\7K\2\2\u016f\u0170\7\\\2\2\u0170<\3\2\2\2\u0171\u0172"+
"\7I\2\2\u0172\u0173\7T\2\2\u0173\u0174\7Q\2\2\u0174\u0175\7W\2\2\u0175"+
"\u0176\7R\2\2\u0176>\3\2\2\2\u0177\u0178\7J\2\2\u0178\u0179\7C\2\2\u0179"+
"\u017a\7X\2\2\u017a\u017b\7K\2\2\u017b\u017c\7P\2\2\u017c\u017d\7I\2\2"+
"\u017d@\3\2\2\2\u017e\u017f\7K\2\2\u017f\u0180\7P\2\2\u0180B\3\2\2\2\u0181"+
"\u0182\7K\2\2\u0182\u0183\7P\2\2\u0183\u0184\7P\2\2\u0184\u0185\7G\2\2"+
"\u0185\u0186\7T\2\2\u0186D\3\2\2\2\u0187\u0188\7K\2\2\u0188\u0189\7U\2"+
"\2\u0189F\3\2\2\2\u018a\u018b\7L\2\2\u018b\u018c\7Q\2\2\u018c\u018d\7"+
"K\2\2\u018d\u018e\7P\2\2\u018eH\3\2\2\2\u018f\u0190\7N\2\2\u0190\u0191"+
"\7G\2\2\u0191\u0192\7H\2\2\u0192\u0193\7V\2\2\u0193J\3\2\2\2\u0194\u0195"+
"\7N\2\2\u0195\u0196\7K\2\2\u0196\u0197\7M\2\2\u0197\u0198\7G\2\2\u0198"+
"L\3\2\2\2\u0199\u019a\7N\2\2\u019a\u019b\7K\2\2\u019b\u019c\7O\2\2\u019c"+
"\u019d\7K\2\2\u019d\u019e\7V\2\2\u019eN\3\2\2\2\u019f\u01a0\7O\2\2\u01a0"+
"\u01a1\7C\2\2\u01a1\u01a2\7R\2\2\u01a2\u01a3\7R\2\2\u01a3\u01a4\7G\2\2"+
"\u01a4\u01a5\7F\2\2\u01a5P\3\2\2\2\u01a6\u01a7\7O\2\2\u01a7\u01a8\7C\2"+
"\2\u01a8\u01a9\7V\2\2\u01a9\u01aa\7E\2\2\u01aa\u01ab\7J\2\2\u01abR\3\2"+
"\2\2\u01ac\u01ad\7P\2\2\u01ad\u01ae\7C\2\2\u01ae\u01af\7V\2\2\u01af\u01b0"+
"\7W\2\2\u01b0\u01b1\7T\2\2\u01b1\u01b2\7C\2\2\u01b2\u01b3\7N\2\2\u01b3"+
"T\3\2\2\2\u01b4\u01b5\7P\2\2\u01b5\u01b6\7Q\2\2\u01b6\u01b7\7V\2\2\u01b7"+
"V\3\2\2\2\u01b8\u01b9\7P\2\2\u01b9\u01ba\7W\2\2\u01ba\u01bb\7N\2\2\u01bb"+
"\u01bc\7N\2\2\u01bcX\3\2\2\2\u01bd\u01be\7Q\2\2\u01be\u01bf\7P\2\2\u01bf"+
"Z\3\2\2\2\u01c0\u01c1\7Q\2\2\u01c1\u01c2\7R\2\2\u01c2\u01c3\7V\2\2\u01c3"+
"\u01c4\7K\2\2\u01c4\u01c5\7O\2\2\u01c5\u01c6\7K\2\2\u01c6\u01c7\7\\\2"+
"\2\u01c7\u01c8\7G\2\2\u01c8\u01c9\7F\2\2\u01c9\\\3\2\2\2\u01ca\u01cb\7"+
"Q\2\2\u01cb\u01cc\7T\2\2\u01cc^\3\2\2\2\u01cd\u01ce\7Q\2\2\u01ce\u01cf"+
"\7T\2\2\u01cf\u01d0\7F\2\2\u01d0\u01d1\7G\2\2\u01d1\u01d2\7T\2\2\u01d2"+
"`\3\2\2\2\u01d3\u01d4\7Q\2\2\u01d4\u01d5\7W\2\2\u01d5\u01d6\7V\2\2\u01d6"+
"\u01d7\7G\2\2\u01d7\u01d8\7T\2\2\u01d8b\3\2\2\2\u01d9\u01da\7R\2\2\u01da"+
"\u01db\7C\2\2\u01db\u01dc\7T\2\2\u01dc\u01dd\7U\2\2\u01dd\u01de\7G\2\2"+
"\u01de\u01df\7F\2\2\u01dfd\3\2\2\2\u01e0\u01e1\7R\2\2\u01e1\u01e2\7J\2"+
"\2\u01e2\u01e3\7[\2\2\u01e3\u01e4\7U\2\2\u01e4\u01e5\7K\2\2\u01e5\u01e6"+
"\7E\2\2\u01e6\u01e7\7C\2\2\u01e7\u01e8\7N\2\2\u01e8f\3\2\2\2\u01e9\u01ea"+
"\7R\2\2\u01ea\u01eb\7N\2\2\u01eb\u01ec\7C\2\2\u01ec\u01ed\7P\2\2\u01ed"+
"h\3\2\2\2\u01ee\u01ef\7T\2\2\u01ef\u01f0\7K\2\2\u01f0\u01f1\7I\2\2\u01f1"+
"\u01f2\7J\2\2\u01f2\u01f3\7V\2\2\u01f3j\3\2\2\2\u01f4\u01f5\7T\2\2\u01f5"+
"\u01f6\7N\2\2\u01f6\u01f7\7K\2\2\u01f7\u01f8\7M\2\2\u01f8\u01f9\7G\2\2"+
"\u01f9l\3\2\2\2\u01fa\u01fb\7S\2\2\u01fb\u01fc\7W\2\2\u01fc\u01fd\7G\2"+
"\2\u01fd\u01fe\7T\2\2\u01fe\u01ff\7[\2\2\u01ffn\3\2\2\2\u0200\u0201\7"+
"U\2\2\u0201\u0202\7E\2\2\u0202\u0203\7J\2\2\u0203\u0204\7G\2\2\u0204\u0205"+
"\7O\2\2\u0205\u0206\7C\2\2\u0206\u0207\7U\2\2\u0207p\3\2\2\2\u0208\u0209"+
"\7U\2\2\u0209\u020a\7G\2\2\u020a\u020b\7N\2\2\u020b\u020c\7G\2\2\u020c"+
"\u020d\7E\2\2\u020d\u020e\7V\2\2\u020er\3\2\2\2\u020f\u0210\7U\2\2\u0210"+
"\u0211\7J\2\2\u0211\u0212\7Q\2\2\u0212\u0213\7Y\2\2\u0213t\3\2\2\2\u0214"+
"\u0215\7U\2\2\u0215\u0216\7[\2\2\u0216\u0217\7U\2\2\u0217v\3\2\2\2\u0218"+
"\u0219\7V\2\2\u0219\u021a\7C\2\2\u021a\u021b\7D\2\2\u021b\u021c\7N\2\2"+
"\u021c\u021d\7G\2\2\u021d\u021e\7U\2\2\u021ex\3\2\2\2\u021f\u0220\7V\2"+
"\2\u0220\u0221\7G\2\2\u0221\u0222\7Z\2\2\u0222\u0223\7V\2\2\u0223z\3\2"+
"\2\2\u0224\u0225\7V\2\2\u0225\u0226\7T\2\2\u0226\u0227\7W\2\2\u0227\u0228"+
"\7G\2\2\u0228|\3\2\2\2\u0229\u022a\7V\2\2\u022a\u022b\7[\2\2\u022b\u022c"+
"\7R\2\2\u022c\u022d\7G\2\2\u022d\u022e\7U\2\2\u022e~\3\2\2\2\u022f\u0230"+
"\7W\2\2\u0230\u0231\7U\2\2\u0231\u0232\7K\2\2\u0232\u0233\7P\2\2\u0233"+
"\u0234\7I\2\2\u0234\u0080\3\2\2\2\u0235\u0236\7X\2\2\u0236\u0237\7G\2"+
"\2\u0237\u0238\7T\2\2\u0238\u0239\7K\2\2\u0239\u023a\7H\2\2\u023a\u023b"+
"\7[\2\2\u023b\u0082\3\2\2\2\u023c\u023d\7Y\2\2\u023d\u023e\7J\2\2\u023e"+
"\u023f\7G\2\2\u023f\u0240\7T\2\2\u0240\u0241\7G\2\2\u0241\u0084\3\2\2"+
"\2\u0242\u0243\7Y\2\2\u0243\u0244\7K\2\2\u0244\u0245\7V\2\2\u0245\u0246"+
"\7J\2\2\u0246\u0086\3\2\2\2\u0247\u0248\7?\2\2\u0248\u0088\3\2\2\2\u0249"+
"\u024a\7>\2\2\u024a\u0251\7@\2\2\u024b\u024c\7#\2\2\u024c\u0251\7?\2\2"+
"\u024d\u024e\7>\2\2\u024e\u024f\7?\2\2\u024f\u0251\7@\2\2\u0250\u0249"+
"\3\2\2\2\u0250\u024b\3\2\2\2\u0250\u024d\3\2\2\2\u0251\u008a\3\2\2\2\u0252"+
"\u0253\7>\2\2\u0253\u008c\3\2\2\2\u0254\u0255\7>\2\2\u0255\u0256\7?\2"+
"\2\u0256\u008e\3\2\2\2\u0257\u0258\7@\2\2\u0258\u0090\3\2\2\2\u0259\u025a"+
"\7@\2\2\u025a\u025b\7?\2\2\u025b\u0092\3\2\2\2\u025c\u025d\7-\2\2\u025d"+
"\u0094\3\2\2\2\u025e\u025f\7/\2\2\u025f\u0096\3\2\2\2\u0260\u0261\7,\2"+
"\2\u0261\u0098\3\2\2\2\u0262\u0263\7\61\2\2\u0263\u009a\3\2\2\2\u0264"+
"\u0265\7\'\2\2\u0265\u009c\3\2\2\2\u0266\u0267\7~\2\2\u0267\u0268\7~\2"+
"\2\u0268\u009e\3\2\2\2\u0269\u026a\7\60\2\2\u026a\u00a0\3\2\2\2\u026b"+
"\u0271\7)\2\2\u026c\u0270\n\2\2\2\u026d\u026e\7)\2\2\u026e\u0270\7)\2"+
"\2\u026f\u026c\3\2\2\2\u026f\u026d\3\2\2\2\u0270\u0273\3\2\2\2\u0271\u026f"+
"\3\2\2\2\u0271\u0272\3\2\2\2\u0272\u0274\3\2\2\2\u0273\u0271\3\2\2\2\u0274"+
"\u0275\7)\2\2\u0275\u00a2\3\2\2\2\u0276\u0278\5\u00b3Z\2\u0277\u0276\3"+
"\2\2\2\u0278\u0279\3\2\2\2\u0279\u0277\3\2\2\2\u0279\u027a\3\2\2\2\u027a"+
"\u00a4\3\2\2\2\u027b\u027d\5\u00b3Z\2\u027c\u027b\3\2\2\2\u027d\u027e"+
"\3\2\2\2\u027e\u027c\3\2\2\2\u027e\u027f\3\2\2\2\u027f\u0280\3\2\2\2\u0280"+
"\u0284\5\u009fP\2\u0281\u0283\5\u00b3Z\2\u0282\u0281\3\2\2\2\u0283\u0286"+
"\3\2\2\2\u0284\u0282\3\2\2\2\u0284\u0285\3\2\2\2\u0285\u02a6\3\2\2\2\u0286"+
"\u0284\3\2\2\2\u0287\u0289\5\u009fP\2\u0288\u028a\5\u00b3Z\2\u0289\u0288"+
"\3\2\2\2\u028a\u028b\3\2\2\2\u028b\u0289\3\2\2\2\u028b\u028c\3\2\2\2\u028c"+
"\u02a6\3\2\2\2\u028d\u028f\5\u00b3Z\2\u028e\u028d\3\2\2\2\u028f\u0290"+
"\3\2\2\2\u0290\u028e\3\2\2\2\u0290\u0291\3\2\2\2\u0291\u0299\3\2\2\2\u0292"+
"\u0296\5\u009fP\2\u0293\u0295\5\u00b3Z\2\u0294\u0293\3\2\2\2\u0295\u0298"+
"\3\2\2\2\u0296\u0294\3\2\2\2\u0296\u0297\3\2\2\2\u0297\u029a\3\2\2\2\u0298"+
"\u0296\3\2\2\2\u0299\u0292\3\2\2\2\u0299\u029a\3\2\2\2\u029a\u029b\3\2"+
"\2\2\u029b\u029c\5\u00b1Y\2\u029c\u02a6\3\2\2\2\u029d\u029f\5\u009fP\2"+
"\u029e\u02a0\5\u00b3Z\2\u029f\u029e\3\2\2\2\u02a0\u02a1\3\2\2\2\u02a1"+
"\u029f\3\2\2\2\u02a1\u02a2\3\2\2\2\u02a2\u02a3\3\2\2\2\u02a3\u02a4\5\u00b1"+
"Y\2\u02a4\u02a6\3\2\2\2\u02a5\u027c\3\2\2\2\u02a5\u0287\3\2\2\2\u02a5"+
"\u028e\3\2\2\2\u02a5\u029d\3\2\2\2\u02a6\u00a6\3\2\2\2\u02a7\u02aa\5\u00b5"+
"[\2\u02a8\u02aa\7a\2\2\u02a9\u02a7\3\2\2\2\u02a9\u02a8\3\2\2\2\u02aa\u02b0"+
"\3\2\2\2\u02ab\u02af\5\u00b5[\2\u02ac\u02af\5\u00b3Z\2\u02ad\u02af\t\3"+
"\2\2\u02ae\u02ab\3\2\2\2\u02ae\u02ac\3\2\2\2\u02ae\u02ad\3\2\2\2\u02af"+
"\u02b2\3\2\2\2\u02b0\u02ae\3\2\2\2\u02b0\u02b1\3\2\2\2\u02b1\u00a8\3\2"+
"\2\2\u02b2\u02b0\3\2\2\2\u02b3\u02b7\5\u00b3Z\2\u02b4\u02b8\5\u00b5[\2"+
"\u02b5\u02b8\5\u00b3Z\2\u02b6\u02b8\t\4\2\2\u02b7\u02b4\3\2\2\2\u02b7"+
"\u02b5\3\2\2\2\u02b7\u02b6\3\2\2\2\u02b8\u02b9\3\2\2\2\u02b9\u02b7\3\2"+
"\2\2\u02b9\u02ba\3\2\2\2\u02ba\u00aa\3\2\2\2\u02bb\u02c0\5\u00b5[\2\u02bc"+
"\u02c0\5\u00b3Z\2\u02bd\u02c0\t\3\2\2\u02be\u02c0\5\u0097L\2\u02bf\u02bb"+
"\3\2\2\2\u02bf\u02bc\3\2\2\2\u02bf\u02bd\3\2\2\2\u02bf\u02be\3\2\2\2\u02c0"+
"\u02c1\3\2\2\2\u02c1\u02bf\3\2\2\2\u02c1\u02c2\3\2\2\2\u02c2\u00ac\3\2"+
"\2\2\u02c3\u02c9\7$\2\2\u02c4\u02c8\n\5\2\2\u02c5\u02c6\7$\2\2\u02c6\u02c8"+
"\7$\2\2\u02c7\u02c4\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c8\u02cb\3\2\2\2\u02c9"+
"\u02c7\3\2\2\2\u02c9\u02ca\3\2\2\2\u02ca\u02cc\3\2\2\2\u02cb\u02c9\3\2"+
"\2\2\u02cc\u02cd\7$\2\2\u02cd\u00ae\3\2\2\2\u02ce\u02d4\7b\2\2\u02cf\u02d3"+
"\n\6\2\2\u02d0\u02d1\7b\2\2\u02d1\u02d3\7b\2\2\u02d2\u02cf\3\2\2\2\u02d2"+
"\u02d0\3\2\2\2\u02d3\u02d6\3\2\2\2\u02d4\u02d2\3\2\2\2\u02d4\u02d5\3\2"+
"\2\2\u02d5\u02d7\3\2\2\2\u02d6\u02d4\3\2\2\2\u02d7\u02d8\7b\2\2\u02d8"+
"\u00b0\3\2\2\2\u02d9\u02db\7G\2\2\u02da\u02dc\t\7\2\2\u02db\u02da\3\2"+
"\2\2\u02db\u02dc\3\2\2\2\u02dc\u02de\3\2\2\2\u02dd\u02df\5\u00b3Z\2\u02de"+
"\u02dd\3\2\2\2\u02df\u02e0\3\2\2\2\u02e0\u02de\3\2\2\2\u02e0\u02e1\3\2"+
"\2\2\u02e1\u00b2\3\2\2\2\u02e2\u02e3\t\b\2\2\u02e3\u00b4\3\2\2\2\u02e4"+
"\u02e5\t\t\2\2\u02e5\u00b6\3\2\2\2\u02e6\u02e7\7/\2\2\u02e7\u02e8\7/\2"+
"\2\u02e8\u02ec\3\2\2\2\u02e9\u02eb\n\n\2\2\u02ea\u02e9\3\2\2\2\u02eb\u02ee"+
"\3\2\2\2\u02ec\u02ea\3\2\2\2\u02ec\u02ed\3\2\2\2\u02ed\u02f0\3\2\2\2\u02ee"+
"\u02ec\3\2\2\2\u02ef\u02f1\7\17\2\2\u02f0\u02ef\3\2\2\2\u02f0\u02f1\3"+
"\2\2\2\u02f1\u02f3\3\2\2\2\u02f2\u02f4\7\f\2\2\u02f3\u02f2\3\2\2\2\u02f3"+
"\u02f4\3\2\2\2\u02f4\u02f5\3\2\2\2\u02f5\u02f6\b\\\2\2\u02f6\u00b8\3\2"+
"\2\2\u02f7\u02f8\7\61\2\2\u02f8\u02f9\7,\2\2\u02f9\u02fe\3\2\2\2\u02fa"+
"\u02fd\5\u00b9]\2\u02fb\u02fd\13\2\2\2\u02fc\u02fa\3\2\2\2\u02fc\u02fb"+
"\3\2\2\2\u02fd\u0300\3\2\2\2\u02fe\u02ff\3\2\2\2\u02fe\u02fc\3\2\2\2\u02ff"+
"\u0301\3\2\2\2\u0300\u02fe\3\2\2\2\u0301\u0302\7,\2\2\u0302\u0303\7\61"+
"\2\2\u0303\u0304\3\2\2\2\u0304\u0305\b]\2\2\u0305\u00ba\3\2\2\2\u0306"+
"\u0308\t\13\2\2\u0307\u0306\3\2\2\2\u0308\u0309\3\2\2\2\u0309\u0307\3"+
"\2\2\2\u0309\u030a\3\2\2\2\u030a\u030b\3\2\2\2\u030b\u030c\b^\2\2\u030c"+
"\u00bc\3\2\2\2\u030d\u030e\13\2\2\2\u030e\u00be\3\2\2\2\"\2\u0250\u026f"+
"\u0271\u0279\u027e\u0284\u028b\u0290\u0296\u0299\u02a1\u02a5\u02a9\u02ae"+
"\u02b0\u02b7\u02b9\u02bf\u02c1\u02c7\u02c9\u02d2\u02d4\u02db\u02e0\u02ec"+
"\u02f0\u02f3\u02fc\u02fe\u0309\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -116,6 +116,42 @@ interface SqlBaseListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitShowSchemas(SqlBaseParser.ShowSchemasContext ctx);
/**
* Enter a parse tree produced by the {@code sysTables}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
*/
void enterSysTables(SqlBaseParser.SysTablesContext ctx);
/**
* Exit a parse tree produced by the {@code sysTables}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
*/
void exitSysTables(SqlBaseParser.SysTablesContext ctx);
/**
* Enter a parse tree produced by the {@code sysColumns}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
*/
void enterSysColumns(SqlBaseParser.SysColumnsContext ctx);
/**
* Exit a parse tree produced by the {@code sysColumns}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
*/
void exitSysColumns(SqlBaseParser.SysColumnsContext ctx);
/**
* Enter a parse tree produced by the {@code sysTypes}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
*/
void enterSysTypes(SqlBaseParser.SysTypesContext ctx);
/**
* Exit a parse tree produced by the {@code sysTypes}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
*/
void exitSysTypes(SqlBaseParser.SysTypesContext ctx);
/**
* Enter a parse tree produced by {@link SqlBaseParser#query}.
* @param ctx the parse tree

View File

@ -76,6 +76,27 @@ interface SqlBaseVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitShowSchemas(SqlBaseParser.ShowSchemasContext ctx);
/**
* Visit a parse tree produced by the {@code sysTables}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSysTables(SqlBaseParser.SysTablesContext ctx);
/**
* Visit a parse tree produced by the {@code sysColumns}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSysColumns(SqlBaseParser.SysColumnsContext ctx);
/**
* Visit a parse tree produced by the {@code sysTypes}
* labeled alternative in {@link SqlBaseParser#statement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSysTypes(SqlBaseParser.SysTypesContext ctx);
/**
* Visit a parse tree produced by {@link SqlBaseParser#query}.
* @param ctx the parse tree

View File

@ -5,17 +5,22 @@
*/
package org.elasticsearch.xpack.sql.plan.logical.command;
import org.elasticsearch.xpack.sql.expression.FieldAttribute;
import org.elasticsearch.xpack.sql.plan.logical.LogicalPlan;
import org.elasticsearch.xpack.sql.session.Executable;
import org.elasticsearch.xpack.sql.tree.Location;
import static java.util.Collections.emptyList;
import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.type.EsField;
import org.elasticsearch.xpack.sql.type.KeywordEsField;
import java.util.List;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
public abstract class Command extends LogicalPlan implements Executable {
public Command(Location location) {
protected Command(Location location) {
super(location, emptyList());
}
@ -28,4 +33,22 @@ public abstract class Command extends LogicalPlan implements Executable {
public boolean expressionsResolved() {
return true;
}
/**
* Syntactic sugar for creating a schema keyword/string field.
*/
protected final FieldAttribute keyword(String name) {
return field(name, new KeywordEsField(name));
}
/**
* Syntactic sugar for creating a schema field.
*/
protected final FieldAttribute field(String name, DataType type) {
return field(name, new EsField(name, type, emptyMap(), true));
}
private FieldAttribute field(String name, EsField field) {
return new FieldAttribute(location(), name, field);
}
}

View File

@ -14,8 +14,8 @@ 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.KeywordEsField;
import org.elasticsearch.xpack.sql.type.EsField;
import org.elasticsearch.xpack.sql.type.KeywordEsField;
import java.util.ArrayList;
import java.util.List;
@ -47,8 +47,7 @@ public class ShowColumns extends Command {
@Override
public List<Attribute> output() {
return asList(new FieldAttribute(location(), "column", new KeywordEsField("column")),
new FieldAttribute(location(), "type", new KeywordEsField("type")));
}
new FieldAttribute(location(), "type", new KeywordEsField("type"))); }
@Override
public void execute(SqlSession session, ActionListener<SchemaRowSet> listener) {

View File

@ -7,14 +7,12 @@ package org.elasticsearch.xpack.sql.plan.logical.command;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.xpack.sql.expression.Attribute;
import org.elasticsearch.xpack.sql.expression.FieldAttribute;
import org.elasticsearch.xpack.sql.expression.regex.LikePattern;
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.KeywordEsField;
import java.util.List;
import java.util.Objects;
@ -42,8 +40,7 @@ public class ShowTables extends Command {
@Override
public List<Attribute> output() {
return asList(new FieldAttribute(location(), "name", new KeywordEsField("name")),
new FieldAttribute(location(), "type", new KeywordEsField("type")));
return asList(keyword("name"), keyword("type"));
}
@Override
@ -52,7 +49,7 @@ public class ShowTables extends Command {
String regex = pattern != null ? pattern.asJavaRegex() : null;
session.indexResolver().resolveNames(index, regex, ActionListener.wrap(result -> {
listener.onResponse(Rows.of(output(), result.stream()
.map(t -> asList(t.name(), t.type()))
.map(t -> asList(t.name(), t.type().toSql()))
.collect(toList())));
}, listener::onFailure));
}

View File

@ -0,0 +1,98 @@
/*
* 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.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 java.util.List;
import java.util.Objects;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.elasticsearch.xpack.sql.util.StringUtils.EMPTY;
public class SysTables extends Command {
private final LikePattern pattern;
public SysTables(Location location, LikePattern pattern) {
super(location);
this.pattern = pattern;
}
@Override
protected NodeInfo<SysTables> info() {
return NodeInfo.create(this, SysTables::new, pattern);
}
public LikePattern pattern() {
return pattern;
}
@Override
public List<Attribute> output() {
return asList(keyword("TABLE_CAT"),
keyword("TABLE_SCHEM"),
keyword("TABLE_NAME"),
keyword("TABLE_TYPE"),
keyword("REMARKS"),
keyword("TYPE_CAT"),
keyword("TYPE_SCHEM"),
keyword("TYPE_NAME"),
keyword("SELF_REFERENCING_COL_NAME"),
keyword("REF_GENERATION")
);
}
@Override
public final void execute(SqlSession session, ActionListener<SchemaRowSet> listener) {
String index = pattern != null ? pattern.asIndexNameWildcard() : "*";
String regex = pattern != null ? pattern.asJavaRegex() : null;
String cluster = session.indexResolver().clusterName();
session.indexResolver().resolveNames(index, regex, ActionListener.wrap(result -> listener.onResponse(
Rows.of(output(), result.stream()
.map(t -> asList(cluster,
EMPTY,
t.name(),
t.type().toSql(),
EMPTY,
null,
null,
null,
null,
null))
.collect(toList())))
, listener::onFailure));
}
@Override
public int hashCode() {
return Objects.hash(pattern);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
SysTables other = (SysTables) obj;
return Objects.equals(pattern, other.pattern);
}
}

View File

@ -0,0 +1,120 @@
/*
* 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.expression.Attribute;
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 java.sql.DatabaseMetaData;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.elasticsearch.xpack.sql.type.DataType.BOOLEAN;
import static org.elasticsearch.xpack.sql.type.DataType.INTEGER;
import static org.elasticsearch.xpack.sql.type.DataType.SHORT;
public class SysTypes extends Command {
public SysTypes(Location location) {
super(location);
}
@Override
protected NodeInfo<SysTypes> info() {
return NodeInfo.create(this);
}
@Override
public List<Attribute> output() {
return asList(keyword("TYPE_NAME"),
field("DATA_TYPE", INTEGER),
field("PRECISION",INTEGER),
keyword("LITERAL_PREFIX"),
keyword("LITERAL_SUFFIX"),
keyword("CREATE_PARAMS"),
field("NULLABLE", SHORT),
field("CASE_SENSITIVE", BOOLEAN),
field("SEARCHABLE", SHORT),
field("UNSIGNED_ATTRIBUTE", BOOLEAN),
field("FIXED_PREC_SCALE", BOOLEAN),
field("AUTO_INCREMENT", BOOLEAN),
keyword("LOCAL_TYPE_NAME"),
field("MINIMUM_SCALE", SHORT),
field("MAXIMUM_SCALE", SHORT),
field("SQL_DATA_TYPE", INTEGER),
field("SQL_DATETIME_SUB", INTEGER),
field("NUM_PREC_RADIX", INTEGER),
// ODBC
field("INTERVAL_PRECISION", INTEGER)
);
}
@Override
public final void execute(SqlSession session, ActionListener<SchemaRowSet> listener) {
List<List<?>> rows = Stream.of(DataType.values())
// sort by SQL int type (that's what the JDBC/ODBC specs want)
.sorted(Comparator.comparing(t -> t.jdbcType))
.map(t -> asList(t.esType.toUpperCase(Locale.ROOT),
t.jdbcType.getVendorTypeNumber(),
t.defaultPrecision,
"'",
"'",
null,
// don't be specific on nullable
DatabaseMetaData.typeNullableUnknown,
// all strings are case-sensitive
t.isString(),
// everything is searchable,
DatabaseMetaData.typeSearchable,
// only numerics are signed
t.isNumeric() ? !t.isSigned : null,
//no fixed precision scale SQL_FALSE
0,
null,
null,
null,
null,
// SQL_DATA_TYPE - ODBC wants this to be not null
0,
null,
// Radix
t.isInteger ? Integer.valueOf(10) : (t.isRational ? Integer.valueOf(2) : null),
null
))
.collect(toList());
listener.onResponse(Rows.of(output(), rows));
}
@Override
public int hashCode() {
return getClass().hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return true;
}
}

View File

@ -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 RestSqlListTablesAction extends BaseRestHandler {
public RestSqlListTablesAction(Settings settings, RestController controller) {
super(settings);
controller.registerHandler(POST, SqlListTablesAction.REST_ENDPOINT, this);
}
@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
SqlListTablesRequest listTablesRequest;
try (XContentParser parser = request.contentOrSourceParamParser()) {
listTablesRequest = SqlListTablesRequest.fromXContent(parser, AbstractSqlRequest.Mode.fromString(request.param("mode")));
}
return channel -> client.executeLocally(SqlListTablesAction.INSTANCE, listTablesRequest, new RestToXContentListener<>(channel));
}
@Override
public String getName() {
return "xpack_sql_list_tables_action";
}
}

View File

@ -79,17 +79,17 @@ public class SqlPlugin extends Plugin implements ActionPlugin {
ResourceWatcherService resourceWatcherService, ScriptService scriptService,
NamedXContentRegistry xContentRegistry, Environment environment,
NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry) {
return createComponents(client);
return createComponents(client, clusterService.getClusterName().value());
}
/**
* Create components used by the sql plugin.
*/
public Collection<Object> createComponents(Client client) {
Collection<Object> createComponents(Client client, String clusterName) {
if (false == enabled) {
return emptyList();
}
indexResolver = new IndexResolver(client);
indexResolver = new IndexResolver(client, clusterName);
return Arrays.asList(sqlLicenseChecker, indexResolver, new PlanExecutor(client, indexResolver));
}
@ -106,7 +106,6 @@ public class SqlPlugin extends Plugin implements ActionPlugin {
return Arrays.asList(new RestSqlQueryAction(settings, restController),
new RestSqlTranslateAction(settings, restController),
new RestSqlClearCursorAction(settings, restController),
new RestSqlListTablesAction(settings, restController),
new RestSqlListColumnsAction(settings, restController));
}
@ -119,7 +118,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<>(SqlListTablesAction.INSTANCE, TransportSqlListTablesAction.class),
new ActionHandler<>(SqlListColumnsAction.INSTANCE, TransportSqlListColumnsAction.class));
}
}

View File

@ -1,49 +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.IndexResolver;
import org.elasticsearch.xpack.sql.analysis.index.IndexResolver.IndexInfo;
import org.elasticsearch.xpack.sql.util.StringUtils;
import static java.util.stream.Collectors.toList;
import static org.elasticsearch.common.Strings.hasText;
public class TransportSqlListTablesAction extends HandledTransportAction<SqlListTablesRequest, SqlListTablesResponse> {
private final SqlLicenseChecker sqlLicenseChecker;
private final IndexResolver indexResolver;
@Inject
public TransportSqlListTablesAction(Settings settings, ThreadPool threadPool,
TransportService transportService, ActionFilters actionFilters,
IndexNameExpressionResolver indexNameExpressionResolver,
SqlLicenseChecker sqlLicenseChecker, IndexResolver indexResolver) {
super(settings, SqlListTablesAction.NAME, threadPool, transportService, actionFilters, SqlListTablesRequest::new,
indexNameExpressionResolver);
this.sqlLicenseChecker = sqlLicenseChecker;
this.indexResolver = indexResolver;
}
@Override
protected void doExecute(SqlListTablesRequest request, ActionListener<SqlListTablesResponse> listener) {
sqlLicenseChecker.checkIfSqlAllowed(request.mode());
String indexPattern = hasText(request.getPattern()) ? StringUtils.likeToIndexWildcard(request.getPattern(), (char) 0) : "*";
String regexPattern = hasText(request.getPattern()) ? StringUtils.likeToJavaPattern(request.getPattern(), (char) 0) : null;
indexResolver.resolveNames(indexPattern, regexPattern, ActionListener.wrap(set -> listener.onResponse(
new SqlListTablesResponse(set.stream()
.map(IndexInfo::name)
.collect(toList()))), listener::onFailure));
}
}

View File

@ -28,15 +28,11 @@ public enum DataType {
HALF_FLOAT( JDBCType.FLOAT, Double.BYTES, 16, 25, true, false, true, true),
// precision is based on long
SCALED_FLOAT(JDBCType.FLOAT, Double.BYTES, 19, 25, true, false, true, true),
// 39 is maximum address in IPv6
IP( JDBCType.VARCHAR, -1, 39, 0),
KEYWORD( JDBCType.VARCHAR, Integer.MAX_VALUE, 256, 0),
TEXT( JDBCType.VARCHAR, Integer.MAX_VALUE, Integer.MAX_VALUE, 0, false, false, false, false),
OBJECT( JDBCType.STRUCT, -1, 0, 0),
NESTED( JDBCType.STRUCT, -1, 0, 0),
TOKEN_COUNT( JDBCType.INTEGER, Integer.BYTES, 10, 11),
BINARY( JDBCType.VARBINARY, -1, Integer.MAX_VALUE, 0),
GEO_POINT( null, -1, Integer.MAX_VALUE, 0),
DATE( JDBCType.TIMESTAMP, Long.BYTES, 19, 20);
// @formatter:on

View File

@ -13,8 +13,6 @@ 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.SqlListTablesAction;
import org.elasticsearch.xpack.sql.plugin.SqlListTablesResponse;
import org.elasticsearch.xpack.sql.plugin.SqlQueryAction;
import org.elasticsearch.xpack.sql.plugin.SqlQueryResponse;
import org.hamcrest.Matchers;
@ -26,9 +24,6 @@ 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.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.emptyCollectionOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
@ -60,35 +55,6 @@ public class SqlActionIT extends AbstractSqlIntegTestCase {
assertEquals(43L, response.rows().get(1).get(countIndex));
}
public void testSqlListTablesAction() throws Exception {
createCompatibleIndex("foo");
createCompatibleIndex("bar");
createCompatibleIndex("baz");
createIncompatibleIndex("broken");
SqlListTablesResponse response = client().prepareExecute(SqlListTablesAction.INSTANCE)
.pattern("").get();
List<String> tables = removeInternal(response.getTables());
assertThat(tables, hasSize(4));
assertThat(tables, containsInAnyOrder("foo", "bar", "baz", "broken"));
response = client().prepareExecute(SqlListTablesAction.INSTANCE).pattern("b%").get();
tables = removeInternal(response.getTables());
assertThat(tables, hasSize(3));
assertThat(tables, containsInAnyOrder("bar", "baz", "broken"));
response = client().prepareExecute(SqlListTablesAction.INSTANCE).pattern("not_found").get();
tables = removeInternal(response.getTables());
assertThat(tables, emptyCollectionOf(String.class));
response = client().prepareExecute(SqlListTablesAction.INSTANCE).pattern("broken").get();
tables = removeInternal(response.getTables());
assertThat(tables, hasSize(1));
}
public void testSqlListColumnsAction() throws Exception {
createCompatibleIndex("bar");

View File

@ -0,0 +1,53 @@
/*
* 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.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.expression.function.FunctionRegistry;
import org.elasticsearch.xpack.sql.parser.SqlParser;
import org.elasticsearch.xpack.sql.plan.logical.command.Command;
import org.elasticsearch.xpack.sql.type.EsField;
import org.elasticsearch.xpack.sql.type.TypesTests;
import org.joda.time.DateTimeZone;
import java.util.List;
import java.util.Map;
import static java.util.Arrays.asList;
public class SysParserTests extends ESTestCase {
private final SqlParser parser = new SqlParser(DateTimeZone.UTC);
private Command sql(String sql) {
Map<String, EsField> mapping = TypesTests.loadMapping("mapping-multi-field-with-nested.json");
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);
}
public void testSysTypes() throws Exception {
Command cmd = sql("SYS TYPES");
List<String> names = asList("BYTE", "SHORT", "INTEGER", "LONG", "HALF_FLOAT", "SCALED_FLOAT", "FLOAT", "DOUBLE", "KEYWORD", "TEXT",
"DATE", "BINARY", "NULL", "UNSUPPORTED", "OBJECT", "NESTED", "BOOLEAN");
cmd.execute(null, ActionListener.wrap(r -> {
assertEquals(19, r.columnCount());
assertEquals(17, r.size());
for (int i = 0; i < r.size(); i++) {
assertEquals(names.get(i), r.column(0));
r.advanceRow();
}
}, ex -> fail(ex.getMessage())));
}
}

View File

@ -24,7 +24,7 @@ public class SqlPluginTests extends ESTestCase {
public void testSqlDisabled() {
SqlPlugin plugin = new SqlPlugin(false, new SqlLicenseChecker((mode) -> {}));
assertThat(plugin.createComponents(mock(Client.class)), empty());
assertThat(plugin.createComponents(mock(Client.class), "cluster"), empty());
assertThat(plugin.getActions(), empty());
assertThat(plugin.getRestHandlers(Settings.EMPTY, mock(RestController.class),
new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS),

View File

@ -180,7 +180,7 @@ public class TypesTests extends ESTestCase {
public void testGeoField() {
Map<String, EsField> mapping = loadMapping("mapping-geo.json");
EsField dt = mapping.get("location");
assertThat(dt.getDataType().esType, is("geo_point"));
assertThat(dt.getDataType().esType, is("unsupported"));
}
public void testUnsupportedTypes() {
@ -194,4 +194,10 @@ public class TypesTests extends ESTestCase {
assertNotNull("Could not find mapping resource:" + name, stream);
return Types.fromEs(XContentHelper.convertToMap(JsonXContent.jsonXContent, stream, randomBoolean()));
}
public static Map<String, EsField> loadMapping(String name, boolean ordered) {
InputStream stream = TypesTests.class.getResourceAsStream("/" + name);
assertNotNull("Could not find mapping resource:" + name, stream);
return Types.fromEs(XContentHelper.convertToMap(JsonXContent.jsonXContent, stream, ordered));
}
}

View File

@ -1,16 +0,0 @@
{
"xpack.sql.tables": {
"documentation": "Returns a list of tables supported by SQL for the current user",
"methods": [ "POST" ],
"url": {
"path": "/_xpack/sql/tables",
"paths": [ "/_xpack/sql/tables" ],
"parts": {},
"params": {}
},
"body": {
"description" : "Specify the table pattern in the `table_pattern` element.",
"required" : true
}
}
}

View File

@ -118,16 +118,6 @@ setup:
- match: { indices.test.total.search.open_contexts: 0 }
---
"Check list of tables":
- do:
xpack.sql.tables:
body:
table_pattern: "t%"
- length: { tables: 1 }
- match: { tables.0: 'test' }
---
"Check list of columns":
- do:

View File

@ -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/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]
- names: bort
privileges: [read, "indices:admin/get", "indices:admin/sql/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]
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/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]
read_test_a:
cluster:
- "cluster:monitor/main" # Used by JDBC's MetaData
indices:
- names: test
privileges: [read, "indices:admin/get", "indices:admin/sql/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]
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/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]
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/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]
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/tables", "indices:admin/sql/columns"]
privileges: [read, "indices:admin/get", "indices:admin/sql/columns"]

View File

@ -231,20 +231,12 @@ public class JdbcSecurityIT extends SqlSecurityTestCase {
con -> con.getMetaData().getTables("%", "%", "%t", null),
"full_access",
con -> con.getMetaData().getTables("%", "%", "%", null));
new AuditLogAsserter()
.expect(true, GetIndexAction.NAME, "test_admin", contains("bort", "test"))
.expect(true, GetIndexAction.NAME, "full_access", contains("bort", "test"))
.assertLogs();
}
public void testMetaDataGetTablesWithNoAccess() throws Exception {
createUser("no_access", "read_nothing");
expectForbidden("no_access", con -> con.getMetaData().getTables("%", "%", "%", null));
new AuditLogAsserter()
// TODO figure out why this generates *no* logs
// .expect(false, GetIndexAction.NAME, "no_access", contains("bort", "test"))
.assertLogs();
}
public void testMetaDataGetTablesWithLimitedAccess() throws Exception {
@ -254,10 +246,6 @@ public class JdbcSecurityIT extends SqlSecurityTestCase {
con -> con.getMetaData().getTables("%", "%", "bort", null),
"read_bort",
con -> con.getMetaData().getTables("%", "%", "%", null));
new AuditLogAsserter()
.expect(true, GetIndexAction.NAME, "test_admin", contains("bort"))
.expect(true, GetIndexAction.NAME, "read_bort", contains("bort"))
.assertLogs();
}
public void testMetaDataGetTablesWithInAccessibleIndex() throws Exception {
@ -267,10 +255,6 @@ public class JdbcSecurityIT extends SqlSecurityTestCase {
con -> con.getMetaData().getTables("%", "%", "not_created", null),
"read_bort",
con -> con.getMetaData().getTables("%", "%", "test", null));
new AuditLogAsserter()
.expect(true, GetIndexAction.NAME, "test_admin", contains("*", "-*"))
.expect(true, GetIndexAction.NAME, "read_bort", contains("*", "-*"))
.assertLogs();
}
public void testMetaDataGetColumnsWorksAsFullAccess() throws Exception {

View File

@ -17,6 +17,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.test.NotEqualMessageBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.sql.JDBCType;
@ -26,11 +27,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.xpack.qa.sql.rest.RestSqlTestCase.columnInfo;
import static java.util.Collections.singletonList;
import static org.elasticsearch.xpack.qa.sql.rest.RestSqlTestCase.randomMode;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
@ -116,7 +115,7 @@ public class RestSqlSecurityIT extends SqlSecurityTestCase {
for (String table : tables) {
List<String> fields = new ArrayList<>();
fields.add(table);
fields.add("INDEX");
fields.add("BASE TABLE");
rows.add(fields);
}
expected.put("rows", rows);

View File

@ -30,7 +30,7 @@ public class ShowTablesTestCase extends JdbcIntegrationTestCase {
for (int i = 0; i < indices; i++) {
String index = String.format(Locale.ROOT, "test%02d", i);
index(index, builder -> builder.field("name", "bob"));
h2.createStatement().executeUpdate("INSERT INTO mock VALUES ('" + index + "', 'INDEX');");
h2.createStatement().executeUpdate("INSERT INTO mock VALUES ('" + index + "', 'BASE TABLE');");
}
ResultSet expected = h2.createStatement().executeQuery("SELECT * FROM mock ORDER BY name");

View File

@ -84,8 +84,8 @@ name:s | type:s
test_alias | ALIAS
test_alias_emp | ALIAS
test_emp | INDEX
test_emp_copy | INDEX
test_emp | BASE TABLE
test_emp_copy | BASE TABLE
;
testGroupByOnAlias

View File

@ -112,7 +112,7 @@ showTables
SHOW TABLES 'test_emp';
name:s | type:s
test_emp |INDEX
test_emp |BASE TABLE
;
// DESCRIBE

View File

@ -9,7 +9,7 @@ CREATE TABLE mock (
SELF_REFERENCING_COL_NAME VARCHAR,
REF_GENERATION VARCHAR
) AS
SELECT '', 'test1', 'TABLE', '', null, null, null, null, null FROM DUAL
SELECT '', 'test1', 'BASE TABLE', '', null, null, null, null, null FROM DUAL
UNION ALL
SELECT '', 'test2', 'TABLE', '', null, null, null, null, null FROM DUAL
SELECT '', 'test2', 'BASE TABLE', '', null, null, null, null, null FROM DUAL
;