Remove support for indices with multiple types
Indices discovery actively ignores indices with more than one type. However queries made such indices throw an exception (assuming the user by mistake or not, selects such an index). Original commit: elastic/x-pack-elasticsearch@16855c7b8f
This commit is contained in:
parent
38ea150f17
commit
0675d08f25
|
@ -5,43 +5,46 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.cli;
|
package org.elasticsearch.xpack.sql.cli;
|
||||||
|
|
||||||
|
import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
@AwaitsFix(bugUrl = "https://github.com/elastic/x-pack-elasticsearch/issues/2074")
|
||||||
public class ExplainIT extends CliIntegrationTestCase {
|
public class ExplainIT extends CliIntegrationTestCase {
|
||||||
public void testExplainBasic() throws IOException {
|
public void testExplainBasic() throws IOException {
|
||||||
index("test", body -> body.field("test_field", "test_value"));
|
index("test", body -> body.field("test_field", "test_value"));
|
||||||
|
|
||||||
command("EXPLAIN (PLAN PARSED) SELECT * FROM test.doc");
|
command("EXPLAIN (PLAN PARSED) SELECT * FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("With[{}]"));
|
assertThat(in.readLine(), startsWith("With[{}]"));
|
||||||
assertThat(in.readLine(), startsWith("\\_Project[[?*]]"));
|
assertThat(in.readLine(), startsWith("\\_Project[[?*]]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_UnresolvedRelation[[index=test, type=doc],null]"));
|
assertThat(in.readLine(), startsWith(" \\_UnresolvedRelation[[test],null]"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT * FROM test.doc");
|
command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT * FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("Project[[test_field{r}#"));
|
assertThat(in.readLine(), startsWith("Project[[test_field{r}#"));
|
||||||
assertThat(in.readLine(), startsWith("\\_SubQueryAlias[doc]"));
|
assertThat(in.readLine(), startsWith("\\_SubQueryAlias[doc]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_CatalogTable[index=test,type=doc][test_field{r}#"));
|
assertThat(in.readLine(), startsWith(" \\_CatalogTable[test][test_field{r}#"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test.doc");
|
command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("Project[[test_field{r}#"));
|
assertThat(in.readLine(), startsWith("Project[[test_field{r}#"));
|
||||||
assertThat(in.readLine(), startsWith("\\_CatalogTable[index=test,type=doc][test_field{r}#"));
|
assertThat(in.readLine(), startsWith("\\_CatalogTable[test][test_field{r}#"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
// TODO in this case we should probably remove the source filtering entirely. Right? It costs but we don't need it.
|
// TODO in this case we should probably remove the source filtering entirely. Right? It costs but we don't need it.
|
||||||
command("EXPLAIN (PLAN EXECUTABLE) SELECT * FROM test.doc");
|
command("EXPLAIN (PLAN EXECUTABLE) SELECT * FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("EsQueryExec[test/doc,{"));
|
assertThat(in.readLine(), startsWith("EsQueryExec[test,{"));
|
||||||
assertThat(in.readLine(), startsWith(" \"_source\" : {"));
|
assertThat(in.readLine(), startsWith(" \"_source\" : {"));
|
||||||
assertThat(in.readLine(), startsWith(" \"includes\" : ["));
|
assertThat(in.readLine(), startsWith(" \"includes\" : ["));
|
||||||
assertThat(in.readLine(), startsWith(" \"test_field\""));
|
assertThat(in.readLine(), startsWith(" \"test_field\""));
|
||||||
|
@ -56,36 +59,36 @@ public class ExplainIT extends CliIntegrationTestCase {
|
||||||
index("test", body -> body.field("test_field", "test_value1").field("i", 1));
|
index("test", body -> body.field("test_field", "test_value1").field("i", 1));
|
||||||
index("test", body -> body.field("test_field", "test_value2").field("i", 2));
|
index("test", body -> body.field("test_field", "test_value2").field("i", 2));
|
||||||
|
|
||||||
command("EXPLAIN (PLAN PARSED) SELECT * FROM test.doc WHERE i = 2");
|
command("EXPLAIN (PLAN PARSED) SELECT * FROM test WHERE i = 2");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("With[{}]"));
|
assertThat(in.readLine(), startsWith("With[{}]"));
|
||||||
assertThat(in.readLine(), startsWith("\\_Project[[?*]]"));
|
assertThat(in.readLine(), startsWith("\\_Project[[?*]]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_Filter[?i = 2]"));
|
assertThat(in.readLine(), startsWith(" \\_Filter[?i = 2]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_UnresolvedRelation[[index=test, type=doc],null]"));
|
assertThat(in.readLine(), startsWith(" \\_UnresolvedRelation[[type],null]"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT * FROM test.doc WHERE i = 2");
|
command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT * FROM test WHERE i = 2");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("Project[[i{r}#"));
|
assertThat(in.readLine(), startsWith("Project[[i{r}#"));
|
||||||
assertThat(in.readLine(), startsWith("\\_Filter[i{r}#"));
|
assertThat(in.readLine(), startsWith("\\_Filter[i{r}#"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_SubQueryAlias[doc]"));
|
assertThat(in.readLine(), startsWith(" \\_SubQueryAlias[doc]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_CatalogTable[index=test,type=doc][i{r}#"));
|
assertThat(in.readLine(), startsWith(" \\_CatalogTable[test][i{r}#"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test.doc WHERE i = 2");
|
command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test WHERE i = 2");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("Project[[i{r}#"));
|
assertThat(in.readLine(), startsWith("Project[[i{r}#"));
|
||||||
assertThat(in.readLine(), startsWith("\\_Filter[i{r}#"));
|
assertThat(in.readLine(), startsWith("\\_Filter[i{r}#"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_CatalogTable[index=test,type=doc][i{r}#"));
|
assertThat(in.readLine(), startsWith(" \\_CatalogTable[test][i{r}#"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN (PLAN EXECUTABLE) SELECT * FROM test.doc WHERE i = 2");
|
command("EXPLAIN (PLAN EXECUTABLE) SELECT * FROM test WHERE i = 2");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("EsQueryExec[test/doc,{"));
|
assertThat(in.readLine(), startsWith("EsQueryExec[test,{"));
|
||||||
assertThat(in.readLine(), startsWith(" \"query\" : {"));
|
assertThat(in.readLine(), startsWith(" \"query\" : {"));
|
||||||
assertThat(in.readLine(), startsWith(" \"term\" : {"));
|
assertThat(in.readLine(), startsWith(" \"term\" : {"));
|
||||||
assertThat(in.readLine(), startsWith(" \"i\" : {"));
|
assertThat(in.readLine(), startsWith(" \"i\" : {"));
|
||||||
|
@ -112,33 +115,33 @@ public class ExplainIT extends CliIntegrationTestCase {
|
||||||
index("test", body -> body.field("test_field", "test_value1").field("i", 1));
|
index("test", body -> body.field("test_field", "test_value1").field("i", 1));
|
||||||
index("test", body -> body.field("test_field", "test_value2").field("i", 2));
|
index("test", body -> body.field("test_field", "test_value2").field("i", 2));
|
||||||
|
|
||||||
command("EXPLAIN (PLAN PARSED) SELECT COUNT(*) FROM test.doc");
|
command("EXPLAIN (PLAN PARSED) SELECT COUNT(*) FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("With[{}]"));
|
assertThat(in.readLine(), startsWith("With[{}]"));
|
||||||
assertThat(in.readLine(), startsWith("\\_Project[[?COUNT(?*)]]"));
|
assertThat(in.readLine(), startsWith("\\_Project[[?COUNT(?*)]]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_UnresolvedRelation[[index=test, type=doc],null]"));
|
assertThat(in.readLine(), startsWith(" \\_UnresolvedRelation[[test],null]"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT COUNT(*) FROM test.doc");
|
command("EXPLAIN " + (randomBoolean() ? "" : "(PLAN ANALYZED) ") + "SELECT COUNT(*) FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("Aggregate[[],[COUNT(1)#"));
|
assertThat(in.readLine(), startsWith("Aggregate[[],[COUNT(1)#"));
|
||||||
assertThat(in.readLine(), startsWith("\\_SubQueryAlias[doc]"));
|
assertThat(in.readLine(), startsWith("\\_SubQueryAlias[doc]"));
|
||||||
assertThat(in.readLine(), startsWith(" \\_CatalogTable[index=test,type=doc][i{r}#"));
|
assertThat(in.readLine(), startsWith(" \\_CatalogTable[test][i{r}#"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN (PLAN OPTIMIZED) SELECT COUNT(*) FROM test.doc");
|
command("EXPLAIN (PLAN OPTIMIZED) SELECT COUNT(*) FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("Aggregate[[],[COUNT(1)#"));
|
assertThat(in.readLine(), startsWith("Aggregate[[],[COUNT(1)#"));
|
||||||
assertThat(in.readLine(), startsWith("\\_CatalogTable[index=test,type=doc][i{r}#"));
|
assertThat(in.readLine(), startsWith("\\_CatalogTable[test][i{r}#"));
|
||||||
assertEquals("", in.readLine());
|
assertEquals("", in.readLine());
|
||||||
|
|
||||||
command("EXPLAIN (PLAN EXECUTABLE) SELECT COUNT(*) FROM test.doc");
|
command("EXPLAIN (PLAN EXECUTABLE) SELECT COUNT(*) FROM test");
|
||||||
assertThat(in.readLine(), containsString("plan"));
|
assertThat(in.readLine(), containsString("plan"));
|
||||||
assertThat(in.readLine(), startsWith("----------"));
|
assertThat(in.readLine(), startsWith("----------"));
|
||||||
assertThat(in.readLine(), startsWith("EsQueryExec[test/doc,{"));
|
assertThat(in.readLine(), startsWith("EsQueryExec[test,{"));
|
||||||
assertThat(in.readLine(), startsWith(" \"size\" : 0,"));
|
assertThat(in.readLine(), startsWith(" \"size\" : 0,"));
|
||||||
assertThat(in.readLine(), startsWith(" \"_source\" : false,"));
|
assertThat(in.readLine(), startsWith(" \"_source\" : false,"));
|
||||||
assertThat(in.readLine(), startsWith(" \"stored_fields\" : \"_none_\""));
|
assertThat(in.readLine(), startsWith(" \"stored_fields\" : \"_none_\""));
|
||||||
|
|
|
@ -134,9 +134,9 @@ public class JdbcHttpClient implements Closeable {
|
||||||
ExceptionResponse ex = (ExceptionResponse) response;
|
ExceptionResponse ex = (ExceptionResponse) response;
|
||||||
throw ex.asException();
|
throw ex.asException();
|
||||||
}
|
}
|
||||||
if (response.responseType() == ResponseType.EXCEPTION) {
|
if (response.responseType() == ResponseType.ERROR) {
|
||||||
ErrorResponse error = (ErrorResponse) response;
|
ErrorResponse error = (ErrorResponse) response;
|
||||||
throw new JdbcException("%s", error.stack);
|
throw new JdbcException("Server returned error: %s", error.stack);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@ public class CsvSpecIT extends SpecBaseIntegrationTestCase {
|
||||||
assertMatchesCsv(testCase.query, testName, testCase.expectedResults);
|
assertMatchesCsv(testCase.query, testName, testCase.expectedResults);
|
||||||
} catch (AssertionError ae) {
|
} catch (AssertionError ae) {
|
||||||
throw reworkException(new AssertionError(errorMessage(ae), ae.getCause()));
|
throw reworkException(new AssertionError(errorMessage(ae), ae.getCause()));
|
||||||
} catch (Throwable th) {
|
|
||||||
throw reworkException(th);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,24 +9,28 @@ import org.elasticsearch.xpack.sql.jdbc.framework.JdbcIntegrationTestCase;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for error messages.
|
* Tests for error messages.
|
||||||
*/
|
*/
|
||||||
public class ErrorsIT extends JdbcIntegrationTestCase {
|
public class ErrorsIT extends JdbcIntegrationTestCase {
|
||||||
|
|
||||||
|
String message(String index) {
|
||||||
|
return String.format(Locale.ROOT, "line 1:15: Cannot resolve index %s (does not exist or has multiple types)", index);
|
||||||
|
}
|
||||||
public void testSelectFromMissingTable() throws Exception {
|
public void testSelectFromMissingTable() throws Exception {
|
||||||
try (Connection c = esJdbc()) {
|
try (Connection c = esJdbc()) {
|
||||||
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from test.doc").executeQuery());
|
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from test").executeQuery());
|
||||||
assertEquals("line 1:15: Cannot resolve index test", e.getMessage());
|
assertEquals(message("test"), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSelectFromMissingType() throws Exception {
|
public void testMultiTypeIndex() throws Exception {
|
||||||
index("test", builder -> builder.field("name", "bob"));
|
|
||||||
|
|
||||||
try (Connection c = esJdbc()) {
|
try (Connection c = esJdbc()) {
|
||||||
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from test.notdoc").executeQuery());
|
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from multi_type").executeQuery());
|
||||||
assertEquals("line 1:15: Cannot resolve type notdoc in index test", e.getMessage());
|
assertEquals(message("multi_type"), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ public class SqlSpecIT extends SpecBaseIntegrationTestCase {
|
||||||
|
|
||||||
@ParametersFactory(shuffle = false, argumentFormatting = PARAM_FORMATTNG)
|
@ParametersFactory(shuffle = false, argumentFormatting = PARAM_FORMATTNG)
|
||||||
public static List<Object[]> readScriptSpec() throws Exception {
|
public static List<Object[]> readScriptSpec() throws Exception {
|
||||||
|
|
||||||
|
// example for enabling logging
|
||||||
|
//JdbcTestUtils.sqlLogging();
|
||||||
|
|
||||||
SqlSpecParser parser = new SqlSpecParser();
|
SqlSpecParser parser = new SqlSpecParser();
|
||||||
return CollectionUtils.combine(
|
return CollectionUtils.combine(
|
||||||
readScriptSpec("/select.sql-spec", parser),
|
readScriptSpec("/select.sql-spec", parser),
|
||||||
|
@ -70,14 +74,14 @@ public class SqlSpecIT extends SpecBaseIntegrationTestCase {
|
||||||
} catch (AssertionError ae) {
|
} catch (AssertionError ae) {
|
||||||
throw reworkException(new AssertionError(errorMessage(ae), ae.getCause()));
|
throw reworkException(new AssertionError(errorMessage(ae), ae.getCause()));
|
||||||
}
|
}
|
||||||
} catch (Throwable th) {
|
|
||||||
throw reworkException(th);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultSet executeQuery(Connection con) throws SQLException {
|
private ResultSet executeQuery(Connection con) throws SQLException {
|
||||||
Statement statement = con.createStatement();
|
Statement statement = con.createStatement();
|
||||||
statement.setFetchSize(randomInt(10));
|
//statement.setFetchSize(randomInt(10));
|
||||||
|
// NOCOMMIT: hook up pagination
|
||||||
|
statement.setFetchSize(1000);
|
||||||
return statement.executeQuery(query);
|
return statement.executeQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.elasticsearch.client.http.entity.ContentType;
|
||||||
import org.elasticsearch.client.http.entity.StringEntity;
|
import org.elasticsearch.client.http.entity.StringEntity;
|
||||||
import org.elasticsearch.common.CheckedBiConsumer;
|
import org.elasticsearch.common.CheckedBiConsumer;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.SqlSpecIT;
|
import org.elasticsearch.xpack.sql.jdbc.SqlSpecIT;
|
||||||
|
@ -26,8 +27,10 @@ import static java.util.Collections.singletonMap;
|
||||||
public class DataLoader {
|
public class DataLoader {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
RestClient client = RestClient.builder(new HttpHost("localhost", 9200)).build();
|
try (RestClient client = RestClient.builder(new HttpHost("localhost", 9200)).build()) {
|
||||||
loadDatasetIntoEs(client);
|
loadDatasetIntoEs(client);
|
||||||
|
Loggers.getLogger(DataLoader.class).info("Data loaded");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void loadDatasetIntoEs(RestClient client) throws Exception {
|
protected static void loadDatasetIntoEs(RestClient client) throws Exception {
|
||||||
|
@ -70,6 +73,7 @@ public class DataLoader {
|
||||||
bulk.append("}\n");
|
bulk.append("}\n");
|
||||||
});
|
});
|
||||||
client.performRequest("POST", "/test_emp/emp/_bulk", singletonMap("refresh", "true"), new StringEntity(bulk.toString(), ContentType.APPLICATION_JSON));
|
client.performRequest("POST", "/test_emp/emp/_bulk", singletonMap("refresh", "true"), new StringEntity(bulk.toString(), ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void csvToLines(String name, CheckedBiConsumer<List<String>, List<String>, Exception> consumeLine) throws Exception {
|
private static void csvToLines(String name, CheckedBiConsumer<List<String>, List<String>, Exception> consumeLine) throws Exception {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.jdbc.framework;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.xpack.sql.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public abstract class JdbcTestUtils {
|
||||||
|
|
||||||
|
public static void sqlLogging() {
|
||||||
|
String t = "TRACE";
|
||||||
|
String d = "DEBUG";
|
||||||
|
|
||||||
|
Map<String, String> of = CollectionUtils.of("org.elasticsearch.xpack.sql.parser", t,
|
||||||
|
"org.elasticsearch.xpack.sql.analysis.analyzer", t,
|
||||||
|
"org.elasticsearch.xpack.sql.optimizer", t,
|
||||||
|
"org.elasticsearch.xpack.sql.rule", t,
|
||||||
|
"org.elasticsearch.xpack.sql.planner", t,
|
||||||
|
"org.elasticsearch.xpack.sql.execution.search", t);
|
||||||
|
|
||||||
|
for (Entry<String, String> entry : of.entrySet()) {
|
||||||
|
Loggers.setLevel(Loggers.getLogger(entry.getKey()), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,14 +5,11 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.framework;
|
package org.elasticsearch.xpack.sql.jdbc.framework;
|
||||||
|
|
||||||
import org.elasticsearch.client.ResponseException;
|
|
||||||
import org.elasticsearch.common.Booleans;
|
import org.elasticsearch.common.Booleans;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.PathUtils;
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -46,21 +43,9 @@ public abstract class SpecBaseIntegrationTestCase extends JdbcIntegrationTestCas
|
||||||
loadDatasetIntoEs();
|
loadDatasetIntoEs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void cleanupTestData() throws IOException {
|
|
||||||
try {
|
|
||||||
client().performRequest("DELETE", "/*");
|
|
||||||
} catch (ResponseException e) {
|
|
||||||
if (e.getResponse().getStatusLine().getStatusCode() != 404) {
|
|
||||||
// 404 means no indices which shouldn't cause a failure
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean preserveIndicesUponCompletion() {
|
protected boolean preserveIndicesUponCompletion() {
|
||||||
return true;
|
return !SETUP_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpecBaseIntegrationTestCase(String groupName, String testName, Integer lineNumber, Path source) {
|
public SpecBaseIntegrationTestCase(String groupName, String testName, Integer lineNumber, Path source) {
|
||||||
|
|
|
@ -3,33 +3,33 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
groupByOnText
|
groupByOnText
|
||||||
SELECT gender g FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g FROM "test_emp" GROUP BY gender;
|
||||||
groupByOnTextWithWhereClause
|
groupByOnTextWithWhereClause
|
||||||
SELECT gender g FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender;
|
SELECT gender g FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender;
|
||||||
groupByOnTextWithWhereAndLimit
|
groupByOnTextWithWhereAndLimit
|
||||||
SELECT gender g FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender LIMIT 1;
|
SELECT gender g FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender LIMIT 1;
|
||||||
groupByOnTextOnAlias
|
groupByOnTextOnAlias
|
||||||
SELECT gender g FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY g;
|
SELECT gender g FROM "test_emp" WHERE emp_no < 10020 GROUP BY g;
|
||||||
groupByOnTextOnAliasOrderDesc
|
groupByOnTextOnAliasOrderDesc
|
||||||
SELECT gender g FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY g ORDER BY g DESC;
|
SELECT gender g FROM "test_emp" WHERE emp_no < 10020 GROUP BY g ORDER BY g DESC;
|
||||||
|
|
||||||
groupByOnDate
|
groupByOnDate
|
||||||
SELECT birth_date b FROM "test_emp.emp" GROUP BY birth_date ORDER BY birth_date DESC;
|
SELECT birth_date b FROM "test_emp" GROUP BY birth_date ORDER BY birth_date DESC;
|
||||||
groupByOnDateWithWhereClause
|
groupByOnDateWithWhereClause
|
||||||
SELECT birth_date b FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY birth_date ORDER BY birth_date DESC;
|
SELECT birth_date b FROM "test_emp" WHERE emp_no < 10020 GROUP BY birth_date ORDER BY birth_date DESC;
|
||||||
groupByOnDateWithWhereAndLimit
|
groupByOnDateWithWhereAndLimit
|
||||||
SELECT birth_date b FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY birth_date ORDER BY birth_date DESC LIMIT 1;
|
SELECT birth_date b FROM "test_emp" WHERE emp_no < 10020 GROUP BY birth_date ORDER BY birth_date DESC LIMIT 1;
|
||||||
groupByOnDateOnAlias
|
groupByOnDateOnAlias
|
||||||
SELECT birth_date b FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY b ORDER BY birth_date DESC;
|
SELECT birth_date b FROM "test_emp" WHERE emp_no < 10020 GROUP BY b ORDER BY birth_date DESC;
|
||||||
|
|
||||||
groupByOnNumber
|
groupByOnNumber
|
||||||
SELECT emp_no e FROM "test_emp.emp" GROUP BY emp_no ORDER BY emp_no DESC;
|
SELECT emp_no e FROM "test_emp" GROUP BY emp_no ORDER BY emp_no DESC;
|
||||||
groupByOnNumberWithWhereClause
|
groupByOnNumberWithWhereClause
|
||||||
SELECT emp_no e FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY emp_no ORDER BY emp_no DESC;
|
SELECT emp_no e FROM "test_emp" WHERE emp_no < 10020 GROUP BY emp_no ORDER BY emp_no DESC;
|
||||||
groupByOnNumberWithWhereAndLimit
|
groupByOnNumberWithWhereAndLimit
|
||||||
SELECT emp_no e FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY emp_no ORDER BY emp_no DESC LIMIT 1;
|
SELECT emp_no e FROM "test_emp" WHERE emp_no < 10020 GROUP BY emp_no ORDER BY emp_no DESC LIMIT 1;
|
||||||
groupByOnNumberOnAlias
|
groupByOnNumberOnAlias
|
||||||
SELECT emp_no e FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY e ORDER BY emp_no DESC;
|
SELECT emp_no e FROM "test_emp" WHERE emp_no < 10020 GROUP BY e ORDER BY emp_no DESC;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Aggregate Functions
|
// Aggregate Functions
|
||||||
|
@ -37,160 +37,160 @@ SELECT emp_no e FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY e ORDER BY emp
|
||||||
|
|
||||||
// COUNT
|
// COUNT
|
||||||
aggCountImplicit
|
aggCountImplicit
|
||||||
SELECT COUNT(*) c FROM "test_emp.emp";
|
SELECT COUNT(*) c FROM "test_emp";
|
||||||
aggCountImplicitWithCast
|
aggCountImplicitWithCast
|
||||||
SELECT CAST(COUNT(*) AS INT) c FROM "test_emp.emp";
|
SELECT CAST(COUNT(*) AS INT) c FROM "test_emp";
|
||||||
aggCountImplicitWithConstant
|
aggCountImplicitWithConstant
|
||||||
SELECT COUNT(1) FROM "test_emp.emp";
|
SELECT COUNT(1) FROM "test_emp";
|
||||||
aggCountImplicitWithConstantAndFilter
|
aggCountImplicitWithConstantAndFilter
|
||||||
SELECT COUNT(1) FROM "test_emp.emp" WHERE emp_no < 10010;
|
SELECT COUNT(1) FROM "test_emp" WHERE emp_no < 10010;
|
||||||
aggCountAliasAndWhereClause
|
aggCountAliasAndWhereClause
|
||||||
SELECT gender g, COUNT(*) c FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender;
|
SELECT gender g, COUNT(*) c FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender;
|
||||||
aggCountAliasAndWhereClauseAndLimit
|
aggCountAliasAndWhereClauseAndLimit
|
||||||
SELECT gender g, COUNT(*) c FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender LIMIT 1;
|
SELECT gender g, COUNT(*) c FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender LIMIT 1;
|
||||||
aggCountAliasWithCastAndFilter
|
aggCountAliasWithCastAndFilter
|
||||||
SELECT gender g, CAST(COUNT(*) AS INT) c FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender;
|
SELECT gender g, CAST(COUNT(*) AS INT) c FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender;
|
||||||
aggCountWithAlias
|
aggCountWithAlias
|
||||||
SELECT gender g, COUNT(*) c FROM "test_emp.emp" GROUP BY g;
|
SELECT gender g, COUNT(*) c FROM "test_emp" GROUP BY g;
|
||||||
|
|
||||||
// Conditional COUNT
|
// Conditional COUNT
|
||||||
aggCountAndHaving
|
aggCountAndHaving
|
||||||
SELECT gender g, COUNT(*) c FROM "test_emp.emp" GROUP BY g HAVING COUNT(*) > 10;
|
SELECT gender g, COUNT(*) c FROM "test_emp" GROUP BY g HAVING COUNT(*) > 10;
|
||||||
aggCountOnColumnAndHaving
|
aggCountOnColumnAndHaving
|
||||||
SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING COUNT(gender) > 10;
|
SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING COUNT(gender) > 10;
|
||||||
// NOT supported yet since Having introduces a new agg
|
// NOT supported yet since Having introduces a new agg
|
||||||
//aggCountOnColumnAndWildcardAndHaving
|
//aggCountOnColumnAndWildcardAndHaving
|
||||||
//SELECT gender g, COUNT(*) c FROM "test_emp.emp" GROUP BY g HAVING COUNT(gender) > 10;
|
//SELECT gender g, COUNT(*) c FROM "test_emp" GROUP BY g HAVING COUNT(gender) > 10;
|
||||||
aggCountAndHavingOnAlias
|
aggCountAndHavingOnAlias
|
||||||
SELECT gender g, COUNT(*) c FROM "test_emp.emp" GROUP BY g HAVING c > 10;
|
SELECT gender g, COUNT(*) c FROM "test_emp" GROUP BY g HAVING c > 10;
|
||||||
aggCountOnColumnAndHavingOnAlias
|
aggCountOnColumnAndHavingOnAlias
|
||||||
SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING c > 10;
|
SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING c > 10;
|
||||||
aggCountOnColumnAndMultipleHaving
|
aggCountOnColumnAndMultipleHaving
|
||||||
SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING c > 10 AND c < 70;
|
SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING c > 10 AND c < 70;
|
||||||
aggCountOnColumnAndMultipleHavingWithLimit
|
aggCountOnColumnAndMultipleHavingWithLimit
|
||||||
SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING c > 10 AND c < 70 LIMIT 1;
|
SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING c > 10 AND c < 70 LIMIT 1;
|
||||||
aggCountOnColumnAndHavingOnAliasAndFunction
|
aggCountOnColumnAndHavingOnAliasAndFunction
|
||||||
SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING c > 10 AND COUNT(gender) < 70;
|
SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING c > 10 AND COUNT(gender) < 70;
|
||||||
// NOT supported yet since Having introduces a new agg
|
// NOT supported yet since Having introduces a new agg
|
||||||
//aggCountOnColumnAndHavingOnAliasAndFunctionWildcard -> COUNT(*/1) vs COUNT(gender)
|
//aggCountOnColumnAndHavingOnAliasAndFunctionWildcard -> COUNT(*/1) vs COUNT(gender)
|
||||||
//SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING c > 10 AND COUNT(*) < 70;
|
//SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING c > 10 AND COUNT(*) < 70;
|
||||||
//aggCountOnColumnAndHavingOnAliasAndFunctionConstant
|
//aggCountOnColumnAndHavingOnAliasAndFunctionConstant
|
||||||
//SELECT gender g, COUNT(gender) c FROM "test_emp.emp" GROUP BY g HAVING c > 10 AND COUNT(1) < 70;
|
//SELECT gender g, COUNT(gender) c FROM "test_emp" GROUP BY g HAVING c > 10 AND COUNT(1) < 70;
|
||||||
|
|
||||||
|
|
||||||
// MIN
|
// MIN
|
||||||
aggMinImplicit
|
aggMinImplicit
|
||||||
SELECT MIN(emp_no) m FROM "test_emp.emp";
|
SELECT MIN(emp_no) m FROM "test_emp";
|
||||||
aggMinImplicitWithCast
|
aggMinImplicitWithCast
|
||||||
SELECT CAST(MIN(emp_no) AS SMALLINT) m FROM "test_emp.emp";
|
SELECT CAST(MIN(emp_no) AS SMALLINT) m FROM "test_emp";
|
||||||
aggMin
|
aggMin
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY gender;
|
||||||
aggMinWithCast
|
aggMinWithCast
|
||||||
SELECT CAST(MIN(emp_no) AS SMALLINT) m FROM "test_emp.emp" GROUP BY gender;
|
SELECT CAST(MIN(emp_no) AS SMALLINT) m FROM "test_emp" GROUP BY gender;
|
||||||
aggMinAndCount
|
aggMinAndCount
|
||||||
SELECT MIN(emp_no) m, COUNT(1) c FROM "test_emp.emp" GROUP BY gender;
|
SELECT MIN(emp_no) m, COUNT(1) c FROM "test_emp" GROUP BY gender;
|
||||||
aggMinAndCountWithFilter
|
aggMinAndCountWithFilter
|
||||||
SELECT MIN(emp_no) m, COUNT(1) c FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender ;
|
SELECT MIN(emp_no) m, COUNT(1) c FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender ;
|
||||||
aggMinAndCountWithFilterAndLimit
|
aggMinAndCountWithFilterAndLimit
|
||||||
SELECT MIN(emp_no) m, COUNT(1) c FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender LIMIT 1;
|
SELECT MIN(emp_no) m, COUNT(1) c FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender LIMIT 1;
|
||||||
aggMinWithCastAndFilter
|
aggMinWithCastAndFilter
|
||||||
SELECT gender g, CAST(MIN(emp_no) AS SMALLINT) m, COUNT(1) c FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY gender;
|
SELECT gender g, CAST(MIN(emp_no) AS SMALLINT) m, COUNT(1) c FROM "test_emp" WHERE emp_no < 10020 GROUP BY gender;
|
||||||
aggMinWithAlias
|
aggMinWithAlias
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY g;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY g;
|
||||||
|
|
||||||
// Conditional MIN
|
// Conditional MIN
|
||||||
aggMinWithHaving
|
aggMinWithHaving
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING MIN(emp_no) > 10;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY g HAVING MIN(emp_no) > 10;
|
||||||
aggMinWithHavingOnAlias
|
aggMinWithHavingOnAlias
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10;
|
||||||
aggMinWithMultipleHaving
|
aggMinWithMultipleHaving
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10 AND m < 99999;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10 AND m < 99999;
|
||||||
aggMinWithMultipleHavingWithLimit
|
aggMinWithMultipleHavingWithLimit
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10 AND m < 99999 LIMIT 1;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10 AND m < 99999 LIMIT 1;
|
||||||
aggMinWithMultipleHavingOnAliasAndFunction
|
aggMinWithMultipleHavingOnAliasAndFunction
|
||||||
SELECT gender g, MIN(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10 AND MIN(emp_no) < 99999;
|
SELECT gender g, MIN(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10 AND MIN(emp_no) < 99999;
|
||||||
|
|
||||||
// MAX
|
// MAX
|
||||||
aggMaxImplicit
|
aggMaxImplicit
|
||||||
SELECT MAX(emp_no) c FROM "test_emp.emp";
|
SELECT MAX(emp_no) c FROM "test_emp";
|
||||||
aggMaxImplicitWithCast
|
aggMaxImplicitWithCast
|
||||||
SELECT CAST(MAX(emp_no) AS SMALLINT) c FROM "test_emp.emp";
|
SELECT CAST(MAX(emp_no) AS SMALLINT) c FROM "test_emp";
|
||||||
aggMax
|
aggMax
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY gender ;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY gender ;
|
||||||
aggMaxWithCast
|
aggMaxWithCast
|
||||||
SELECT gender g, CAST(MAX(emp_no) AS SMALLINT) m FROM "test_emp.emp" GROUP BY gender ;
|
SELECT gender g, CAST(MAX(emp_no) AS SMALLINT) m FROM "test_emp" GROUP BY gender ;
|
||||||
aggMaxAndCount
|
aggMaxAndCount
|
||||||
SELECT MAX(emp_no) m, COUNT(1) c FROM "test_emp.emp" GROUP BY gender;
|
SELECT MAX(emp_no) m, COUNT(1) c FROM "test_emp" GROUP BY gender;
|
||||||
aggMaxAndCountWithFilter
|
aggMaxAndCountWithFilter
|
||||||
SELECT gender g, MAX(emp_no) m, COUNT(1) c FROM "test_emp.emp" WHERE emp_no > 10000 GROUP BY gender;
|
SELECT gender g, MAX(emp_no) m, COUNT(1) c FROM "test_emp" WHERE emp_no > 10000 GROUP BY gender;
|
||||||
aggMaxAndCountWithFilterAndLimit
|
aggMaxAndCountWithFilterAndLimit
|
||||||
SELECT gender g, MAX(emp_no) m, COUNT(1) c FROM "test_emp.emp" WHERE emp_no > 10000 GROUP BY gender LIMIT 1;
|
SELECT gender g, MAX(emp_no) m, COUNT(1) c FROM "test_emp" WHERE emp_no > 10000 GROUP BY gender LIMIT 1;
|
||||||
aggMaxWithAlias
|
aggMaxWithAlias
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY g;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY g;
|
||||||
|
|
||||||
// Conditional MAX
|
// Conditional MAX
|
||||||
aggMaxWithHaving
|
aggMaxWithHaving
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING MAX(emp_no) > 10;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY g HAVING MAX(emp_no) > 10;
|
||||||
aggMaxWithHavingOnAlias
|
aggMaxWithHavingOnAlias
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10;
|
||||||
aggMaxWithMultipleHaving
|
aggMaxWithMultipleHaving
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10 AND m < 99999;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10 AND m < 99999;
|
||||||
aggMaxWithMultipleHavingWithLimit
|
aggMaxWithMultipleHavingWithLimit
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10 AND m < 99999 LIMIT 1;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10 AND m < 99999 LIMIT 1;
|
||||||
aggMaxWithMultipleHavingOnAliasAndFunction
|
aggMaxWithMultipleHavingOnAliasAndFunction
|
||||||
SELECT gender g, MAX(emp_no) m FROM "test_emp.emp" GROUP BY g HAVING m > 10 AND MAX(emp_no) < 99999;
|
SELECT gender g, MAX(emp_no) m FROM "test_emp" GROUP BY g HAVING m > 10 AND MAX(emp_no) < 99999;
|
||||||
|
|
||||||
// SUM
|
// SUM
|
||||||
aggSumImplicitWithCast
|
aggSumImplicitWithCast
|
||||||
SELECT CAST(SUM(emp_no) AS BIGINT) s FROM "test_emp.emp";
|
SELECT CAST(SUM(emp_no) AS BIGINT) s FROM "test_emp";
|
||||||
aggSumWithCast
|
aggSumWithCast
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s FROM "test_emp" GROUP BY gender;
|
||||||
aggSumWithCastAndCount
|
aggSumWithCastAndCount
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s, COUNT(1) c FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s, COUNT(1) c FROM "test_emp" GROUP BY gender;
|
||||||
aggSumWithCastAndCountWithFilter
|
aggSumWithCastAndCountWithFilter
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s, COUNT(1) c FROM "test_emp.emp" WHERE emp_no > 10000 GROUP BY gender;
|
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s, COUNT(1) c FROM "test_emp" WHERE emp_no > 10000 GROUP BY gender;
|
||||||
aggSumWithCastAndCountWithFilterAndLimit
|
aggSumWithCastAndCountWithFilterAndLimit
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s, COUNT(1) c FROM "test_emp.emp" WHERE emp_no > 10000 GROUP BY gender LIMIT 1;
|
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s, COUNT(1) c FROM "test_emp" WHERE emp_no > 10000 GROUP BY gender LIMIT 1;
|
||||||
aggSumWithAlias
|
aggSumWithAlias
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s FROM "test_emp.emp" GROUP BY g;
|
SELECT gender g, CAST(SUM(emp_no) AS BIGINT) s FROM "test_emp" GROUP BY g;
|
||||||
|
|
||||||
// Conditional SUM
|
// Conditional SUM
|
||||||
aggSumWithHaving
|
aggSumWithHaving
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY g HAVING SUM(emp_no) > 10;
|
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY g HAVING SUM(emp_no) > 10;
|
||||||
aggSumWithHavingOnAlias
|
aggSumWithHavingOnAlias
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY g HAVING s > 10;
|
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY g HAVING s > 10;
|
||||||
aggSumWithMultipleHaving
|
aggSumWithMultipleHaving
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY g HAVING s > 10 AND s < 10000000;
|
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY g HAVING s > 10 AND s < 10000000;
|
||||||
aggSumWithMultipleHavingWithLimit
|
aggSumWithMultipleHavingWithLimit
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY g HAVING s > 10 AND s < 10000000 LIMIT 1;
|
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY g HAVING s > 10 AND s < 10000000 LIMIT 1;
|
||||||
aggSumWithMultipleHavingOnAliasAndFunction
|
aggSumWithMultipleHavingOnAliasAndFunction
|
||||||
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY g HAVING s > 10 AND SUM(emp_no) > 10000000;
|
SELECT gender g, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY g HAVING s > 10 AND SUM(emp_no) > 10000000;
|
||||||
|
|
||||||
// AVG
|
// AVG
|
||||||
aggAvgImplicitWithCast
|
aggAvgImplicitWithCast
|
||||||
SELECT CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp";
|
SELECT CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp";
|
||||||
aggAvgWithCastToFloat
|
aggAvgWithCastToFloat
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY gender;
|
||||||
// casting to an exact type - varchar, bigint, etc... will likely fail due to rounding error
|
// casting to an exact type - varchar, bigint, etc... will likely fail due to rounding error
|
||||||
aggAvgWithCastToDouble
|
aggAvgWithCastToDouble
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS DOUBLE) a FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g, CAST(AVG(emp_no) AS DOUBLE) a FROM "test_emp" GROUP BY gender;
|
||||||
aggAvgWithCastAndCount
|
aggAvgWithCastAndCount
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a, COUNT(1) c FROM "test_emp.emp" GROUP BY gender;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a, COUNT(1) c FROM "test_emp" GROUP BY gender;
|
||||||
aggAvgWithCastAndCountWithFilter
|
aggAvgWithCastAndCountWithFilter
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a, COUNT(1) c FROM "test_emp.emp" WHERE emp_no > 10000 GROUP BY gender ;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a, COUNT(1) c FROM "test_emp" WHERE emp_no > 10000 GROUP BY gender ;
|
||||||
aggAvgWithCastAndCountWithFilterAndLimit
|
aggAvgWithCastAndCountWithFilterAndLimit
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a, COUNT(1) c FROM "test_emp.emp" WHERE emp_no > 10000 GROUP BY gender LIMIT 1;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a, COUNT(1) c FROM "test_emp" WHERE emp_no > 10000 GROUP BY gender LIMIT 1;
|
||||||
aggAvgWithAlias
|
aggAvgWithAlias
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY g;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY g;
|
||||||
|
|
||||||
// Conditional AVG
|
// Conditional AVG
|
||||||
aggAvgWithHaving
|
aggAvgWithHaving
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY g HAVING AVG(emp_no) > 10;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY g HAVING AVG(emp_no) > 10;
|
||||||
aggAvgWithHavingOnAlias
|
aggAvgWithHavingOnAlias
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY g HAVING a > 10;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY g HAVING a > 10;
|
||||||
aggAvgWithMultipleHaving
|
aggAvgWithMultipleHaving
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY g HAVING a > 10 AND a < 10000000;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY g HAVING a > 10 AND a < 10000000;
|
||||||
aggAvgWithMultipleHavingWithLimit
|
aggAvgWithMultipleHavingWithLimit
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY g HAVING a > 10 AND a < 10000000 LIMIT 1;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY g HAVING a > 10 AND a < 10000000 LIMIT 1;
|
||||||
aggAvgWithMultipleHavingOnAliasAndFunction
|
aggAvgWithMultipleHavingOnAliasAndFunction
|
||||||
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp.emp" GROUP BY g HAVING a > 10 AND AVG(emp_no) > 10000000;
|
SELECT gender g, CAST(AVG(emp_no) AS FLOAT) a FROM "test_emp" GROUP BY g HAVING a > 10 AND AVG(emp_no) > 10000000;
|
||||||
|
|
|
@ -108,7 +108,7 @@ test_emp |emp
|
||||||
// DESCRIBE
|
// DESCRIBE
|
||||||
|
|
||||||
describe
|
describe
|
||||||
DESCRIBE "test_emp.emp";
|
DESCRIBE "test_emp";
|
||||||
|
|
||||||
column | type
|
column | type
|
||||||
birth_date |TIMESTAMP
|
birth_date |TIMESTAMP
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
// Time
|
// Time
|
||||||
//
|
//
|
||||||
dateTimeSecond
|
dateTimeSecond
|
||||||
SELECT SECOND(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT SECOND(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
dateTimeMinute
|
dateTimeMinute
|
||||||
SELECT MINUTE(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT MINUTE(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
dateTimeHour
|
dateTimeHour
|
||||||
SELECT HOUR(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT HOUR(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -18,17 +18,17 @@ SELECT HOUR(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010
|
||||||
//
|
//
|
||||||
|
|
||||||
dateTimeDay
|
dateTimeDay
|
||||||
SELECT DAY(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT DAY(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
dateTimeDayOfMonth
|
dateTimeDayOfMonth
|
||||||
SELECT DAY_OF_MONTH(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT DAY_OF_MONTH(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
// dateTimeDayOfWeek - disable since it starts at 0 not 1
|
// dateTimeDayOfWeek - disable since it starts at 0 not 1
|
||||||
// SELECT DAY_OF_WEEK(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
// SELECT DAY_OF_WEEK(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
dateTimeDayOfYear
|
dateTimeDayOfYear
|
||||||
SELECT DAY_OF_YEAR(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT DAY_OF_YEAR(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
dateTimeMonth
|
dateTimeMonth
|
||||||
SELECT MONTH(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT MONTH(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
dateTimeYear
|
dateTimeYear
|
||||||
SELECT YEAR(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT YEAR(birth_date) d, last_name l FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
|
|
||||||
// NOCOMMIT figure out a way to test the aliases that are unsupported by h2 but are supported by us because they are like PostgreSQL
|
// NOCOMMIT figure out a way to test the aliases that are unsupported by h2 but are supported by us because they are like PostgreSQL
|
||||||
|
|
||||||
|
@ -37,19 +37,19 @@ SELECT YEAR(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010
|
||||||
// Filter
|
// Filter
|
||||||
//
|
//
|
||||||
dateTimeFilterDayOfMonth
|
dateTimeFilterDayOfMonth
|
||||||
SELECT DAY_OF_MONTH(birth_date) AS d, last_name l FROM "test_emp.emp" WHERE DAY_OF_MONTH(birth_date) <= 10 ORDER BY emp_no LIMIT 5;
|
SELECT DAY_OF_MONTH(birth_date) AS d, last_name l FROM "test_emp" WHERE DAY_OF_MONTH(birth_date) <= 10 ORDER BY emp_no LIMIT 5;
|
||||||
dateTimeFilterMonth
|
dateTimeFilterMonth
|
||||||
SELECT MONTH(birth_date) AS d, last_name l FROM "test_emp.emp" WHERE MONTH(birth_date) <= 5 ORDER BY emp_no LIMIT 5;
|
SELECT MONTH(birth_date) AS d, last_name l FROM "test_emp" WHERE MONTH(birth_date) <= 5 ORDER BY emp_no LIMIT 5;
|
||||||
dateTimeFilterYear
|
dateTimeFilterYear
|
||||||
SELECT YEAR(birth_date) AS d, last_name l FROM "test_emp.emp" WHERE YEAR(birth_date) <= 1960 ORDER BY emp_no LIMIT 5;
|
SELECT YEAR(birth_date) AS d, last_name l FROM "test_emp" WHERE YEAR(birth_date) <= 1960 ORDER BY emp_no LIMIT 5;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Aggregate
|
// Aggregate
|
||||||
//
|
//
|
||||||
dateTimeAggByYear
|
dateTimeAggByYear
|
||||||
SELECT YEAR(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY YEAR(birth_date) ORDER BY YEAR(birth_date) LIMIT 5;
|
SELECT YEAR(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY YEAR(birth_date) ORDER BY YEAR(birth_date) LIMIT 5;
|
||||||
// NOCOMMIT Elasticsearch doesn't line up
|
// NOCOMMIT Elasticsearch doesn't line up
|
||||||
// dateTimeAggByMonth
|
// dateTimeAggByMonth
|
||||||
// SELECT MONTH(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY MONTH(birth_date) ORDER BY MONTH(birth_date) LIMIT 5;
|
// SELECT MONTH(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY MONTH(birth_date) ORDER BY MONTH(birth_date) LIMIT 5;
|
||||||
// dateTimeAggByDayOfMonth
|
// dateTimeAggByDayOfMonth
|
||||||
// SELECT DAY_OF_MONTH(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp.emp" GROUP BY DAY_OF_MONTH(birth_date) ORDER BY DAY_OF_MONTH(birth_date) DESC;
|
// SELECT DAY_OF_MONTH(birth_date) AS d, CAST(SUM(emp_no) AS INT) s FROM "test_emp" GROUP BY DAY_OF_MONTH(birth_date) ORDER BY DAY_OF_MONTH(birth_date) DESC;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
name
|
name
|
||||||
|
|
||||||
// ES SQL query
|
// ES SQL query
|
||||||
SELECT COUNT(*) FROM "emp.emp";
|
SELECT COUNT(*) FROM "emp";
|
||||||
|
|
||||||
//
|
//
|
||||||
// expected result in CSV format
|
// expected result in CSV format
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
// name of the test - translated into 'testName'
|
// name of the test - translated into 'testName'
|
||||||
name
|
name
|
||||||
// SQL query to be executed against H2 and ES
|
// SQL query to be executed against H2 and ES
|
||||||
SELECT COUNT(*) FROM "emp.emp";
|
SELECT COUNT(*) FROM "emp";
|
||||||
|
|
||||||
// repeat the above
|
// repeat the above
|
|
@ -3,18 +3,18 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
whereFieldQuality
|
whereFieldQuality
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no = 10000 LIMIT 5;
|
SELECT last_name l FROM "test_emp" WHERE emp_no = 10000 LIMIT 5;
|
||||||
whereFieldLessThan
|
whereFieldLessThan
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no < 10003 ORDER BY emp_no LIMIT 5;
|
SELECT last_name l FROM "test_emp" WHERE emp_no < 10003 ORDER BY emp_no LIMIT 5;
|
||||||
whereFieldAndComparison
|
whereFieldAndComparison
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no > 10000 AND emp_no < 10005 ORDER BY emp_no LIMIT 5;
|
SELECT last_name l FROM "test_emp" WHERE emp_no > 10000 AND emp_no < 10005 ORDER BY emp_no LIMIT 5;
|
||||||
whereFieldOrComparison
|
whereFieldOrComparison
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no < 10003 OR emp_no = 10005 ORDER BY emp_no LIMIT 5;
|
SELECT last_name l FROM "test_emp" WHERE emp_no < 10003 OR emp_no = 10005 ORDER BY emp_no LIMIT 5;
|
||||||
whereFieldWithOrder
|
whereFieldWithOrder
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no < 10003 ORDER BY emp_no;
|
SELECT last_name l FROM "test_emp" WHERE emp_no < 10003 ORDER BY emp_no;
|
||||||
whereFieldWithExactMatchOnString
|
whereFieldWithExactMatchOnString
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no < 10003 AND gender = 'M';
|
SELECT last_name l FROM "test_emp" WHERE emp_no < 10003 AND gender = 'M';
|
||||||
whereFieldWithLikeMatch
|
whereFieldWithLikeMatch
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no < 10003 AND last_name LIKE 'K%';
|
SELECT last_name l FROM "test_emp" WHERE emp_no < 10003 AND last_name LIKE 'K%';
|
||||||
whereFieldOnMatchWithAndAndOr
|
whereFieldOnMatchWithAndAndOr
|
||||||
SELECT last_name l FROM "test_emp.emp" WHERE emp_no < 10003 AND (gender = 'M' AND NOT FALSE OR last_name LIKE 'K%') ORDER BY emp_no;
|
SELECT last_name l FROM "test_emp" WHERE emp_no < 10003 AND (gender = 'M' AND NOT FALSE OR last_name LIKE 'K%') ORDER BY emp_no;
|
||||||
|
|
|
@ -3,28 +3,28 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
simpleQueryAllFields
|
simpleQueryAllFields
|
||||||
SELECT emp_no, first_name, gender, last_name FROM test_emp.emp WHERE QUERY('Baek fox') LIMIT 3;
|
SELECT emp_no, first_name, gender, last_name FROM test_emp WHERE QUERY('Baek fox') LIMIT 3;
|
||||||
|
|
||||||
emp_no | first_name | gender | last_name
|
emp_no | first_name | gender | last_name
|
||||||
10080 |Premal |M |Baek
|
10080 |Premal |M |Baek
|
||||||
;
|
;
|
||||||
|
|
||||||
simpleQueryDedicatedField
|
simpleQueryDedicatedField
|
||||||
SELECT emp_no, first_name, gender, last_name FROM test_emp.emp WHERE QUERY('Man*', 'fields=last_name') LIMIT 5;
|
SELECT emp_no, first_name, gender, last_name FROM test_emp WHERE QUERY('Man*', 'fields=last_name') LIMIT 5;
|
||||||
|
|
||||||
emp_no | first_name | gender | last_name
|
emp_no | first_name | gender | last_name
|
||||||
10096 |Jayson |M |Mandell
|
10096 |Jayson |M |Mandell
|
||||||
;
|
;
|
||||||
|
|
||||||
matchQuery
|
matchQuery
|
||||||
SELECT emp_no, first_name, gender, last_name FROM test_emp.emp WHERE MATCH(first_name, 'Erez');
|
SELECT emp_no, first_name, gender, last_name FROM test_emp WHERE MATCH(first_name, 'Erez');
|
||||||
|
|
||||||
emp_no | first_name | gender | last_name
|
emp_no | first_name | gender | last_name
|
||||||
10076 |Erez |F |Ritzmann
|
10076 |Erez |F |Ritzmann
|
||||||
;
|
;
|
||||||
|
|
||||||
multiMatchQuery
|
multiMatchQuery
|
||||||
SELECT emp_no, first_name, gender, last_name FROM test_emp.emp WHERE MATCH('first_name,last_name', 'Morton', 'type=best_fields;default_operator=OR');
|
SELECT emp_no, first_name, gender, last_name FROM test_emp WHERE MATCH('first_name,last_name', 'Morton', 'type=best_fields;default_operator=OR');
|
||||||
|
|
||||||
emp_no | first_name | gender | last_name
|
emp_no | first_name | gender | last_name
|
||||||
10095 |Hilari |M |Morton
|
10095 |Hilari |M |Morton
|
||||||
|
|
|
@ -3,73 +3,73 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
mathAbs
|
mathAbs
|
||||||
SELECT ABS(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT ABS(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathACos
|
mathACos
|
||||||
SELECT ACOS(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT ACOS(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathASin
|
mathASin
|
||||||
SELECT ASIN(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT ASIN(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathATan
|
mathATan
|
||||||
SELECT ATAN(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT ATAN(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
//mathCbrt
|
//mathCbrt
|
||||||
//SELECT CBRT(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
//SELECT CBRT(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathCeil
|
mathCeil
|
||||||
SELECT CEIL(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT CEIL(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathCos
|
mathCos
|
||||||
SELECT COS(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT COS(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathCosh
|
mathCosh
|
||||||
SELECT COSH(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT COSH(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathDegrees
|
mathDegrees
|
||||||
SELECT DEGREES(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT DEGREES(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathFloor
|
mathFloor
|
||||||
SELECT CAST(FLOOR(emp_no) AS INT) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT CAST(FLOOR(emp_no) AS INT) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathLog
|
mathLog
|
||||||
SELECT LOG(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT LOG(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathLog10
|
mathLog10
|
||||||
SELECT LOG10(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT LOG10(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathRadians
|
mathRadians
|
||||||
SELECT RADIANS(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT RADIANS(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathRound
|
mathRound
|
||||||
SELECT CAST(ROUND(emp_no) AS INT) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT CAST(ROUND(emp_no) AS INT) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathSin
|
mathSin
|
||||||
SELECT SIN(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT SIN(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathSinH
|
mathSinH
|
||||||
SELECT SINH(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT SINH(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathSqrt
|
mathSqrt
|
||||||
SELECT SQRT(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT SQRT(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathTan
|
mathTan
|
||||||
SELECT TAN(emp_no) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT TAN(emp_no) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Combined methods
|
// Combined methods
|
||||||
//
|
//
|
||||||
|
|
||||||
mathAbsOfSin
|
mathAbsOfSin
|
||||||
SELECT ABS(SIN(emp_no)) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT ABS(SIN(emp_no)) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathAbsOfCeilOfSin
|
mathAbsOfCeilOfSin
|
||||||
SELECT EXP(ABS(CEIL(SIN(DEGREES(emp_no))))) m, first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
SELECT EXP(ABS(CEIL(SIN(DEGREES(emp_no))))) m, first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
mathAbsOfCeilOfSinWithFilter
|
mathAbsOfCeilOfSinWithFilter
|
||||||
SELECT EXP(ABS(CEIL(SIN(DEGREES(emp_no))))) m, first_name FROM "test_emp.emp" WHERE EXP(ABS(CEIL(SIN(DEGREES(emp_no))))) < 10 ORDER BY emp_no;
|
SELECT EXP(ABS(CEIL(SIN(DEGREES(emp_no))))) m, first_name FROM "test_emp" WHERE EXP(ABS(CEIL(SIN(DEGREES(emp_no))))) < 10 ORDER BY emp_no;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Filter by Scalar
|
// Filter by Scalar
|
||||||
//
|
//
|
||||||
mathAbsFilterAndOrder
|
mathAbsFilterAndOrder
|
||||||
SELECT emp_no, ABS(emp_no) m, first_name FROM "test_emp.emp" WHERE ABS(emp_no) < 10010 ORDER BY ABS(emp_no);
|
SELECT emp_no, ABS(emp_no) m, first_name FROM "test_emp" WHERE ABS(emp_no) < 10010 ORDER BY ABS(emp_no);
|
||||||
mathACosFilterAndOrder
|
mathACosFilterAndOrder
|
||||||
SELECT emp_no, ACOS(emp_no) m, first_name FROM "test_emp.emp" WHERE ACOS(emp_no) < 10010 ORDER BY ACOS(emp_no);
|
SELECT emp_no, ACOS(emp_no) m, first_name FROM "test_emp" WHERE ACOS(emp_no) < 10010 ORDER BY ACOS(emp_no);
|
||||||
mathASinFilterAndOrder
|
mathASinFilterAndOrder
|
||||||
SELECT emp_no, ASIN(emp_no) m, first_name FROM "test_emp.emp" WHERE ASIN(emp_no) < 10010 ORDER BY ASIN(emp_no);
|
SELECT emp_no, ASIN(emp_no) m, first_name FROM "test_emp" WHERE ASIN(emp_no) < 10010 ORDER BY ASIN(emp_no);
|
||||||
//mathATanFilterAndOrder
|
//mathATanFilterAndOrder
|
||||||
//SELECT emp_no, ATAN(emp_no) m, first_name FROM "test_emp.emp" WHERE ATAN(emp_no) < 10010 ORDER BY ATAN(emp_no);
|
//SELECT emp_no, ATAN(emp_no) m, first_name FROM "test_emp" WHERE ATAN(emp_no) < 10010 ORDER BY ATAN(emp_no);
|
||||||
mathCeilFilterAndOrder
|
mathCeilFilterAndOrder
|
||||||
SELECT emp_no, CEIL(emp_no) m, first_name FROM "test_emp.emp" WHERE CEIL(emp_no) < 10010 ORDER BY CEIL(emp_no);
|
SELECT emp_no, CEIL(emp_no) m, first_name FROM "test_emp" WHERE CEIL(emp_no) < 10010 ORDER BY CEIL(emp_no);
|
||||||
//mathCosFilterAndOrder
|
//mathCosFilterAndOrder
|
||||||
//SELECT emp_no, COS(emp_no) m, first_name FROM "test_emp.emp" WHERE COS(emp_no) < 10010 ORDER BY COS(emp_no);
|
//SELECT emp_no, COS(emp_no) m, first_name FROM "test_emp" WHERE COS(emp_no) < 10010 ORDER BY COS(emp_no);
|
||||||
//mathCoshFilterAndOrder
|
//mathCoshFilterAndOrder
|
||||||
//SELECT emp_no, COSH(emp_no) m, first_name FROM "test_emp.emp" WHERE COSH(emp_no) < 10010 ORDER BY COSH(emp_no);
|
//SELECT emp_no, COSH(emp_no) m, first_name FROM "test_emp" WHERE COSH(emp_no) < 10010 ORDER BY COSH(emp_no);
|
||||||
|
|
||||||
//
|
//
|
||||||
// constants - added when folding will be supported
|
// constants - added when folding will be supported
|
||||||
//
|
//
|
||||||
//mathConstantPI
|
//mathConstantPI
|
||||||
//SELECT ABS(emp_no) m, PI(), first_name FROM "test_emp.emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
//SELECT ABS(emp_no) m, PI(), first_name FROM "test_emp" WHERE emp_no < 10010 ORDER BY emp_no;
|
||||||
|
|
|
@ -3,36 +3,36 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
wildcardWithOrder
|
wildcardWithOrder
|
||||||
SELECT * FROM "test_emp.emp" ORDER BY emp_no;
|
SELECT * FROM "test_emp" ORDER BY emp_no;
|
||||||
column
|
column
|
||||||
SELECT last_name FROM "test_emp.emp" ORDER BY emp_no;
|
SELECT last_name FROM "test_emp" ORDER BY emp_no;
|
||||||
columnWithAlias
|
columnWithAlias
|
||||||
SELECT last_name AS l FROM "test_emp.emp" ORDER BY emp_no;
|
SELECT last_name AS l FROM "test_emp" ORDER BY emp_no;
|
||||||
columnWithAliasNoAs
|
columnWithAliasNoAs
|
||||||
SELECT last_name l FROM "test_emp.emp" ORDER BY emp_no;
|
SELECT last_name l FROM "test_emp" ORDER BY emp_no;
|
||||||
multipleColumnsNoAlias
|
multipleColumnsNoAlias
|
||||||
SELECT first_name, last_name FROM "test_emp.emp" ORDER BY emp_no;
|
SELECT first_name, last_name FROM "test_emp" ORDER BY emp_no;
|
||||||
multipleColumnWithAliasWithAndWithoutAs
|
multipleColumnWithAliasWithAndWithoutAs
|
||||||
SELECT first_name f, last_name AS l FROM "test_emp.emp" ORDER BY emp_no;
|
SELECT first_name f, last_name AS l FROM "test_emp" ORDER BY emp_no;
|
||||||
|
|
||||||
//
|
//
|
||||||
// SELECT with LIMIT
|
// SELECT with LIMIT
|
||||||
//
|
//
|
||||||
|
|
||||||
wildcardWithLimit
|
wildcardWithLimit
|
||||||
SELECT * FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT * FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
wildcardWithOrderWithLimit
|
wildcardWithOrderWithLimit
|
||||||
SELECT * FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT * FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
columnWithLimit
|
columnWithLimit
|
||||||
SELECT last_name FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT last_name FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
columnWithAliasWithLimit
|
columnWithAliasWithLimit
|
||||||
SELECT last_name AS l FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT last_name AS l FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
columnWithAliasNoAsWithLimit
|
columnWithAliasNoAsWithLimit
|
||||||
SELECT last_name l FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT last_name l FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
multipleColumnsNoAliasWithLimit
|
multipleColumnsNoAliasWithLimit
|
||||||
SELECT first_name, last_name FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT first_name, last_name FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
multipleColumnWithAliasWithAndWithoutAsWithLimit
|
multipleColumnWithAliasWithAndWithoutAsWithLimit
|
||||||
SELECT first_name f, last_name AS l FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT first_name f, last_name AS l FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -41,16 +41,16 @@ SELECT first_name f, last_name AS l FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
||||||
//castWithLiteralToInt
|
//castWithLiteralToInt
|
||||||
//SELECT CAST(1 AS INT);
|
//SELECT CAST(1 AS INT);
|
||||||
castOnColumnNumberToVarchar
|
castOnColumnNumberToVarchar
|
||||||
SELECT CAST(emp_no AS VARCHAR) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS VARCHAR) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
castOnColumnNumberToLong
|
castOnColumnNumberToLong
|
||||||
SELECT CAST(emp_no AS BIGINT) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS BIGINT) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
castOnColumnNumberToSmallint
|
castOnColumnNumberToSmallint
|
||||||
SELECT CAST(emp_no AS SMALLINT) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS SMALLINT) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
castOnColumnNumberWithAliasToInt
|
castOnColumnNumberWithAliasToInt
|
||||||
SELECT CAST(emp_no AS INT) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS INT) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
castOnColumnNumberToReal
|
castOnColumnNumberToReal
|
||||||
SELECT CAST(emp_no AS REAL) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS REAL) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
castOnColumnNumberToDouble
|
castOnColumnNumberToDouble
|
||||||
SELECT CAST(emp_no AS DOUBLE) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS DOUBLE) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
||||||
castOnColumnNumberToBoolean
|
castOnColumnNumberToBoolean
|
||||||
SELECT CAST(emp_no AS BOOL) AS emp_no_cast FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
|
SELECT CAST(emp_no AS BOOL) AS emp_no_cast FROM "test_emp" ORDER BY emp_no LIMIT 5;
|
|
@ -1,5 +1,5 @@
|
||||||
DROP TABLE IF EXISTS "test_emp.emp";
|
DROP TABLE IF EXISTS "test_emp";
|
||||||
CREATE TABLE "test_emp.emp" ("birth_date" TIMESTAMP,
|
CREATE TABLE "test_emp" ("birth_date" TIMESTAMP,
|
||||||
"emp_no" INT,
|
"emp_no" INT,
|
||||||
"first_name" VARCHAR(50),
|
"first_name" VARCHAR(50),
|
||||||
"gender" VARCHAR(1),
|
"gender" VARCHAR(1),
|
||||||
|
|
|
@ -51,7 +51,7 @@ statement
|
||||||
)*
|
)*
|
||||||
')')?
|
')')?
|
||||||
statement #debug
|
statement #debug
|
||||||
| SHOW TABLES ((FROM | IN) index=identifier)? (LIKE? pattern=STRING)? #showTables
|
| SHOW TABLES (LIKE? pattern=STRING)? #showTables
|
||||||
| SHOW COLUMNS (FROM | IN) tableIdentifier #showColumns
|
| SHOW COLUMNS (FROM | IN) tableIdentifier #showColumns
|
||||||
| (DESCRIBE | DESC) tableIdentifier #showColumns
|
| (DESCRIBE | DESC) tableIdentifier #showColumns
|
||||||
| SHOW FUNCTIONS (LIKE? pattern=STRING)? #showFunctions
|
| SHOW FUNCTIONS (LIKE? pattern=STRING)? #showFunctions
|
||||||
|
@ -232,8 +232,7 @@ qualifiedName
|
||||||
;
|
;
|
||||||
|
|
||||||
tableIdentifier
|
tableIdentifier
|
||||||
: index=identifier ('.' type=identifier)?
|
: index=identifier
|
||||||
| '"' uindex=unquoteIdentifier ('.' utype=unquoteIdentifier)? '"'
|
|
||||||
;
|
;
|
||||||
|
|
||||||
identifier
|
identifier
|
||||||
|
|
|
@ -2,204 +2,202 @@ T__0=1
|
||||||
T__1=2
|
T__1=2
|
||||||
T__2=3
|
T__2=3
|
||||||
T__3=4
|
T__3=4
|
||||||
T__4=5
|
SELECT=5
|
||||||
SELECT=6
|
FROM=6
|
||||||
FROM=7
|
AS=7
|
||||||
AS=8
|
ALL=8
|
||||||
ALL=9
|
WHEN=9
|
||||||
WHEN=10
|
THEN=10
|
||||||
THEN=11
|
ANY=11
|
||||||
ANY=12
|
DISTINCT=12
|
||||||
DISTINCT=13
|
WHERE=13
|
||||||
WHERE=14
|
GROUP=14
|
||||||
GROUP=15
|
BY=15
|
||||||
BY=16
|
GROUPING=16
|
||||||
GROUPING=17
|
SETS=17
|
||||||
SETS=18
|
ORDER=18
|
||||||
ORDER=19
|
HAVING=19
|
||||||
HAVING=20
|
LIMIT=20
|
||||||
LIMIT=21
|
OR=21
|
||||||
OR=22
|
AND=22
|
||||||
AND=23
|
IN=23
|
||||||
IN=24
|
NOT=24
|
||||||
NOT=25
|
NO=25
|
||||||
NO=26
|
EXISTS=26
|
||||||
EXISTS=27
|
BETWEEN=27
|
||||||
BETWEEN=28
|
LIKE=28
|
||||||
LIKE=29
|
RLIKE=29
|
||||||
RLIKE=30
|
IS=30
|
||||||
IS=31
|
NULL=31
|
||||||
NULL=32
|
TRUE=32
|
||||||
TRUE=33
|
FALSE=33
|
||||||
FALSE=34
|
LAST=34
|
||||||
LAST=35
|
ASC=35
|
||||||
ASC=36
|
DESC=36
|
||||||
DESC=37
|
FOR=37
|
||||||
FOR=38
|
INTEGER=38
|
||||||
INTEGER=39
|
JOIN=39
|
||||||
JOIN=40
|
CROSS=40
|
||||||
CROSS=41
|
OUTER=41
|
||||||
OUTER=42
|
INNER=42
|
||||||
INNER=43
|
LEFT=43
|
||||||
LEFT=44
|
RIGHT=44
|
||||||
RIGHT=45
|
FULL=45
|
||||||
FULL=46
|
NATURAL=46
|
||||||
NATURAL=47
|
USING=47
|
||||||
USING=48
|
ON=48
|
||||||
ON=49
|
WITH=49
|
||||||
WITH=50
|
TABLE=50
|
||||||
TABLE=51
|
INTO=51
|
||||||
INTO=52
|
DESCRIBE=52
|
||||||
DESCRIBE=53
|
OPTION=53
|
||||||
OPTION=54
|
EXPLAIN=54
|
||||||
EXPLAIN=55
|
ANALYZE=55
|
||||||
ANALYZE=56
|
FORMAT=56
|
||||||
FORMAT=57
|
TYPE=57
|
||||||
TYPE=58
|
TEXT=58
|
||||||
TEXT=59
|
VERIFY=59
|
||||||
VERIFY=60
|
GRAPHVIZ=60
|
||||||
GRAPHVIZ=61
|
LOGICAL=61
|
||||||
LOGICAL=62
|
PHYSICAL=62
|
||||||
PHYSICAL=63
|
SHOW=63
|
||||||
SHOW=64
|
TABLES=64
|
||||||
TABLES=65
|
COLUMNS=65
|
||||||
COLUMNS=66
|
COLUMN=66
|
||||||
COLUMN=67
|
FUNCTIONS=67
|
||||||
FUNCTIONS=68
|
TO=68
|
||||||
TO=69
|
DEBUG=69
|
||||||
DEBUG=70
|
PLAN=70
|
||||||
PLAN=71
|
PARSED=71
|
||||||
PARSED=72
|
ANALYZED=72
|
||||||
ANALYZED=73
|
OPTIMIZED=73
|
||||||
OPTIMIZED=74
|
MAPPED=74
|
||||||
MAPPED=75
|
EXECUTABLE=75
|
||||||
EXECUTABLE=76
|
USE=76
|
||||||
USE=77
|
SET=77
|
||||||
SET=78
|
RESET=78
|
||||||
RESET=79
|
SESSION=79
|
||||||
SESSION=80
|
SCHEMAS=80
|
||||||
SCHEMAS=81
|
EXTRACT=81
|
||||||
EXTRACT=82
|
QUERY=82
|
||||||
QUERY=83
|
MATCH=83
|
||||||
MATCH=84
|
CAST=84
|
||||||
CAST=85
|
EQ=85
|
||||||
EQ=86
|
NEQ=86
|
||||||
NEQ=87
|
LT=87
|
||||||
LT=88
|
LTE=88
|
||||||
LTE=89
|
GT=89
|
||||||
GT=90
|
GTE=90
|
||||||
GTE=91
|
PLUS=91
|
||||||
PLUS=92
|
MINUS=92
|
||||||
MINUS=93
|
ASTERISK=93
|
||||||
ASTERISK=94
|
SLASH=94
|
||||||
SLASH=95
|
PERCENT=95
|
||||||
PERCENT=96
|
CONCAT=96
|
||||||
CONCAT=97
|
STRING=97
|
||||||
STRING=98
|
INTEGER_VALUE=98
|
||||||
INTEGER_VALUE=99
|
DECIMAL_VALUE=99
|
||||||
DECIMAL_VALUE=100
|
IDENTIFIER=100
|
||||||
IDENTIFIER=101
|
DIGIT_IDENTIFIER=101
|
||||||
DIGIT_IDENTIFIER=102
|
QUOTED_IDENTIFIER=102
|
||||||
QUOTED_IDENTIFIER=103
|
BACKQUOTED_IDENTIFIER=103
|
||||||
BACKQUOTED_IDENTIFIER=104
|
SIMPLE_COMMENT=104
|
||||||
SIMPLE_COMMENT=105
|
BRACKETED_COMMENT=105
|
||||||
BRACKETED_COMMENT=106
|
WS=106
|
||||||
WS=107
|
UNRECOGNIZED=107
|
||||||
UNRECOGNIZED=108
|
DELIMITER=108
|
||||||
DELIMITER=109
|
|
||||||
'('=1
|
'('=1
|
||||||
')'=2
|
')'=2
|
||||||
','=3
|
','=3
|
||||||
'.'=4
|
'.'=4
|
||||||
'"'=5
|
'SELECT'=5
|
||||||
'SELECT'=6
|
'FROM'=6
|
||||||
'FROM'=7
|
'AS'=7
|
||||||
'AS'=8
|
'ALL'=8
|
||||||
'ALL'=9
|
'WHEN'=9
|
||||||
'WHEN'=10
|
'THEN'=10
|
||||||
'THEN'=11
|
'ANY'=11
|
||||||
'ANY'=12
|
'DISTINCT'=12
|
||||||
'DISTINCT'=13
|
'WHERE'=13
|
||||||
'WHERE'=14
|
'GROUP'=14
|
||||||
'GROUP'=15
|
'BY'=15
|
||||||
'BY'=16
|
'GROUPING'=16
|
||||||
'GROUPING'=17
|
'SETS'=17
|
||||||
'SETS'=18
|
'ORDER'=18
|
||||||
'ORDER'=19
|
'HAVING'=19
|
||||||
'HAVING'=20
|
'LIMIT'=20
|
||||||
'LIMIT'=21
|
'OR'=21
|
||||||
'OR'=22
|
'AND'=22
|
||||||
'AND'=23
|
'IN'=23
|
||||||
'IN'=24
|
'NOT'=24
|
||||||
'NOT'=25
|
'NO'=25
|
||||||
'NO'=26
|
'EXISTS'=26
|
||||||
'EXISTS'=27
|
'BETWEEN'=27
|
||||||
'BETWEEN'=28
|
'LIKE'=28
|
||||||
'LIKE'=29
|
'RLIKE'=29
|
||||||
'RLIKE'=30
|
'IS'=30
|
||||||
'IS'=31
|
'NULL'=31
|
||||||
'NULL'=32
|
'TRUE'=32
|
||||||
'TRUE'=33
|
'FALSE'=33
|
||||||
'FALSE'=34
|
'LAST'=34
|
||||||
'LAST'=35
|
'ASC'=35
|
||||||
'ASC'=36
|
'DESC'=36
|
||||||
'DESC'=37
|
'FOR'=37
|
||||||
'FOR'=38
|
'INTEGER'=38
|
||||||
'INTEGER'=39
|
'JOIN'=39
|
||||||
'JOIN'=40
|
'CROSS'=40
|
||||||
'CROSS'=41
|
'OUTER'=41
|
||||||
'OUTER'=42
|
'INNER'=42
|
||||||
'INNER'=43
|
'LEFT'=43
|
||||||
'LEFT'=44
|
'RIGHT'=44
|
||||||
'RIGHT'=45
|
'FULL'=45
|
||||||
'FULL'=46
|
'NATURAL'=46
|
||||||
'NATURAL'=47
|
'USING'=47
|
||||||
'USING'=48
|
'ON'=48
|
||||||
'ON'=49
|
'WITH'=49
|
||||||
'WITH'=50
|
'TABLE'=50
|
||||||
'TABLE'=51
|
'INTO'=51
|
||||||
'INTO'=52
|
'DESCRIBE'=52
|
||||||
'DESCRIBE'=53
|
'OPTION'=53
|
||||||
'OPTION'=54
|
'EXPLAIN'=54
|
||||||
'EXPLAIN'=55
|
'ANALYZE'=55
|
||||||
'ANALYZE'=56
|
'FORMAT'=56
|
||||||
'FORMAT'=57
|
'TYPE'=57
|
||||||
'TYPE'=58
|
'TEXT'=58
|
||||||
'TEXT'=59
|
'VERIFY'=59
|
||||||
'VERIFY'=60
|
'GRAPHVIZ'=60
|
||||||
'GRAPHVIZ'=61
|
'LOGICAL'=61
|
||||||
'LOGICAL'=62
|
'PHYSICAL'=62
|
||||||
'PHYSICAL'=63
|
'SHOW'=63
|
||||||
'SHOW'=64
|
'TABLES'=64
|
||||||
'TABLES'=65
|
'COLUMNS'=65
|
||||||
'COLUMNS'=66
|
'COLUMN'=66
|
||||||
'COLUMN'=67
|
'FUNCTIONS'=67
|
||||||
'FUNCTIONS'=68
|
'TO'=68
|
||||||
'TO'=69
|
'DEBUG'=69
|
||||||
'DEBUG'=70
|
'PLAN'=70
|
||||||
'PLAN'=71
|
'PARSED'=71
|
||||||
'PARSED'=72
|
'ANALYZED'=72
|
||||||
'ANALYZED'=73
|
'OPTIMIZED'=73
|
||||||
'OPTIMIZED'=74
|
'MAPPED'=74
|
||||||
'MAPPED'=75
|
'EXECUTABLE'=75
|
||||||
'EXECUTABLE'=76
|
'USE'=76
|
||||||
'USE'=77
|
'SET'=77
|
||||||
'SET'=78
|
'RESET'=78
|
||||||
'RESET'=79
|
'SESSION'=79
|
||||||
'SESSION'=80
|
'SCHEMAS'=80
|
||||||
'SCHEMAS'=81
|
'EXTRACT'=81
|
||||||
'EXTRACT'=82
|
'QUERY'=82
|
||||||
'QUERY'=83
|
'MATCH'=83
|
||||||
'MATCH'=84
|
'CAST'=84
|
||||||
'CAST'=85
|
'='=85
|
||||||
'='=86
|
'<'=87
|
||||||
'<'=88
|
'<='=88
|
||||||
'<='=89
|
'>'=89
|
||||||
'>'=90
|
'>='=90
|
||||||
'>='=91
|
'+'=91
|
||||||
'+'=92
|
'-'=92
|
||||||
'-'=93
|
'*'=93
|
||||||
'*'=94
|
'/'=94
|
||||||
'/'=95
|
'%'=95
|
||||||
'%'=96
|
'||'=96
|
||||||
'||'=97
|
|
||||||
|
|
|
@ -2,203 +2,201 @@ T__0=1
|
||||||
T__1=2
|
T__1=2
|
||||||
T__2=3
|
T__2=3
|
||||||
T__3=4
|
T__3=4
|
||||||
T__4=5
|
SELECT=5
|
||||||
SELECT=6
|
FROM=6
|
||||||
FROM=7
|
AS=7
|
||||||
AS=8
|
ALL=8
|
||||||
ALL=9
|
WHEN=9
|
||||||
WHEN=10
|
THEN=10
|
||||||
THEN=11
|
ANY=11
|
||||||
ANY=12
|
DISTINCT=12
|
||||||
DISTINCT=13
|
WHERE=13
|
||||||
WHERE=14
|
GROUP=14
|
||||||
GROUP=15
|
BY=15
|
||||||
BY=16
|
GROUPING=16
|
||||||
GROUPING=17
|
SETS=17
|
||||||
SETS=18
|
ORDER=18
|
||||||
ORDER=19
|
HAVING=19
|
||||||
HAVING=20
|
LIMIT=20
|
||||||
LIMIT=21
|
OR=21
|
||||||
OR=22
|
AND=22
|
||||||
AND=23
|
IN=23
|
||||||
IN=24
|
NOT=24
|
||||||
NOT=25
|
NO=25
|
||||||
NO=26
|
EXISTS=26
|
||||||
EXISTS=27
|
BETWEEN=27
|
||||||
BETWEEN=28
|
LIKE=28
|
||||||
LIKE=29
|
RLIKE=29
|
||||||
RLIKE=30
|
IS=30
|
||||||
IS=31
|
NULL=31
|
||||||
NULL=32
|
TRUE=32
|
||||||
TRUE=33
|
FALSE=33
|
||||||
FALSE=34
|
LAST=34
|
||||||
LAST=35
|
ASC=35
|
||||||
ASC=36
|
DESC=36
|
||||||
DESC=37
|
FOR=37
|
||||||
FOR=38
|
INTEGER=38
|
||||||
INTEGER=39
|
JOIN=39
|
||||||
JOIN=40
|
CROSS=40
|
||||||
CROSS=41
|
OUTER=41
|
||||||
OUTER=42
|
INNER=42
|
||||||
INNER=43
|
LEFT=43
|
||||||
LEFT=44
|
RIGHT=44
|
||||||
RIGHT=45
|
FULL=45
|
||||||
FULL=46
|
NATURAL=46
|
||||||
NATURAL=47
|
USING=47
|
||||||
USING=48
|
ON=48
|
||||||
ON=49
|
WITH=49
|
||||||
WITH=50
|
TABLE=50
|
||||||
TABLE=51
|
INTO=51
|
||||||
INTO=52
|
DESCRIBE=52
|
||||||
DESCRIBE=53
|
OPTION=53
|
||||||
OPTION=54
|
EXPLAIN=54
|
||||||
EXPLAIN=55
|
ANALYZE=55
|
||||||
ANALYZE=56
|
FORMAT=56
|
||||||
FORMAT=57
|
TYPE=57
|
||||||
TYPE=58
|
TEXT=58
|
||||||
TEXT=59
|
VERIFY=59
|
||||||
VERIFY=60
|
GRAPHVIZ=60
|
||||||
GRAPHVIZ=61
|
LOGICAL=61
|
||||||
LOGICAL=62
|
PHYSICAL=62
|
||||||
PHYSICAL=63
|
SHOW=63
|
||||||
SHOW=64
|
TABLES=64
|
||||||
TABLES=65
|
COLUMNS=65
|
||||||
COLUMNS=66
|
COLUMN=66
|
||||||
COLUMN=67
|
FUNCTIONS=67
|
||||||
FUNCTIONS=68
|
TO=68
|
||||||
TO=69
|
DEBUG=69
|
||||||
DEBUG=70
|
PLAN=70
|
||||||
PLAN=71
|
PARSED=71
|
||||||
PARSED=72
|
ANALYZED=72
|
||||||
ANALYZED=73
|
OPTIMIZED=73
|
||||||
OPTIMIZED=74
|
MAPPED=74
|
||||||
MAPPED=75
|
EXECUTABLE=75
|
||||||
EXECUTABLE=76
|
USE=76
|
||||||
USE=77
|
SET=77
|
||||||
SET=78
|
RESET=78
|
||||||
RESET=79
|
SESSION=79
|
||||||
SESSION=80
|
SCHEMAS=80
|
||||||
SCHEMAS=81
|
EXTRACT=81
|
||||||
EXTRACT=82
|
QUERY=82
|
||||||
QUERY=83
|
MATCH=83
|
||||||
MATCH=84
|
CAST=84
|
||||||
CAST=85
|
EQ=85
|
||||||
EQ=86
|
NEQ=86
|
||||||
NEQ=87
|
LT=87
|
||||||
LT=88
|
LTE=88
|
||||||
LTE=89
|
GT=89
|
||||||
GT=90
|
GTE=90
|
||||||
GTE=91
|
PLUS=91
|
||||||
PLUS=92
|
MINUS=92
|
||||||
MINUS=93
|
ASTERISK=93
|
||||||
ASTERISK=94
|
SLASH=94
|
||||||
SLASH=95
|
PERCENT=95
|
||||||
PERCENT=96
|
CONCAT=96
|
||||||
CONCAT=97
|
STRING=97
|
||||||
STRING=98
|
INTEGER_VALUE=98
|
||||||
INTEGER_VALUE=99
|
DECIMAL_VALUE=99
|
||||||
DECIMAL_VALUE=100
|
IDENTIFIER=100
|
||||||
IDENTIFIER=101
|
DIGIT_IDENTIFIER=101
|
||||||
DIGIT_IDENTIFIER=102
|
QUOTED_IDENTIFIER=102
|
||||||
QUOTED_IDENTIFIER=103
|
BACKQUOTED_IDENTIFIER=103
|
||||||
BACKQUOTED_IDENTIFIER=104
|
SIMPLE_COMMENT=104
|
||||||
SIMPLE_COMMENT=105
|
BRACKETED_COMMENT=105
|
||||||
BRACKETED_COMMENT=106
|
WS=106
|
||||||
WS=107
|
UNRECOGNIZED=107
|
||||||
UNRECOGNIZED=108
|
|
||||||
'('=1
|
'('=1
|
||||||
')'=2
|
')'=2
|
||||||
','=3
|
','=3
|
||||||
'.'=4
|
'.'=4
|
||||||
'"'=5
|
'SELECT'=5
|
||||||
'SELECT'=6
|
'FROM'=6
|
||||||
'FROM'=7
|
'AS'=7
|
||||||
'AS'=8
|
'ALL'=8
|
||||||
'ALL'=9
|
'WHEN'=9
|
||||||
'WHEN'=10
|
'THEN'=10
|
||||||
'THEN'=11
|
'ANY'=11
|
||||||
'ANY'=12
|
'DISTINCT'=12
|
||||||
'DISTINCT'=13
|
'WHERE'=13
|
||||||
'WHERE'=14
|
'GROUP'=14
|
||||||
'GROUP'=15
|
'BY'=15
|
||||||
'BY'=16
|
'GROUPING'=16
|
||||||
'GROUPING'=17
|
'SETS'=17
|
||||||
'SETS'=18
|
'ORDER'=18
|
||||||
'ORDER'=19
|
'HAVING'=19
|
||||||
'HAVING'=20
|
'LIMIT'=20
|
||||||
'LIMIT'=21
|
'OR'=21
|
||||||
'OR'=22
|
'AND'=22
|
||||||
'AND'=23
|
'IN'=23
|
||||||
'IN'=24
|
'NOT'=24
|
||||||
'NOT'=25
|
'NO'=25
|
||||||
'NO'=26
|
'EXISTS'=26
|
||||||
'EXISTS'=27
|
'BETWEEN'=27
|
||||||
'BETWEEN'=28
|
'LIKE'=28
|
||||||
'LIKE'=29
|
'RLIKE'=29
|
||||||
'RLIKE'=30
|
'IS'=30
|
||||||
'IS'=31
|
'NULL'=31
|
||||||
'NULL'=32
|
'TRUE'=32
|
||||||
'TRUE'=33
|
'FALSE'=33
|
||||||
'FALSE'=34
|
'LAST'=34
|
||||||
'LAST'=35
|
'ASC'=35
|
||||||
'ASC'=36
|
'DESC'=36
|
||||||
'DESC'=37
|
'FOR'=37
|
||||||
'FOR'=38
|
'INTEGER'=38
|
||||||
'INTEGER'=39
|
'JOIN'=39
|
||||||
'JOIN'=40
|
'CROSS'=40
|
||||||
'CROSS'=41
|
'OUTER'=41
|
||||||
'OUTER'=42
|
'INNER'=42
|
||||||
'INNER'=43
|
'LEFT'=43
|
||||||
'LEFT'=44
|
'RIGHT'=44
|
||||||
'RIGHT'=45
|
'FULL'=45
|
||||||
'FULL'=46
|
'NATURAL'=46
|
||||||
'NATURAL'=47
|
'USING'=47
|
||||||
'USING'=48
|
'ON'=48
|
||||||
'ON'=49
|
'WITH'=49
|
||||||
'WITH'=50
|
'TABLE'=50
|
||||||
'TABLE'=51
|
'INTO'=51
|
||||||
'INTO'=52
|
'DESCRIBE'=52
|
||||||
'DESCRIBE'=53
|
'OPTION'=53
|
||||||
'OPTION'=54
|
'EXPLAIN'=54
|
||||||
'EXPLAIN'=55
|
'ANALYZE'=55
|
||||||
'ANALYZE'=56
|
'FORMAT'=56
|
||||||
'FORMAT'=57
|
'TYPE'=57
|
||||||
'TYPE'=58
|
'TEXT'=58
|
||||||
'TEXT'=59
|
'VERIFY'=59
|
||||||
'VERIFY'=60
|
'GRAPHVIZ'=60
|
||||||
'GRAPHVIZ'=61
|
'LOGICAL'=61
|
||||||
'LOGICAL'=62
|
'PHYSICAL'=62
|
||||||
'PHYSICAL'=63
|
'SHOW'=63
|
||||||
'SHOW'=64
|
'TABLES'=64
|
||||||
'TABLES'=65
|
'COLUMNS'=65
|
||||||
'COLUMNS'=66
|
'COLUMN'=66
|
||||||
'COLUMN'=67
|
'FUNCTIONS'=67
|
||||||
'FUNCTIONS'=68
|
'TO'=68
|
||||||
'TO'=69
|
'DEBUG'=69
|
||||||
'DEBUG'=70
|
'PLAN'=70
|
||||||
'PLAN'=71
|
'PARSED'=71
|
||||||
'PARSED'=72
|
'ANALYZED'=72
|
||||||
'ANALYZED'=73
|
'OPTIMIZED'=73
|
||||||
'OPTIMIZED'=74
|
'MAPPED'=74
|
||||||
'MAPPED'=75
|
'EXECUTABLE'=75
|
||||||
'EXECUTABLE'=76
|
'USE'=76
|
||||||
'USE'=77
|
'SET'=77
|
||||||
'SET'=78
|
'RESET'=78
|
||||||
'RESET'=79
|
'SESSION'=79
|
||||||
'SESSION'=80
|
'SCHEMAS'=80
|
||||||
'SCHEMAS'=81
|
'EXTRACT'=81
|
||||||
'EXTRACT'=82
|
'QUERY'=82
|
||||||
'QUERY'=83
|
'MATCH'=83
|
||||||
'MATCH'=84
|
'CAST'=84
|
||||||
'CAST'=85
|
'='=85
|
||||||
'='=86
|
'<'=87
|
||||||
'<'=88
|
'<='=88
|
||||||
'<='=89
|
'>'=89
|
||||||
'>'=90
|
'>='=90
|
||||||
'>='=91
|
'+'=91
|
||||||
'+'=92
|
'-'=92
|
||||||
'-'=93
|
'*'=93
|
||||||
'*'=94
|
'/'=94
|
||||||
'/'=95
|
'%'=95
|
||||||
'%'=96
|
'||'=96
|
||||||
'||'=97
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ package org.elasticsearch.xpack.sql.analysis;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.tree.Node;
|
import org.elasticsearch.xpack.sql.tree.Node;
|
||||||
|
|
||||||
public class UnknownTypeException extends AnalysisException {
|
public class InvalidIndexException extends AnalysisException {
|
||||||
|
|
||||||
public UnknownTypeException(String index, String type, Node<?> source) {
|
public InvalidIndexException(String index, Node<?> source) {
|
||||||
super(source, "Cannot resolve type %s in index %s", type, index);
|
super(source, "Invalid index %s; contains more than one type", index);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,9 +6,9 @@
|
||||||
package org.elasticsearch.xpack.sql.analysis.analyzer;
|
package org.elasticsearch.xpack.sql.analysis.analyzer;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.analysis.AnalysisException;
|
import org.elasticsearch.xpack.sql.analysis.AnalysisException;
|
||||||
|
import org.elasticsearch.xpack.sql.analysis.InvalidIndexException;
|
||||||
import org.elasticsearch.xpack.sql.analysis.UnknownFunctionException;
|
import org.elasticsearch.xpack.sql.analysis.UnknownFunctionException;
|
||||||
import org.elasticsearch.xpack.sql.analysis.UnknownIndexException;
|
import org.elasticsearch.xpack.sql.analysis.UnknownIndexException;
|
||||||
import org.elasticsearch.xpack.sql.analysis.UnknownTypeException;
|
|
||||||
import org.elasticsearch.xpack.sql.analysis.analyzer.Verifier.Failure;
|
import org.elasticsearch.xpack.sql.analysis.analyzer.Verifier.Failure;
|
||||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
||||||
import org.elasticsearch.xpack.sql.capabilities.Resolvables;
|
import org.elasticsearch.xpack.sql.capabilities.Resolvables;
|
||||||
|
@ -217,7 +217,7 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
|
||||||
private LogicalPlan substituteCTE(LogicalPlan p, Map<String, SubQueryAlias> subQueries) {
|
private LogicalPlan substituteCTE(LogicalPlan p, Map<String, SubQueryAlias> subQueries) {
|
||||||
if (p instanceof UnresolvedRelation) {
|
if (p instanceof UnresolvedRelation) {
|
||||||
UnresolvedRelation ur = (UnresolvedRelation) p;
|
UnresolvedRelation ur = (UnresolvedRelation) p;
|
||||||
SubQueryAlias subQueryAlias = subQueries.get(ur.table().type());
|
SubQueryAlias subQueryAlias = subQueries.get(ur.table().index());
|
||||||
if (subQueryAlias != null) {
|
if (subQueryAlias != null) {
|
||||||
if (ur.alias() != null) {
|
if (ur.alias() != null) {
|
||||||
return new SubQueryAlias(ur.location(), subQueryAlias, ur.alias());
|
return new SubQueryAlias(ur.location(), subQueryAlias, ur.alias());
|
||||||
|
@ -246,13 +246,12 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
|
||||||
throw new UnknownIndexException(index, plan);
|
throw new UnknownIndexException(index, plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
String type = table.type();
|
if (!catalog.indexIsValid(index)) {
|
||||||
if (!catalog.typeExists(index, type)) {
|
throw new InvalidIndexException(index, plan);
|
||||||
throw new UnknownTypeException(index, type, plan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalPlan catalogTable = new CatalogTable(plan.location(), catalog.getType(index, type));
|
LogicalPlan catalogTable = new CatalogTable(plan.location(), catalog.getIndex(index));
|
||||||
SubQueryAlias sa = new SubQueryAlias(plan.location(), catalogTable, type);
|
SubQueryAlias sa = new SubQueryAlias(plan.location(), catalogTable, index);
|
||||||
|
|
||||||
if (plan.alias() != null) {
|
if (plan.alias() != null) {
|
||||||
sa = new SubQueryAlias(plan.location(), sa, plan.alias());
|
sa = new SubQueryAlias(plan.location(), sa, plan.alias());
|
||||||
|
|
|
@ -9,21 +9,14 @@ import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
public interface Catalog {
|
public interface Catalog {
|
||||||
// NOCOMMIT make sure we need all of these methods....
|
|
||||||
|
|
||||||
EsIndex getIndex(String index);
|
|
||||||
|
|
||||||
boolean indexExists(String index);
|
boolean indexExists(String index);
|
||||||
|
|
||||||
|
boolean indexIsValid(String index);
|
||||||
|
|
||||||
|
EsIndex getIndex(String index);
|
||||||
|
|
||||||
List<EsIndex> listIndices();
|
List<EsIndex> listIndices();
|
||||||
|
|
||||||
List<EsIndex> listIndices(String pattern);
|
List<EsIndex> listIndices(String pattern);
|
||||||
|
|
||||||
EsType getType(String index, String type);
|
|
||||||
|
|
||||||
boolean typeExists(String index, String type);
|
|
||||||
|
|
||||||
List<EsType> listTypes(String index);
|
|
||||||
|
|
||||||
List<EsType> listTypes(String index, String pattern);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ import org.elasticsearch.action.support.IndicesOptions;
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
|
||||||
import org.elasticsearch.cluster.metadata.MetaData;
|
import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -20,8 +18,6 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
public class EsCatalog implements Catalog {
|
public class EsCatalog implements Catalog {
|
||||||
|
|
||||||
private static final String WILDCARD = "*";
|
|
||||||
|
|
||||||
private final Supplier<ClusterState> clusterState;
|
private final Supplier<ClusterState> clusterState;
|
||||||
private IndexNameExpressionResolver indexNameExpressionResolver;
|
private IndexNameExpressionResolver indexNameExpressionResolver;
|
||||||
|
|
||||||
|
@ -48,8 +44,14 @@ public class EsCatalog implements Catalog {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean indexExists(String index) {
|
public boolean indexExists(String index) {
|
||||||
MetaData meta = metadata();
|
IndexMetaData idx = metadata().index(index);
|
||||||
return meta.hasIndex(index);
|
return idx != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean indexIsValid(String index) {
|
||||||
|
IndexMetaData idx = metadata().index(index);
|
||||||
|
return idx != null && indexHasOnlyOneType(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,60 +70,25 @@ public class EsCatalog implements Catalog {
|
||||||
String[] indexNames = resolveIndex(pattern);
|
String[] indexNames = resolveIndex(pattern);
|
||||||
List<IndexMetaData> indices = new ArrayList<>(indexNames.length);
|
List<IndexMetaData> indices = new ArrayList<>(indexNames.length);
|
||||||
for (String indexName : indexNames) {
|
for (String indexName : indexNames) {
|
||||||
indices.add(md.index(indexName));
|
indices.add(md.index(indexName));
|
||||||
}
|
}
|
||||||
indexMetadata = indices.iterator();
|
indexMetadata = indices.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
return EsIndex.build(indexMetadata);
|
List<EsIndex> list = new ArrayList<>();
|
||||||
}
|
// filter unsupported (indices with more than one type) indices
|
||||||
|
while (indexMetadata.hasNext()) {
|
||||||
@Override
|
IndexMetaData imd = indexMetadata.next();
|
||||||
public EsType getType(String index, String type) {
|
if (indexHasOnlyOneType(imd)) {
|
||||||
if (!indexExists(index)) {
|
list.add(EsIndex.build(imd));
|
||||||
return EsType.NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOCOMMIT verify that this works if the index isn't on the node
|
|
||||||
MappingMetaData mapping = metadata().index(index).mapping(type);
|
|
||||||
if (mapping == null) {
|
|
||||||
return EsType.NOT_FOUND;
|
|
||||||
}
|
|
||||||
return EsType.build(index, type, mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean typeExists(String index, String type) {
|
|
||||||
return indexExists(index) && metadata().index(index).getMappings().containsKey(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EsType> listTypes(String index) {
|
|
||||||
return listTypes(index, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EsType> listTypes(String indexPattern, String pattern) {
|
|
||||||
if (!Strings.hasText(indexPattern)) {
|
|
||||||
indexPattern = WILDCARD;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] iName = indexNameExpressionResolver.concreteIndexNames(clusterState.get(), IndicesOptions.strictExpandOpenAndForbidClosed(), indexPattern);
|
|
||||||
|
|
||||||
List<EsType> types = new ArrayList<>();
|
|
||||||
|
|
||||||
for (String cIndex : iName) {
|
|
||||||
IndexMetaData imd = metadata().index(cIndex);
|
|
||||||
|
|
||||||
if (Strings.hasText(pattern)) {
|
|
||||||
types.add(EsType.build(cIndex, pattern, imd.mapping(pattern)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
types.addAll(EsType.build(cIndex, imd.getMappings()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return types;
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean indexHasOnlyOneType(IndexMetaData index) {
|
||||||
|
return index.getMappings().size() <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] resolveIndex(String pattern) {
|
private String[] resolveIndex(String pattern) {
|
||||||
|
|
|
@ -5,29 +5,36 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.analysis.catalog;
|
package org.elasticsearch.xpack.sql.analysis.catalog;
|
||||||
|
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
|
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
||||||
|
import org.elasticsearch.xpack.sql.type.DataType;
|
||||||
|
import org.elasticsearch.xpack.sql.type.Types;
|
||||||
|
import org.elasticsearch.xpack.sql.util.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
|
|
||||||
public class EsIndex {
|
public class EsIndex {
|
||||||
|
|
||||||
public static final EsIndex NOT_FOUND = new EsIndex("", emptyList(), emptyList(), Settings.EMPTY);
|
public static final EsIndex NOT_FOUND = new EsIndex(StringUtils.EMPTY, emptyMap(), emptyList(), Settings.EMPTY);
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final List<String> types;
|
private final Map<String, DataType> mapping;
|
||||||
private final List<String> aliases;
|
private final List<String> aliases;
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
|
|
||||||
public EsIndex(String name, List<String> types, List<String> aliases, Settings settings) {
|
public EsIndex(String name, Map<String, DataType> mapping, List<String> aliases, Settings settings) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.types = types;
|
this.mapping = mapping;
|
||||||
this.aliases = aliases;
|
this.aliases = aliases;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
@ -36,17 +43,14 @@ public class EsIndex {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, DataType> mapping() {
|
||||||
public List<String> types() {
|
return mapping;
|
||||||
return types;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<String> aliases() {
|
public List<String> aliases() {
|
||||||
return aliases;
|
return aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Settings settings() {
|
public Settings settings() {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
@ -57,14 +61,25 @@ public class EsIndex {
|
||||||
}
|
}
|
||||||
List<EsIndex> list = new ArrayList<>();
|
List<EsIndex> list = new ArrayList<>();
|
||||||
while (metadata.hasNext()) {
|
while (metadata.hasNext()) {
|
||||||
list.add(build(metadata.next()));
|
build(metadata.next());
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EsIndex build(IndexMetaData metadata) {
|
static EsIndex build(IndexMetaData metadata) {
|
||||||
List<String> types = Arrays.asList(metadata.getMappings().keys().toArray(String.class));
|
ImmutableOpenMap<String, MappingMetaData> mappings = metadata.getMappings();
|
||||||
|
if (mappings.size() > 1) {
|
||||||
|
throw new SqlIllegalArgumentException("Cannot use index [%s] as it contains multiple types %s", metadata.getIndex().getName(), Arrays.toString(mappings.keys().toArray()));
|
||||||
|
}
|
||||||
|
MappingMetaData mm = mappings.isEmpty() ? null : mappings.valuesIt().next();
|
||||||
|
Map<String, DataType> mapping = mm != null ? Types.fromEs(mm.sourceAsMap()) : emptyMap();
|
||||||
|
|
||||||
List<String> aliases = Arrays.asList(metadata.getAliases().keys().toArray(String.class));
|
List<String> aliases = Arrays.asList(metadata.getAliases().keys().toArray(String.class));
|
||||||
return new EsIndex(metadata.getIndex().getName(), types, aliases, metadata.getSettings());
|
return new EsIndex(metadata.getIndex().getName(), mapping, aliases, metadata.getSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,73 +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.analysis.catalog;
|
|
||||||
|
|
||||||
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
|
||||||
|
|
||||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
|
||||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
|
||||||
import org.elasticsearch.xpack.sql.type.DataType;
|
|
||||||
import org.elasticsearch.xpack.sql.type.Types;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class EsType {
|
|
||||||
|
|
||||||
public static final EsType NOT_FOUND = new EsType("", "", Collections.emptyMap());
|
|
||||||
|
|
||||||
private final String index;
|
|
||||||
private final String name;
|
|
||||||
private final Map<String, DataType> mapping;
|
|
||||||
|
|
||||||
public EsType(String index, String name, Map<String, DataType> mapping) {
|
|
||||||
this.index = index;
|
|
||||||
this.name = name;
|
|
||||||
this.mapping = mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String index() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, DataType> mapping() {
|
|
||||||
return mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EsType build(String index, String type, MappingMetaData metaData) {
|
|
||||||
Map<String, Object> asMap = metaData.sourceAsMap();
|
|
||||||
|
|
||||||
Map<String, DataType> mapping = Types.fromEs(asMap);
|
|
||||||
return new EsType(index, type, mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Collection<EsType> build(String index, ImmutableOpenMap<String, MappingMetaData> mapping) {
|
|
||||||
List<EsType> tps = new ArrayList<>();
|
|
||||||
|
|
||||||
for (ObjectObjectCursor<String, MappingMetaData> entry : mapping) {
|
|
||||||
tps.add(build(index, entry.key, entry.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return tps;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("index=");
|
|
||||||
sb.append(index);
|
|
||||||
sb.append(",type=");
|
|
||||||
sb.append(name);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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.analysis.catalog;
|
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
public abstract class InMemoryCatalog implements Catalog {
|
|
||||||
|
|
||||||
protected final Map<String, EsIndex> indices = new LinkedHashMap<>();
|
|
||||||
protected final Map<String, Map<String, EsType>> types = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
{
|
|
||||||
List<EsIndex> idxs = indices();
|
|
||||||
for (EsIndex esIndex : idxs) {
|
|
||||||
indices.put(esIndex.name(), esIndex);
|
|
||||||
types.put(esIndex.name(), new LinkedHashMap<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<EsType> tps = types();
|
|
||||||
for (EsType esType : tps) {
|
|
||||||
Map<String, EsType> idxTypes = types.get(esType.index());
|
|
||||||
idxTypes.put(esType.name(), esType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EsIndex getIndex(String index) {
|
|
||||||
EsIndex idx = indices.get(index);
|
|
||||||
return (idx == null ? EsIndex.NOT_FOUND : idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean indexExists(String index) {
|
|
||||||
return indices.containsKey(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EsIndex> listIndices() {
|
|
||||||
return new ArrayList<>(indices.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EsIndex> listIndices(String pattern) {
|
|
||||||
Pattern p = StringUtils.likeRegex(pattern);
|
|
||||||
return indices.entrySet().stream()
|
|
||||||
.filter(e -> p.matcher(e.getKey()).matches())
|
|
||||||
.map(Map.Entry::getValue)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EsType getType(String index, String type) {
|
|
||||||
Map<String, EsType> typs = types.get(index);
|
|
||||||
if (typs == null) {
|
|
||||||
return EsType.NOT_FOUND;
|
|
||||||
}
|
|
||||||
EsType esType = typs.get(type);
|
|
||||||
return (esType == null ? EsType.NOT_FOUND : esType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean typeExists(String index, String type) {
|
|
||||||
Map<String, EsType> typs = types.get(index);
|
|
||||||
return (typs != null && typs.containsKey(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EsType> listTypes(String index) {
|
|
||||||
Map<String, EsType> typs = types.get(index);
|
|
||||||
return typs != null ? new ArrayList<>(typs.values()) : emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<EsType> listTypes(String index, String pattern) {
|
|
||||||
Map<String, EsType> typs = types.get(index);
|
|
||||||
if (typs == null) {
|
|
||||||
return emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Pattern p = StringUtils.likeRegex(pattern);
|
|
||||||
return typs.entrySet().stream()
|
|
||||||
.filter(e -> p.matcher(e.getKey()).matches())
|
|
||||||
.map(Map.Entry::getValue)
|
|
||||||
.collect(toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
indices.clear();
|
|
||||||
types.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract List<EsIndex> indices();
|
|
||||||
|
|
||||||
protected abstract List<EsType> types();
|
|
||||||
}
|
|
|
@ -64,13 +64,13 @@ public class Scroller {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scroll(Schema schema, QueryContainer query, String index, String type, ActionListener<RowSetCursor> listener) {
|
public void scroll(Schema schema, QueryContainer query, String index, ActionListener<RowSetCursor> listener) {
|
||||||
// prepare the request
|
// prepare the request
|
||||||
SearchSourceBuilder sourceBuilder = SourceGenerator.sourceBuilder(query);
|
SearchSourceBuilder sourceBuilder = SourceGenerator.sourceBuilder(query);
|
||||||
|
|
||||||
log.trace("About to execute query {}", sourceBuilder);
|
log.trace("About to execute query {} on {}", sourceBuilder, index);
|
||||||
|
|
||||||
SearchRequest search = client.prepareSearch(index).setTypes(type).setSource(sourceBuilder).request();
|
SearchRequest search = client.prepareSearch(index).setSource(sourceBuilder).request();
|
||||||
search.scroll(keepAlive).source().timeout(timeout);
|
search.scroll(keepAlive).source().timeout(timeout);
|
||||||
|
|
||||||
// set the size only if it hasn't been specified (aggs only queries set the size to 0)
|
// set the size only if it hasn't been specified (aggs only queries set the size to 0)
|
||||||
|
@ -280,7 +280,7 @@ public class Scroller {
|
||||||
// is all the content already retrieved?
|
// is all the content already retrieved?
|
||||||
if (Boolean.TRUE.equals(response.isTerminatedEarly()) || response.getHits().getTotalHits() == hits.length
|
if (Boolean.TRUE.equals(response.isTerminatedEarly()) || response.getHits().getTotalHits() == hits.length
|
||||||
// or maybe the limit has been reached
|
// or maybe the limit has been reached
|
||||||
|| docsRead >= limit) {
|
|| (docsRead >= limit && limit > -1)) {
|
||||||
// if so, clear the scroll
|
// if so, clear the scroll
|
||||||
clearScroll(scrollId);
|
clearScroll(scrollId);
|
||||||
// and remove it to indicate no more data is expected
|
// and remove it to indicate no more data is expected
|
||||||
|
|
|
@ -108,7 +108,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitShowTables(ShowTablesContext ctx) {
|
public Object visitShowTables(ShowTablesContext ctx) {
|
||||||
return new ShowTables(source(ctx), visitIdentifier(ctx.index), text(ctx.pattern));
|
return new ShowTables(source(ctx), text(ctx.pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -120,10 +120,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
|
||||||
@Override
|
@Override
|
||||||
public Object visitShowColumns(ShowColumnsContext ctx) {
|
public Object visitShowColumns(ShowColumnsContext ctx) {
|
||||||
TableIdentifier identifier = visitTableIdentifier(ctx.tableIdentifier());
|
TableIdentifier identifier = visitTableIdentifier(ctx.tableIdentifier());
|
||||||
if (!identifier.hasType()) {
|
return new ShowColumns(source(ctx), identifier.index());
|
||||||
throw new ParsingException(identifier.location(), "Target type needs to be specified");
|
|
||||||
}
|
|
||||||
return new ShowColumns(source(ctx), identifier.index(), identifier.type());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -133,7 +133,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
|
||||||
}
|
}
|
||||||
else if (ctx.table != null) {
|
else if (ctx.table != null) {
|
||||||
TableIdentifier table = visitTableIdentifier(ctx.table);
|
TableIdentifier table = visitTableIdentifier(ctx.table);
|
||||||
qualifier = table.index() + "." + table.type();
|
qualifier = table.index();
|
||||||
}
|
}
|
||||||
return new UnresolvedAttribute(source(ctx), visitIdentifier(ctx.name), qualifier);
|
return new UnresolvedAttribute(source(ctx), visitIdentifier(ctx.name), qualifier);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.parser;
|
package org.elasticsearch.xpack.sql.parser;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.IdentifierContext;
|
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.IdentifierContext;
|
||||||
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.QualifiedNameContext;
|
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.QualifiedNameContext;
|
||||||
|
@ -14,28 +12,20 @@ import org.elasticsearch.xpack.sql.parser.SqlBaseParser.TableIdentifierContext;
|
||||||
import org.elasticsearch.xpack.sql.plan.TableIdentifier;
|
import org.elasticsearch.xpack.sql.plan.TableIdentifier;
|
||||||
import org.elasticsearch.xpack.sql.tree.Location;
|
import org.elasticsearch.xpack.sql.tree.Location;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
|
|
||||||
abstract class IdentifierBuilder extends AbstractBuilder {
|
abstract class IdentifierBuilder extends AbstractBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableIdentifier visitTableIdentifier(TableIdentifierContext ctx) {
|
public TableIdentifier visitTableIdentifier(TableIdentifierContext ctx) {
|
||||||
String index = null;
|
String index = text(ctx.index);
|
||||||
String type = null;
|
|
||||||
|
|
||||||
index = text(ctx.uindex);
|
|
||||||
type = text(ctx.utype);
|
|
||||||
|
|
||||||
if (index == null) {
|
|
||||||
index = text(ctx.index);
|
|
||||||
type = text(ctx.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
Location source = source(ctx);
|
Location source = source(ctx);
|
||||||
validateIndex(index, source);
|
validateIndex(index, source);
|
||||||
validateType(type, source);
|
|
||||||
|
|
||||||
return new TableIdentifier(source, index, type);
|
return new TableIdentifier(source, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://github.com/elastic/elasticsearch/issues/6736
|
// see https://github.com/elastic/elasticsearch/issues/6736
|
||||||
|
@ -51,10 +41,6 @@ abstract class IdentifierBuilder extends AbstractBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateType(String type, Location source) {
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String visitIdentifier(IdentifierContext ctx) {
|
public String visitIdentifier(IdentifierContext ctx) {
|
||||||
return ctx == null ? null : ctx.quoteIdentifier() != null ? text(ctx.quoteIdentifier()) : text(ctx.unquoteIdentifier());
|
return ctx == null ? null : ctx.quoteIdentifier() != null ? text(ctx.quoteIdentifier()) : text(ctx.unquoteIdentifier());
|
||||||
|
|
|
@ -195,9 +195,6 @@ abstract class LogicalPlanBuilder extends ExpressionBuilder {
|
||||||
public LogicalPlan visitTableName(TableNameContext ctx) {
|
public LogicalPlan visitTableName(TableNameContext ctx) {
|
||||||
String alias = visitQualifiedName(ctx.qualifiedName());
|
String alias = visitQualifiedName(ctx.qualifiedName());
|
||||||
TableIdentifier tableIdentifier = visitTableIdentifier(ctx.tableIdentifier());
|
TableIdentifier tableIdentifier = visitTableIdentifier(ctx.tableIdentifier());
|
||||||
if (!tableIdentifier.hasType()) {
|
|
||||||
throw new ParsingException(source(ctx), "Index type is required");
|
|
||||||
}
|
|
||||||
return new UnresolvedRelation(source(ctx), tableIdentifier, alias);
|
return new UnresolvedRelation(source(ctx), tableIdentifier, alias);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,30 +22,30 @@ class SqlBaseLexer extends Lexer {
|
||||||
protected static final PredictionContextCache _sharedContextCache =
|
protected static final PredictionContextCache _sharedContextCache =
|
||||||
new PredictionContextCache();
|
new PredictionContextCache();
|
||||||
public static final int
|
public static final int
|
||||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, SELECT=6, FROM=7, AS=8, ALL=9,
|
T__0=1, T__1=2, T__2=3, T__3=4, SELECT=5, FROM=6, AS=7, ALL=8, WHEN=9,
|
||||||
WHEN=10, THEN=11, ANY=12, DISTINCT=13, WHERE=14, GROUP=15, BY=16, GROUPING=17,
|
THEN=10, ANY=11, DISTINCT=12, WHERE=13, GROUP=14, BY=15, GROUPING=16,
|
||||||
SETS=18, ORDER=19, HAVING=20, LIMIT=21, OR=22, AND=23, IN=24, NOT=25,
|
SETS=17, ORDER=18, HAVING=19, LIMIT=20, OR=21, AND=22, IN=23, NOT=24,
|
||||||
NO=26, EXISTS=27, BETWEEN=28, LIKE=29, RLIKE=30, IS=31, NULL=32, TRUE=33,
|
NO=25, EXISTS=26, BETWEEN=27, LIKE=28, RLIKE=29, IS=30, NULL=31, TRUE=32,
|
||||||
FALSE=34, LAST=35, ASC=36, DESC=37, FOR=38, INTEGER=39, JOIN=40, CROSS=41,
|
FALSE=33, LAST=34, ASC=35, DESC=36, FOR=37, INTEGER=38, JOIN=39, CROSS=40,
|
||||||
OUTER=42, INNER=43, LEFT=44, RIGHT=45, FULL=46, NATURAL=47, USING=48,
|
OUTER=41, INNER=42, LEFT=43, RIGHT=44, FULL=45, NATURAL=46, USING=47,
|
||||||
ON=49, WITH=50, TABLE=51, INTO=52, DESCRIBE=53, OPTION=54, EXPLAIN=55,
|
ON=48, WITH=49, TABLE=50, INTO=51, DESCRIBE=52, OPTION=53, EXPLAIN=54,
|
||||||
ANALYZE=56, FORMAT=57, TYPE=58, TEXT=59, VERIFY=60, GRAPHVIZ=61, LOGICAL=62,
|
ANALYZE=55, FORMAT=56, TYPE=57, TEXT=58, VERIFY=59, GRAPHVIZ=60, LOGICAL=61,
|
||||||
PHYSICAL=63, SHOW=64, TABLES=65, COLUMNS=66, COLUMN=67, FUNCTIONS=68,
|
PHYSICAL=62, SHOW=63, TABLES=64, COLUMNS=65, COLUMN=66, FUNCTIONS=67,
|
||||||
TO=69, DEBUG=70, PLAN=71, PARSED=72, ANALYZED=73, OPTIMIZED=74, MAPPED=75,
|
TO=68, DEBUG=69, PLAN=70, PARSED=71, ANALYZED=72, OPTIMIZED=73, MAPPED=74,
|
||||||
EXECUTABLE=76, USE=77, SET=78, RESET=79, SESSION=80, SCHEMAS=81, EXTRACT=82,
|
EXECUTABLE=75, USE=76, SET=77, RESET=78, SESSION=79, SCHEMAS=80, EXTRACT=81,
|
||||||
QUERY=83, MATCH=84, CAST=85, EQ=86, NEQ=87, LT=88, LTE=89, GT=90, GTE=91,
|
QUERY=82, MATCH=83, CAST=84, EQ=85, NEQ=86, LT=87, LTE=88, GT=89, GTE=90,
|
||||||
PLUS=92, MINUS=93, ASTERISK=94, SLASH=95, PERCENT=96, CONCAT=97, STRING=98,
|
PLUS=91, MINUS=92, ASTERISK=93, SLASH=94, PERCENT=95, CONCAT=96, STRING=97,
|
||||||
INTEGER_VALUE=99, DECIMAL_VALUE=100, IDENTIFIER=101, DIGIT_IDENTIFIER=102,
|
INTEGER_VALUE=98, DECIMAL_VALUE=99, IDENTIFIER=100, DIGIT_IDENTIFIER=101,
|
||||||
QUOTED_IDENTIFIER=103, BACKQUOTED_IDENTIFIER=104, SIMPLE_COMMENT=105,
|
QUOTED_IDENTIFIER=102, BACKQUOTED_IDENTIFIER=103, SIMPLE_COMMENT=104,
|
||||||
BRACKETED_COMMENT=106, WS=107, UNRECOGNIZED=108;
|
BRACKETED_COMMENT=105, WS=106, UNRECOGNIZED=107;
|
||||||
public static String[] modeNames = {
|
public static String[] modeNames = {
|
||||||
"DEFAULT_MODE"
|
"DEFAULT_MODE"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final String[] ruleNames = {
|
public static final String[] ruleNames = {
|
||||||
"T__0", "T__1", "T__2", "T__3", "T__4", "SELECT", "FROM", "AS", "ALL",
|
"T__0", "T__1", "T__2", "T__3", "SELECT", "FROM", "AS", "ALL", "WHEN",
|
||||||
"WHEN", "THEN", "ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING",
|
"THEN", "ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING", "SETS",
|
||||||
"SETS", "ORDER", "HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS",
|
"ORDER", "HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS",
|
||||||
"BETWEEN", "LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC",
|
"BETWEEN", "LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC",
|
||||||
"DESC", "FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
|
"DESC", "FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
|
||||||
"FULL", "NATURAL", "USING", "ON", "WITH", "TABLE", "INTO", "DESCRIBE",
|
"FULL", "NATURAL", "USING", "ON", "WITH", "TABLE", "INTO", "DESCRIBE",
|
||||||
|
@ -61,10 +61,10 @@ class SqlBaseLexer extends Lexer {
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] _LITERAL_NAMES = {
|
private static final String[] _LITERAL_NAMES = {
|
||||||
null, "'('", "')'", "','", "'.'", "'\"'", "'SELECT'", "'FROM'", "'AS'",
|
null, "'('", "')'", "','", "'.'", "'SELECT'", "'FROM'", "'AS'", "'ALL'",
|
||||||
"'ALL'", "'WHEN'", "'THEN'", "'ANY'", "'DISTINCT'", "'WHERE'", "'GROUP'",
|
"'WHEN'", "'THEN'", "'ANY'", "'DISTINCT'", "'WHERE'", "'GROUP'", "'BY'",
|
||||||
"'BY'", "'GROUPING'", "'SETS'", "'ORDER'", "'HAVING'", "'LIMIT'", "'OR'",
|
"'GROUPING'", "'SETS'", "'ORDER'", "'HAVING'", "'LIMIT'", "'OR'", "'AND'",
|
||||||
"'AND'", "'IN'", "'NOT'", "'NO'", "'EXISTS'", "'BETWEEN'", "'LIKE'", "'RLIKE'",
|
"'IN'", "'NOT'", "'NO'", "'EXISTS'", "'BETWEEN'", "'LIKE'", "'RLIKE'",
|
||||||
"'IS'", "'NULL'", "'TRUE'", "'FALSE'", "'LAST'", "'ASC'", "'DESC'", "'FOR'",
|
"'IS'", "'NULL'", "'TRUE'", "'FALSE'", "'LAST'", "'ASC'", "'DESC'", "'FOR'",
|
||||||
"'INTEGER'", "'JOIN'", "'CROSS'", "'OUTER'", "'INNER'", "'LEFT'", "'RIGHT'",
|
"'INTEGER'", "'JOIN'", "'CROSS'", "'OUTER'", "'INNER'", "'LEFT'", "'RIGHT'",
|
||||||
"'FULL'", "'NATURAL'", "'USING'", "'ON'", "'WITH'", "'TABLE'", "'INTO'",
|
"'FULL'", "'NATURAL'", "'USING'", "'ON'", "'WITH'", "'TABLE'", "'INTO'",
|
||||||
|
@ -77,11 +77,11 @@ class SqlBaseLexer extends Lexer {
|
||||||
"'-'", "'*'", "'/'", "'%'", "'||'"
|
"'-'", "'*'", "'/'", "'%'", "'||'"
|
||||||
};
|
};
|
||||||
private static final String[] _SYMBOLIC_NAMES = {
|
private static final String[] _SYMBOLIC_NAMES = {
|
||||||
null, null, null, null, null, null, "SELECT", "FROM", "AS", "ALL", "WHEN",
|
null, null, null, null, null, "SELECT", "FROM", "AS", "ALL", "WHEN", "THEN",
|
||||||
"THEN", "ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING", "SETS",
|
"ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING", "SETS", "ORDER",
|
||||||
"ORDER", "HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS",
|
"HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS", "BETWEEN",
|
||||||
"BETWEEN", "LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC",
|
"LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC", "DESC",
|
||||||
"DESC", "FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
|
"FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
|
||||||
"FULL", "NATURAL", "USING", "ON", "WITH", "TABLE", "INTO", "DESCRIBE",
|
"FULL", "NATURAL", "USING", "ON", "WITH", "TABLE", "INTO", "DESCRIBE",
|
||||||
"OPTION", "EXPLAIN", "ANALYZE", "FORMAT", "TYPE", "TEXT", "VERIFY", "GRAPHVIZ",
|
"OPTION", "EXPLAIN", "ANALYZE", "FORMAT", "TYPE", "TEXT", "VERIFY", "GRAPHVIZ",
|
||||||
"LOGICAL", "PHYSICAL", "SHOW", "TABLES", "COLUMNS", "COLUMN", "FUNCTIONS",
|
"LOGICAL", "PHYSICAL", "SHOW", "TABLES", "COLUMNS", "COLUMN", "FUNCTIONS",
|
||||||
|
@ -147,7 +147,7 @@ class SqlBaseLexer extends Lexer {
|
||||||
public ATN getATN() { return _ATN; }
|
public ATN getATN() { return _ATN; }
|
||||||
|
|
||||||
public static final String _serializedATN =
|
public static final String _serializedATN =
|
||||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2n\u038a\b\1\4\2\t"+
|
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2m\u0386\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
||||||
|
@ -159,298 +159,297 @@ class SqlBaseLexer extends Lexer {
|
||||||
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
|
"\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]\4^\t^\4_\t_\4"+
|
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\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\t"+
|
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
|
||||||
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3"+
|
"k\4l\tl\4m\tm\4n\tn\4o\to\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6"+
|
||||||
"\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\n\3\n"+
|
"\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3"+
|
||||||
"\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r"+
|
"\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3"+
|
||||||
"\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17"+
|
"\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3"+
|
||||||
"\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\22\3\22\3\22\3\22"+
|
"\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3"+
|
||||||
"\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24"+
|
"\21\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3"+
|
||||||
"\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26"+
|
"\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3"+
|
||||||
"\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\32\3\32\3\32"+
|
"\27\3\27\3\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3"+
|
||||||
"\3\32\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35"+
|
"\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3"+
|
||||||
"\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37"+
|
"\34\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3"+
|
||||||
"\3\37\3\37\3 \3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\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\'\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+\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\60\3\61\3\61\3\61\3\61\3\61\3\61\3\62"+
|
"/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3"+
|
||||||
"\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\64\3\65"+
|
"\62\3\62\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"+
|
||||||
"\3\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\67"+
|
"\65\3\65\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"+
|
||||||
"\3\67\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\38\38\38\39\39\39\39\39"+
|
"\66\3\67\3\67\3\67\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\38\38\38\3"+
|
||||||
"\39\39\39\3:\3:\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;\3<\3<\3<\3<\3<\3=\3=\3="+
|
"9\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=\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\3B\3B\3B\3B\3B\3C\3C\3C\3C"+
|
"?\3?\3?\3?\3@\3@\3@\3@\3@\3A\3A\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3B\3"+
|
||||||
"\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F"+
|
"B\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3F\3F\3"+
|
||||||
"\3F\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J"+
|
"F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3"+
|
||||||
"\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M"+
|
"I\3I\3J\3J\3J\3J\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3"+
|
||||||
"\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P"+
|
"L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3P\3P\3"+
|
||||||
"\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S"+
|
"P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3S\3"+
|
||||||
"\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V\3V\3W\3W\3X\3X"+
|
"S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3W\3W\3W\3W\3W\3"+
|
||||||
"\3X\3X\3X\3X\3X\5X\u02d7\nX\3Y\3Y\3Z\3Z\3Z\3[\3[\3\\\3\\\3\\\3]\3]\3^"+
|
"W\3W\5W\u02d3\nW\3X\3X\3Y\3Y\3Y\3Z\3Z\3[\3[\3[\3\\\3\\\3]\3]\3^\3^\3_"+
|
||||||
"\3^\3_\3_\3`\3`\3a\3a\3b\3b\3b\3c\3c\3c\3c\7c\u02f4\nc\fc\16c\u02f7\13"+
|
"\3_\3`\3`\3a\3a\3a\3b\3b\3b\3b\7b\u02f0\nb\fb\16b\u02f3\13b\3b\3b\3c\6"+
|
||||||
"c\3c\3c\3d\6d\u02fc\nd\rd\16d\u02fd\3e\6e\u0301\ne\re\16e\u0302\3e\3e"+
|
"c\u02f8\nc\rc\16c\u02f9\3d\6d\u02fd\nd\rd\16d\u02fe\3d\3d\7d\u0303\nd"+
|
||||||
"\7e\u0307\ne\fe\16e\u030a\13e\3e\3e\6e\u030e\ne\re\16e\u030f\3e\6e\u0313"+
|
"\fd\16d\u0306\13d\3d\3d\6d\u030a\nd\rd\16d\u030b\3d\6d\u030f\nd\rd\16"+
|
||||||
"\ne\re\16e\u0314\3e\3e\7e\u0319\ne\fe\16e\u031c\13e\5e\u031e\ne\3e\3e"+
|
"d\u0310\3d\3d\7d\u0315\nd\fd\16d\u0318\13d\5d\u031a\nd\3d\3d\3d\3d\6d"+
|
||||||
"\3e\3e\6e\u0324\ne\re\16e\u0325\3e\3e\5e\u032a\ne\3f\3f\5f\u032e\nf\3"+
|
"\u0320\nd\rd\16d\u0321\3d\3d\5d\u0326\nd\3e\3e\5e\u032a\ne\3e\3e\3e\7"+
|
||||||
"f\3f\3f\7f\u0333\nf\ff\16f\u0336\13f\3g\3g\3g\3g\6g\u033c\ng\rg\16g\u033d"+
|
"e\u032f\ne\fe\16e\u0332\13e\3f\3f\3f\3f\6f\u0338\nf\rf\16f\u0339\3g\3"+
|
||||||
"\3h\3h\3h\7h\u0343\nh\fh\16h\u0346\13h\3h\3h\3i\3i\3i\3i\7i\u034e\ni\f"+
|
"g\3g\7g\u033f\ng\fg\16g\u0342\13g\3g\3g\3h\3h\3h\3h\7h\u034a\nh\fh\16"+
|
||||||
"i\16i\u0351\13i\3i\3i\3j\3j\5j\u0357\nj\3j\6j\u035a\nj\rj\16j\u035b\3"+
|
"h\u034d\13h\3h\3h\3i\3i\5i\u0353\ni\3i\6i\u0356\ni\ri\16i\u0357\3j\3j"+
|
||||||
"k\3k\3l\3l\3m\3m\3m\3m\7m\u0366\nm\fm\16m\u0369\13m\3m\5m\u036c\nm\3m"+
|
"\3k\3k\3l\3l\3l\3l\7l\u0362\nl\fl\16l\u0365\13l\3l\5l\u0368\nl\3l\5l\u036b"+
|
||||||
"\5m\u036f\nm\3m\3m\3n\3n\3n\3n\3n\7n\u0378\nn\fn\16n\u037b\13n\3n\3n\3"+
|
"\nl\3l\3l\3m\3m\3m\3m\3m\7m\u0374\nm\fm\16m\u0377\13m\3m\3m\3m\3m\3m\3"+
|
||||||
"n\3n\3n\3o\6o\u0383\no\ro\16o\u0384\3o\3o\3p\3p\3\u0379\2q\3\3\5\4\7\5"+
|
"n\6n\u037f\nn\rn\16n\u0380\3n\3n\3o\3o\3\u0375\2p\3\3\5\4\7\5\t\6\13\7"+
|
||||||
"\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"+
|
"\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25"+
|
||||||
"%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G"+
|
")\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O"+
|
||||||
"%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{"+
|
")Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081"+
|
||||||
"?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091"+
|
"B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095"+
|
||||||
"J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5"+
|
"L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9"+
|
||||||
"T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9"+
|
"V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd"+
|
||||||
"^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cd"+
|
"`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1"+
|
||||||
"h\u00cfi\u00d1j\u00d3\2\u00d5\2\u00d7\2\u00d9k\u00dbl\u00ddm\u00dfn\3"+
|
"\2\u00d3\2\u00d5\2\u00d7j\u00d9k\u00dbl\u00ddm\3\2\13\3\2))\5\2<<BBaa"+
|
||||||
"\2\13\3\2))\5\2<<BBaa\6\2$$))\60\60~~\6\2))\60\60bb~~\4\2--//\3\2\62;"+
|
"\6\2$$))\60\60~~\6\2))\60\60bb~~\4\2--//\3\2\62;\3\2C\\\4\2\f\f\17\17"+
|
||||||
"\3\2C\\\4\2\f\f\17\17\5\2\13\f\17\17\"\"\u03a8\2\3\3\2\2\2\2\5\3\2\2\2"+
|
"\5\2\13\f\17\17\"\"\u03a4\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\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\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"+
|
||||||
"\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"+
|
"\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\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\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-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\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"+
|
||||||
"\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"+
|
"\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\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"+
|
"\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"+
|
||||||
"\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"+
|
"\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\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\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\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"+
|
"\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"+
|
||||||
"\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"+
|
"\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"+
|
||||||
"\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\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"+
|
||||||
"\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"+
|
"\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\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2"+
|
"\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\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"+
|
"\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\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2"+
|
"\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2"+
|
||||||
"\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5"+
|
"\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7"+
|
||||||
"\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"+
|
"\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2"+
|
||||||
"\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7"+
|
"\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9"+
|
||||||
"\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2"+
|
"\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d7\3\2\2"+
|
||||||
"\2\2\u00d1\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df"+
|
"\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\3\u00df\3\2\2\2\5\u00e1"+
|
||||||
"\3\2\2\2\3\u00e1\3\2\2\2\5\u00e3\3\2\2\2\7\u00e5\3\2\2\2\t\u00e7\3\2\2"+
|
"\3\2\2\2\7\u00e3\3\2\2\2\t\u00e5\3\2\2\2\13\u00e7\3\2\2\2\r\u00ee\3\2"+
|
||||||
"\2\13\u00e9\3\2\2\2\r\u00eb\3\2\2\2\17\u00f2\3\2\2\2\21\u00f7\3\2\2\2"+
|
"\2\2\17\u00f3\3\2\2\2\21\u00f6\3\2\2\2\23\u00fa\3\2\2\2\25\u00ff\3\2\2"+
|
||||||
"\23\u00fa\3\2\2\2\25\u00fe\3\2\2\2\27\u0103\3\2\2\2\31\u0108\3\2\2\2\33"+
|
"\2\27\u0104\3\2\2\2\31\u0108\3\2\2\2\33\u0111\3\2\2\2\35\u0117\3\2\2\2"+
|
||||||
"\u010c\3\2\2\2\35\u0115\3\2\2\2\37\u011b\3\2\2\2!\u0121\3\2\2\2#\u0124"+
|
"\37\u011d\3\2\2\2!\u0120\3\2\2\2#\u0129\3\2\2\2%\u012e\3\2\2\2\'\u0134"+
|
||||||
"\3\2\2\2%\u012d\3\2\2\2\'\u0132\3\2\2\2)\u0138\3\2\2\2+\u013f\3\2\2\2"+
|
"\3\2\2\2)\u013b\3\2\2\2+\u0141\3\2\2\2-\u0144\3\2\2\2/\u0148\3\2\2\2\61"+
|
||||||
"-\u0145\3\2\2\2/\u0148\3\2\2\2\61\u014c\3\2\2\2\63\u014f\3\2\2\2\65\u0153"+
|
"\u014b\3\2\2\2\63\u014f\3\2\2\2\65\u0152\3\2\2\2\67\u0159\3\2\2\29\u0161"+
|
||||||
"\3\2\2\2\67\u0156\3\2\2\29\u015d\3\2\2\2;\u0165\3\2\2\2=\u016a\3\2\2\2"+
|
"\3\2\2\2;\u0166\3\2\2\2=\u016c\3\2\2\2?\u016f\3\2\2\2A\u0174\3\2\2\2C"+
|
||||||
"?\u0170\3\2\2\2A\u0173\3\2\2\2C\u0178\3\2\2\2E\u017d\3\2\2\2G\u0183\3"+
|
"\u0179\3\2\2\2E\u017f\3\2\2\2G\u0184\3\2\2\2I\u0188\3\2\2\2K\u018d\3\2"+
|
||||||
"\2\2\2I\u0188\3\2\2\2K\u018c\3\2\2\2M\u0191\3\2\2\2O\u0195\3\2\2\2Q\u019d"+
|
"\2\2M\u0191\3\2\2\2O\u0199\3\2\2\2Q\u019e\3\2\2\2S\u01a4\3\2\2\2U\u01aa"+
|
||||||
"\3\2\2\2S\u01a2\3\2\2\2U\u01a8\3\2\2\2W\u01ae\3\2\2\2Y\u01b4\3\2\2\2["+
|
"\3\2\2\2W\u01b0\3\2\2\2Y\u01b5\3\2\2\2[\u01bb\3\2\2\2]\u01c0\3\2\2\2_"+
|
||||||
"\u01b9\3\2\2\2]\u01bf\3\2\2\2_\u01c4\3\2\2\2a\u01cc\3\2\2\2c\u01d2\3\2"+
|
"\u01c8\3\2\2\2a\u01ce\3\2\2\2c\u01d1\3\2\2\2e\u01d6\3\2\2\2g\u01dc\3\2"+
|
||||||
"\2\2e\u01d5\3\2\2\2g\u01da\3\2\2\2i\u01e0\3\2\2\2k\u01e5\3\2\2\2m\u01ee"+
|
"\2\2i\u01e1\3\2\2\2k\u01ea\3\2\2\2m\u01f1\3\2\2\2o\u01f9\3\2\2\2q\u0201"+
|
||||||
"\3\2\2\2o\u01f5\3\2\2\2q\u01fd\3\2\2\2s\u0205\3\2\2\2u\u020c\3\2\2\2w"+
|
"\3\2\2\2s\u0208\3\2\2\2u\u020d\3\2\2\2w\u0212\3\2\2\2y\u0219\3\2\2\2{"+
|
||||||
"\u0211\3\2\2\2y\u0216\3\2\2\2{\u021d\3\2\2\2}\u0226\3\2\2\2\177\u022e"+
|
"\u0222\3\2\2\2}\u022a\3\2\2\2\177\u0233\3\2\2\2\u0081\u0238\3\2\2\2\u0083"+
|
||||||
"\3\2\2\2\u0081\u0237\3\2\2\2\u0083\u023c\3\2\2\2\u0085\u0243\3\2\2\2\u0087"+
|
"\u023f\3\2\2\2\u0085\u0247\3\2\2\2\u0087\u024e\3\2\2\2\u0089\u0258\3\2"+
|
||||||
"\u024b\3\2\2\2\u0089\u0252\3\2\2\2\u008b\u025c\3\2\2\2\u008d\u025f\3\2"+
|
"\2\2\u008b\u025b\3\2\2\2\u008d\u0261\3\2\2\2\u008f\u0266\3\2\2\2\u0091"+
|
||||||
"\2\2\u008f\u0265\3\2\2\2\u0091\u026a\3\2\2\2\u0093\u0271\3\2\2\2\u0095"+
|
"\u026d\3\2\2\2\u0093\u0276\3\2\2\2\u0095\u0280\3\2\2\2\u0097\u0287\3\2"+
|
||||||
"\u027a\3\2\2\2\u0097\u0284\3\2\2\2\u0099\u028b\3\2\2\2\u009b\u0296\3\2"+
|
"\2\2\u0099\u0292\3\2\2\2\u009b\u0296\3\2\2\2\u009d\u029a\3\2\2\2\u009f"+
|
||||||
"\2\2\u009d\u029a\3\2\2\2\u009f\u029e\3\2\2\2\u00a1\u02a4\3\2\2\2\u00a3"+
|
"\u02a0\3\2\2\2\u00a1\u02a8\3\2\2\2\u00a3\u02b0\3\2\2\2\u00a5\u02b8\3\2"+
|
||||||
"\u02ac\3\2\2\2\u00a5\u02b4\3\2\2\2\u00a7\u02bc\3\2\2\2\u00a9\u02c2\3\2"+
|
"\2\2\u00a7\u02be\3\2\2\2\u00a9\u02c4\3\2\2\2\u00ab\u02c9\3\2\2\2\u00ad"+
|
||||||
"\2\2\u00ab\u02c8\3\2\2\2\u00ad\u02cd\3\2\2\2\u00af\u02d6\3\2\2\2\u00b1"+
|
"\u02d2\3\2\2\2\u00af\u02d4\3\2\2\2\u00b1\u02d6\3\2\2\2\u00b3\u02d9\3\2"+
|
||||||
"\u02d8\3\2\2\2\u00b3\u02da\3\2\2\2\u00b5\u02dd\3\2\2\2\u00b7\u02df\3\2"+
|
"\2\2\u00b5\u02db\3\2\2\2\u00b7\u02de\3\2\2\2\u00b9\u02e0\3\2\2\2\u00bb"+
|
||||||
"\2\2\u00b9\u02e2\3\2\2\2\u00bb\u02e4\3\2\2\2\u00bd\u02e6\3\2\2\2\u00bf"+
|
"\u02e2\3\2\2\2\u00bd\u02e4\3\2\2\2\u00bf\u02e6\3\2\2\2\u00c1\u02e8\3\2"+
|
||||||
"\u02e8\3\2\2\2\u00c1\u02ea\3\2\2\2\u00c3\u02ec\3\2\2\2\u00c5\u02ef\3\2"+
|
"\2\2\u00c3\u02eb\3\2\2\2\u00c5\u02f7\3\2\2\2\u00c7\u0325\3\2\2\2\u00c9"+
|
||||||
"\2\2\u00c7\u02fb\3\2\2\2\u00c9\u0329\3\2\2\2\u00cb\u032d\3\2\2\2\u00cd"+
|
"\u0329\3\2\2\2\u00cb\u0333\3\2\2\2\u00cd\u033b\3\2\2\2\u00cf\u0345\3\2"+
|
||||||
"\u0337\3\2\2\2\u00cf\u033f\3\2\2\2\u00d1\u0349\3\2\2\2\u00d3\u0354\3\2"+
|
"\2\2\u00d1\u0350\3\2\2\2\u00d3\u0359\3\2\2\2\u00d5\u035b\3\2\2\2\u00d7"+
|
||||||
"\2\2\u00d5\u035d\3\2\2\2\u00d7\u035f\3\2\2\2\u00d9\u0361\3\2\2\2\u00db"+
|
"\u035d\3\2\2\2\u00d9\u036e\3\2\2\2\u00db\u037e\3\2\2\2\u00dd\u0384\3\2"+
|
||||||
"\u0372\3\2\2\2\u00dd\u0382\3\2\2\2\u00df\u0388\3\2\2\2\u00e1\u00e2\7*"+
|
"\2\2\u00df\u00e0\7*\2\2\u00e0\4\3\2\2\2\u00e1\u00e2\7+\2\2\u00e2\6\3\2"+
|
||||||
"\2\2\u00e2\4\3\2\2\2\u00e3\u00e4\7+\2\2\u00e4\6\3\2\2\2\u00e5\u00e6\7"+
|
"\2\2\u00e3\u00e4\7.\2\2\u00e4\b\3\2\2\2\u00e5\u00e6\7\60\2\2\u00e6\n\3"+
|
||||||
".\2\2\u00e6\b\3\2\2\2\u00e7\u00e8\7\60\2\2\u00e8\n\3\2\2\2\u00e9\u00ea"+
|
"\2\2\2\u00e7\u00e8\7U\2\2\u00e8\u00e9\7G\2\2\u00e9\u00ea\7N\2\2\u00ea"+
|
||||||
"\7$\2\2\u00ea\f\3\2\2\2\u00eb\u00ec\7U\2\2\u00ec\u00ed\7G\2\2\u00ed\u00ee"+
|
"\u00eb\7G\2\2\u00eb\u00ec\7E\2\2\u00ec\u00ed\7V\2\2\u00ed\f\3\2\2\2\u00ee"+
|
||||||
"\7N\2\2\u00ee\u00ef\7G\2\2\u00ef\u00f0\7E\2\2\u00f0\u00f1\7V\2\2\u00f1"+
|
"\u00ef\7H\2\2\u00ef\u00f0\7T\2\2\u00f0\u00f1\7Q\2\2\u00f1\u00f2\7O\2\2"+
|
||||||
"\16\3\2\2\2\u00f2\u00f3\7H\2\2\u00f3\u00f4\7T\2\2\u00f4\u00f5\7Q\2\2\u00f5"+
|
"\u00f2\16\3\2\2\2\u00f3\u00f4\7C\2\2\u00f4\u00f5\7U\2\2\u00f5\20\3\2\2"+
|
||||||
"\u00f6\7O\2\2\u00f6\20\3\2\2\2\u00f7\u00f8\7C\2\2\u00f8\u00f9\7U\2\2\u00f9"+
|
"\2\u00f6\u00f7\7C\2\2\u00f7\u00f8\7N\2\2\u00f8\u00f9\7N\2\2\u00f9\22\3"+
|
||||||
"\22\3\2\2\2\u00fa\u00fb\7C\2\2\u00fb\u00fc\7N\2\2\u00fc\u00fd\7N\2\2\u00fd"+
|
"\2\2\2\u00fa\u00fb\7Y\2\2\u00fb\u00fc\7J\2\2\u00fc\u00fd\7G\2\2\u00fd"+
|
||||||
"\24\3\2\2\2\u00fe\u00ff\7Y\2\2\u00ff\u0100\7J\2\2\u0100\u0101\7G\2\2\u0101"+
|
"\u00fe\7P\2\2\u00fe\24\3\2\2\2\u00ff\u0100\7V\2\2\u0100\u0101\7J\2\2\u0101"+
|
||||||
"\u0102\7P\2\2\u0102\26\3\2\2\2\u0103\u0104\7V\2\2\u0104\u0105\7J\2\2\u0105"+
|
"\u0102\7G\2\2\u0102\u0103\7P\2\2\u0103\26\3\2\2\2\u0104\u0105\7C\2\2\u0105"+
|
||||||
"\u0106\7G\2\2\u0106\u0107\7P\2\2\u0107\30\3\2\2\2\u0108\u0109\7C\2\2\u0109"+
|
"\u0106\7P\2\2\u0106\u0107\7[\2\2\u0107\30\3\2\2\2\u0108\u0109\7F\2\2\u0109"+
|
||||||
"\u010a\7P\2\2\u010a\u010b\7[\2\2\u010b\32\3\2\2\2\u010c\u010d\7F\2\2\u010d"+
|
"\u010a\7K\2\2\u010a\u010b\7U\2\2\u010b\u010c\7V\2\2\u010c\u010d\7K\2\2"+
|
||||||
"\u010e\7K\2\2\u010e\u010f\7U\2\2\u010f\u0110\7V\2\2\u0110\u0111\7K\2\2"+
|
"\u010d\u010e\7P\2\2\u010e\u010f\7E\2\2\u010f\u0110\7V\2\2\u0110\32\3\2"+
|
||||||
"\u0111\u0112\7P\2\2\u0112\u0113\7E\2\2\u0113\u0114\7V\2\2\u0114\34\3\2"+
|
"\2\2\u0111\u0112\7Y\2\2\u0112\u0113\7J\2\2\u0113\u0114\7G\2\2\u0114\u0115"+
|
||||||
"\2\2\u0115\u0116\7Y\2\2\u0116\u0117\7J\2\2\u0117\u0118\7G\2\2\u0118\u0119"+
|
"\7T\2\2\u0115\u0116\7G\2\2\u0116\34\3\2\2\2\u0117\u0118\7I\2\2\u0118\u0119"+
|
||||||
"\7T\2\2\u0119\u011a\7G\2\2\u011a\36\3\2\2\2\u011b\u011c\7I\2\2\u011c\u011d"+
|
"\7T\2\2\u0119\u011a\7Q\2\2\u011a\u011b\7W\2\2\u011b\u011c\7R\2\2\u011c"+
|
||||||
"\7T\2\2\u011d\u011e\7Q\2\2\u011e\u011f\7W\2\2\u011f\u0120\7R\2\2\u0120"+
|
"\36\3\2\2\2\u011d\u011e\7D\2\2\u011e\u011f\7[\2\2\u011f \3\2\2\2\u0120"+
|
||||||
" \3\2\2\2\u0121\u0122\7D\2\2\u0122\u0123\7[\2\2\u0123\"\3\2\2\2\u0124"+
|
"\u0121\7I\2\2\u0121\u0122\7T\2\2\u0122\u0123\7Q\2\2\u0123\u0124\7W\2\2"+
|
||||||
"\u0125\7I\2\2\u0125\u0126\7T\2\2\u0126\u0127\7Q\2\2\u0127\u0128\7W\2\2"+
|
"\u0124\u0125\7R\2\2\u0125\u0126\7K\2\2\u0126\u0127\7P\2\2\u0127\u0128"+
|
||||||
"\u0128\u0129\7R\2\2\u0129\u012a\7K\2\2\u012a\u012b\7P\2\2\u012b\u012c"+
|
"\7I\2\2\u0128\"\3\2\2\2\u0129\u012a\7U\2\2\u012a\u012b\7G\2\2\u012b\u012c"+
|
||||||
"\7I\2\2\u012c$\3\2\2\2\u012d\u012e\7U\2\2\u012e\u012f\7G\2\2\u012f\u0130"+
|
"\7V\2\2\u012c\u012d\7U\2\2\u012d$\3\2\2\2\u012e\u012f\7Q\2\2\u012f\u0130"+
|
||||||
"\7V\2\2\u0130\u0131\7U\2\2\u0131&\3\2\2\2\u0132\u0133\7Q\2\2\u0133\u0134"+
|
"\7T\2\2\u0130\u0131\7F\2\2\u0131\u0132\7G\2\2\u0132\u0133\7T\2\2\u0133"+
|
||||||
"\7T\2\2\u0134\u0135\7F\2\2\u0135\u0136\7G\2\2\u0136\u0137\7T\2\2\u0137"+
|
"&\3\2\2\2\u0134\u0135\7J\2\2\u0135\u0136\7C\2\2\u0136\u0137\7X\2\2\u0137"+
|
||||||
"(\3\2\2\2\u0138\u0139\7J\2\2\u0139\u013a\7C\2\2\u013a\u013b\7X\2\2\u013b"+
|
"\u0138\7K\2\2\u0138\u0139\7P\2\2\u0139\u013a\7I\2\2\u013a(\3\2\2\2\u013b"+
|
||||||
"\u013c\7K\2\2\u013c\u013d\7P\2\2\u013d\u013e\7I\2\2\u013e*\3\2\2\2\u013f"+
|
"\u013c\7N\2\2\u013c\u013d\7K\2\2\u013d\u013e\7O\2\2\u013e\u013f\7K\2\2"+
|
||||||
"\u0140\7N\2\2\u0140\u0141\7K\2\2\u0141\u0142\7O\2\2\u0142\u0143\7K\2\2"+
|
"\u013f\u0140\7V\2\2\u0140*\3\2\2\2\u0141\u0142\7Q\2\2\u0142\u0143\7T\2"+
|
||||||
"\u0143\u0144\7V\2\2\u0144,\3\2\2\2\u0145\u0146\7Q\2\2\u0146\u0147\7T\2"+
|
"\2\u0143,\3\2\2\2\u0144\u0145\7C\2\2\u0145\u0146\7P\2\2\u0146\u0147\7"+
|
||||||
"\2\u0147.\3\2\2\2\u0148\u0149\7C\2\2\u0149\u014a\7P\2\2\u014a\u014b\7"+
|
"F\2\2\u0147.\3\2\2\2\u0148\u0149\7K\2\2\u0149\u014a\7P\2\2\u014a\60\3"+
|
||||||
"F\2\2\u014b\60\3\2\2\2\u014c\u014d\7K\2\2\u014d\u014e\7P\2\2\u014e\62"+
|
"\2\2\2\u014b\u014c\7P\2\2\u014c\u014d\7Q\2\2\u014d\u014e\7V\2\2\u014e"+
|
||||||
"\3\2\2\2\u014f\u0150\7P\2\2\u0150\u0151\7Q\2\2\u0151\u0152\7V\2\2\u0152"+
|
"\62\3\2\2\2\u014f\u0150\7P\2\2\u0150\u0151\7Q\2\2\u0151\64\3\2\2\2\u0152"+
|
||||||
"\64\3\2\2\2\u0153\u0154\7P\2\2\u0154\u0155\7Q\2\2\u0155\66\3\2\2\2\u0156"+
|
"\u0153\7G\2\2\u0153\u0154\7Z\2\2\u0154\u0155\7K\2\2\u0155\u0156\7U\2\2"+
|
||||||
"\u0157\7G\2\2\u0157\u0158\7Z\2\2\u0158\u0159\7K\2\2\u0159\u015a\7U\2\2"+
|
"\u0156\u0157\7V\2\2\u0157\u0158\7U\2\2\u0158\66\3\2\2\2\u0159\u015a\7"+
|
||||||
"\u015a\u015b\7V\2\2\u015b\u015c\7U\2\2\u015c8\3\2\2\2\u015d\u015e\7D\2"+
|
"D\2\2\u015a\u015b\7G\2\2\u015b\u015c\7V\2\2\u015c\u015d\7Y\2\2\u015d\u015e"+
|
||||||
"\2\u015e\u015f\7G\2\2\u015f\u0160\7V\2\2\u0160\u0161\7Y\2\2\u0161\u0162"+
|
"\7G\2\2\u015e\u015f\7G\2\2\u015f\u0160\7P\2\2\u01608\3\2\2\2\u0161\u0162"+
|
||||||
"\7G\2\2\u0162\u0163\7G\2\2\u0163\u0164\7P\2\2\u0164:\3\2\2\2\u0165\u0166"+
|
"\7N\2\2\u0162\u0163\7K\2\2\u0163\u0164\7M\2\2\u0164\u0165\7G\2\2\u0165"+
|
||||||
"\7N\2\2\u0166\u0167\7K\2\2\u0167\u0168\7M\2\2\u0168\u0169\7G\2\2\u0169"+
|
":\3\2\2\2\u0166\u0167\7T\2\2\u0167\u0168\7N\2\2\u0168\u0169\7K\2\2\u0169"+
|
||||||
"<\3\2\2\2\u016a\u016b\7T\2\2\u016b\u016c\7N\2\2\u016c\u016d\7K\2\2\u016d"+
|
"\u016a\7M\2\2\u016a\u016b\7G\2\2\u016b<\3\2\2\2\u016c\u016d\7K\2\2\u016d"+
|
||||||
"\u016e\7M\2\2\u016e\u016f\7G\2\2\u016f>\3\2\2\2\u0170\u0171\7K\2\2\u0171"+
|
"\u016e\7U\2\2\u016e>\3\2\2\2\u016f\u0170\7P\2\2\u0170\u0171\7W\2\2\u0171"+
|
||||||
"\u0172\7U\2\2\u0172@\3\2\2\2\u0173\u0174\7P\2\2\u0174\u0175\7W\2\2\u0175"+
|
"\u0172\7N\2\2\u0172\u0173\7N\2\2\u0173@\3\2\2\2\u0174\u0175\7V\2\2\u0175"+
|
||||||
"\u0176\7N\2\2\u0176\u0177\7N\2\2\u0177B\3\2\2\2\u0178\u0179\7V\2\2\u0179"+
|
"\u0176\7T\2\2\u0176\u0177\7W\2\2\u0177\u0178\7G\2\2\u0178B\3\2\2\2\u0179"+
|
||||||
"\u017a\7T\2\2\u017a\u017b\7W\2\2\u017b\u017c\7G\2\2\u017cD\3\2\2\2\u017d"+
|
"\u017a\7H\2\2\u017a\u017b\7C\2\2\u017b\u017c\7N\2\2\u017c\u017d\7U\2\2"+
|
||||||
"\u017e\7H\2\2\u017e\u017f\7C\2\2\u017f\u0180\7N\2\2\u0180\u0181\7U\2\2"+
|
"\u017d\u017e\7G\2\2\u017eD\3\2\2\2\u017f\u0180\7N\2\2\u0180\u0181\7C\2"+
|
||||||
"\u0181\u0182\7G\2\2\u0182F\3\2\2\2\u0183\u0184\7N\2\2\u0184\u0185\7C\2"+
|
"\2\u0181\u0182\7U\2\2\u0182\u0183\7V\2\2\u0183F\3\2\2\2\u0184\u0185\7"+
|
||||||
"\2\u0185\u0186\7U\2\2\u0186\u0187\7V\2\2\u0187H\3\2\2\2\u0188\u0189\7"+
|
"C\2\2\u0185\u0186\7U\2\2\u0186\u0187\7E\2\2\u0187H\3\2\2\2\u0188\u0189"+
|
||||||
"C\2\2\u0189\u018a\7U\2\2\u018a\u018b\7E\2\2\u018bJ\3\2\2\2\u018c\u018d"+
|
"\7F\2\2\u0189\u018a\7G\2\2\u018a\u018b\7U\2\2\u018b\u018c\7E\2\2\u018c"+
|
||||||
"\7F\2\2\u018d\u018e\7G\2\2\u018e\u018f\7U\2\2\u018f\u0190\7E\2\2\u0190"+
|
"J\3\2\2\2\u018d\u018e\7H\2\2\u018e\u018f\7Q\2\2\u018f\u0190\7T\2\2\u0190"+
|
||||||
"L\3\2\2\2\u0191\u0192\7H\2\2\u0192\u0193\7Q\2\2\u0193\u0194\7T\2\2\u0194"+
|
"L\3\2\2\2\u0191\u0192\7K\2\2\u0192\u0193\7P\2\2\u0193\u0194\7V\2\2\u0194"+
|
||||||
"N\3\2\2\2\u0195\u0196\7K\2\2\u0196\u0197\7P\2\2\u0197\u0198\7V\2\2\u0198"+
|
"\u0195\7G\2\2\u0195\u0196\7I\2\2\u0196\u0197\7G\2\2\u0197\u0198\7T\2\2"+
|
||||||
"\u0199\7G\2\2\u0199\u019a\7I\2\2\u019a\u019b\7G\2\2\u019b\u019c\7T\2\2"+
|
"\u0198N\3\2\2\2\u0199\u019a\7L\2\2\u019a\u019b\7Q\2\2\u019b\u019c\7K\2"+
|
||||||
"\u019cP\3\2\2\2\u019d\u019e\7L\2\2\u019e\u019f\7Q\2\2\u019f\u01a0\7K\2"+
|
"\2\u019c\u019d\7P\2\2\u019dP\3\2\2\2\u019e\u019f\7E\2\2\u019f\u01a0\7"+
|
||||||
"\2\u01a0\u01a1\7P\2\2\u01a1R\3\2\2\2\u01a2\u01a3\7E\2\2\u01a3\u01a4\7"+
|
"T\2\2\u01a0\u01a1\7Q\2\2\u01a1\u01a2\7U\2\2\u01a2\u01a3\7U\2\2\u01a3R"+
|
||||||
"T\2\2\u01a4\u01a5\7Q\2\2\u01a5\u01a6\7U\2\2\u01a6\u01a7\7U\2\2\u01a7T"+
|
"\3\2\2\2\u01a4\u01a5\7Q\2\2\u01a5\u01a6\7W\2\2\u01a6\u01a7\7V\2\2\u01a7"+
|
||||||
"\3\2\2\2\u01a8\u01a9\7Q\2\2\u01a9\u01aa\7W\2\2\u01aa\u01ab\7V\2\2\u01ab"+
|
"\u01a8\7G\2\2\u01a8\u01a9\7T\2\2\u01a9T\3\2\2\2\u01aa\u01ab\7K\2\2\u01ab"+
|
||||||
"\u01ac\7G\2\2\u01ac\u01ad\7T\2\2\u01adV\3\2\2\2\u01ae\u01af\7K\2\2\u01af"+
|
"\u01ac\7P\2\2\u01ac\u01ad\7P\2\2\u01ad\u01ae\7G\2\2\u01ae\u01af\7T\2\2"+
|
||||||
"\u01b0\7P\2\2\u01b0\u01b1\7P\2\2\u01b1\u01b2\7G\2\2\u01b2\u01b3\7T\2\2"+
|
"\u01afV\3\2\2\2\u01b0\u01b1\7N\2\2\u01b1\u01b2\7G\2\2\u01b2\u01b3\7H\2"+
|
||||||
"\u01b3X\3\2\2\2\u01b4\u01b5\7N\2\2\u01b5\u01b6\7G\2\2\u01b6\u01b7\7H\2"+
|
"\2\u01b3\u01b4\7V\2\2\u01b4X\3\2\2\2\u01b5\u01b6\7T\2\2\u01b6\u01b7\7"+
|
||||||
"\2\u01b7\u01b8\7V\2\2\u01b8Z\3\2\2\2\u01b9\u01ba\7T\2\2\u01ba\u01bb\7"+
|
"K\2\2\u01b7\u01b8\7I\2\2\u01b8\u01b9\7J\2\2\u01b9\u01ba\7V\2\2\u01baZ"+
|
||||||
"K\2\2\u01bb\u01bc\7I\2\2\u01bc\u01bd\7J\2\2\u01bd\u01be\7V\2\2\u01be\\"+
|
"\3\2\2\2\u01bb\u01bc\7H\2\2\u01bc\u01bd\7W\2\2\u01bd\u01be\7N\2\2\u01be"+
|
||||||
"\3\2\2\2\u01bf\u01c0\7H\2\2\u01c0\u01c1\7W\2\2\u01c1\u01c2\7N\2\2\u01c2"+
|
"\u01bf\7N\2\2\u01bf\\\3\2\2\2\u01c0\u01c1\7P\2\2\u01c1\u01c2\7C\2\2\u01c2"+
|
||||||
"\u01c3\7N\2\2\u01c3^\3\2\2\2\u01c4\u01c5\7P\2\2\u01c5\u01c6\7C\2\2\u01c6"+
|
"\u01c3\7V\2\2\u01c3\u01c4\7W\2\2\u01c4\u01c5\7T\2\2\u01c5\u01c6\7C\2\2"+
|
||||||
"\u01c7\7V\2\2\u01c7\u01c8\7W\2\2\u01c8\u01c9\7T\2\2\u01c9\u01ca\7C\2\2"+
|
"\u01c6\u01c7\7N\2\2\u01c7^\3\2\2\2\u01c8\u01c9\7W\2\2\u01c9\u01ca\7U\2"+
|
||||||
"\u01ca\u01cb\7N\2\2\u01cb`\3\2\2\2\u01cc\u01cd\7W\2\2\u01cd\u01ce\7U\2"+
|
"\2\u01ca\u01cb\7K\2\2\u01cb\u01cc\7P\2\2\u01cc\u01cd\7I\2\2\u01cd`\3\2"+
|
||||||
"\2\u01ce\u01cf\7K\2\2\u01cf\u01d0\7P\2\2\u01d0\u01d1\7I\2\2\u01d1b\3\2"+
|
"\2\2\u01ce\u01cf\7Q\2\2\u01cf\u01d0\7P\2\2\u01d0b\3\2\2\2\u01d1\u01d2"+
|
||||||
"\2\2\u01d2\u01d3\7Q\2\2\u01d3\u01d4\7P\2\2\u01d4d\3\2\2\2\u01d5\u01d6"+
|
"\7Y\2\2\u01d2\u01d3\7K\2\2\u01d3\u01d4\7V\2\2\u01d4\u01d5\7J\2\2\u01d5"+
|
||||||
"\7Y\2\2\u01d6\u01d7\7K\2\2\u01d7\u01d8\7V\2\2\u01d8\u01d9\7J\2\2\u01d9"+
|
"d\3\2\2\2\u01d6\u01d7\7V\2\2\u01d7\u01d8\7C\2\2\u01d8\u01d9\7D\2\2\u01d9"+
|
||||||
"f\3\2\2\2\u01da\u01db\7V\2\2\u01db\u01dc\7C\2\2\u01dc\u01dd\7D\2\2\u01dd"+
|
"\u01da\7N\2\2\u01da\u01db\7G\2\2\u01dbf\3\2\2\2\u01dc\u01dd\7K\2\2\u01dd"+
|
||||||
"\u01de\7N\2\2\u01de\u01df\7G\2\2\u01dfh\3\2\2\2\u01e0\u01e1\7K\2\2\u01e1"+
|
"\u01de\7P\2\2\u01de\u01df\7V\2\2\u01df\u01e0\7Q\2\2\u01e0h\3\2\2\2\u01e1"+
|
||||||
"\u01e2\7P\2\2\u01e2\u01e3\7V\2\2\u01e3\u01e4\7Q\2\2\u01e4j\3\2\2\2\u01e5"+
|
"\u01e2\7F\2\2\u01e2\u01e3\7G\2\2\u01e3\u01e4\7U\2\2\u01e4\u01e5\7E\2\2"+
|
||||||
"\u01e6\7F\2\2\u01e6\u01e7\7G\2\2\u01e7\u01e8\7U\2\2\u01e8\u01e9\7E\2\2"+
|
"\u01e5\u01e6\7T\2\2\u01e6\u01e7\7K\2\2\u01e7\u01e8\7D\2\2\u01e8\u01e9"+
|
||||||
"\u01e9\u01ea\7T\2\2\u01ea\u01eb\7K\2\2\u01eb\u01ec\7D\2\2\u01ec\u01ed"+
|
"\7G\2\2\u01e9j\3\2\2\2\u01ea\u01eb\7Q\2\2\u01eb\u01ec\7R\2\2\u01ec\u01ed"+
|
||||||
"\7G\2\2\u01edl\3\2\2\2\u01ee\u01ef\7Q\2\2\u01ef\u01f0\7R\2\2\u01f0\u01f1"+
|
"\7V\2\2\u01ed\u01ee\7K\2\2\u01ee\u01ef\7Q\2\2\u01ef\u01f0\7P\2\2\u01f0"+
|
||||||
"\7V\2\2\u01f1\u01f2\7K\2\2\u01f2\u01f3\7Q\2\2\u01f3\u01f4\7P\2\2\u01f4"+
|
"l\3\2\2\2\u01f1\u01f2\7G\2\2\u01f2\u01f3\7Z\2\2\u01f3\u01f4\7R\2\2\u01f4"+
|
||||||
"n\3\2\2\2\u01f5\u01f6\7G\2\2\u01f6\u01f7\7Z\2\2\u01f7\u01f8\7R\2\2\u01f8"+
|
"\u01f5\7N\2\2\u01f5\u01f6\7C\2\2\u01f6\u01f7\7K\2\2\u01f7\u01f8\7P\2\2"+
|
||||||
"\u01f9\7N\2\2\u01f9\u01fa\7C\2\2\u01fa\u01fb\7K\2\2\u01fb\u01fc\7P\2\2"+
|
"\u01f8n\3\2\2\2\u01f9\u01fa\7C\2\2\u01fa\u01fb\7P\2\2\u01fb\u01fc\7C\2"+
|
||||||
"\u01fcp\3\2\2\2\u01fd\u01fe\7C\2\2\u01fe\u01ff\7P\2\2\u01ff\u0200\7C\2"+
|
"\2\u01fc\u01fd\7N\2\2\u01fd\u01fe\7[\2\2\u01fe\u01ff\7\\\2\2\u01ff\u0200"+
|
||||||
"\2\u0200\u0201\7N\2\2\u0201\u0202\7[\2\2\u0202\u0203\7\\\2\2\u0203\u0204"+
|
"\7G\2\2\u0200p\3\2\2\2\u0201\u0202\7H\2\2\u0202\u0203\7Q\2\2\u0203\u0204"+
|
||||||
"\7G\2\2\u0204r\3\2\2\2\u0205\u0206\7H\2\2\u0206\u0207\7Q\2\2\u0207\u0208"+
|
"\7T\2\2\u0204\u0205\7O\2\2\u0205\u0206\7C\2\2\u0206\u0207\7V\2\2\u0207"+
|
||||||
"\7T\2\2\u0208\u0209\7O\2\2\u0209\u020a\7C\2\2\u020a\u020b\7V\2\2\u020b"+
|
"r\3\2\2\2\u0208\u0209\7V\2\2\u0209\u020a\7[\2\2\u020a\u020b\7R\2\2\u020b"+
|
||||||
"t\3\2\2\2\u020c\u020d\7V\2\2\u020d\u020e\7[\2\2\u020e\u020f\7R\2\2\u020f"+
|
"\u020c\7G\2\2\u020ct\3\2\2\2\u020d\u020e\7V\2\2\u020e\u020f\7G\2\2\u020f"+
|
||||||
"\u0210\7G\2\2\u0210v\3\2\2\2\u0211\u0212\7V\2\2\u0212\u0213\7G\2\2\u0213"+
|
"\u0210\7Z\2\2\u0210\u0211\7V\2\2\u0211v\3\2\2\2\u0212\u0213\7X\2\2\u0213"+
|
||||||
"\u0214\7Z\2\2\u0214\u0215\7V\2\2\u0215x\3\2\2\2\u0216\u0217\7X\2\2\u0217"+
|
"\u0214\7G\2\2\u0214\u0215\7T\2\2\u0215\u0216\7K\2\2\u0216\u0217\7H\2\2"+
|
||||||
"\u0218\7G\2\2\u0218\u0219\7T\2\2\u0219\u021a\7K\2\2\u021a\u021b\7H\2\2"+
|
"\u0217\u0218\7[\2\2\u0218x\3\2\2\2\u0219\u021a\7I\2\2\u021a\u021b\7T\2"+
|
||||||
"\u021b\u021c\7[\2\2\u021cz\3\2\2\2\u021d\u021e\7I\2\2\u021e\u021f\7T\2"+
|
"\2\u021b\u021c\7C\2\2\u021c\u021d\7R\2\2\u021d\u021e\7J\2\2\u021e\u021f"+
|
||||||
"\2\u021f\u0220\7C\2\2\u0220\u0221\7R\2\2\u0221\u0222\7J\2\2\u0222\u0223"+
|
"\7X\2\2\u021f\u0220\7K\2\2\u0220\u0221\7\\\2\2\u0221z\3\2\2\2\u0222\u0223"+
|
||||||
"\7X\2\2\u0223\u0224\7K\2\2\u0224\u0225\7\\\2\2\u0225|\3\2\2\2\u0226\u0227"+
|
"\7N\2\2\u0223\u0224\7Q\2\2\u0224\u0225\7I\2\2\u0225\u0226\7K\2\2\u0226"+
|
||||||
"\7N\2\2\u0227\u0228\7Q\2\2\u0228\u0229\7I\2\2\u0229\u022a\7K\2\2\u022a"+
|
"\u0227\7E\2\2\u0227\u0228\7C\2\2\u0228\u0229\7N\2\2\u0229|\3\2\2\2\u022a"+
|
||||||
"\u022b\7E\2\2\u022b\u022c\7C\2\2\u022c\u022d\7N\2\2\u022d~\3\2\2\2\u022e"+
|
"\u022b\7R\2\2\u022b\u022c\7J\2\2\u022c\u022d\7[\2\2\u022d\u022e\7U\2\2"+
|
||||||
"\u022f\7R\2\2\u022f\u0230\7J\2\2\u0230\u0231\7[\2\2\u0231\u0232\7U\2\2"+
|
"\u022e\u022f\7K\2\2\u022f\u0230\7E\2\2\u0230\u0231\7C\2\2\u0231\u0232"+
|
||||||
"\u0232\u0233\7K\2\2\u0233\u0234\7E\2\2\u0234\u0235\7C\2\2\u0235\u0236"+
|
"\7N\2\2\u0232~\3\2\2\2\u0233\u0234\7U\2\2\u0234\u0235\7J\2\2\u0235\u0236"+
|
||||||
"\7N\2\2\u0236\u0080\3\2\2\2\u0237\u0238\7U\2\2\u0238\u0239\7J\2\2\u0239"+
|
"\7Q\2\2\u0236\u0237\7Y\2\2\u0237\u0080\3\2\2\2\u0238\u0239\7V\2\2\u0239"+
|
||||||
"\u023a\7Q\2\2\u023a\u023b\7Y\2\2\u023b\u0082\3\2\2\2\u023c\u023d\7V\2"+
|
"\u023a\7C\2\2\u023a\u023b\7D\2\2\u023b\u023c\7N\2\2\u023c\u023d\7G\2\2"+
|
||||||
"\2\u023d\u023e\7C\2\2\u023e\u023f\7D\2\2\u023f\u0240\7N\2\2\u0240\u0241"+
|
"\u023d\u023e\7U\2\2\u023e\u0082\3\2\2\2\u023f\u0240\7E\2\2\u0240\u0241"+
|
||||||
"\7G\2\2\u0241\u0242\7U\2\2\u0242\u0084\3\2\2\2\u0243\u0244\7E\2\2\u0244"+
|
"\7Q\2\2\u0241\u0242\7N\2\2\u0242\u0243\7W\2\2\u0243\u0244\7O\2\2\u0244"+
|
||||||
"\u0245\7Q\2\2\u0245\u0246\7N\2\2\u0246\u0247\7W\2\2\u0247\u0248\7O\2\2"+
|
"\u0245\7P\2\2\u0245\u0246\7U\2\2\u0246\u0084\3\2\2\2\u0247\u0248\7E\2"+
|
||||||
"\u0248\u0249\7P\2\2\u0249\u024a\7U\2\2\u024a\u0086\3\2\2\2\u024b\u024c"+
|
"\2\u0248\u0249\7Q\2\2\u0249\u024a\7N\2\2\u024a\u024b\7W\2\2\u024b\u024c"+
|
||||||
"\7E\2\2\u024c\u024d\7Q\2\2\u024d\u024e\7N\2\2\u024e\u024f\7W\2\2\u024f"+
|
"\7O\2\2\u024c\u024d\7P\2\2\u024d\u0086\3\2\2\2\u024e\u024f\7H\2\2\u024f"+
|
||||||
"\u0250\7O\2\2\u0250\u0251\7P\2\2\u0251\u0088\3\2\2\2\u0252\u0253\7H\2"+
|
"\u0250\7W\2\2\u0250\u0251\7P\2\2\u0251\u0252\7E\2\2\u0252\u0253\7V\2\2"+
|
||||||
"\2\u0253\u0254\7W\2\2\u0254\u0255\7P\2\2\u0255\u0256\7E\2\2\u0256\u0257"+
|
"\u0253\u0254\7K\2\2\u0254\u0255\7Q\2\2\u0255\u0256\7P\2\2\u0256\u0257"+
|
||||||
"\7V\2\2\u0257\u0258\7K\2\2\u0258\u0259\7Q\2\2\u0259\u025a\7P\2\2\u025a"+
|
"\7U\2\2\u0257\u0088\3\2\2\2\u0258\u0259\7V\2\2\u0259\u025a\7Q\2\2\u025a"+
|
||||||
"\u025b\7U\2\2\u025b\u008a\3\2\2\2\u025c\u025d\7V\2\2\u025d\u025e\7Q\2"+
|
"\u008a\3\2\2\2\u025b\u025c\7F\2\2\u025c\u025d\7G\2\2\u025d\u025e\7D\2"+
|
||||||
"\2\u025e\u008c\3\2\2\2\u025f\u0260\7F\2\2\u0260\u0261\7G\2\2\u0261\u0262"+
|
"\2\u025e\u025f\7W\2\2\u025f\u0260\7I\2\2\u0260\u008c\3\2\2\2\u0261\u0262"+
|
||||||
"\7D\2\2\u0262\u0263\7W\2\2\u0263\u0264\7I\2\2\u0264\u008e\3\2\2\2\u0265"+
|
"\7R\2\2\u0262\u0263\7N\2\2\u0263\u0264\7C\2\2\u0264\u0265\7P\2\2\u0265"+
|
||||||
"\u0266\7R\2\2\u0266\u0267\7N\2\2\u0267\u0268\7C\2\2\u0268\u0269\7P\2\2"+
|
"\u008e\3\2\2\2\u0266\u0267\7R\2\2\u0267\u0268\7C\2\2\u0268\u0269\7T\2"+
|
||||||
"\u0269\u0090\3\2\2\2\u026a\u026b\7R\2\2\u026b\u026c\7C\2\2\u026c\u026d"+
|
"\2\u0269\u026a\7U\2\2\u026a\u026b\7G\2\2\u026b\u026c\7F\2\2\u026c\u0090"+
|
||||||
"\7T\2\2\u026d\u026e\7U\2\2\u026e\u026f\7G\2\2\u026f\u0270\7F\2\2\u0270"+
|
"\3\2\2\2\u026d\u026e\7C\2\2\u026e\u026f\7P\2\2\u026f\u0270\7C\2\2\u0270"+
|
||||||
"\u0092\3\2\2\2\u0271\u0272\7C\2\2\u0272\u0273\7P\2\2\u0273\u0274\7C\2"+
|
"\u0271\7N\2\2\u0271\u0272\7[\2\2\u0272\u0273\7\\\2\2\u0273\u0274\7G\2"+
|
||||||
"\2\u0274\u0275\7N\2\2\u0275\u0276\7[\2\2\u0276\u0277\7\\\2\2\u0277\u0278"+
|
"\2\u0274\u0275\7F\2\2\u0275\u0092\3\2\2\2\u0276\u0277\7Q\2\2\u0277\u0278"+
|
||||||
"\7G\2\2\u0278\u0279\7F\2\2\u0279\u0094\3\2\2\2\u027a\u027b\7Q\2\2\u027b"+
|
"\7R\2\2\u0278\u0279\7V\2\2\u0279\u027a\7K\2\2\u027a\u027b\7O\2\2\u027b"+
|
||||||
"\u027c\7R\2\2\u027c\u027d\7V\2\2\u027d\u027e\7K\2\2\u027e\u027f\7O\2\2"+
|
"\u027c\7K\2\2\u027c\u027d\7\\\2\2\u027d\u027e\7G\2\2\u027e\u027f\7F\2"+
|
||||||
"\u027f\u0280\7K\2\2\u0280\u0281\7\\\2\2\u0281\u0282\7G\2\2\u0282\u0283"+
|
"\2\u027f\u0094\3\2\2\2\u0280\u0281\7O\2\2\u0281\u0282\7C\2\2\u0282\u0283"+
|
||||||
"\7F\2\2\u0283\u0096\3\2\2\2\u0284\u0285\7O\2\2\u0285\u0286\7C\2\2\u0286"+
|
"\7R\2\2\u0283\u0284\7R\2\2\u0284\u0285\7G\2\2\u0285\u0286\7F\2\2\u0286"+
|
||||||
"\u0287\7R\2\2\u0287\u0288\7R\2\2\u0288\u0289\7G\2\2\u0289\u028a\7F\2\2"+
|
"\u0096\3\2\2\2\u0287\u0288\7G\2\2\u0288\u0289\7Z\2\2\u0289\u028a\7G\2"+
|
||||||
"\u028a\u0098\3\2\2\2\u028b\u028c\7G\2\2\u028c\u028d\7Z\2\2\u028d\u028e"+
|
"\2\u028a\u028b\7E\2\2\u028b\u028c\7W\2\2\u028c\u028d\7V\2\2\u028d\u028e"+
|
||||||
"\7G\2\2\u028e\u028f\7E\2\2\u028f\u0290\7W\2\2\u0290\u0291\7V\2\2\u0291"+
|
"\7C\2\2\u028e\u028f\7D\2\2\u028f\u0290\7N\2\2\u0290\u0291\7G\2\2\u0291"+
|
||||||
"\u0292\7C\2\2\u0292\u0293\7D\2\2\u0293\u0294\7N\2\2\u0294\u0295\7G\2\2"+
|
"\u0098\3\2\2\2\u0292\u0293\7W\2\2\u0293\u0294\7U\2\2\u0294\u0295\7G\2"+
|
||||||
"\u0295\u009a\3\2\2\2\u0296\u0297\7W\2\2\u0297\u0298\7U\2\2\u0298\u0299"+
|
"\2\u0295\u009a\3\2\2\2\u0296\u0297\7U\2\2\u0297\u0298\7G\2\2\u0298\u0299"+
|
||||||
"\7G\2\2\u0299\u009c\3\2\2\2\u029a\u029b\7U\2\2\u029b\u029c\7G\2\2\u029c"+
|
"\7V\2\2\u0299\u009c\3\2\2\2\u029a\u029b\7T\2\2\u029b\u029c\7G\2\2\u029c"+
|
||||||
"\u029d\7V\2\2\u029d\u009e\3\2\2\2\u029e\u029f\7T\2\2\u029f\u02a0\7G\2"+
|
"\u029d\7U\2\2\u029d\u029e\7G\2\2\u029e\u029f\7V\2\2\u029f\u009e\3\2\2"+
|
||||||
"\2\u02a0\u02a1\7U\2\2\u02a1\u02a2\7G\2\2\u02a2\u02a3\7V\2\2\u02a3\u00a0"+
|
"\2\u02a0\u02a1\7U\2\2\u02a1\u02a2\7G\2\2\u02a2\u02a3\7U\2\2\u02a3\u02a4"+
|
||||||
"\3\2\2\2\u02a4\u02a5\7U\2\2\u02a5\u02a6\7G\2\2\u02a6\u02a7\7U\2\2\u02a7"+
|
"\7U\2\2\u02a4\u02a5\7K\2\2\u02a5\u02a6\7Q\2\2\u02a6\u02a7\7P\2\2\u02a7"+
|
||||||
"\u02a8\7U\2\2\u02a8\u02a9\7K\2\2\u02a9\u02aa\7Q\2\2\u02aa\u02ab\7P\2\2"+
|
"\u00a0\3\2\2\2\u02a8\u02a9\7U\2\2\u02a9\u02aa\7E\2\2\u02aa\u02ab\7J\2"+
|
||||||
"\u02ab\u00a2\3\2\2\2\u02ac\u02ad\7U\2\2\u02ad\u02ae\7E\2\2\u02ae\u02af"+
|
"\2\u02ab\u02ac\7G\2\2\u02ac\u02ad\7O\2\2\u02ad\u02ae\7C\2\2\u02ae\u02af"+
|
||||||
"\7J\2\2\u02af\u02b0\7G\2\2\u02b0\u02b1\7O\2\2\u02b1\u02b2\7C\2\2\u02b2"+
|
"\7U\2\2\u02af\u00a2\3\2\2\2\u02b0\u02b1\7G\2\2\u02b1\u02b2\7Z\2\2\u02b2"+
|
||||||
"\u02b3\7U\2\2\u02b3\u00a4\3\2\2\2\u02b4\u02b5\7G\2\2\u02b5\u02b6\7Z\2"+
|
"\u02b3\7V\2\2\u02b3\u02b4\7T\2\2\u02b4\u02b5\7C\2\2\u02b5\u02b6\7E\2\2"+
|
||||||
"\2\u02b6\u02b7\7V\2\2\u02b7\u02b8\7T\2\2\u02b8\u02b9\7C\2\2\u02b9\u02ba"+
|
"\u02b6\u02b7\7V\2\2\u02b7\u00a4\3\2\2\2\u02b8\u02b9\7S\2\2\u02b9\u02ba"+
|
||||||
"\7E\2\2\u02ba\u02bb\7V\2\2\u02bb\u00a6\3\2\2\2\u02bc\u02bd\7S\2\2\u02bd"+
|
"\7W\2\2\u02ba\u02bb\7G\2\2\u02bb\u02bc\7T\2\2\u02bc\u02bd\7[\2\2\u02bd"+
|
||||||
"\u02be\7W\2\2\u02be\u02bf\7G\2\2\u02bf\u02c0\7T\2\2\u02c0\u02c1\7[\2\2"+
|
"\u00a6\3\2\2\2\u02be\u02bf\7O\2\2\u02bf\u02c0\7C\2\2\u02c0\u02c1\7V\2"+
|
||||||
"\u02c1\u00a8\3\2\2\2\u02c2\u02c3\7O\2\2\u02c3\u02c4\7C\2\2\u02c4\u02c5"+
|
"\2\u02c1\u02c2\7E\2\2\u02c2\u02c3\7J\2\2\u02c3\u00a8\3\2\2\2\u02c4\u02c5"+
|
||||||
"\7V\2\2\u02c5\u02c6\7E\2\2\u02c6\u02c7\7J\2\2\u02c7\u00aa\3\2\2\2\u02c8"+
|
"\7E\2\2\u02c5\u02c6\7C\2\2\u02c6\u02c7\7U\2\2\u02c7\u02c8\7V\2\2\u02c8"+
|
||||||
"\u02c9\7E\2\2\u02c9\u02ca\7C\2\2\u02ca\u02cb\7U\2\2\u02cb\u02cc\7V\2\2"+
|
"\u00aa\3\2\2\2\u02c9\u02ca\7?\2\2\u02ca\u00ac\3\2\2\2\u02cb\u02cc\7>\2"+
|
||||||
"\u02cc\u00ac\3\2\2\2\u02cd\u02ce\7?\2\2\u02ce\u00ae\3\2\2\2\u02cf\u02d0"+
|
"\2\u02cc\u02d3\7@\2\2\u02cd\u02ce\7#\2\2\u02ce\u02d3\7?\2\2\u02cf\u02d0"+
|
||||||
"\7>\2\2\u02d0\u02d7\7@\2\2\u02d1\u02d2\7#\2\2\u02d2\u02d7\7?\2\2\u02d3"+
|
"\7>\2\2\u02d0\u02d1\7?\2\2\u02d1\u02d3\7@\2\2\u02d2\u02cb\3\2\2\2\u02d2"+
|
||||||
"\u02d4\7>\2\2\u02d4\u02d5\7?\2\2\u02d5\u02d7\7@\2\2\u02d6\u02cf\3\2\2"+
|
"\u02cd\3\2\2\2\u02d2\u02cf\3\2\2\2\u02d3\u00ae\3\2\2\2\u02d4\u02d5\7>"+
|
||||||
"\2\u02d6\u02d1\3\2\2\2\u02d6\u02d3\3\2\2\2\u02d7\u00b0\3\2\2\2\u02d8\u02d9"+
|
"\2\2\u02d5\u00b0\3\2\2\2\u02d6\u02d7\7>\2\2\u02d7\u02d8\7?\2\2\u02d8\u00b2"+
|
||||||
"\7>\2\2\u02d9\u00b2\3\2\2\2\u02da\u02db\7>\2\2\u02db\u02dc\7?\2\2\u02dc"+
|
"\3\2\2\2\u02d9\u02da\7@\2\2\u02da\u00b4\3\2\2\2\u02db\u02dc\7@\2\2\u02dc"+
|
||||||
"\u00b4\3\2\2\2\u02dd\u02de\7@\2\2\u02de\u00b6\3\2\2\2\u02df\u02e0\7@\2"+
|
"\u02dd\7?\2\2\u02dd\u00b6\3\2\2\2\u02de\u02df\7-\2\2\u02df\u00b8\3\2\2"+
|
||||||
"\2\u02e0\u02e1\7?\2\2\u02e1\u00b8\3\2\2\2\u02e2\u02e3\7-\2\2\u02e3\u00ba"+
|
"\2\u02e0\u02e1\7/\2\2\u02e1\u00ba\3\2\2\2\u02e2\u02e3\7,\2\2\u02e3\u00bc"+
|
||||||
"\3\2\2\2\u02e4\u02e5\7/\2\2\u02e5\u00bc\3\2\2\2\u02e6\u02e7\7,\2\2\u02e7"+
|
"\3\2\2\2\u02e4\u02e5\7\61\2\2\u02e5\u00be\3\2\2\2\u02e6\u02e7\7\'\2\2"+
|
||||||
"\u00be\3\2\2\2\u02e8\u02e9\7\61\2\2\u02e9\u00c0\3\2\2\2\u02ea\u02eb\7"+
|
"\u02e7\u00c0\3\2\2\2\u02e8\u02e9\7~\2\2\u02e9\u02ea\7~\2\2\u02ea\u00c2"+
|
||||||
"\'\2\2\u02eb\u00c2\3\2\2\2\u02ec\u02ed\7~\2\2\u02ed\u02ee\7~\2\2\u02ee"+
|
"\3\2\2\2\u02eb\u02f1\7)\2\2\u02ec\u02f0\n\2\2\2\u02ed\u02ee\7)\2\2\u02ee"+
|
||||||
"\u00c4\3\2\2\2\u02ef\u02f5\7)\2\2\u02f0\u02f4\n\2\2\2\u02f1\u02f2\7)\2"+
|
"\u02f0\7)\2\2\u02ef\u02ec\3\2\2\2\u02ef\u02ed\3\2\2\2\u02f0\u02f3\3\2"+
|
||||||
"\2\u02f2\u02f4\7)\2\2\u02f3\u02f0\3\2\2\2\u02f3\u02f1\3\2\2\2\u02f4\u02f7"+
|
"\2\2\u02f1\u02ef\3\2\2\2\u02f1\u02f2\3\2\2\2\u02f2\u02f4\3\2\2\2\u02f3"+
|
||||||
"\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f5\u02f6\3\2\2\2\u02f6\u02f8\3\2\2\2\u02f7"+
|
"\u02f1\3\2\2\2\u02f4\u02f5\7)\2\2\u02f5\u00c4\3\2\2\2\u02f6\u02f8\5\u00d3"+
|
||||||
"\u02f5\3\2\2\2\u02f8\u02f9\7)\2\2\u02f9\u00c6\3\2\2\2\u02fa\u02fc\5\u00d5"+
|
"j\2\u02f7\u02f6\3\2\2\2\u02f8\u02f9\3\2\2\2\u02f9\u02f7\3\2\2\2\u02f9"+
|
||||||
"k\2\u02fb\u02fa\3\2\2\2\u02fc\u02fd\3\2\2\2\u02fd\u02fb\3\2\2\2\u02fd"+
|
"\u02fa\3\2\2\2\u02fa\u00c6\3\2\2\2\u02fb\u02fd\5\u00d3j\2\u02fc\u02fb"+
|
||||||
"\u02fe\3\2\2\2\u02fe\u00c8\3\2\2\2\u02ff\u0301\5\u00d5k\2\u0300\u02ff"+
|
"\3\2\2\2\u02fd\u02fe\3\2\2\2\u02fe\u02fc\3\2\2\2\u02fe\u02ff\3\2\2\2\u02ff"+
|
||||||
"\3\2\2\2\u0301\u0302\3\2\2\2\u0302\u0300\3\2\2\2\u0302\u0303\3\2\2\2\u0303"+
|
"\u0300\3\2\2\2\u0300\u0304\7\60\2\2\u0301\u0303\5\u00d3j\2\u0302\u0301"+
|
||||||
"\u0304\3\2\2\2\u0304\u0308\7\60\2\2\u0305\u0307\5\u00d5k\2\u0306\u0305"+
|
"\3\2\2\2\u0303\u0306\3\2\2\2\u0304\u0302\3\2\2\2\u0304\u0305\3\2\2\2\u0305"+
|
||||||
"\3\2\2\2\u0307\u030a\3\2\2\2\u0308\u0306\3\2\2\2\u0308\u0309\3\2\2\2\u0309"+
|
"\u0326\3\2\2\2\u0306\u0304\3\2\2\2\u0307\u0309\7\60\2\2\u0308\u030a\5"+
|
||||||
"\u032a\3\2\2\2\u030a\u0308\3\2\2\2\u030b\u030d\7\60\2\2\u030c\u030e\5"+
|
"\u00d3j\2\u0309\u0308\3\2\2\2\u030a\u030b\3\2\2\2\u030b\u0309\3\2\2\2"+
|
||||||
"\u00d5k\2\u030d\u030c\3\2\2\2\u030e\u030f\3\2\2\2\u030f\u030d\3\2\2\2"+
|
"\u030b\u030c\3\2\2\2\u030c\u0326\3\2\2\2\u030d\u030f\5\u00d3j\2\u030e"+
|
||||||
"\u030f\u0310\3\2\2\2\u0310\u032a\3\2\2\2\u0311\u0313\5\u00d5k\2\u0312"+
|
"\u030d\3\2\2\2\u030f\u0310\3\2\2\2\u0310\u030e\3\2\2\2\u0310\u0311\3\2"+
|
||||||
"\u0311\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0312\3\2\2\2\u0314\u0315\3\2"+
|
"\2\2\u0311\u0319\3\2\2\2\u0312\u0316\7\60\2\2\u0313\u0315\5\u00d3j\2\u0314"+
|
||||||
"\2\2\u0315\u031d\3\2\2\2\u0316\u031a\7\60\2\2\u0317\u0319\5\u00d5k\2\u0318"+
|
"\u0313\3\2\2\2\u0315\u0318\3\2\2\2\u0316\u0314\3\2\2\2\u0316\u0317\3\2"+
|
||||||
"\u0317\3\2\2\2\u0319\u031c\3\2\2\2\u031a\u0318\3\2\2\2\u031a\u031b\3\2"+
|
"\2\2\u0317\u031a\3\2\2\2\u0318\u0316\3\2\2\2\u0319\u0312\3\2\2\2\u0319"+
|
||||||
"\2\2\u031b\u031e\3\2\2\2\u031c\u031a\3\2\2\2\u031d\u0316\3\2\2\2\u031d"+
|
"\u031a\3\2\2\2\u031a\u031b\3\2\2\2\u031b\u031c\5\u00d1i\2\u031c\u0326"+
|
||||||
"\u031e\3\2\2\2\u031e\u031f\3\2\2\2\u031f\u0320\5\u00d3j\2\u0320\u032a"+
|
"\3\2\2\2\u031d\u031f\7\60\2\2\u031e\u0320\5\u00d3j\2\u031f\u031e\3\2\2"+
|
||||||
"\3\2\2\2\u0321\u0323\7\60\2\2\u0322\u0324\5\u00d5k\2\u0323\u0322\3\2\2"+
|
"\2\u0320\u0321\3\2\2\2\u0321\u031f\3\2\2\2\u0321\u0322\3\2\2\2\u0322\u0323"+
|
||||||
"\2\u0324\u0325\3\2\2\2\u0325\u0323\3\2\2\2\u0325\u0326\3\2\2\2\u0326\u0327"+
|
"\3\2\2\2\u0323\u0324\5\u00d1i\2\u0324\u0326\3\2\2\2\u0325\u02fc\3\2\2"+
|
||||||
"\3\2\2\2\u0327\u0328\5\u00d3j\2\u0328\u032a\3\2\2\2\u0329\u0300\3\2\2"+
|
"\2\u0325\u0307\3\2\2\2\u0325\u030e\3\2\2\2\u0325\u031d\3\2\2\2\u0326\u00c8"+
|
||||||
"\2\u0329\u030b\3\2\2\2\u0329\u0312\3\2\2\2\u0329\u0321\3\2\2\2\u032a\u00ca"+
|
"\3\2\2\2\u0327\u032a\5\u00d5k\2\u0328\u032a\7a\2\2\u0329\u0327\3\2\2\2"+
|
||||||
"\3\2\2\2\u032b\u032e\5\u00d7l\2\u032c\u032e\7a\2\2\u032d\u032b\3\2\2\2"+
|
"\u0329\u0328\3\2\2\2\u032a\u0330\3\2\2\2\u032b\u032f\5\u00d5k\2\u032c"+
|
||||||
"\u032d\u032c\3\2\2\2\u032e\u0334\3\2\2\2\u032f\u0333\5\u00d7l\2\u0330"+
|
"\u032f\5\u00d3j\2\u032d\u032f\t\3\2\2\u032e\u032b\3\2\2\2\u032e\u032c"+
|
||||||
"\u0333\5\u00d5k\2\u0331\u0333\t\3\2\2\u0332\u032f\3\2\2\2\u0332\u0330"+
|
"\3\2\2\2\u032e\u032d\3\2\2\2\u032f\u0332\3\2\2\2\u0330\u032e\3\2\2\2\u0330"+
|
||||||
"\3\2\2\2\u0332\u0331\3\2\2\2\u0333\u0336\3\2\2\2\u0334\u0332\3\2\2\2\u0334"+
|
"\u0331\3\2\2\2\u0331\u00ca\3\2\2\2\u0332\u0330\3\2\2\2\u0333\u0337\5\u00d3"+
|
||||||
"\u0335\3\2\2\2\u0335\u00cc\3\2\2\2\u0336\u0334\3\2\2\2\u0337\u033b\5\u00d5"+
|
"j\2\u0334\u0338\5\u00d5k\2\u0335\u0338\5\u00d3j\2\u0336\u0338\t\3\2\2"+
|
||||||
"k\2\u0338\u033c\5\u00d7l\2\u0339\u033c\5\u00d5k\2\u033a\u033c\t\3\2\2"+
|
"\u0337\u0334\3\2\2\2\u0337\u0335\3\2\2\2\u0337\u0336\3\2\2\2\u0338\u0339"+
|
||||||
"\u033b\u0338\3\2\2\2\u033b\u0339\3\2\2\2\u033b\u033a\3\2\2\2\u033c\u033d"+
|
"\3\2\2\2\u0339\u0337\3\2\2\2\u0339\u033a\3\2\2\2\u033a\u00cc\3\2\2\2\u033b"+
|
||||||
"\3\2\2\2\u033d\u033b\3\2\2\2\u033d\u033e\3\2\2\2\u033e\u00ce\3\2\2\2\u033f"+
|
"\u0340\7$\2\2\u033c\u033f\n\4\2\2\u033d\u033f\7$\2\2\u033e\u033c\3\2\2"+
|
||||||
"\u0344\7$\2\2\u0340\u0343\n\4\2\2\u0341\u0343\7$\2\2\u0342\u0340\3\2\2"+
|
"\2\u033e\u033d\3\2\2\2\u033f\u0342\3\2\2\2\u0340\u033e\3\2\2\2\u0340\u0341"+
|
||||||
"\2\u0342\u0341\3\2\2\2\u0343\u0346\3\2\2\2\u0344\u0342\3\2\2\2\u0344\u0345"+
|
"\3\2\2\2\u0341\u0343\3\2\2\2\u0342\u0340\3\2\2\2\u0343\u0344\7$\2\2\u0344"+
|
||||||
"\3\2\2\2\u0345\u0347\3\2\2\2\u0346\u0344\3\2\2\2\u0347\u0348\7$\2\2\u0348"+
|
"\u00ce\3\2\2\2\u0345\u034b\7b\2\2\u0346\u034a\n\5\2\2\u0347\u0348\7b\2"+
|
||||||
"\u00d0\3\2\2\2\u0349\u034f\7b\2\2\u034a\u034e\n\5\2\2\u034b\u034c\7b\2"+
|
"\2\u0348\u034a\7b\2\2\u0349\u0346\3\2\2\2\u0349\u0347\3\2\2\2\u034a\u034d"+
|
||||||
"\2\u034c\u034e\7b\2\2\u034d\u034a\3\2\2\2\u034d\u034b\3\2\2\2\u034e\u0351"+
|
"\3\2\2\2\u034b\u0349\3\2\2\2\u034b\u034c\3\2\2\2\u034c\u034e\3\2\2\2\u034d"+
|
||||||
"\3\2\2\2\u034f\u034d\3\2\2\2\u034f\u0350\3\2\2\2\u0350\u0352\3\2\2\2\u0351"+
|
"\u034b\3\2\2\2\u034e\u034f\7b\2\2\u034f\u00d0\3\2\2\2\u0350\u0352\7G\2"+
|
||||||
"\u034f\3\2\2\2\u0352\u0353\7b\2\2\u0353\u00d2\3\2\2\2\u0354\u0356\7G\2"+
|
"\2\u0351\u0353\t\6\2\2\u0352\u0351\3\2\2\2\u0352\u0353\3\2\2\2\u0353\u0355"+
|
||||||
"\2\u0355\u0357\t\6\2\2\u0356\u0355\3\2\2\2\u0356\u0357\3\2\2\2\u0357\u0359"+
|
"\3\2\2\2\u0354\u0356\5\u00d3j\2\u0355\u0354\3\2\2\2\u0356\u0357\3\2\2"+
|
||||||
"\3\2\2\2\u0358\u035a\5\u00d5k\2\u0359\u0358\3\2\2\2\u035a\u035b\3\2\2"+
|
"\2\u0357\u0355\3\2\2\2\u0357\u0358\3\2\2\2\u0358\u00d2\3\2\2\2\u0359\u035a"+
|
||||||
"\2\u035b\u0359\3\2\2\2\u035b\u035c\3\2\2\2\u035c\u00d4\3\2\2\2\u035d\u035e"+
|
"\t\7\2\2\u035a\u00d4\3\2\2\2\u035b\u035c\t\b\2\2\u035c\u00d6\3\2\2\2\u035d"+
|
||||||
"\t\7\2\2\u035e\u00d6\3\2\2\2\u035f\u0360\t\b\2\2\u0360\u00d8\3\2\2\2\u0361"+
|
"\u035e\7/\2\2\u035e\u035f\7/\2\2\u035f\u0363\3\2\2\2\u0360\u0362\n\t\2"+
|
||||||
"\u0362\7/\2\2\u0362\u0363\7/\2\2\u0363\u0367\3\2\2\2\u0364\u0366\n\t\2"+
|
"\2\u0361\u0360\3\2\2\2\u0362\u0365\3\2\2\2\u0363\u0361\3\2\2\2\u0363\u0364"+
|
||||||
"\2\u0365\u0364\3\2\2\2\u0366\u0369\3\2\2\2\u0367\u0365\3\2\2\2\u0367\u0368"+
|
"\3\2\2\2\u0364\u0367\3\2\2\2\u0365\u0363\3\2\2\2\u0366\u0368\7\17\2\2"+
|
||||||
"\3\2\2\2\u0368\u036b\3\2\2\2\u0369\u0367\3\2\2\2\u036a\u036c\7\17\2\2"+
|
"\u0367\u0366\3\2\2\2\u0367\u0368\3\2\2\2\u0368\u036a\3\2\2\2\u0369\u036b"+
|
||||||
"\u036b\u036a\3\2\2\2\u036b\u036c\3\2\2\2\u036c\u036e\3\2\2\2\u036d\u036f"+
|
"\7\f\2\2\u036a\u0369\3\2\2\2\u036a\u036b\3\2\2\2\u036b\u036c\3\2\2\2\u036c"+
|
||||||
"\7\f\2\2\u036e\u036d\3\2\2\2\u036e\u036f\3\2\2\2\u036f\u0370\3\2\2\2\u0370"+
|
"\u036d\bl\2\2\u036d\u00d8\3\2\2\2\u036e\u036f\7\61\2\2\u036f\u0370\7,"+
|
||||||
"\u0371\bm\2\2\u0371\u00da\3\2\2\2\u0372\u0373\7\61\2\2\u0373\u0374\7,"+
|
"\2\2\u0370\u0375\3\2\2\2\u0371\u0374\5\u00d9m\2\u0372\u0374\13\2\2\2\u0373"+
|
||||||
"\2\2\u0374\u0379\3\2\2\2\u0375\u0378\5\u00dbn\2\u0376\u0378\13\2\2\2\u0377"+
|
"\u0371\3\2\2\2\u0373\u0372\3\2\2\2\u0374\u0377\3\2\2\2\u0375\u0376\3\2"+
|
||||||
"\u0375\3\2\2\2\u0377\u0376\3\2\2\2\u0378\u037b\3\2\2\2\u0379\u037a\3\2"+
|
"\2\2\u0375\u0373\3\2\2\2\u0376\u0378\3\2\2\2\u0377\u0375\3\2\2\2\u0378"+
|
||||||
"\2\2\u0379\u0377\3\2\2\2\u037a\u037c\3\2\2\2\u037b\u0379\3\2\2\2\u037c"+
|
"\u0379\7,\2\2\u0379\u037a\7\61\2\2\u037a\u037b\3\2\2\2\u037b\u037c\bm"+
|
||||||
"\u037d\7,\2\2\u037d\u037e\7\61\2\2\u037e\u037f\3\2\2\2\u037f\u0380\bn"+
|
"\2\2\u037c\u00da\3\2\2\2\u037d\u037f\t\n\2\2\u037e\u037d\3\2\2\2\u037f"+
|
||||||
"\2\2\u0380\u00dc\3\2\2\2\u0381\u0383\t\n\2\2\u0382\u0381\3\2\2\2\u0383"+
|
"\u0380\3\2\2\2\u0380\u037e\3\2\2\2\u0380\u0381\3\2\2\2\u0381\u0382\3\2"+
|
||||||
"\u0384\3\2\2\2\u0384\u0382\3\2\2\2\u0384\u0385\3\2\2\2\u0385\u0386\3\2"+
|
"\2\2\u0382\u0383\bn\2\2\u0383\u00dc\3\2\2\2\u0384\u0385\13\2\2\2\u0385"+
|
||||||
"\2\2\u0386\u0387\bo\2\2\u0387\u00de\3\2\2\2\u0388\u0389\13\2\2\2\u0389"+
|
"\u00de\3\2\2\2 \2\u02d2\u02ef\u02f1\u02f9\u02fe\u0304\u030b\u0310\u0316"+
|
||||||
"\u00e0\3\2\2\2 \2\u02d6\u02f3\u02f5\u02fd\u0302\u0308\u030f\u0314\u031a"+
|
"\u0319\u0321\u0325\u0329\u032e\u0330\u0337\u0339\u033e\u0340\u0349\u034b"+
|
||||||
"\u031d\u0325\u0329\u032d\u0332\u0334\u033b\u033d\u0342\u0344\u034d\u034f"+
|
"\u0352\u0357\u0363\u0367\u036a\u0373\u0375\u0380\3\2\3\2";
|
||||||
"\u0356\u035b\u0367\u036b\u036e\u0377\u0379\u0384\3\2\3\2";
|
|
||||||
public static final ATN _ATN =
|
public static final ATN _ATN =
|
||||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||||
static {
|
static {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,37 +5,27 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.plan;
|
package org.elasticsearch.xpack.sql.plan;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.xpack.sql.tree.Location;
|
import org.elasticsearch.xpack.sql.tree.Location;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class TableIdentifier {
|
public class TableIdentifier {
|
||||||
|
|
||||||
private final String index, type;
|
private final String index;
|
||||||
private final Location location;
|
private final Location location;
|
||||||
|
|
||||||
public TableIdentifier(Location location, String index, String type) {
|
public TableIdentifier(Location location, String index) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String index() {
|
public String index() {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String type() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasType() {
|
|
||||||
return Strings.hasText(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(index, type);
|
return Objects.hash(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,8 +39,7 @@ public class TableIdentifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
TableIdentifier other = (TableIdentifier) obj;
|
TableIdentifier other = (TableIdentifier) obj;
|
||||||
return Objects.equals(index, other.index)
|
return Objects.equals(index, other.index);
|
||||||
&& Objects.equals(type, other.type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location location() {
|
public Location location() {
|
||||||
|
@ -62,8 +51,6 @@ public class TableIdentifier {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("[index=");
|
builder.append("[index=");
|
||||||
builder.append(index);
|
builder.append(index);
|
||||||
builder.append(", type=");
|
|
||||||
builder.append(type);
|
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,8 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.plan.logical;
|
package org.elasticsearch.xpack.sql.plan.logical;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
||||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsType;
|
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||||
import org.elasticsearch.xpack.sql.expression.NestedFieldAttribute;
|
import org.elasticsearch.xpack.sql.expression.NestedFieldAttribute;
|
||||||
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
||||||
|
@ -21,20 +16,24 @@ import org.elasticsearch.xpack.sql.type.NestedType;
|
||||||
import org.elasticsearch.xpack.sql.type.StringType;
|
import org.elasticsearch.xpack.sql.type.StringType;
|
||||||
import org.elasticsearch.xpack.sql.util.StringUtils;
|
import org.elasticsearch.xpack.sql.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.sql.util.CollectionUtils.combine;
|
import static org.elasticsearch.xpack.sql.util.CollectionUtils.combine;
|
||||||
|
|
||||||
public class CatalogTable extends LeafPlan {
|
public class CatalogTable extends LeafPlan {
|
||||||
|
|
||||||
private final EsType type;
|
private final EsIndex index;
|
||||||
private final List<Attribute> attrs;
|
private final List<Attribute> attrs;
|
||||||
|
|
||||||
public CatalogTable(Location location, EsType type) {
|
public CatalogTable(Location location, EsIndex index) {
|
||||||
super(location);
|
super(location);
|
||||||
this.type = type;
|
this.index = index;
|
||||||
attrs = flatten(location, type.mapping()).collect(toList());
|
attrs = flatten(location, index.mapping()).collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<Attribute> flatten(Location location, Map<String, DataType> mapping) {
|
private static Stream<Attribute> flatten(Location location, Map<String, DataType> mapping) {
|
||||||
|
@ -62,8 +61,8 @@ public class CatalogTable extends LeafPlan {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public EsType type() {
|
public EsIndex index() {
|
||||||
return type;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,7 +77,7 @@ public class CatalogTable extends LeafPlan {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(type);
|
return Objects.hash(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,11 +91,11 @@ public class CatalogTable extends LeafPlan {
|
||||||
}
|
}
|
||||||
|
|
||||||
CatalogTable other = (CatalogTable) obj;
|
CatalogTable other = (CatalogTable) obj;
|
||||||
return Objects.equals(type, other.type);
|
return Objects.equals(index, other.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String nodeString() {
|
public String nodeString() {
|
||||||
return nodeName() + "[" + type + "]" + StringUtils.limitedToString(attrs);
|
return nodeName() + "[" + index + "]" + StringUtils.limitedToString(attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.plan.logical.command;
|
package org.elasticsearch.xpack.sql.plan.logical.command;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
|
||||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||||
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
||||||
|
@ -21,28 +16,27 @@ import org.elasticsearch.xpack.sql.type.CompoundDataType;
|
||||||
import org.elasticsearch.xpack.sql.type.DataType;
|
import org.elasticsearch.xpack.sql.type.DataType;
|
||||||
import org.elasticsearch.xpack.sql.type.DataTypes;
|
import org.elasticsearch.xpack.sql.type.DataTypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
public class ShowColumns extends Command {
|
public class ShowColumns extends Command {
|
||||||
|
|
||||||
private final String index, type;
|
private final String index;
|
||||||
|
|
||||||
public ShowColumns(Location location, String index, String type) {
|
public ShowColumns(Location location, String index) {
|
||||||
super(location);
|
super(location);
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String index() {
|
public String index() {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String type() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Attribute> output() {
|
public List<Attribute> output() {
|
||||||
return asList(new RootFieldAttribute(location(), "column", DataTypes.KEYWORD),
|
return asList(new RootFieldAttribute(location(), "column", DataTypes.KEYWORD),
|
||||||
|
@ -52,7 +46,7 @@ public class ShowColumns extends Command {
|
||||||
@Override
|
@Override
|
||||||
protected RowSetCursor execute(SqlSession session) {
|
protected RowSetCursor execute(SqlSession session) {
|
||||||
Catalog catalog = session.catalog();
|
Catalog catalog = session.catalog();
|
||||||
Map<String, DataType> mapping = catalog.getType(index, type).mapping();
|
Map<String, DataType> mapping = catalog.getIndex(index).mapping();
|
||||||
|
|
||||||
List<List<?>> rows = new ArrayList<>();
|
List<List<?>> rows = new ArrayList<>();
|
||||||
fillInRows(mapping, null, rows);
|
fillInRows(mapping, null, rows);
|
||||||
|
@ -75,7 +69,7 @@ public class ShowColumns extends Command {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(index, type);
|
return Objects.hash(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -89,7 +83,6 @@ public class ShowColumns extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowColumns other = (ShowColumns) obj;
|
ShowColumns other = (ShowColumns) obj;
|
||||||
return Objects.equals(index, other.index)
|
return Objects.equals(index, other.index);
|
||||||
&& Objects.equals(type, other.type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.plan.logical.command;
|
package org.elasticsearch.xpack.sql.plan.logical.command;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsType;
|
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||||
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
import org.elasticsearch.xpack.sql.expression.RootFieldAttribute;
|
||||||
import org.elasticsearch.xpack.sql.session.RowSetCursor;
|
import org.elasticsearch.xpack.sql.session.RowSetCursor;
|
||||||
|
@ -19,47 +19,42 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Comparator.comparing;
|
import static java.util.Comparator.comparing;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
public class ShowTables extends Command {
|
public class ShowTables extends Command {
|
||||||
|
|
||||||
private final String index, pattern;
|
private final String pattern;
|
||||||
|
|
||||||
public ShowTables(Location location, String index, String pattern) {
|
public ShowTables(Location location, String pattern) {
|
||||||
super(location);
|
super(location);
|
||||||
this.index = index;
|
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String index() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String pattern() {
|
public String pattern() {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Attribute> output() {
|
public List<Attribute> output() {
|
||||||
return asList(new RootFieldAttribute(location(), "index", DataTypes.KEYWORD),
|
return asList(new RootFieldAttribute(location(), "table", DataTypes.KEYWORD));
|
||||||
new RootFieldAttribute(location(), "type", DataTypes.KEYWORD));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RowSetCursor execute(SqlSession session) {
|
protected RowSetCursor execute(SqlSession session) {
|
||||||
List<EsType> types = session.catalog().listTypes(index, pattern);
|
List<EsIndex> indices = session.catalog().listIndices(pattern);
|
||||||
// Consistent sorting is nice both for testing and humans
|
// Consistent sorting is nice both for testing and humans
|
||||||
Collections.sort(types, comparing(EsType::index).thenComparing(EsType::name));
|
Collections.sort(indices, comparing(EsIndex::name));
|
||||||
|
|
||||||
return Rows.of(output(), types.stream()
|
return Rows.of(output(), indices.stream()
|
||||||
.map(t -> asList(t.index(), t.name()))
|
.map(t -> singletonList(t.name()))
|
||||||
.collect(toList()));
|
.collect(toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(index, pattern);
|
return Objects.hash(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,7 +68,6 @@ public class ShowTables extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowTables other = (ShowTables) obj;
|
ShowTables other = (ShowTables) obj;
|
||||||
return Objects.equals(index, other.index)
|
return Objects.equals(pattern, other.pattern);
|
||||||
&& Objects.equals(pattern, other.pattern);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,31 +19,26 @@ import java.util.Objects;
|
||||||
|
|
||||||
public class EsQueryExec extends LeafExec {
|
public class EsQueryExec extends LeafExec {
|
||||||
|
|
||||||
private final String index, type;
|
private final String index;
|
||||||
private final List<Attribute> output;
|
private final List<Attribute> output;
|
||||||
|
|
||||||
private final QueryContainer queryContainer;
|
private final QueryContainer queryContainer;
|
||||||
|
|
||||||
public EsQueryExec(Location location, String index, String type, List<Attribute> output, QueryContainer queryContainer) {
|
public EsQueryExec(Location location, String index, List<Attribute> output, QueryContainer queryContainer) {
|
||||||
super(location);
|
super(location);
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.type = type;
|
|
||||||
this.output = output;
|
this.output = output;
|
||||||
this.queryContainer = queryContainer;
|
this.queryContainer = queryContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EsQueryExec with(QueryContainer queryContainer) {
|
public EsQueryExec with(QueryContainer queryContainer) {
|
||||||
return new EsQueryExec(location(), index, type, output, queryContainer);
|
return new EsQueryExec(location(), index, output, queryContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String index() {
|
public String index() {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String type() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public QueryContainer queryContainer() {
|
public QueryContainer queryContainer() {
|
||||||
return queryContainer;
|
return queryContainer;
|
||||||
}
|
}
|
||||||
|
@ -56,12 +51,12 @@ public class EsQueryExec extends LeafExec {
|
||||||
@Override
|
@Override
|
||||||
public void execute(SqlSession session, ActionListener<RowSetCursor> listener) {
|
public void execute(SqlSession session, ActionListener<RowSetCursor> listener) {
|
||||||
Scroller scroller = new Scroller(session.client(), session.settings());
|
Scroller scroller = new Scroller(session.client(), session.settings());
|
||||||
scroller.scroll(Rows.schema(output), queryContainer, index, type, listener);
|
scroller.scroll(Rows.schema(output), queryContainer, index, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(index, type, queryContainer, output);
|
return Objects.hash(index, queryContainer, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,13 +71,12 @@ public class EsQueryExec extends LeafExec {
|
||||||
|
|
||||||
EsQueryExec other = (EsQueryExec) obj;
|
EsQueryExec other = (EsQueryExec) obj;
|
||||||
return Objects.equals(index, other.index)
|
return Objects.equals(index, other.index)
|
||||||
&& Objects.equals(type, other.type)
|
|
||||||
&& Objects.equals(queryContainer, other.queryContainer)
|
&& Objects.equals(queryContainer, other.queryContainer)
|
||||||
&& Objects.equals(output, other.output);
|
&& Objects.equals(output, other.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String nodeString() {
|
public String nodeString() {
|
||||||
return nodeName() + "[" + index + "/" + type + "," + queryContainer + "]";
|
return nodeName() + "[" + index + "," + queryContainer + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,9 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.planner;
|
package org.elasticsearch.xpack.sql.planner;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.expression.Attribute;
|
import org.elasticsearch.xpack.sql.expression.Attribute;
|
||||||
import org.elasticsearch.xpack.sql.plan.logical.Aggregate;
|
import org.elasticsearch.xpack.sql.plan.logical.Aggregate;
|
||||||
import org.elasticsearch.xpack.sql.plan.logical.CatalogTable;
|
import org.elasticsearch.xpack.sql.plan.logical.CatalogTable;
|
||||||
|
@ -35,6 +32,9 @@ import org.elasticsearch.xpack.sql.rule.Rule;
|
||||||
import org.elasticsearch.xpack.sql.rule.RuleExecutor;
|
import org.elasticsearch.xpack.sql.rule.RuleExecutor;
|
||||||
import org.elasticsearch.xpack.sql.util.ReflectionUtils;
|
import org.elasticsearch.xpack.sql.util.ReflectionUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
class Mapper extends RuleExecutor<PhysicalPlan> {
|
class Mapper extends RuleExecutor<PhysicalPlan> {
|
||||||
|
|
||||||
public PhysicalPlan map(LogicalPlan plan) {
|
public PhysicalPlan map(LogicalPlan plan) {
|
||||||
|
@ -91,7 +91,7 @@ class Mapper extends RuleExecutor<PhysicalPlan> {
|
||||||
if (p instanceof CatalogTable) {
|
if (p instanceof CatalogTable) {
|
||||||
CatalogTable c = (CatalogTable) p;
|
CatalogTable c = (CatalogTable) p;
|
||||||
List<Attribute> output = c.output();
|
List<Attribute> output = c.output();
|
||||||
return new EsQueryExec(c.location(), c.type().index(), c.type().name(), output, new QueryContainer());
|
return new EsQueryExec(c.location(), c.index().name(), output, new QueryContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p instanceof Limit) {
|
if (p instanceof Limit) {
|
||||||
|
|
|
@ -118,7 +118,7 @@ class QueryFolder extends RuleExecutor<PhysicalPlan> {
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryContainer clone = new QueryContainer(queryC.query(), queryC.aggs(), queryC.refs(), aliases, processors, queryC.pseudoFunctions(), queryC.sort(), queryC.limit());
|
QueryContainer clone = new QueryContainer(queryC.query(), queryC.aggs(), queryC.refs(), aliases, processors, queryC.pseudoFunctions(), queryC.sort(), queryC.limit());
|
||||||
return new EsQueryExec(exec.location(), exec.index(), exec.type(), project.output(), clone);
|
return new EsQueryExec(exec.location(), exec.index(), project.output(), clone);
|
||||||
}
|
}
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ class QueryFolder extends RuleExecutor<PhysicalPlan> {
|
||||||
if (!aliases.isEmpty()) {
|
if (!aliases.isEmpty()) {
|
||||||
queryC = queryC.withAliases(combine(queryC.aliases(), aliases));
|
queryC = queryC.withAliases(combine(queryC.aliases(), aliases));
|
||||||
}
|
}
|
||||||
return new EsQueryExec(exec.location(), exec.index(), exec.type(), a.output(), queryC);
|
return new EsQueryExec(exec.location(), exec.index(), a.output(), queryC);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.xpack.sql.analysis.catalog.EsType;
|
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
|
||||||
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
import org.elasticsearch.xpack.sql.execution.PlanExecutor;
|
||||||
import org.elasticsearch.xpack.sql.execution.search.SearchHitRowSetCursor;
|
import org.elasticsearch.xpack.sql.execution.search.SearchHitRowSetCursor;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.ColumnInfo;
|
import org.elasticsearch.xpack.sql.jdbc.net.protocol.ColumnInfo;
|
||||||
|
@ -45,9 +45,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static org.elasticsearch.action.ActionListener.wrap;
|
import static org.elasticsearch.action.ActionListener.wrap;
|
||||||
import static org.elasticsearch.common.Strings.coalesceToEmpty;
|
|
||||||
import static org.elasticsearch.common.Strings.hasText;
|
import static org.elasticsearch.common.Strings.hasText;
|
||||||
import static org.elasticsearch.common.Strings.tokenizeToStringArray;
|
|
||||||
import static org.elasticsearch.xpack.sql.util.StringUtils.EMPTY;
|
import static org.elasticsearch.xpack.sql.util.StringUtils.EMPTY;
|
||||||
|
|
||||||
public class JdbcServer extends AbstractSqlServer {
|
public class JdbcServer extends AbstractSqlServer {
|
||||||
|
@ -100,35 +98,29 @@ public class JdbcServer extends AbstractSqlServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MetaTableResponse metaTable(MetaTableRequest req) {
|
public MetaTableResponse metaTable(MetaTableRequest req) {
|
||||||
String[] split = splitToIndexAndType(req.pattern());
|
String indexPattern = hasText(req.pattern()) ? StringUtils.jdbcToEsPattern(req.pattern()) : "*";
|
||||||
String index = split[0];
|
|
||||||
String type = split[1];
|
|
||||||
String indexPattern = hasText(index) ? StringUtils.jdbcToEsPattern(index) : "*";
|
|
||||||
|
|
||||||
Collection<EsType> types = executor.catalog().listTypes(indexPattern, type);
|
Collection<EsIndex> indices = executor.catalog().listIndices(indexPattern);
|
||||||
return new MetaTableResponse(types.stream()
|
return new MetaTableResponse(indices.stream()
|
||||||
.map(t -> t.index() + "." + t.name())
|
.map(EsIndex::name)
|
||||||
.collect(toList()));
|
.collect(toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MetaColumnResponse metaColumn(MetaColumnRequest req) {
|
public MetaColumnResponse metaColumn(MetaColumnRequest req) {
|
||||||
String[] split = splitToIndexAndType(req.tablePattern());
|
String pattern = Strings.hasText(req.tablePattern()) ? StringUtils.jdbcToEsPattern(req.tablePattern()) : "*";
|
||||||
String index = split[0];
|
|
||||||
String type = split[1];
|
|
||||||
String indexPattern = Strings.hasText(index) ? StringUtils.jdbcToEsPattern(index) : "*";
|
|
||||||
|
|
||||||
Collection<EsType> types = executor.catalog().listTypes(indexPattern, type);
|
Collection<EsIndex> indices = executor.catalog().listIndices(pattern);
|
||||||
|
|
||||||
Pattern columnMatcher = hasText(req.columnPattern()) ? StringUtils.likeRegex(req.columnPattern()) : null;
|
Pattern columnMatcher = hasText(req.columnPattern()) ? StringUtils.likeRegex(req.columnPattern()) : null;
|
||||||
|
|
||||||
List<MetaColumnInfo> resp = new ArrayList<>();
|
List<MetaColumnInfo> resp = new ArrayList<>();
|
||||||
for (EsType esType : types) {
|
for (EsIndex esIndex : indices) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for (Entry<String, DataType> entry : esType.mapping().entrySet()) {
|
for (Entry<String, DataType> entry : esIndex.mapping().entrySet()) {
|
||||||
pos++;
|
pos++;
|
||||||
if (columnMatcher == null || columnMatcher.matcher(entry.getKey()).matches()) {
|
if (columnMatcher == null || columnMatcher.matcher(entry.getKey()).matches()) {
|
||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
String table = esType.index() + "." + esType.name();
|
String table = esIndex.name();
|
||||||
JDBCType tp = entry.getValue().sqlType();
|
JDBCType tp = entry.getValue().sqlType();
|
||||||
int size = entry.getValue().precision();
|
int size = entry.getValue().precision();
|
||||||
resp.add(new MetaColumnInfo(table, name, tp, size, pos));
|
resp.add(new MetaColumnInfo(table, name, tp, size, pos));
|
||||||
|
@ -149,6 +141,7 @@ public class JdbcServer extends AbstractSqlServer {
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//NOCOMMIT: this should be pushed down to the TransportSqlAction to hook up pagination
|
||||||
executor.sql(sqlCfg, req.query, wrap(c -> {
|
executor.sql(sqlCfg, req.query, wrap(c -> {
|
||||||
long stop = System.currentTimeMillis();
|
long stop = System.currentTimeMillis();
|
||||||
String requestId = EMPTY;
|
String requestId = EMPTY;
|
||||||
|
@ -167,17 +160,4 @@ public class JdbcServer extends AbstractSqlServer {
|
||||||
public void queryPage(QueryPageRequest req, ActionListener<Response> listener) {
|
public void queryPage(QueryPageRequest req, ActionListener<Response> listener) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
static String[] splitToIndexAndType(String pattern) {
|
|
||||||
String[] tokens = tokenizeToStringArray(pattern, ".");
|
|
||||||
|
|
||||||
if (tokens.length == 2) {
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
if (tokens.length != 1) {
|
|
||||||
throw new IllegalArgumentException("bad pattern: [" + pattern + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String[] {coalesceToEmpty(pattern), ""};
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -60,10 +60,6 @@ public class TransportSqlAction extends HandledTransportAction<SqlRequest, SqlRe
|
||||||
String sessionId = request.sessionId();
|
String sessionId = request.sessionId();
|
||||||
String query = request.query();
|
String query = request.query();
|
||||||
|
|
||||||
// NOCOMMIT this should be linked up
|
|
||||||
// SqlSettings sqlCfg = new SqlSettings(Settings.builder()
|
|
||||||
// // .put(SqlSettings.PAGE_SIZE, req.fetchSize)
|
|
||||||
// .put(SqlSettings.TIMEZONE_ID, request.timeZone().getID()).build());
|
|
||||||
try {
|
try {
|
||||||
if (sessionId == null) {
|
if (sessionId == null) {
|
||||||
if (!Strings.hasText(query)) {
|
if (!Strings.hasText(query)) {
|
||||||
|
@ -71,6 +67,11 @@ public class TransportSqlAction extends HandledTransportAction<SqlRequest, SqlRe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOCOMMIT this should be linked up
|
||||||
|
// SqlSettings sqlCfg = new SqlSettings(Settings.builder()
|
||||||
|
// .put(SqlSettings.PAGE_SIZE, req.fetchSize)
|
||||||
|
// .put(SqlSettings.TIMEZONE_ID, request.timeZone().getID()).build());
|
||||||
|
|
||||||
planExecutor.sql(query, chain(listener, c -> {
|
planExecutor.sql(query, chain(listener, c -> {
|
||||||
String id = generateId();
|
String id = generateId();
|
||||||
SESSIONS.put(id, c);
|
SESSIONS.put(id, c);
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class SqlSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTimeZone timeZone() {
|
public DateTimeZone timeZone() {
|
||||||
return DateTimeZone.forID(TIMEZONE_ID);
|
return DateTimeZone.forID(timeZoneId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int pageSize() {
|
public int pageSize() {
|
||||||
|
|
Loading…
Reference in New Issue