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:
Costin Leau 2017-08-02 17:03:49 +03:00
parent 38ea150f17
commit 0675d08f25
46 changed files with 1786 additions and 2142 deletions

View File

@ -5,43 +5,46 @@
*/
package org.elasticsearch.xpack.sql.cli;
import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
import java.io.IOException;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.startsWith;
@AwaitsFix(bugUrl = "https://github.com/elastic/x-pack-elasticsearch/issues/2074")
public class ExplainIT extends CliIntegrationTestCase {
public void testExplainBasic() throws IOException {
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("With[{}]"));
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());
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("Project[[test_field{r}#"));
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());
command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test.doc");
command("EXPLAIN (PLAN OPTIMIZED) SELECT * FROM test");
assertThat(in.readLine(), containsString("plan"));
assertThat(in.readLine(), startsWith("----------"));
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());
// 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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("EsQueryExec[test/doc,{"));
assertThat(in.readLine(), startsWith("EsQueryExec[test,{"));
assertThat(in.readLine(), startsWith(" \"_source\" : {"));
assertThat(in.readLine(), startsWith(" \"includes\" : ["));
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_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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("With[{}]"));
assertThat(in.readLine(), startsWith("\\_Project[[?*]]"));
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());
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("Project[[i{r}#"));
assertThat(in.readLine(), startsWith("\\_Filter[i{r}#"));
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());
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("Project[[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());
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("EsQueryExec[test/doc,{"));
assertThat(in.readLine(), startsWith("EsQueryExec[test,{"));
assertThat(in.readLine(), startsWith(" \"query\" : {"));
assertThat(in.readLine(), startsWith(" \"term\" : {"));
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_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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("With[{}]"));
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());
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("Aggregate[[],[COUNT(1)#"));
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());
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(), startsWith("----------"));
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());
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(), startsWith("----------"));
assertThat(in.readLine(), startsWith("EsQueryExec[test/doc,{"));
assertThat(in.readLine(), startsWith("EsQueryExec[test,{"));
assertThat(in.readLine(), startsWith(" \"size\" : 0,"));
assertThat(in.readLine(), startsWith(" \"_source\" : false,"));
assertThat(in.readLine(), startsWith(" \"stored_fields\" : \"_none_\""));

View File

@ -134,9 +134,9 @@ public class JdbcHttpClient implements Closeable {
ExceptionResponse ex = (ExceptionResponse) response;
throw ex.asException();
}
if (response.responseType() == ResponseType.EXCEPTION) {
if (response.responseType() == ResponseType.ERROR) {
ErrorResponse error = (ErrorResponse) response;
throw new JdbcException("%s", error.stack);
throw new JdbcException("Server returned error: %s", error.stack);
}
return response;
}

View File

@ -43,8 +43,6 @@ public class CsvSpecIT extends SpecBaseIntegrationTestCase {
assertMatchesCsv(testCase.query, testName, testCase.expectedResults);
} catch (AssertionError ae) {
throw reworkException(new AssertionError(errorMessage(ae), ae.getCause()));
} catch (Throwable th) {
throw reworkException(th);
}
}
@ -93,4 +91,4 @@ public class CsvSpecIT extends SpecBaseIntegrationTestCase {
String query;
String expectedResults;
}
}
}

View File

@ -9,24 +9,28 @@ import org.elasticsearch.xpack.sql.jdbc.framework.JdbcIntegrationTestCase;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Locale;
/**
* Tests for error messages.
*/
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 {
try (Connection c = esJdbc()) {
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from test.doc").executeQuery());
assertEquals("line 1:15: Cannot resolve index test", e.getMessage());
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from test").executeQuery());
assertEquals(message("test"), e.getMessage());
}
}
public void testSelectFromMissingType() throws Exception {
index("test", builder -> builder.field("name", "bob"));
public void testMultiTypeIndex() throws Exception {
try (Connection c = esJdbc()) {
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from test.notdoc").executeQuery());
assertEquals("line 1:15: Cannot resolve type notdoc in index test", e.getMessage());
SQLException e = expectThrows(SQLException.class, () -> c.prepareStatement("SELECT * from multi_type").executeQuery());
assertEquals(message("multi_type"), e.getMessage());
}
}
}

View File

@ -37,6 +37,10 @@ public class SqlSpecIT extends SpecBaseIntegrationTestCase {
@ParametersFactory(shuffle = false, argumentFormatting = PARAM_FORMATTNG)
public static List<Object[]> readScriptSpec() throws Exception {
// example for enabling logging
//JdbcTestUtils.sqlLogging();
SqlSpecParser parser = new SqlSpecParser();
return CollectionUtils.combine(
readScriptSpec("/select.sql-spec", parser),
@ -45,7 +49,7 @@ public class SqlSpecIT extends SpecBaseIntegrationTestCase {
readScriptSpec("/math.sql-spec", parser),
readScriptSpec("/agg.sql-spec", parser));
}
private static class SqlSpecParser implements Parser {
@Override
public Object parse(String line) {
@ -70,14 +74,14 @@ public class SqlSpecIT extends SpecBaseIntegrationTestCase {
} catch (AssertionError ae) {
throw reworkException(new AssertionError(errorMessage(ae), ae.getCause()));
}
} catch (Throwable th) {
throw reworkException(th);
}
}
private ResultSet executeQuery(Connection con) throws SQLException {
Statement statement = con.createStatement();
statement.setFetchSize(randomInt(10));
//statement.setFetchSize(randomInt(10));
// NOCOMMIT: hook up pagination
statement.setFetchSize(1000);
return statement.executeQuery(query);
}

View File

@ -11,6 +11,7 @@ import org.elasticsearch.client.http.entity.ContentType;
import org.elasticsearch.client.http.entity.StringEntity;
import org.elasticsearch.common.CheckedBiConsumer;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.xpack.sql.jdbc.SqlSpecIT;
@ -26,8 +27,10 @@ import static java.util.Collections.singletonMap;
public class DataLoader {
public static void main(String[] args) throws Exception {
RestClient client = RestClient.builder(new HttpHost("localhost", 9200)).build();
loadDatasetIntoEs(client);
try (RestClient client = RestClient.builder(new HttpHost("localhost", 9200)).build()) {
loadDatasetIntoEs(client);
Loggers.getLogger(DataLoader.class).info("Data loaded");
}
}
protected static void loadDatasetIntoEs(RestClient client) throws Exception {
@ -70,6 +73,7 @@ public class DataLoader {
bulk.append("}\n");
});
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 {

View File

@ -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());
}
}
}

View File

@ -5,14 +5,11 @@
*/
package org.elasticsearch.xpack.sql.jdbc.framework;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.PathUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@ -46,21 +43,9 @@ public abstract class SpecBaseIntegrationTestCase extends JdbcIntegrationTestCas
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
protected boolean preserveIndicesUponCompletion() {
return true;
return !SETUP_DATA;
}
public SpecBaseIntegrationTestCase(String groupName, String testName, Integer lineNumber, Path source) {
@ -125,7 +110,7 @@ public abstract class SpecBaseIntegrationTestCase extends JdbcIntegrationTestCas
return pairs;
}
public interface Parser {
Object parse(String line);
}

View File

@ -3,33 +3,33 @@
//
groupByOnText
SELECT gender g FROM "test_emp.emp" GROUP BY gender;
SELECT gender g FROM "test_emp" GROUP BY gender;
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
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
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
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
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
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
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
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
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
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
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
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
@ -37,160 +37,160 @@ SELECT emp_no e FROM "test_emp.emp" WHERE emp_no < 10020 GROUP BY e ORDER BY emp
// COUNT
aggCountImplicit
SELECT COUNT(*) c FROM "test_emp.emp";
SELECT COUNT(*) c FROM "test_emp";
aggCountImplicitWithCast
SELECT CAST(COUNT(*) AS INT) c FROM "test_emp.emp";
SELECT CAST(COUNT(*) AS INT) c FROM "test_emp";
aggCountImplicitWithConstant
SELECT COUNT(1) FROM "test_emp.emp";
SELECT COUNT(1) FROM "test_emp";
aggCountImplicitWithConstantAndFilter
SELECT COUNT(1) FROM "test_emp.emp" WHERE emp_no < 10010;
SELECT COUNT(1) FROM "test_emp" WHERE emp_no < 10010;
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
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
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
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
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
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
//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
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
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
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
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
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
//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
//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
aggMinImplicit
SELECT MIN(emp_no) m FROM "test_emp.emp";
SELECT MIN(emp_no) m FROM "test_emp";
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
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
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
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
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
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
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
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
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
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
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
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
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
aggMaxImplicit
SELECT MAX(emp_no) c FROM "test_emp.emp";
SELECT MAX(emp_no) c FROM "test_emp";
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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;

View File

@ -108,7 +108,7 @@ test_emp |emp
// DESCRIBE
describe
DESCRIBE "test_emp.emp";
DESCRIBE "test_emp";
column | type
birth_date |TIMESTAMP

View File

@ -6,11 +6,11 @@
// Time
//
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
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
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
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
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
// 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
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
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
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
@ -37,19 +37,19 @@ SELECT YEAR(birth_date) d, last_name l FROM "test_emp.emp" WHERE emp_no < 10010
// Filter
//
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
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
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
//
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
// 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
// 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;

View File

@ -4,7 +4,7 @@
name
// ES SQL query
SELECT COUNT(*) FROM "emp.emp";
SELECT COUNT(*) FROM "emp";
//
// expected result in CSV format

View File

@ -3,6 +3,6 @@
// name of the test - translated into 'testName'
name
// SQL query to be executed against H2 and ES
SELECT COUNT(*) FROM "emp.emp";
SELECT COUNT(*) FROM "emp";
// repeat the above

View File

@ -3,18 +3,18 @@
//
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
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
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
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
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
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
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
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;

View File

@ -3,28 +3,28 @@
//
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
10080 |Premal |M |Baek
;
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
10096 |Jayson |M |Mandell
;
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
10076 |Erez |F |Ritzmann
;
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
10095 |Hilari |M |Morton

View File

@ -3,73 +3,73 @@
//
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
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
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
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
//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
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
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
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
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
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
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
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
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
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
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
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
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
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
//
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
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
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
//
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
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
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
//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
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
//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
//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
//
//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;

View File

@ -3,36 +3,36 @@
//
wildcardWithOrder
SELECT * FROM "test_emp.emp" ORDER BY emp_no;
SELECT * FROM "test_emp" ORDER BY emp_no;
column
SELECT last_name FROM "test_emp.emp" ORDER BY emp_no;
SELECT last_name FROM "test_emp" ORDER BY emp_no;
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
SELECT last_name l FROM "test_emp.emp" ORDER BY emp_no;
SELECT last_name l FROM "test_emp" ORDER BY emp_no;
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
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
//
wildcardWithLimit
SELECT * FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
SELECT * FROM "test_emp" ORDER BY emp_no LIMIT 5;
wildcardWithOrderWithLimit
SELECT * FROM "test_emp.emp" ORDER BY emp_no LIMIT 5;
SELECT * FROM "test_emp" ORDER BY emp_no LIMIT 5;
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
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
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
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
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
//SELECT CAST(1 AS INT);
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
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
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
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
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
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
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;

View File

@ -1,5 +1,5 @@
DROP TABLE IF EXISTS "test_emp.emp";
CREATE TABLE "test_emp.emp" ("birth_date" TIMESTAMP,
DROP TABLE IF EXISTS "test_emp";
CREATE TABLE "test_emp" ("birth_date" TIMESTAMP,
"emp_no" INT,
"first_name" VARCHAR(50),
"gender" VARCHAR(1),

View File

@ -51,7 +51,7 @@ statement
)*
')')?
statement #debug
| SHOW TABLES ((FROM | IN) index=identifier)? (LIKE? pattern=STRING)? #showTables
| SHOW TABLES (LIKE? pattern=STRING)? #showTables
| SHOW COLUMNS (FROM | IN) tableIdentifier #showColumns
| (DESCRIBE | DESC) tableIdentifier #showColumns
| SHOW FUNCTIONS (LIKE? pattern=STRING)? #showFunctions
@ -232,8 +232,7 @@ qualifiedName
;
tableIdentifier
: index=identifier ('.' type=identifier)?
| '"' uindex=unquoteIdentifier ('.' utype=unquoteIdentifier)? '"'
: index=identifier
;
identifier

View File

@ -2,204 +2,202 @@ T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
SELECT=6
FROM=7
AS=8
ALL=9
WHEN=10
THEN=11
ANY=12
DISTINCT=13
WHERE=14
GROUP=15
BY=16
GROUPING=17
SETS=18
ORDER=19
HAVING=20
LIMIT=21
OR=22
AND=23
IN=24
NOT=25
NO=26
EXISTS=27
BETWEEN=28
LIKE=29
RLIKE=30
IS=31
NULL=32
TRUE=33
FALSE=34
LAST=35
ASC=36
DESC=37
FOR=38
INTEGER=39
JOIN=40
CROSS=41
OUTER=42
INNER=43
LEFT=44
RIGHT=45
FULL=46
NATURAL=47
USING=48
ON=49
WITH=50
TABLE=51
INTO=52
DESCRIBE=53
OPTION=54
EXPLAIN=55
ANALYZE=56
FORMAT=57
TYPE=58
TEXT=59
VERIFY=60
GRAPHVIZ=61
LOGICAL=62
PHYSICAL=63
SHOW=64
TABLES=65
COLUMNS=66
COLUMN=67
FUNCTIONS=68
TO=69
DEBUG=70
PLAN=71
PARSED=72
ANALYZED=73
OPTIMIZED=74
MAPPED=75
EXECUTABLE=76
USE=77
SET=78
RESET=79
SESSION=80
SCHEMAS=81
EXTRACT=82
QUERY=83
MATCH=84
CAST=85
EQ=86
NEQ=87
LT=88
LTE=89
GT=90
GTE=91
PLUS=92
MINUS=93
ASTERISK=94
SLASH=95
PERCENT=96
CONCAT=97
STRING=98
INTEGER_VALUE=99
DECIMAL_VALUE=100
IDENTIFIER=101
DIGIT_IDENTIFIER=102
QUOTED_IDENTIFIER=103
BACKQUOTED_IDENTIFIER=104
SIMPLE_COMMENT=105
BRACKETED_COMMENT=106
WS=107
UNRECOGNIZED=108
DELIMITER=109
SELECT=5
FROM=6
AS=7
ALL=8
WHEN=9
THEN=10
ANY=11
DISTINCT=12
WHERE=13
GROUP=14
BY=15
GROUPING=16
SETS=17
ORDER=18
HAVING=19
LIMIT=20
OR=21
AND=22
IN=23
NOT=24
NO=25
EXISTS=26
BETWEEN=27
LIKE=28
RLIKE=29
IS=30
NULL=31
TRUE=32
FALSE=33
LAST=34
ASC=35
DESC=36
FOR=37
INTEGER=38
JOIN=39
CROSS=40
OUTER=41
INNER=42
LEFT=43
RIGHT=44
FULL=45
NATURAL=46
USING=47
ON=48
WITH=49
TABLE=50
INTO=51
DESCRIBE=52
OPTION=53
EXPLAIN=54
ANALYZE=55
FORMAT=56
TYPE=57
TEXT=58
VERIFY=59
GRAPHVIZ=60
LOGICAL=61
PHYSICAL=62
SHOW=63
TABLES=64
COLUMNS=65
COLUMN=66
FUNCTIONS=67
TO=68
DEBUG=69
PLAN=70
PARSED=71
ANALYZED=72
OPTIMIZED=73
MAPPED=74
EXECUTABLE=75
USE=76
SET=77
RESET=78
SESSION=79
SCHEMAS=80
EXTRACT=81
QUERY=82
MATCH=83
CAST=84
EQ=85
NEQ=86
LT=87
LTE=88
GT=89
GTE=90
PLUS=91
MINUS=92
ASTERISK=93
SLASH=94
PERCENT=95
CONCAT=96
STRING=97
INTEGER_VALUE=98
DECIMAL_VALUE=99
IDENTIFIER=100
DIGIT_IDENTIFIER=101
QUOTED_IDENTIFIER=102
BACKQUOTED_IDENTIFIER=103
SIMPLE_COMMENT=104
BRACKETED_COMMENT=105
WS=106
UNRECOGNIZED=107
DELIMITER=108
'('=1
')'=2
','=3
'.'=4
'"'=5
'SELECT'=6
'FROM'=7
'AS'=8
'ALL'=9
'WHEN'=10
'THEN'=11
'ANY'=12
'DISTINCT'=13
'WHERE'=14
'GROUP'=15
'BY'=16
'GROUPING'=17
'SETS'=18
'ORDER'=19
'HAVING'=20
'LIMIT'=21
'OR'=22
'AND'=23
'IN'=24
'NOT'=25
'NO'=26
'EXISTS'=27
'BETWEEN'=28
'LIKE'=29
'RLIKE'=30
'IS'=31
'NULL'=32
'TRUE'=33
'FALSE'=34
'LAST'=35
'ASC'=36
'DESC'=37
'FOR'=38
'INTEGER'=39
'JOIN'=40
'CROSS'=41
'OUTER'=42
'INNER'=43
'LEFT'=44
'RIGHT'=45
'FULL'=46
'NATURAL'=47
'USING'=48
'ON'=49
'WITH'=50
'TABLE'=51
'INTO'=52
'DESCRIBE'=53
'OPTION'=54
'EXPLAIN'=55
'ANALYZE'=56
'FORMAT'=57
'TYPE'=58
'TEXT'=59
'VERIFY'=60
'GRAPHVIZ'=61
'LOGICAL'=62
'PHYSICAL'=63
'SHOW'=64
'TABLES'=65
'COLUMNS'=66
'COLUMN'=67
'FUNCTIONS'=68
'TO'=69
'DEBUG'=70
'PLAN'=71
'PARSED'=72
'ANALYZED'=73
'OPTIMIZED'=74
'MAPPED'=75
'EXECUTABLE'=76
'USE'=77
'SET'=78
'RESET'=79
'SESSION'=80
'SCHEMAS'=81
'EXTRACT'=82
'QUERY'=83
'MATCH'=84
'CAST'=85
'='=86
'<'=88
'<='=89
'>'=90
'>='=91
'+'=92
'-'=93
'*'=94
'/'=95
'%'=96
'||'=97
'SELECT'=5
'FROM'=6
'AS'=7
'ALL'=8
'WHEN'=9
'THEN'=10
'ANY'=11
'DISTINCT'=12
'WHERE'=13
'GROUP'=14
'BY'=15
'GROUPING'=16
'SETS'=17
'ORDER'=18
'HAVING'=19
'LIMIT'=20
'OR'=21
'AND'=22
'IN'=23
'NOT'=24
'NO'=25
'EXISTS'=26
'BETWEEN'=27
'LIKE'=28
'RLIKE'=29
'IS'=30
'NULL'=31
'TRUE'=32
'FALSE'=33
'LAST'=34
'ASC'=35
'DESC'=36
'FOR'=37
'INTEGER'=38
'JOIN'=39
'CROSS'=40
'OUTER'=41
'INNER'=42
'LEFT'=43
'RIGHT'=44
'FULL'=45
'NATURAL'=46
'USING'=47
'ON'=48
'WITH'=49
'TABLE'=50
'INTO'=51
'DESCRIBE'=52
'OPTION'=53
'EXPLAIN'=54
'ANALYZE'=55
'FORMAT'=56
'TYPE'=57
'TEXT'=58
'VERIFY'=59
'GRAPHVIZ'=60
'LOGICAL'=61
'PHYSICAL'=62
'SHOW'=63
'TABLES'=64
'COLUMNS'=65
'COLUMN'=66
'FUNCTIONS'=67
'TO'=68
'DEBUG'=69
'PLAN'=70
'PARSED'=71
'ANALYZED'=72
'OPTIMIZED'=73
'MAPPED'=74
'EXECUTABLE'=75
'USE'=76
'SET'=77
'RESET'=78
'SESSION'=79
'SCHEMAS'=80
'EXTRACT'=81
'QUERY'=82
'MATCH'=83
'CAST'=84
'='=85
'<'=87
'<='=88
'>'=89
'>='=90
'+'=91
'-'=92
'*'=93
'/'=94
'%'=95
'||'=96

View File

@ -2,203 +2,201 @@ T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
SELECT=6
FROM=7
AS=8
ALL=9
WHEN=10
THEN=11
ANY=12
DISTINCT=13
WHERE=14
GROUP=15
BY=16
GROUPING=17
SETS=18
ORDER=19
HAVING=20
LIMIT=21
OR=22
AND=23
IN=24
NOT=25
NO=26
EXISTS=27
BETWEEN=28
LIKE=29
RLIKE=30
IS=31
NULL=32
TRUE=33
FALSE=34
LAST=35
ASC=36
DESC=37
FOR=38
INTEGER=39
JOIN=40
CROSS=41
OUTER=42
INNER=43
LEFT=44
RIGHT=45
FULL=46
NATURAL=47
USING=48
ON=49
WITH=50
TABLE=51
INTO=52
DESCRIBE=53
OPTION=54
EXPLAIN=55
ANALYZE=56
FORMAT=57
TYPE=58
TEXT=59
VERIFY=60
GRAPHVIZ=61
LOGICAL=62
PHYSICAL=63
SHOW=64
TABLES=65
COLUMNS=66
COLUMN=67
FUNCTIONS=68
TO=69
DEBUG=70
PLAN=71
PARSED=72
ANALYZED=73
OPTIMIZED=74
MAPPED=75
EXECUTABLE=76
USE=77
SET=78
RESET=79
SESSION=80
SCHEMAS=81
EXTRACT=82
QUERY=83
MATCH=84
CAST=85
EQ=86
NEQ=87
LT=88
LTE=89
GT=90
GTE=91
PLUS=92
MINUS=93
ASTERISK=94
SLASH=95
PERCENT=96
CONCAT=97
STRING=98
INTEGER_VALUE=99
DECIMAL_VALUE=100
IDENTIFIER=101
DIGIT_IDENTIFIER=102
QUOTED_IDENTIFIER=103
BACKQUOTED_IDENTIFIER=104
SIMPLE_COMMENT=105
BRACKETED_COMMENT=106
WS=107
UNRECOGNIZED=108
SELECT=5
FROM=6
AS=7
ALL=8
WHEN=9
THEN=10
ANY=11
DISTINCT=12
WHERE=13
GROUP=14
BY=15
GROUPING=16
SETS=17
ORDER=18
HAVING=19
LIMIT=20
OR=21
AND=22
IN=23
NOT=24
NO=25
EXISTS=26
BETWEEN=27
LIKE=28
RLIKE=29
IS=30
NULL=31
TRUE=32
FALSE=33
LAST=34
ASC=35
DESC=36
FOR=37
INTEGER=38
JOIN=39
CROSS=40
OUTER=41
INNER=42
LEFT=43
RIGHT=44
FULL=45
NATURAL=46
USING=47
ON=48
WITH=49
TABLE=50
INTO=51
DESCRIBE=52
OPTION=53
EXPLAIN=54
ANALYZE=55
FORMAT=56
TYPE=57
TEXT=58
VERIFY=59
GRAPHVIZ=60
LOGICAL=61
PHYSICAL=62
SHOW=63
TABLES=64
COLUMNS=65
COLUMN=66
FUNCTIONS=67
TO=68
DEBUG=69
PLAN=70
PARSED=71
ANALYZED=72
OPTIMIZED=73
MAPPED=74
EXECUTABLE=75
USE=76
SET=77
RESET=78
SESSION=79
SCHEMAS=80
EXTRACT=81
QUERY=82
MATCH=83
CAST=84
EQ=85
NEQ=86
LT=87
LTE=88
GT=89
GTE=90
PLUS=91
MINUS=92
ASTERISK=93
SLASH=94
PERCENT=95
CONCAT=96
STRING=97
INTEGER_VALUE=98
DECIMAL_VALUE=99
IDENTIFIER=100
DIGIT_IDENTIFIER=101
QUOTED_IDENTIFIER=102
BACKQUOTED_IDENTIFIER=103
SIMPLE_COMMENT=104
BRACKETED_COMMENT=105
WS=106
UNRECOGNIZED=107
'('=1
')'=2
','=3
'.'=4
'"'=5
'SELECT'=6
'FROM'=7
'AS'=8
'ALL'=9
'WHEN'=10
'THEN'=11
'ANY'=12
'DISTINCT'=13
'WHERE'=14
'GROUP'=15
'BY'=16
'GROUPING'=17
'SETS'=18
'ORDER'=19
'HAVING'=20
'LIMIT'=21
'OR'=22
'AND'=23
'IN'=24
'NOT'=25
'NO'=26
'EXISTS'=27
'BETWEEN'=28
'LIKE'=29
'RLIKE'=30
'IS'=31
'NULL'=32
'TRUE'=33
'FALSE'=34
'LAST'=35
'ASC'=36
'DESC'=37
'FOR'=38
'INTEGER'=39
'JOIN'=40
'CROSS'=41
'OUTER'=42
'INNER'=43
'LEFT'=44
'RIGHT'=45
'FULL'=46
'NATURAL'=47
'USING'=48
'ON'=49
'WITH'=50
'TABLE'=51
'INTO'=52
'DESCRIBE'=53
'OPTION'=54
'EXPLAIN'=55
'ANALYZE'=56
'FORMAT'=57
'TYPE'=58
'TEXT'=59
'VERIFY'=60
'GRAPHVIZ'=61
'LOGICAL'=62
'PHYSICAL'=63
'SHOW'=64
'TABLES'=65
'COLUMNS'=66
'COLUMN'=67
'FUNCTIONS'=68
'TO'=69
'DEBUG'=70
'PLAN'=71
'PARSED'=72
'ANALYZED'=73
'OPTIMIZED'=74
'MAPPED'=75
'EXECUTABLE'=76
'USE'=77
'SET'=78
'RESET'=79
'SESSION'=80
'SCHEMAS'=81
'EXTRACT'=82
'QUERY'=83
'MATCH'=84
'CAST'=85
'='=86
'<'=88
'<='=89
'>'=90
'>='=91
'+'=92
'-'=93
'*'=94
'/'=95
'%'=96
'||'=97
'SELECT'=5
'FROM'=6
'AS'=7
'ALL'=8
'WHEN'=9
'THEN'=10
'ANY'=11
'DISTINCT'=12
'WHERE'=13
'GROUP'=14
'BY'=15
'GROUPING'=16
'SETS'=17
'ORDER'=18
'HAVING'=19
'LIMIT'=20
'OR'=21
'AND'=22
'IN'=23
'NOT'=24
'NO'=25
'EXISTS'=26
'BETWEEN'=27
'LIKE'=28
'RLIKE'=29
'IS'=30
'NULL'=31
'TRUE'=32
'FALSE'=33
'LAST'=34
'ASC'=35
'DESC'=36
'FOR'=37
'INTEGER'=38
'JOIN'=39
'CROSS'=40
'OUTER'=41
'INNER'=42
'LEFT'=43
'RIGHT'=44
'FULL'=45
'NATURAL'=46
'USING'=47
'ON'=48
'WITH'=49
'TABLE'=50
'INTO'=51
'DESCRIBE'=52
'OPTION'=53
'EXPLAIN'=54
'ANALYZE'=55
'FORMAT'=56
'TYPE'=57
'TEXT'=58
'VERIFY'=59
'GRAPHVIZ'=60
'LOGICAL'=61
'PHYSICAL'=62
'SHOW'=63
'TABLES'=64
'COLUMNS'=65
'COLUMN'=66
'FUNCTIONS'=67
'TO'=68
'DEBUG'=69
'PLAN'=70
'PARSED'=71
'ANALYZED'=72
'OPTIMIZED'=73
'MAPPED'=74
'EXECUTABLE'=75
'USE'=76
'SET'=77
'RESET'=78
'SESSION'=79
'SCHEMAS'=80
'EXTRACT'=81
'QUERY'=82
'MATCH'=83
'CAST'=84
'='=85
'<'=87
'<='=88
'>'=89
'>='=90
'+'=91
'-'=92
'*'=93
'/'=94
'%'=95
'||'=96

View File

@ -7,9 +7,9 @@ package org.elasticsearch.xpack.sql.analysis;
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) {
super(source, "Cannot resolve type %s in index %s", type, index);
public InvalidIndexException(String index, Node<?> source) {
super(source, "Invalid index %s; contains more than one type", index);
}
}

View File

@ -6,9 +6,9 @@
package org.elasticsearch.xpack.sql.analysis.analyzer;
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.UnknownIndexException;
import org.elasticsearch.xpack.sql.analysis.UnknownTypeException;
import org.elasticsearch.xpack.sql.analysis.analyzer.Verifier.Failure;
import org.elasticsearch.xpack.sql.analysis.catalog.Catalog;
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) {
if (p instanceof UnresolvedRelation) {
UnresolvedRelation ur = (UnresolvedRelation) p;
SubQueryAlias subQueryAlias = subQueries.get(ur.table().type());
SubQueryAlias subQueryAlias = subQueries.get(ur.table().index());
if (subQueryAlias != null) {
if (ur.alias() != null) {
return new SubQueryAlias(ur.location(), subQueryAlias, ur.alias());
@ -245,14 +245,13 @@ public class Analyzer extends RuleExecutor<LogicalPlan> {
if (!catalog.indexExists(index)) {
throw new UnknownIndexException(index, plan);
}
String type = table.type();
if (!catalog.typeExists(index, type)) {
throw new UnknownTypeException(index, type, plan);
if (!catalog.indexIsValid(index)) {
throw new InvalidIndexException(index, plan);
}
LogicalPlan catalogTable = new CatalogTable(plan.location(), catalog.getType(index, type));
SubQueryAlias sa = new SubQueryAlias(plan.location(), catalogTable, type);
LogicalPlan catalogTable = new CatalogTable(plan.location(), catalog.getIndex(index));
SubQueryAlias sa = new SubQueryAlias(plan.location(), catalogTable, index);
if (plan.alias() != null) {
sa = new SubQueryAlias(plan.location(), sa, plan.alias());

View File

@ -9,21 +9,14 @@ import java.util.List;
public interface Catalog {
// NOCOMMIT make sure we need all of these methods....
EsIndex getIndex(String index);
boolean indexExists(String index);
boolean indexIsValid(String index);
EsIndex getIndex(String index);
List<EsIndex> listIndices();
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);
}

View File

@ -9,9 +9,7 @@ import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.Strings;
import java.util.ArrayList;
import java.util.Iterator;
@ -20,8 +18,6 @@ import java.util.function.Supplier;
public class EsCatalog implements Catalog {
private static final String WILDCARD = "*";
private final Supplier<ClusterState> clusterState;
private IndexNameExpressionResolver indexNameExpressionResolver;
@ -48,8 +44,14 @@ public class EsCatalog implements Catalog {
@Override
public boolean indexExists(String index) {
MetaData meta = metadata();
return meta.hasIndex(index);
IndexMetaData idx = metadata().index(index);
return idx != null;
}
@Override
public boolean indexIsValid(String index) {
IndexMetaData idx = metadata().index(index);
return idx != null && indexHasOnlyOneType(idx);
}
@Override
@ -68,62 +70,27 @@ public class EsCatalog implements Catalog {
String[] indexNames = resolveIndex(pattern);
List<IndexMetaData> indices = new ArrayList<>(indexNames.length);
for (String indexName : indexNames) {
indices.add(md.index(indexName));
indices.add(md.index(indexName));
}
indexMetadata = indices.iterator();
}
return EsIndex.build(indexMetadata);
}
@Override
public EsType getType(String index, String type) {
if (!indexExists(index)) {
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()));
List<EsIndex> list = new ArrayList<>();
// filter unsupported (indices with more than one type) indices
while (indexMetadata.hasNext()) {
IndexMetaData imd = indexMetadata.next();
if (indexHasOnlyOneType(imd)) {
list.add(EsIndex.build(imd));
}
}
return types;
return list;
}
private boolean indexHasOnlyOneType(IndexMetaData index) {
return index.getMappings().size() <= 1;
}
private String[] resolveIndex(String pattern) {
return indexNameExpressionResolver.concreteIndexNames(clusterState.get(), IndicesOptions.strictExpandOpenAndForbidClosed(), pattern);
}

View File

@ -5,29 +5,36 @@
*/
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.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import java.util.Map;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
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 List<String> types;
private final Map<String, DataType> mapping;
private final List<String> aliases;
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.types = types;
this.mapping = mapping;
this.aliases = aliases;
this.settings = settings;
}
@ -36,17 +43,14 @@ public class EsIndex {
return name;
}
public List<String> types() {
return types;
public Map<String, DataType> mapping() {
return mapping;
}
public List<String> aliases() {
return aliases;
}
public Settings settings() {
return settings;
}
@ -57,14 +61,25 @@ public class EsIndex {
}
List<EsIndex> list = new ArrayList<>();
while (metadata.hasNext()) {
list.add(build(metadata.next()));
build(metadata.next());
}
return list;
}
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));
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;
}
}

View File

@ -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();
}
}

View File

@ -1,108 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.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();
}

View File

@ -64,13 +64,13 @@ public class Scroller {
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
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);
// 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?
if (Boolean.TRUE.equals(response.isTerminatedEarly()) || response.getHits().getTotalHits() == hits.length
// or maybe the limit has been reached
|| docsRead >= limit) {
|| (docsRead >= limit && limit > -1)) {
// if so, clear the scroll
clearScroll(scrollId);
// and remove it to indicate no more data is expected

View File

@ -155,7 +155,7 @@ abstract class AbstractFunctionRegistry implements FunctionRegistry {
if (timezoneAware) {
args.add(settings.timeZone());
}
}
}
return (Function) info.ctr.newInstance(args.toArray());
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new SqlIllegalArgumentException(ex, "Cannot create instance of function %s", ur.name());

View File

@ -108,7 +108,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
@Override
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
@ -120,10 +120,7 @@ abstract class CommandBuilder extends LogicalPlanBuilder {
@Override
public Object visitShowColumns(ShowColumnsContext ctx) {
TableIdentifier identifier = visitTableIdentifier(ctx.tableIdentifier());
if (!identifier.hasType()) {
throw new ParsingException(identifier.location(), "Target type needs to be specified");
}
return new ShowColumns(source(ctx), identifier.index(), identifier.type());
return new ShowColumns(source(ctx), identifier.index());
}
@Override

View File

@ -133,7 +133,7 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
}
else if (ctx.table != null) {
TableIdentifier table = visitTableIdentifier(ctx.table);
qualifier = table.index() + "." + table.type();
qualifier = table.index();
}
return new UnresolvedAttribute(source(ctx), visitIdentifier(ctx.name), qualifier);
}

View File

@ -5,8 +5,6 @@
*/
package org.elasticsearch.xpack.sql.parser;
import java.util.Locale;
import org.elasticsearch.common.Strings;
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.IdentifierContext;
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.tree.Location;
import java.util.Locale;
import static java.lang.String.format;
abstract class IdentifierBuilder extends AbstractBuilder {
@Override
public TableIdentifier visitTableIdentifier(TableIdentifierContext ctx) {
String index = null;
String type = null;
index = text(ctx.uindex);
type = text(ctx.utype);
String index = text(ctx.index);
if (index == null) {
index = text(ctx.index);
type = text(ctx.type);
}
Location source = source(ctx);
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
@ -51,10 +41,6 @@ abstract class IdentifierBuilder extends AbstractBuilder {
}
}
private static void validateType(String type, Location source) {
// no-op
}
@Override
public String visitIdentifier(IdentifierContext ctx) {
return ctx == null ? null : ctx.quoteIdentifier() != null ? text(ctx.quoteIdentifier()) : text(ctx.unquoteIdentifier());

View File

@ -195,9 +195,6 @@ abstract class LogicalPlanBuilder extends ExpressionBuilder {
public LogicalPlan visitTableName(TableNameContext ctx) {
String alias = visitQualifiedName(ctx.qualifiedName());
TableIdentifier tableIdentifier = visitTableIdentifier(ctx.tableIdentifier());
if (!tableIdentifier.hasType()) {
throw new ParsingException(source(ctx), "Index type is required");
}
return new UnresolvedRelation(source(ctx), tableIdentifier, alias);
}
}

View File

@ -22,30 +22,30 @@ class SqlBaseLexer extends Lexer {
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
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,
WHEN=10, THEN=11, ANY=12, DISTINCT=13, WHERE=14, GROUP=15, BY=16, GROUPING=17,
SETS=18, ORDER=19, HAVING=20, LIMIT=21, OR=22, AND=23, IN=24, NOT=25,
NO=26, EXISTS=27, BETWEEN=28, LIKE=29, RLIKE=30, IS=31, NULL=32, TRUE=33,
FALSE=34, LAST=35, ASC=36, DESC=37, FOR=38, INTEGER=39, JOIN=40, CROSS=41,
OUTER=42, INNER=43, LEFT=44, RIGHT=45, FULL=46, NATURAL=47, USING=48,
ON=49, WITH=50, TABLE=51, INTO=52, DESCRIBE=53, OPTION=54, EXPLAIN=55,
ANALYZE=56, FORMAT=57, TYPE=58, TEXT=59, VERIFY=60, GRAPHVIZ=61, LOGICAL=62,
PHYSICAL=63, SHOW=64, TABLES=65, COLUMNS=66, COLUMN=67, FUNCTIONS=68,
TO=69, DEBUG=70, PLAN=71, PARSED=72, ANALYZED=73, OPTIMIZED=74, MAPPED=75,
EXECUTABLE=76, USE=77, SET=78, RESET=79, SESSION=80, SCHEMAS=81, EXTRACT=82,
QUERY=83, MATCH=84, CAST=85, EQ=86, NEQ=87, LT=88, LTE=89, GT=90, GTE=91,
PLUS=92, MINUS=93, ASTERISK=94, SLASH=95, PERCENT=96, CONCAT=97, STRING=98,
INTEGER_VALUE=99, DECIMAL_VALUE=100, IDENTIFIER=101, DIGIT_IDENTIFIER=102,
QUOTED_IDENTIFIER=103, BACKQUOTED_IDENTIFIER=104, SIMPLE_COMMENT=105,
BRACKETED_COMMENT=106, WS=107, UNRECOGNIZED=108;
T__0=1, T__1=2, T__2=3, T__3=4, SELECT=5, FROM=6, AS=7, ALL=8, WHEN=9,
THEN=10, ANY=11, DISTINCT=12, WHERE=13, GROUP=14, BY=15, GROUPING=16,
SETS=17, ORDER=18, HAVING=19, LIMIT=20, OR=21, AND=22, IN=23, NOT=24,
NO=25, EXISTS=26, BETWEEN=27, LIKE=28, RLIKE=29, IS=30, NULL=31, TRUE=32,
FALSE=33, LAST=34, ASC=35, DESC=36, FOR=37, INTEGER=38, JOIN=39, CROSS=40,
OUTER=41, INNER=42, LEFT=43, RIGHT=44, FULL=45, NATURAL=46, USING=47,
ON=48, WITH=49, TABLE=50, INTO=51, DESCRIBE=52, OPTION=53, EXPLAIN=54,
ANALYZE=55, FORMAT=56, TYPE=57, TEXT=58, VERIFY=59, GRAPHVIZ=60, LOGICAL=61,
PHYSICAL=62, SHOW=63, TABLES=64, COLUMNS=65, COLUMN=66, FUNCTIONS=67,
TO=68, DEBUG=69, PLAN=70, PARSED=71, ANALYZED=72, OPTIMIZED=73, MAPPED=74,
EXECUTABLE=75, USE=76, SET=77, RESET=78, SESSION=79, SCHEMAS=80, EXTRACT=81,
QUERY=82, MATCH=83, CAST=84, EQ=85, NEQ=86, LT=87, LTE=88, GT=89, GTE=90,
PLUS=91, MINUS=92, ASTERISK=93, SLASH=94, PERCENT=95, CONCAT=96, STRING=97,
INTEGER_VALUE=98, DECIMAL_VALUE=99, IDENTIFIER=100, DIGIT_IDENTIFIER=101,
QUOTED_IDENTIFIER=102, BACKQUOTED_IDENTIFIER=103, SIMPLE_COMMENT=104,
BRACKETED_COMMENT=105, WS=106, UNRECOGNIZED=107;
public static String[] modeNames = {
"DEFAULT_MODE"
};
public static final String[] ruleNames = {
"T__0", "T__1", "T__2", "T__3", "T__4", "SELECT", "FROM", "AS", "ALL",
"WHEN", "THEN", "ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING",
"SETS", "ORDER", "HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS",
"T__0", "T__1", "T__2", "T__3", "SELECT", "FROM", "AS", "ALL", "WHEN",
"THEN", "ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING", "SETS",
"ORDER", "HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS",
"BETWEEN", "LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC",
"DESC", "FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
"FULL", "NATURAL", "USING", "ON", "WITH", "TABLE", "INTO", "DESCRIBE",
@ -61,10 +61,10 @@ class SqlBaseLexer extends Lexer {
};
private static final String[] _LITERAL_NAMES = {
null, "'('", "')'", "','", "'.'", "'\"'", "'SELECT'", "'FROM'", "'AS'",
"'ALL'", "'WHEN'", "'THEN'", "'ANY'", "'DISTINCT'", "'WHERE'", "'GROUP'",
"'BY'", "'GROUPING'", "'SETS'", "'ORDER'", "'HAVING'", "'LIMIT'", "'OR'",
"'AND'", "'IN'", "'NOT'", "'NO'", "'EXISTS'", "'BETWEEN'", "'LIKE'", "'RLIKE'",
null, "'('", "')'", "','", "'.'", "'SELECT'", "'FROM'", "'AS'", "'ALL'",
"'WHEN'", "'THEN'", "'ANY'", "'DISTINCT'", "'WHERE'", "'GROUP'", "'BY'",
"'GROUPING'", "'SETS'", "'ORDER'", "'HAVING'", "'LIMIT'", "'OR'", "'AND'",
"'IN'", "'NOT'", "'NO'", "'EXISTS'", "'BETWEEN'", "'LIKE'", "'RLIKE'",
"'IS'", "'NULL'", "'TRUE'", "'FALSE'", "'LAST'", "'ASC'", "'DESC'", "'FOR'",
"'INTEGER'", "'JOIN'", "'CROSS'", "'OUTER'", "'INNER'", "'LEFT'", "'RIGHT'",
"'FULL'", "'NATURAL'", "'USING'", "'ON'", "'WITH'", "'TABLE'", "'INTO'",
@ -77,11 +77,11 @@ class SqlBaseLexer extends Lexer {
"'-'", "'*'", "'/'", "'%'", "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, "SELECT", "FROM", "AS", "ALL", "WHEN",
"THEN", "ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING", "SETS",
"ORDER", "HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS",
"BETWEEN", "LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC",
"DESC", "FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
null, null, null, null, null, "SELECT", "FROM", "AS", "ALL", "WHEN", "THEN",
"ANY", "DISTINCT", "WHERE", "GROUP", "BY", "GROUPING", "SETS", "ORDER",
"HAVING", "LIMIT", "OR", "AND", "IN", "NOT", "NO", "EXISTS", "BETWEEN",
"LIKE", "RLIKE", "IS", "NULL", "TRUE", "FALSE", "LAST", "ASC", "DESC",
"FOR", "INTEGER", "JOIN", "CROSS", "OUTER", "INNER", "LEFT", "RIGHT",
"FULL", "NATURAL", "USING", "ON", "WITH", "TABLE", "INTO", "DESCRIBE",
"OPTION", "EXPLAIN", "ANALYZE", "FORMAT", "TYPE", "TEXT", "VERIFY", "GRAPHVIZ",
"LOGICAL", "PHYSICAL", "SHOW", "TABLES", "COLUMNS", "COLUMN", "FUNCTIONS",
@ -147,7 +147,7 @@ class SqlBaseLexer extends Lexer {
public ATN getATN() { return _ATN; }
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"+
"\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"+
@ -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"+
"\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"+
"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"+
"\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\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\3\37\3\37\3 \3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#"+
"\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3(\3"+
"(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3+\3"+
",\3,\3,\3,\3,\3,\3-\3-\3-\3-\3-\3.\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3\60"+
"\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\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"+
"\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"+
"\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"+
"\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@\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C"+
"\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F"+
"\3F\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J"+
"\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M"+
"\3M\3M\3M\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P"+
"\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S"+
"\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V\3V\3W\3W\3X\3X"+
"\3X\3X\3X\3X\3X\5X\u02d7\nX\3Y\3Y\3Z\3Z\3Z\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"+
"c\3c\3c\3d\6d\u02fc\nd\rd\16d\u02fd\3e\6e\u0301\ne\re\16e\u0302\3e\3e"+
"\7e\u0307\ne\fe\16e\u030a\13e\3e\3e\6e\u030e\ne\re\16e\u030f\3e\6e\u0313"+
"\ne\re\16e\u0314\3e\3e\7e\u0319\ne\fe\16e\u031c\13e\5e\u031e\ne\3e\3e"+
"\3e\3e\6e\u0324\ne\re\16e\u0325\3e\3e\5e\u032a\ne\3f\3f\5f\u032e\nf\3"+
"f\3f\3f\7f\u0333\nf\ff\16f\u0336\13f\3g\3g\3g\3g\6g\u033c\ng\rg\16g\u033d"+
"\3h\3h\3h\7h\u0343\nh\fh\16h\u0346\13h\3h\3h\3i\3i\3i\3i\7i\u034e\ni\f"+
"i\16i\u0351\13i\3i\3i\3j\3j\5j\u0357\nj\3j\6j\u035a\nj\rj\16j\u035b\3"+
"k\3k\3l\3l\3m\3m\3m\3m\7m\u0366\nm\fm\16m\u0369\13m\3m\5m\u036c\nm\3m"+
"\5m\u036f\nm\3m\3m\3n\3n\3n\3n\3n\7n\u0378\nn\fn\16n\u037b\13n\3n\3n\3"+
"n\3n\3n\3o\6o\u0383\no\ro\16o\u0384\3o\3o\3p\3p\3\u0379\2q\3\3\5\4\7\5"+
"\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23"+
"%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G"+
"%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{"+
"?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091"+
"J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5"+
"T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9"+
"^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cd"+
"h\u00cfi\u00d1j\u00d3\2\u00d5\2\u00d7\2\u00d9k\u00dbl\u00ddm\u00dfn\3"+
"\2\13\3\2))\5\2<<BBaa\6\2$$))\60\60~~\6\2))\60\60bb~~\4\2--//\3\2\62;"+
"\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"+
"\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3"+
"\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2"+
"\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2"+
"\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2"+
"\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2"+
"\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2"+
"\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y"+
"\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2"+
"\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2"+
"\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177"+
"\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2"+
"\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091"+
"\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2"+
"\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3"+
"\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2"+
"\2\2\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"+
"\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2"+
"\2\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\u010c\3\2\2\2\35\u0115\3\2\2\2\37\u011b\3\2\2\2!\u0121\3\2\2\2#\u0124"+
"\3\2\2\2%\u012d\3\2\2\2\'\u0132\3\2\2\2)\u0138\3\2\2\2+\u013f\3\2\2\2"+
"-\u0145\3\2\2\2/\u0148\3\2\2\2\61\u014c\3\2\2\2\63\u014f\3\2\2\2\65\u0153"+
"\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"+
"?\u0170\3\2\2\2A\u0173\3\2\2\2C\u0178\3\2\2\2E\u017d\3\2\2\2G\u0183\3"+
"\2\2\2I\u0188\3\2\2\2K\u018c\3\2\2\2M\u0191\3\2\2\2O\u0195\3\2\2\2Q\u019d"+
"\3\2\2\2S\u01a2\3\2\2\2U\u01a8\3\2\2\2W\u01ae\3\2\2\2Y\u01b4\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"+
"\2\2e\u01d5\3\2\2\2g\u01da\3\2\2\2i\u01e0\3\2\2\2k\u01e5\3\2\2\2m\u01ee"+
"\3\2\2\2o\u01f5\3\2\2\2q\u01fd\3\2\2\2s\u0205\3\2\2\2u\u020c\3\2\2\2w"+
"\u0211\3\2\2\2y\u0216\3\2\2\2{\u021d\3\2\2\2}\u0226\3\2\2\2\177\u022e"+
"\3\2\2\2\u0081\u0237\3\2\2\2\u0083\u023c\3\2\2\2\u0085\u0243\3\2\2\2\u0087"+
"\u024b\3\2\2\2\u0089\u0252\3\2\2\2\u008b\u025c\3\2\2\2\u008d\u025f\3\2"+
"\2\2\u008f\u0265\3\2\2\2\u0091\u026a\3\2\2\2\u0093\u0271\3\2\2\2\u0095"+
"\u027a\3\2\2\2\u0097\u0284\3\2\2\2\u0099\u028b\3\2\2\2\u009b\u0296\3\2"+
"\2\2\u009d\u029a\3\2\2\2\u009f\u029e\3\2\2\2\u00a1\u02a4\3\2\2\2\u00a3"+
"\u02ac\3\2\2\2\u00a5\u02b4\3\2\2\2\u00a7\u02bc\3\2\2\2\u00a9\u02c2\3\2"+
"\2\2\u00ab\u02c8\3\2\2\2\u00ad\u02cd\3\2\2\2\u00af\u02d6\3\2\2\2\u00b1"+
"\u02d8\3\2\2\2\u00b3\u02da\3\2\2\2\u00b5\u02dd\3\2\2\2\u00b7\u02df\3\2"+
"\2\2\u00b9\u02e2\3\2\2\2\u00bb\u02e4\3\2\2\2\u00bd\u02e6\3\2\2\2\u00bf"+
"\u02e8\3\2\2\2\u00c1\u02ea\3\2\2\2\u00c3\u02ec\3\2\2\2\u00c5\u02ef\3\2"+
"\2\2\u00c7\u02fb\3\2\2\2\u00c9\u0329\3\2\2\2\u00cb\u032d\3\2\2\2\u00cd"+
"\u0337\3\2\2\2\u00cf\u033f\3\2\2\2\u00d1\u0349\3\2\2\2\u00d3\u0354\3\2"+
"\2\2\u00d5\u035d\3\2\2\2\u00d7\u035f\3\2\2\2\u00d9\u0361\3\2\2\2\u00db"+
"\u0372\3\2\2\2\u00dd\u0382\3\2\2\2\u00df\u0388\3\2\2\2\u00e1\u00e2\7*"+
"\2\2\u00e2\4\3\2\2\2\u00e3\u00e4\7+\2\2\u00e4\6\3\2\2\2\u00e5\u00e6\7"+
".\2\2\u00e6\b\3\2\2\2\u00e7\u00e8\7\60\2\2\u00e8\n\3\2\2\2\u00e9\u00ea"+
"\7$\2\2\u00ea\f\3\2\2\2\u00eb\u00ec\7U\2\2\u00ec\u00ed\7G\2\2\u00ed\u00ee"+
"\7N\2\2\u00ee\u00ef\7G\2\2\u00ef\u00f0\7E\2\2\u00f0\u00f1\7V\2\2\u00f1"+
"\16\3\2\2\2\u00f2\u00f3\7H\2\2\u00f3\u00f4\7T\2\2\u00f4\u00f5\7Q\2\2\u00f5"+
"\u00f6\7O\2\2\u00f6\20\3\2\2\2\u00f7\u00f8\7C\2\2\u00f8\u00f9\7U\2\2\u00f9"+
"\22\3\2\2\2\u00fa\u00fb\7C\2\2\u00fb\u00fc\7N\2\2\u00fc\u00fd\7N\2\2\u00fd"+
"\24\3\2\2\2\u00fe\u00ff\7Y\2\2\u00ff\u0100\7J\2\2\u0100\u0101\7G\2\2\u0101"+
"\u0102\7P\2\2\u0102\26\3\2\2\2\u0103\u0104\7V\2\2\u0104\u0105\7J\2\2\u0105"+
"\u0106\7G\2\2\u0106\u0107\7P\2\2\u0107\30\3\2\2\2\u0108\u0109\7C\2\2\u0109"+
"\u010a\7P\2\2\u010a\u010b\7[\2\2\u010b\32\3\2\2\2\u010c\u010d\7F\2\2\u010d"+
"\u010e\7K\2\2\u010e\u010f\7U\2\2\u010f\u0110\7V\2\2\u0110\u0111\7K\2\2"+
"\u0111\u0112\7P\2\2\u0112\u0113\7E\2\2\u0113\u0114\7V\2\2\u0114\34\3\2"+
"\2\2\u0115\u0116\7Y\2\2\u0116\u0117\7J\2\2\u0117\u0118\7G\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\u011d\u011e\7Q\2\2\u011e\u011f\7W\2\2\u011f\u0120\7R\2\2\u0120"+
" \3\2\2\2\u0121\u0122\7D\2\2\u0122\u0123\7[\2\2\u0123\"\3\2\2\2\u0124"+
"\u0125\7I\2\2\u0125\u0126\7T\2\2\u0126\u0127\7Q\2\2\u0127\u0128\7W\2\2"+
"\u0128\u0129\7R\2\2\u0129\u012a\7K\2\2\u012a\u012b\7P\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\u0130\u0131\7U\2\2\u0131&\3\2\2\2\u0132\u0133\7Q\2\2\u0133\u0134"+
"\7T\2\2\u0134\u0135\7F\2\2\u0135\u0136\7G\2\2\u0136\u0137\7T\2\2\u0137"+
"(\3\2\2\2\u0138\u0139\7J\2\2\u0139\u013a\7C\2\2\u013a\u013b\7X\2\2\u013b"+
"\u013c\7K\2\2\u013c\u013d\7P\2\2\u013d\u013e\7I\2\2\u013e*\3\2\2\2\u013f"+
"\u0140\7N\2\2\u0140\u0141\7K\2\2\u0141\u0142\7O\2\2\u0142\u0143\7K\2\2"+
"\u0143\u0144\7V\2\2\u0144,\3\2\2\2\u0145\u0146\7Q\2\2\u0146\u0147\7T\2"+
"\2\u0147.\3\2\2\2\u0148\u0149\7C\2\2\u0149\u014a\7P\2\2\u014a\u014b\7"+
"F\2\2\u014b\60\3\2\2\2\u014c\u014d\7K\2\2\u014d\u014e\7P\2\2\u014e\62"+
"\3\2\2\2\u014f\u0150\7P\2\2\u0150\u0151\7Q\2\2\u0151\u0152\7V\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"+
"\u0157\7G\2\2\u0157\u0158\7Z\2\2\u0158\u0159\7K\2\2\u0159\u015a\7U\2\2"+
"\u015a\u015b\7V\2\2\u015b\u015c\7U\2\2\u015c8\3\2\2\2\u015d\u015e\7D\2"+
"\2\u015e\u015f\7G\2\2\u015f\u0160\7V\2\2\u0160\u0161\7Y\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\u0166\u0167\7K\2\2\u0167\u0168\7M\2\2\u0168\u0169\7G\2\2\u0169"+
"<\3\2\2\2\u016a\u016b\7T\2\2\u016b\u016c\7N\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"+
"\u0172\7U\2\2\u0172@\3\2\2\2\u0173\u0174\7P\2\2\u0174\u0175\7W\2\2\u0175"+
"\u0176\7N\2\2\u0176\u0177\7N\2\2\u0177B\3\2\2\2\u0178\u0179\7V\2\2\u0179"+
"\u017a\7T\2\2\u017a\u017b\7W\2\2\u017b\u017c\7G\2\2\u017cD\3\2\2\2\u017d"+
"\u017e\7H\2\2\u017e\u017f\7C\2\2\u017f\u0180\7N\2\2\u0180\u0181\7U\2\2"+
"\u0181\u0182\7G\2\2\u0182F\3\2\2\2\u0183\u0184\7N\2\2\u0184\u0185\7C\2"+
"\2\u0185\u0186\7U\2\2\u0186\u0187\7V\2\2\u0187H\3\2\2\2\u0188\u0189\7"+
"C\2\2\u0189\u018a\7U\2\2\u018a\u018b\7E\2\2\u018bJ\3\2\2\2\u018c\u018d"+
"\7F\2\2\u018d\u018e\7G\2\2\u018e\u018f\7U\2\2\u018f\u0190\7E\2\2\u0190"+
"L\3\2\2\2\u0191\u0192\7H\2\2\u0192\u0193\7Q\2\2\u0193\u0194\7T\2\2\u0194"+
"N\3\2\2\2\u0195\u0196\7K\2\2\u0196\u0197\7P\2\2\u0197\u0198\7V\2\2\u0198"+
"\u0199\7G\2\2\u0199\u019a\7I\2\2\u019a\u019b\7G\2\2\u019b\u019c\7T\2\2"+
"\u019cP\3\2\2\2\u019d\u019e\7L\2\2\u019e\u019f\7Q\2\2\u019f\u01a0\7K\2"+
"\2\u01a0\u01a1\7P\2\2\u01a1R\3\2\2\2\u01a2\u01a3\7E\2\2\u01a3\u01a4\7"+
"T\2\2\u01a4\u01a5\7Q\2\2\u01a5\u01a6\7U\2\2\u01a6\u01a7\7U\2\2\u01a7T"+
"\3\2\2\2\u01a8\u01a9\7Q\2\2\u01a9\u01aa\7W\2\2\u01aa\u01ab\7V\2\2\u01ab"+
"\u01ac\7G\2\2\u01ac\u01ad\7T\2\2\u01adV\3\2\2\2\u01ae\u01af\7K\2\2\u01af"+
"\u01b0\7P\2\2\u01b0\u01b1\7P\2\2\u01b1\u01b2\7G\2\2\u01b2\u01b3\7T\2\2"+
"\u01b3X\3\2\2\2\u01b4\u01b5\7N\2\2\u01b5\u01b6\7G\2\2\u01b6\u01b7\7H\2"+
"\2\u01b7\u01b8\7V\2\2\u01b8Z\3\2\2\2\u01b9\u01ba\7T\2\2\u01ba\u01bb\7"+
"K\2\2\u01bb\u01bc\7I\2\2\u01bc\u01bd\7J\2\2\u01bd\u01be\7V\2\2\u01be\\"+
"\3\2\2\2\u01bf\u01c0\7H\2\2\u01c0\u01c1\7W\2\2\u01c1\u01c2\7N\2\2\u01c2"+
"\u01c3\7N\2\2\u01c3^\3\2\2\2\u01c4\u01c5\7P\2\2\u01c5\u01c6\7C\2\2\u01c6"+
"\u01c7\7V\2\2\u01c7\u01c8\7W\2\2\u01c8\u01c9\7T\2\2\u01c9\u01ca\7C\2\2"+
"\u01ca\u01cb\7N\2\2\u01cb`\3\2\2\2\u01cc\u01cd\7W\2\2\u01cd\u01ce\7U\2"+
"\2\u01ce\u01cf\7K\2\2\u01cf\u01d0\7P\2\2\u01d0\u01d1\7I\2\2\u01d1b\3\2"+
"\2\2\u01d2\u01d3\7Q\2\2\u01d3\u01d4\7P\2\2\u01d4d\3\2\2\2\u01d5\u01d6"+
"\7Y\2\2\u01d6\u01d7\7K\2\2\u01d7\u01d8\7V\2\2\u01d8\u01d9\7J\2\2\u01d9"+
"f\3\2\2\2\u01da\u01db\7V\2\2\u01db\u01dc\7C\2\2\u01dc\u01dd\7D\2\2\u01dd"+
"\u01de\7N\2\2\u01de\u01df\7G\2\2\u01dfh\3\2\2\2\u01e0\u01e1\7K\2\2\u01e1"+
"\u01e2\7P\2\2\u01e2\u01e3\7V\2\2\u01e3\u01e4\7Q\2\2\u01e4j\3\2\2\2\u01e5"+
"\u01e6\7F\2\2\u01e6\u01e7\7G\2\2\u01e7\u01e8\7U\2\2\u01e8\u01e9\7E\2\2"+
"\u01e9\u01ea\7T\2\2\u01ea\u01eb\7K\2\2\u01eb\u01ec\7D\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\u01f1\u01f2\7K\2\2\u01f2\u01f3\7Q\2\2\u01f3\u01f4\7P\2\2\u01f4"+
"n\3\2\2\2\u01f5\u01f6\7G\2\2\u01f6\u01f7\7Z\2\2\u01f7\u01f8\7R\2\2\u01f8"+
"\u01f9\7N\2\2\u01f9\u01fa\7C\2\2\u01fa\u01fb\7K\2\2\u01fb\u01fc\7P\2\2"+
"\u01fcp\3\2\2\2\u01fd\u01fe\7C\2\2\u01fe\u01ff\7P\2\2\u01ff\u0200\7C\2"+
"\2\u0200\u0201\7N\2\2\u0201\u0202\7[\2\2\u0202\u0203\7\\\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\u0208\u0209\7O\2\2\u0209\u020a\7C\2\2\u020a\u020b\7V\2\2\u020b"+
"t\3\2\2\2\u020c\u020d\7V\2\2\u020d\u020e\7[\2\2\u020e\u020f\7R\2\2\u020f"+
"\u0210\7G\2\2\u0210v\3\2\2\2\u0211\u0212\7V\2\2\u0212\u0213\7G\2\2\u0213"+
"\u0214\7Z\2\2\u0214\u0215\7V\2\2\u0215x\3\2\2\2\u0216\u0217\7X\2\2\u0217"+
"\u0218\7G\2\2\u0218\u0219\7T\2\2\u0219\u021a\7K\2\2\u021a\u021b\7H\2\2"+
"\u021b\u021c\7[\2\2\u021cz\3\2\2\2\u021d\u021e\7I\2\2\u021e\u021f\7T\2"+
"\2\u021f\u0220\7C\2\2\u0220\u0221\7R\2\2\u0221\u0222\7J\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\u0227\u0228\7Q\2\2\u0228\u0229\7I\2\2\u0229\u022a\7K\2\2\u022a"+
"\u022b\7E\2\2\u022b\u022c\7C\2\2\u022c\u022d\7N\2\2\u022d~\3\2\2\2\u022e"+
"\u022f\7R\2\2\u022f\u0230\7J\2\2\u0230\u0231\7[\2\2\u0231\u0232\7U\2\2"+
"\u0232\u0233\7K\2\2\u0233\u0234\7E\2\2\u0234\u0235\7C\2\2\u0235\u0236"+
"\7N\2\2\u0236\u0080\3\2\2\2\u0237\u0238\7U\2\2\u0238\u0239\7J\2\2\u0239"+
"\u023a\7Q\2\2\u023a\u023b\7Y\2\2\u023b\u0082\3\2\2\2\u023c\u023d\7V\2"+
"\2\u023d\u023e\7C\2\2\u023e\u023f\7D\2\2\u023f\u0240\7N\2\2\u0240\u0241"+
"\7G\2\2\u0241\u0242\7U\2\2\u0242\u0084\3\2\2\2\u0243\u0244\7E\2\2\u0244"+
"\u0245\7Q\2\2\u0245\u0246\7N\2\2\u0246\u0247\7W\2\2\u0247\u0248\7O\2\2"+
"\u0248\u0249\7P\2\2\u0249\u024a\7U\2\2\u024a\u0086\3\2\2\2\u024b\u024c"+
"\7E\2\2\u024c\u024d\7Q\2\2\u024d\u024e\7N\2\2\u024e\u024f\7W\2\2\u024f"+
"\u0250\7O\2\2\u0250\u0251\7P\2\2\u0251\u0088\3\2\2\2\u0252\u0253\7H\2"+
"\2\u0253\u0254\7W\2\2\u0254\u0255\7P\2\2\u0255\u0256\7E\2\2\u0256\u0257"+
"\7V\2\2\u0257\u0258\7K\2\2\u0258\u0259\7Q\2\2\u0259\u025a\7P\2\2\u025a"+
"\u025b\7U\2\2\u025b\u008a\3\2\2\2\u025c\u025d\7V\2\2\u025d\u025e\7Q\2"+
"\2\u025e\u008c\3\2\2\2\u025f\u0260\7F\2\2\u0260\u0261\7G\2\2\u0261\u0262"+
"\7D\2\2\u0262\u0263\7W\2\2\u0263\u0264\7I\2\2\u0264\u008e\3\2\2\2\u0265"+
"\u0266\7R\2\2\u0266\u0267\7N\2\2\u0267\u0268\7C\2\2\u0268\u0269\7P\2\2"+
"\u0269\u0090\3\2\2\2\u026a\u026b\7R\2\2\u026b\u026c\7C\2\2\u026c\u026d"+
"\7T\2\2\u026d\u026e\7U\2\2\u026e\u026f\7G\2\2\u026f\u0270\7F\2\2\u0270"+
"\u0092\3\2\2\2\u0271\u0272\7C\2\2\u0272\u0273\7P\2\2\u0273\u0274\7C\2"+
"\2\u0274\u0275\7N\2\2\u0275\u0276\7[\2\2\u0276\u0277\7\\\2\2\u0277\u0278"+
"\7G\2\2\u0278\u0279\7F\2\2\u0279\u0094\3\2\2\2\u027a\u027b\7Q\2\2\u027b"+
"\u027c\7R\2\2\u027c\u027d\7V\2\2\u027d\u027e\7K\2\2\u027e\u027f\7O\2\2"+
"\u027f\u0280\7K\2\2\u0280\u0281\7\\\2\2\u0281\u0282\7G\2\2\u0282\u0283"+
"\7F\2\2\u0283\u0096\3\2\2\2\u0284\u0285\7O\2\2\u0285\u0286\7C\2\2\u0286"+
"\u0287\7R\2\2\u0287\u0288\7R\2\2\u0288\u0289\7G\2\2\u0289\u028a\7F\2\2"+
"\u028a\u0098\3\2\2\2\u028b\u028c\7G\2\2\u028c\u028d\7Z\2\2\u028d\u028e"+
"\7G\2\2\u028e\u028f\7E\2\2\u028f\u0290\7W\2\2\u0290\u0291\7V\2\2\u0291"+
"\u0292\7C\2\2\u0292\u0293\7D\2\2\u0293\u0294\7N\2\2\u0294\u0295\7G\2\2"+
"\u0295\u009a\3\2\2\2\u0296\u0297\7W\2\2\u0297\u0298\7U\2\2\u0298\u0299"+
"\7G\2\2\u0299\u009c\3\2\2\2\u029a\u029b\7U\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"+
"\2\u02a0\u02a1\7U\2\2\u02a1\u02a2\7G\2\2\u02a2\u02a3\7V\2\2\u02a3\u00a0"+
"\3\2\2\2\u02a4\u02a5\7U\2\2\u02a5\u02a6\7G\2\2\u02a6\u02a7\7U\2\2\u02a7"+
"\u02a8\7U\2\2\u02a8\u02a9\7K\2\2\u02a9\u02aa\7Q\2\2\u02aa\u02ab\7P\2\2"+
"\u02ab\u00a2\3\2\2\2\u02ac\u02ad\7U\2\2\u02ad\u02ae\7E\2\2\u02ae\u02af"+
"\7J\2\2\u02af\u02b0\7G\2\2\u02b0\u02b1\7O\2\2\u02b1\u02b2\7C\2\2\u02b2"+
"\u02b3\7U\2\2\u02b3\u00a4\3\2\2\2\u02b4\u02b5\7G\2\2\u02b5\u02b6\7Z\2"+
"\2\u02b6\u02b7\7V\2\2\u02b7\u02b8\7T\2\2\u02b8\u02b9\7C\2\2\u02b9\u02ba"+
"\7E\2\2\u02ba\u02bb\7V\2\2\u02bb\u00a6\3\2\2\2\u02bc\u02bd\7S\2\2\u02bd"+
"\u02be\7W\2\2\u02be\u02bf\7G\2\2\u02bf\u02c0\7T\2\2\u02c0\u02c1\7[\2\2"+
"\u02c1\u00a8\3\2\2\2\u02c2\u02c3\7O\2\2\u02c3\u02c4\7C\2\2\u02c4\u02c5"+
"\7V\2\2\u02c5\u02c6\7E\2\2\u02c6\u02c7\7J\2\2\u02c7\u00aa\3\2\2\2\u02c8"+
"\u02c9\7E\2\2\u02c9\u02ca\7C\2\2\u02ca\u02cb\7U\2\2\u02cb\u02cc\7V\2\2"+
"\u02cc\u00ac\3\2\2\2\u02cd\u02ce\7?\2\2\u02ce\u00ae\3\2\2\2\u02cf\u02d0"+
"\7>\2\2\u02d0\u02d7\7@\2\2\u02d1\u02d2\7#\2\2\u02d2\u02d7\7?\2\2\u02d3"+
"\u02d4\7>\2\2\u02d4\u02d5\7?\2\2\u02d5\u02d7\7@\2\2\u02d6\u02cf\3\2\2"+
"\2\u02d6\u02d1\3\2\2\2\u02d6\u02d3\3\2\2\2\u02d7\u00b0\3\2\2\2\u02d8\u02d9"+
"\7>\2\2\u02d9\u00b2\3\2\2\2\u02da\u02db\7>\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"+
"\2\u02e0\u02e1\7?\2\2\u02e1\u00b8\3\2\2\2\u02e2\u02e3\7-\2\2\u02e3\u00ba"+
"\3\2\2\2\u02e4\u02e5\7/\2\2\u02e5\u00bc\3\2\2\2\u02e6\u02e7\7,\2\2\u02e7"+
"\u00be\3\2\2\2\u02e8\u02e9\7\61\2\2\u02e9\u00c0\3\2\2\2\u02ea\u02eb\7"+
"\'\2\2\u02eb\u00c2\3\2\2\2\u02ec\u02ed\7~\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"+
"\2\u02f2\u02f4\7)\2\2\u02f3\u02f0\3\2\2\2\u02f3\u02f1\3\2\2\2\u02f4\u02f7"+
"\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f5\u02f6\3\2\2\2\u02f6\u02f8\3\2\2\2\u02f7"+
"\u02f5\3\2\2\2\u02f8\u02f9\7)\2\2\u02f9\u00c6\3\2\2\2\u02fa\u02fc\5\u00d5"+
"k\2\u02fb\u02fa\3\2\2\2\u02fc\u02fd\3\2\2\2\u02fd\u02fb\3\2\2\2\u02fd"+
"\u02fe\3\2\2\2\u02fe\u00c8\3\2\2\2\u02ff\u0301\5\u00d5k\2\u0300\u02ff"+
"\3\2\2\2\u0301\u0302\3\2\2\2\u0302\u0300\3\2\2\2\u0302\u0303\3\2\2\2\u0303"+
"\u0304\3\2\2\2\u0304\u0308\7\60\2\2\u0305\u0307\5\u00d5k\2\u0306\u0305"+
"\3\2\2\2\u0307\u030a\3\2\2\2\u0308\u0306\3\2\2\2\u0308\u0309\3\2\2\2\u0309"+
"\u032a\3\2\2\2\u030a\u0308\3\2\2\2\u030b\u030d\7\60\2\2\u030c\u030e\5"+
"\u00d5k\2\u030d\u030c\3\2\2\2\u030e\u030f\3\2\2\2\u030f\u030d\3\2\2\2"+
"\u030f\u0310\3\2\2\2\u0310\u032a\3\2\2\2\u0311\u0313\5\u00d5k\2\u0312"+
"\u0311\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0312\3\2\2\2\u0314\u0315\3\2"+
"\2\2\u0315\u031d\3\2\2\2\u0316\u031a\7\60\2\2\u0317\u0319\5\u00d5k\2\u0318"+
"\u0317\3\2\2\2\u0319\u031c\3\2\2\2\u031a\u0318\3\2\2\2\u031a\u031b\3\2"+
"\2\2\u031b\u031e\3\2\2\2\u031c\u031a\3\2\2\2\u031d\u0316\3\2\2\2\u031d"+
"\u031e\3\2\2\2\u031e\u031f\3\2\2\2\u031f\u0320\5\u00d3j\2\u0320\u032a"+
"\3\2\2\2\u0321\u0323\7\60\2\2\u0322\u0324\5\u00d5k\2\u0323\u0322\3\2\2"+
"\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\u0327\u0328\5\u00d3j\2\u0328\u032a\3\2\2\2\u0329\u0300\3\2\2"+
"\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\u032b\u032e\5\u00d7l\2\u032c\u032e\7a\2\2\u032d\u032b\3\2\2\2"+
"\u032d\u032c\3\2\2\2\u032e\u0334\3\2\2\2\u032f\u0333\5\u00d7l\2\u0330"+
"\u0333\5\u00d5k\2\u0331\u0333\t\3\2\2\u0332\u032f\3\2\2\2\u0332\u0330"+
"\3\2\2\2\u0332\u0331\3\2\2\2\u0333\u0336\3\2\2\2\u0334\u0332\3\2\2\2\u0334"+
"\u0335\3\2\2\2\u0335\u00cc\3\2\2\2\u0336\u0334\3\2\2\2\u0337\u033b\5\u00d5"+
"k\2\u0338\u033c\5\u00d7l\2\u0339\u033c\5\u00d5k\2\u033a\u033c\t\3\2\2"+
"\u033b\u0338\3\2\2\2\u033b\u0339\3\2\2\2\u033b\u033a\3\2\2\2\u033c\u033d"+
"\3\2\2\2\u033d\u033b\3\2\2\2\u033d\u033e\3\2\2\2\u033e\u00ce\3\2\2\2\u033f"+
"\u0344\7$\2\2\u0340\u0343\n\4\2\2\u0341\u0343\7$\2\2\u0342\u0340\3\2\2"+
"\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\u0345\u0347\3\2\2\2\u0346\u0344\3\2\2\2\u0347\u0348\7$\2\2\u0348"+
"\u00d0\3\2\2\2\u0349\u034f\7b\2\2\u034a\u034e\n\5\2\2\u034b\u034c\7b\2"+
"\2\u034c\u034e\7b\2\2\u034d\u034a\3\2\2\2\u034d\u034b\3\2\2\2\u034e\u0351"+
"\3\2\2\2\u034f\u034d\3\2\2\2\u034f\u0350\3\2\2\2\u0350\u0352\3\2\2\2\u0351"+
"\u034f\3\2\2\2\u0352\u0353\7b\2\2\u0353\u00d2\3\2\2\2\u0354\u0356\7G\2"+
"\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\u0358\u035a\5\u00d5k\2\u0359\u0358\3\2\2\2\u035a\u035b\3\2\2"+
"\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\u035e\u00d6\3\2\2\2\u035f\u0360\t\b\2\2\u0360\u00d8\3\2\2\2\u0361"+
"\u0362\7/\2\2\u0362\u0363\7/\2\2\u0363\u0367\3\2\2\2\u0364\u0366\n\t\2"+
"\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\u0368\u036b\3\2\2\2\u0369\u0367\3\2\2\2\u036a\u036c\7\17\2\2"+
"\u036b\u036a\3\2\2\2\u036b\u036c\3\2\2\2\u036c\u036e\3\2\2\2\u036d\u036f"+
"\7\f\2\2\u036e\u036d\3\2\2\2\u036e\u036f\3\2\2\2\u036f\u0370\3\2\2\2\u0370"+
"\u0371\bm\2\2\u0371\u00da\3\2\2\2\u0372\u0373\7\61\2\2\u0373\u0374\7,"+
"\2\2\u0374\u0379\3\2\2\2\u0375\u0378\5\u00dbn\2\u0376\u0378\13\2\2\2\u0377"+
"\u0375\3\2\2\2\u0377\u0376\3\2\2\2\u0378\u037b\3\2\2\2\u0379\u037a\3\2"+
"\2\2\u0379\u0377\3\2\2\2\u037a\u037c\3\2\2\2\u037b\u0379\3\2\2\2\u037c"+
"\u037d\7,\2\2\u037d\u037e\7\61\2\2\u037e\u037f\3\2\2\2\u037f\u0380\bn"+
"\2\2\u0380\u00dc\3\2\2\2\u0381\u0383\t\n\2\2\u0382\u0381\3\2\2\2\u0383"+
"\u0384\3\2\2\2\u0384\u0382\3\2\2\2\u0384\u0385\3\2\2\2\u0385\u0386\3\2"+
"\2\2\u0386\u0387\bo\2\2\u0387\u00de\3\2\2\2\u0388\u0389\13\2\2\2\u0389"+
"\u00e0\3\2\2\2 \2\u02d6\u02f3\u02f5\u02fd\u0302\u0308\u030f\u0314\u031a"+
"\u031d\u0325\u0329\u032d\u0332\u0334\u033b\u033d\u0342\u0344\u034d\u034f"+
"\u0356\u035b\u0367\u036b\u036e\u0377\u0379\u0384\3\2\3\2";
"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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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"+
"\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\60\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3"+
"\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"+
"\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"+
"\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"+
"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@\3A\3A\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3B\3"+
"B\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3F\3F\3"+
"F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3"+
"I\3I\3J\3J\3J\3J\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3"+
"L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3P\3P\3"+
"P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3S\3"+
"S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3W\3W\3W\3W\3W\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`\3a\3a\3a\3b\3b\3b\3b\7b\u02f0\nb\fb\16b\u02f3\13b\3b\3b\3c\6"+
"c\u02f8\nc\rc\16c\u02f9\3d\6d\u02fd\nd\rd\16d\u02fe\3d\3d\7d\u0303\nd"+
"\fd\16d\u0306\13d\3d\3d\6d\u030a\nd\rd\16d\u030b\3d\6d\u030f\nd\rd\16"+
"d\u0310\3d\3d\7d\u0315\nd\fd\16d\u0318\13d\5d\u031a\nd\3d\3d\3d\3d\6d"+
"\u0320\nd\rd\16d\u0321\3d\3d\5d\u0326\nd\3e\3e\5e\u032a\ne\3e\3e\3e\7"+
"e\u032f\ne\fe\16e\u0332\13e\3f\3f\3f\3f\6f\u0338\nf\rf\16f\u0339\3g\3"+
"g\3g\7g\u033f\ng\fg\16g\u0342\13g\3g\3g\3h\3h\3h\3h\7h\u034a\nh\fh\16"+
"h\u034d\13h\3h\3h\3i\3i\5i\u0353\ni\3i\6i\u0356\ni\ri\16i\u0357\3j\3j"+
"\3k\3k\3l\3l\3l\3l\7l\u0362\nl\fl\16l\u0365\13l\3l\5l\u0368\nl\3l\5l\u036b"+
"\nl\3l\3l\3m\3m\3m\3m\3m\7m\u0374\nm\fm\16m\u0377\13m\3m\3m\3m\3m\3m\3"+
"n\6n\u037f\nn\rn\16n\u0380\3n\3n\3o\3o\3\u0375\2p\3\3\5\4\7\5\t\6\13\7"+
"\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25"+
")\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O"+
")Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081"+
"B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095"+
"L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9"+
"V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd"+
"`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1"+
"\2\u00d3\2\u00d5\2\u00d7j\u00d9k\u00dbl\u00ddm\3\2\13\3\2))\5\2<<BBaa"+
"\6\2$$))\60\60~~\6\2))\60\60bb~~\4\2--//\3\2\62;\3\2C\\\4\2\f\f\17\17"+
"\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\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2"+
"\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3"+
"\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2"+
"\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67"+
"\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2"+
"\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2"+
"\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]"+
"\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2"+
"\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2"+
"\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2"+
"\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2"+
"\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093"+
"\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2"+
"\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5"+
"\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\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\3\2\2\2\2\u00b7"+
"\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\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\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\2\2\u00d7\3\2\2"+
"\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\7\u00e3\3\2\2\2\t\u00e5\3\2\2\2\13\u00e7\3\2\2\2\r\u00ee\3\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"+
"\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"+
"\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)\u013b\3\2\2\2+\u0141\3\2\2\2-\u0144\3\2\2\2/\u0148\3\2\2\2\61"+
"\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;\u0166\3\2\2\2=\u016c\3\2\2\2?\u016f\3\2\2\2A\u0174\3\2\2\2C"+
"\u0179\3\2\2\2E\u017f\3\2\2\2G\u0184\3\2\2\2I\u0188\3\2\2\2K\u018d\3\2"+
"\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\2W\u01b0\3\2\2\2Y\u01b5\3\2\2\2[\u01bb\3\2\2\2]\u01c0\3\2\2\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\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\2s\u0208\3\2\2\2u\u020d\3\2\2\2w\u0212\3\2\2\2y\u0219\3\2\2\2{"+
"\u0222\3\2\2\2}\u022a\3\2\2\2\177\u0233\3\2\2\2\u0081\u0238\3\2\2\2\u0083"+
"\u023f\3\2\2\2\u0085\u0247\3\2\2\2\u0087\u024e\3\2\2\2\u0089\u0258\3\2"+
"\2\2\u008b\u025b\3\2\2\2\u008d\u0261\3\2\2\2\u008f\u0266\3\2\2\2\u0091"+
"\u026d\3\2\2\2\u0093\u0276\3\2\2\2\u0095\u0280\3\2\2\2\u0097\u0287\3\2"+
"\2\2\u0099\u0292\3\2\2\2\u009b\u0296\3\2\2\2\u009d\u029a\3\2\2\2\u009f"+
"\u02a0\3\2\2\2\u00a1\u02a8\3\2\2\2\u00a3\u02b0\3\2\2\2\u00a5\u02b8\3\2"+
"\2\2\u00a7\u02be\3\2\2\2\u00a9\u02c4\3\2\2\2\u00ab\u02c9\3\2\2\2\u00ad"+
"\u02d2\3\2\2\2\u00af\u02d4\3\2\2\2\u00b1\u02d6\3\2\2\2\u00b3\u02d9\3\2"+
"\2\2\u00b5\u02db\3\2\2\2\u00b7\u02de\3\2\2\2\u00b9\u02e0\3\2\2\2\u00bb"+
"\u02e2\3\2\2\2\u00bd\u02e4\3\2\2\2\u00bf\u02e6\3\2\2\2\u00c1\u02e8\3\2"+
"\2\2\u00c3\u02eb\3\2\2\2\u00c5\u02f7\3\2\2\2\u00c7\u0325\3\2\2\2\u00c9"+
"\u0329\3\2\2\2\u00cb\u0333\3\2\2\2\u00cd\u033b\3\2\2\2\u00cf\u0345\3\2"+
"\2\2\u00d1\u0350\3\2\2\2\u00d3\u0359\3\2\2\2\u00d5\u035b\3\2\2\2\u00d7"+
"\u035d\3\2\2\2\u00d9\u036e\3\2\2\2\u00db\u037e\3\2\2\2\u00dd\u0384\3\2"+
"\2\2\u00df\u00e0\7*\2\2\u00e0\4\3\2\2\2\u00e1\u00e2\7+\2\2\u00e2\6\3\2"+
"\2\2\u00e3\u00e4\7.\2\2\u00e4\b\3\2\2\2\u00e5\u00e6\7\60\2\2\u00e6\n\3"+
"\2\2\2\u00e7\u00e8\7U\2\2\u00e8\u00e9\7G\2\2\u00e9\u00ea\7N\2\2\u00ea"+
"\u00eb\7G\2\2\u00eb\u00ec\7E\2\2\u00ec\u00ed\7V\2\2\u00ed\f\3\2\2\2\u00ee"+
"\u00ef\7H\2\2\u00ef\u00f0\7T\2\2\u00f0\u00f1\7Q\2\2\u00f1\u00f2\7O\2\2"+
"\u00f2\16\3\2\2\2\u00f3\u00f4\7C\2\2\u00f4\u00f5\7U\2\2\u00f5\20\3\2\2"+
"\2\u00f6\u00f7\7C\2\2\u00f7\u00f8\7N\2\2\u00f8\u00f9\7N\2\2\u00f9\22\3"+
"\2\2\2\u00fa\u00fb\7Y\2\2\u00fb\u00fc\7J\2\2\u00fc\u00fd\7G\2\2\u00fd"+
"\u00fe\7P\2\2\u00fe\24\3\2\2\2\u00ff\u0100\7V\2\2\u0100\u0101\7J\2\2\u0101"+
"\u0102\7G\2\2\u0102\u0103\7P\2\2\u0103\26\3\2\2\2\u0104\u0105\7C\2\2\u0105"+
"\u0106\7P\2\2\u0106\u0107\7[\2\2\u0107\30\3\2\2\2\u0108\u0109\7F\2\2\u0109"+
"\u010a\7K\2\2\u010a\u010b\7U\2\2\u010b\u010c\7V\2\2\u010c\u010d\7K\2\2"+
"\u010d\u010e\7P\2\2\u010e\u010f\7E\2\2\u010f\u0110\7V\2\2\u0110\32\3\2"+
"\2\2\u0111\u0112\7Y\2\2\u0112\u0113\7J\2\2\u0113\u0114\7G\2\2\u0114\u0115"+
"\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\7Q\2\2\u011a\u011b\7W\2\2\u011b\u011c\7R\2\2\u011c"+
"\36\3\2\2\2\u011d\u011e\7D\2\2\u011e\u011f\7[\2\2\u011f \3\2\2\2\u0120"+
"\u0121\7I\2\2\u0121\u0122\7T\2\2\u0122\u0123\7Q\2\2\u0123\u0124\7W\2\2"+
"\u0124\u0125\7R\2\2\u0125\u0126\7K\2\2\u0126\u0127\7P\2\2\u0127\u0128"+
"\7I\2\2\u0128\"\3\2\2\2\u0129\u012a\7U\2\2\u012a\u012b\7G\2\2\u012b\u012c"+
"\7V\2\2\u012c\u012d\7U\2\2\u012d$\3\2\2\2\u012e\u012f\7Q\2\2\u012f\u0130"+
"\7T\2\2\u0130\u0131\7F\2\2\u0131\u0132\7G\2\2\u0132\u0133\7T\2\2\u0133"+
"&\3\2\2\2\u0134\u0135\7J\2\2\u0135\u0136\7C\2\2\u0136\u0137\7X\2\2\u0137"+
"\u0138\7K\2\2\u0138\u0139\7P\2\2\u0139\u013a\7I\2\2\u013a(\3\2\2\2\u013b"+
"\u013c\7N\2\2\u013c\u013d\7K\2\2\u013d\u013e\7O\2\2\u013e\u013f\7K\2\2"+
"\u013f\u0140\7V\2\2\u0140*\3\2\2\2\u0141\u0142\7Q\2\2\u0142\u0143\7T\2"+
"\2\u0143,\3\2\2\2\u0144\u0145\7C\2\2\u0145\u0146\7P\2\2\u0146\u0147\7"+
"F\2\2\u0147.\3\2\2\2\u0148\u0149\7K\2\2\u0149\u014a\7P\2\2\u014a\60\3"+
"\2\2\2\u014b\u014c\7P\2\2\u014c\u014d\7Q\2\2\u014d\u014e\7V\2\2\u014e"+
"\62\3\2\2\2\u014f\u0150\7P\2\2\u0150\u0151\7Q\2\2\u0151\64\3\2\2\2\u0152"+
"\u0153\7G\2\2\u0153\u0154\7Z\2\2\u0154\u0155\7K\2\2\u0155\u0156\7U\2\2"+
"\u0156\u0157\7V\2\2\u0157\u0158\7U\2\2\u0158\66\3\2\2\2\u0159\u015a\7"+
"D\2\2\u015a\u015b\7G\2\2\u015b\u015c\7V\2\2\u015c\u015d\7Y\2\2\u015d\u015e"+
"\7G\2\2\u015e\u015f\7G\2\2\u015f\u0160\7P\2\2\u01608\3\2\2\2\u0161\u0162"+
"\7N\2\2\u0162\u0163\7K\2\2\u0163\u0164\7M\2\2\u0164\u0165\7G\2\2\u0165"+
":\3\2\2\2\u0166\u0167\7T\2\2\u0167\u0168\7N\2\2\u0168\u0169\7K\2\2\u0169"+
"\u016a\7M\2\2\u016a\u016b\7G\2\2\u016b<\3\2\2\2\u016c\u016d\7K\2\2\u016d"+
"\u016e\7U\2\2\u016e>\3\2\2\2\u016f\u0170\7P\2\2\u0170\u0171\7W\2\2\u0171"+
"\u0172\7N\2\2\u0172\u0173\7N\2\2\u0173@\3\2\2\2\u0174\u0175\7V\2\2\u0175"+
"\u0176\7T\2\2\u0176\u0177\7W\2\2\u0177\u0178\7G\2\2\u0178B\3\2\2\2\u0179"+
"\u017a\7H\2\2\u017a\u017b\7C\2\2\u017b\u017c\7N\2\2\u017c\u017d\7U\2\2"+
"\u017d\u017e\7G\2\2\u017eD\3\2\2\2\u017f\u0180\7N\2\2\u0180\u0181\7C\2"+
"\2\u0181\u0182\7U\2\2\u0182\u0183\7V\2\2\u0183F\3\2\2\2\u0184\u0185\7"+
"C\2\2\u0185\u0186\7U\2\2\u0186\u0187\7E\2\2\u0187H\3\2\2\2\u0188\u0189"+
"\7F\2\2\u0189\u018a\7G\2\2\u018a\u018b\7U\2\2\u018b\u018c\7E\2\2\u018c"+
"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\7K\2\2\u0192\u0193\7P\2\2\u0193\u0194\7V\2\2\u0194"+
"\u0195\7G\2\2\u0195\u0196\7I\2\2\u0196\u0197\7G\2\2\u0197\u0198\7T\2\2"+
"\u0198N\3\2\2\2\u0199\u019a\7L\2\2\u019a\u019b\7Q\2\2\u019b\u019c\7K\2"+
"\2\u019c\u019d\7P\2\2\u019dP\3\2\2\2\u019e\u019f\7E\2\2\u019f\u01a0\7"+
"T\2\2\u01a0\u01a1\7Q\2\2\u01a1\u01a2\7U\2\2\u01a2\u01a3\7U\2\2\u01a3R"+
"\3\2\2\2\u01a4\u01a5\7Q\2\2\u01a5\u01a6\7W\2\2\u01a6\u01a7\7V\2\2\u01a7"+
"\u01a8\7G\2\2\u01a8\u01a9\7T\2\2\u01a9T\3\2\2\2\u01aa\u01ab\7K\2\2\u01ab"+
"\u01ac\7P\2\2\u01ac\u01ad\7P\2\2\u01ad\u01ae\7G\2\2\u01ae\u01af\7T\2\2"+
"\u01afV\3\2\2\2\u01b0\u01b1\7N\2\2\u01b1\u01b2\7G\2\2\u01b2\u01b3\7H\2"+
"\2\u01b3\u01b4\7V\2\2\u01b4X\3\2\2\2\u01b5\u01b6\7T\2\2\u01b6\u01b7\7"+
"K\2\2\u01b7\u01b8\7I\2\2\u01b8\u01b9\7J\2\2\u01b9\u01ba\7V\2\2\u01baZ"+
"\3\2\2\2\u01bb\u01bc\7H\2\2\u01bc\u01bd\7W\2\2\u01bd\u01be\7N\2\2\u01be"+
"\u01bf\7N\2\2\u01bf\\\3\2\2\2\u01c0\u01c1\7P\2\2\u01c1\u01c2\7C\2\2\u01c2"+
"\u01c3\7V\2\2\u01c3\u01c4\7W\2\2\u01c4\u01c5\7T\2\2\u01c5\u01c6\7C\2\2"+
"\u01c6\u01c7\7N\2\2\u01c7^\3\2\2\2\u01c8\u01c9\7W\2\2\u01c9\u01ca\7U\2"+
"\2\u01ca\u01cb\7K\2\2\u01cb\u01cc\7P\2\2\u01cc\u01cd\7I\2\2\u01cd`\3\2"+
"\2\2\u01ce\u01cf\7Q\2\2\u01cf\u01d0\7P\2\2\u01d0b\3\2\2\2\u01d1\u01d2"+
"\7Y\2\2\u01d2\u01d3\7K\2\2\u01d3\u01d4\7V\2\2\u01d4\u01d5\7J\2\2\u01d5"+
"d\3\2\2\2\u01d6\u01d7\7V\2\2\u01d7\u01d8\7C\2\2\u01d8\u01d9\7D\2\2\u01d9"+
"\u01da\7N\2\2\u01da\u01db\7G\2\2\u01dbf\3\2\2\2\u01dc\u01dd\7K\2\2\u01dd"+
"\u01de\7P\2\2\u01de\u01df\7V\2\2\u01df\u01e0\7Q\2\2\u01e0h\3\2\2\2\u01e1"+
"\u01e2\7F\2\2\u01e2\u01e3\7G\2\2\u01e3\u01e4\7U\2\2\u01e4\u01e5\7E\2\2"+
"\u01e5\u01e6\7T\2\2\u01e6\u01e7\7K\2\2\u01e7\u01e8\7D\2\2\u01e8\u01e9"+
"\7G\2\2\u01e9j\3\2\2\2\u01ea\u01eb\7Q\2\2\u01eb\u01ec\7R\2\2\u01ec\u01ed"+
"\7V\2\2\u01ed\u01ee\7K\2\2\u01ee\u01ef\7Q\2\2\u01ef\u01f0\7P\2\2\u01f0"+
"l\3\2\2\2\u01f1\u01f2\7G\2\2\u01f2\u01f3\7Z\2\2\u01f3\u01f4\7R\2\2\u01f4"+
"\u01f5\7N\2\2\u01f5\u01f6\7C\2\2\u01f6\u01f7\7K\2\2\u01f7\u01f8\7P\2\2"+
"\u01f8n\3\2\2\2\u01f9\u01fa\7C\2\2\u01fa\u01fb\7P\2\2\u01fb\u01fc\7C\2"+
"\2\u01fc\u01fd\7N\2\2\u01fd\u01fe\7[\2\2\u01fe\u01ff\7\\\2\2\u01ff\u0200"+
"\7G\2\2\u0200p\3\2\2\2\u0201\u0202\7H\2\2\u0202\u0203\7Q\2\2\u0203\u0204"+
"\7T\2\2\u0204\u0205\7O\2\2\u0205\u0206\7C\2\2\u0206\u0207\7V\2\2\u0207"+
"r\3\2\2\2\u0208\u0209\7V\2\2\u0209\u020a\7[\2\2\u020a\u020b\7R\2\2\u020b"+
"\u020c\7G\2\2\u020ct\3\2\2\2\u020d\u020e\7V\2\2\u020e\u020f\7G\2\2\u020f"+
"\u0210\7Z\2\2\u0210\u0211\7V\2\2\u0211v\3\2\2\2\u0212\u0213\7X\2\2\u0213"+
"\u0214\7G\2\2\u0214\u0215\7T\2\2\u0215\u0216\7K\2\2\u0216\u0217\7H\2\2"+
"\u0217\u0218\7[\2\2\u0218x\3\2\2\2\u0219\u021a\7I\2\2\u021a\u021b\7T\2"+
"\2\u021b\u021c\7C\2\2\u021c\u021d\7R\2\2\u021d\u021e\7J\2\2\u021e\u021f"+
"\7X\2\2\u021f\u0220\7K\2\2\u0220\u0221\7\\\2\2\u0221z\3\2\2\2\u0222\u0223"+
"\7N\2\2\u0223\u0224\7Q\2\2\u0224\u0225\7I\2\2\u0225\u0226\7K\2\2\u0226"+
"\u0227\7E\2\2\u0227\u0228\7C\2\2\u0228\u0229\7N\2\2\u0229|\3\2\2\2\u022a"+
"\u022b\7R\2\2\u022b\u022c\7J\2\2\u022c\u022d\7[\2\2\u022d\u022e\7U\2\2"+
"\u022e\u022f\7K\2\2\u022f\u0230\7E\2\2\u0230\u0231\7C\2\2\u0231\u0232"+
"\7N\2\2\u0232~\3\2\2\2\u0233\u0234\7U\2\2\u0234\u0235\7J\2\2\u0235\u0236"+
"\7Q\2\2\u0236\u0237\7Y\2\2\u0237\u0080\3\2\2\2\u0238\u0239\7V\2\2\u0239"+
"\u023a\7C\2\2\u023a\u023b\7D\2\2\u023b\u023c\7N\2\2\u023c\u023d\7G\2\2"+
"\u023d\u023e\7U\2\2\u023e\u0082\3\2\2\2\u023f\u0240\7E\2\2\u0240\u0241"+
"\7Q\2\2\u0241\u0242\7N\2\2\u0242\u0243\7W\2\2\u0243\u0244\7O\2\2\u0244"+
"\u0245\7P\2\2\u0245\u0246\7U\2\2\u0246\u0084\3\2\2\2\u0247\u0248\7E\2"+
"\2\u0248\u0249\7Q\2\2\u0249\u024a\7N\2\2\u024a\u024b\7W\2\2\u024b\u024c"+
"\7O\2\2\u024c\u024d\7P\2\2\u024d\u0086\3\2\2\2\u024e\u024f\7H\2\2\u024f"+
"\u0250\7W\2\2\u0250\u0251\7P\2\2\u0251\u0252\7E\2\2\u0252\u0253\7V\2\2"+
"\u0253\u0254\7K\2\2\u0254\u0255\7Q\2\2\u0255\u0256\7P\2\2\u0256\u0257"+
"\7U\2\2\u0257\u0088\3\2\2\2\u0258\u0259\7V\2\2\u0259\u025a\7Q\2\2\u025a"+
"\u008a\3\2\2\2\u025b\u025c\7F\2\2\u025c\u025d\7G\2\2\u025d\u025e\7D\2"+
"\2\u025e\u025f\7W\2\2\u025f\u0260\7I\2\2\u0260\u008c\3\2\2\2\u0261\u0262"+
"\7R\2\2\u0262\u0263\7N\2\2\u0263\u0264\7C\2\2\u0264\u0265\7P\2\2\u0265"+
"\u008e\3\2\2\2\u0266\u0267\7R\2\2\u0267\u0268\7C\2\2\u0268\u0269\7T\2"+
"\2\u0269\u026a\7U\2\2\u026a\u026b\7G\2\2\u026b\u026c\7F\2\2\u026c\u0090"+
"\3\2\2\2\u026d\u026e\7C\2\2\u026e\u026f\7P\2\2\u026f\u0270\7C\2\2\u0270"+
"\u0271\7N\2\2\u0271\u0272\7[\2\2\u0272\u0273\7\\\2\2\u0273\u0274\7G\2"+
"\2\u0274\u0275\7F\2\2\u0275\u0092\3\2\2\2\u0276\u0277\7Q\2\2\u0277\u0278"+
"\7R\2\2\u0278\u0279\7V\2\2\u0279\u027a\7K\2\2\u027a\u027b\7O\2\2\u027b"+
"\u027c\7K\2\2\u027c\u027d\7\\\2\2\u027d\u027e\7G\2\2\u027e\u027f\7F\2"+
"\2\u027f\u0094\3\2\2\2\u0280\u0281\7O\2\2\u0281\u0282\7C\2\2\u0282\u0283"+
"\7R\2\2\u0283\u0284\7R\2\2\u0284\u0285\7G\2\2\u0285\u0286\7F\2\2\u0286"+
"\u0096\3\2\2\2\u0287\u0288\7G\2\2\u0288\u0289\7Z\2\2\u0289\u028a\7G\2"+
"\2\u028a\u028b\7E\2\2\u028b\u028c\7W\2\2\u028c\u028d\7V\2\2\u028d\u028e"+
"\7C\2\2\u028e\u028f\7D\2\2\u028f\u0290\7N\2\2\u0290\u0291\7G\2\2\u0291"+
"\u0098\3\2\2\2\u0292\u0293\7W\2\2\u0293\u0294\7U\2\2\u0294\u0295\7G\2"+
"\2\u0295\u009a\3\2\2\2\u0296\u0297\7U\2\2\u0297\u0298\7G\2\2\u0298\u0299"+
"\7V\2\2\u0299\u009c\3\2\2\2\u029a\u029b\7T\2\2\u029b\u029c\7G\2\2\u029c"+
"\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\7U\2\2\u02a3\u02a4"+
"\7U\2\2\u02a4\u02a5\7K\2\2\u02a5\u02a6\7Q\2\2\u02a6\u02a7\7P\2\2\u02a7"+
"\u00a0\3\2\2\2\u02a8\u02a9\7U\2\2\u02a9\u02aa\7E\2\2\u02aa\u02ab\7J\2"+
"\2\u02ab\u02ac\7G\2\2\u02ac\u02ad\7O\2\2\u02ad\u02ae\7C\2\2\u02ae\u02af"+
"\7U\2\2\u02af\u00a2\3\2\2\2\u02b0\u02b1\7G\2\2\u02b1\u02b2\7Z\2\2\u02b2"+
"\u02b3\7V\2\2\u02b3\u02b4\7T\2\2\u02b4\u02b5\7C\2\2\u02b5\u02b6\7E\2\2"+
"\u02b6\u02b7\7V\2\2\u02b7\u00a4\3\2\2\2\u02b8\u02b9\7S\2\2\u02b9\u02ba"+
"\7W\2\2\u02ba\u02bb\7G\2\2\u02bb\u02bc\7T\2\2\u02bc\u02bd\7[\2\2\u02bd"+
"\u00a6\3\2\2\2\u02be\u02bf\7O\2\2\u02bf\u02c0\7C\2\2\u02c0\u02c1\7V\2"+
"\2\u02c1\u02c2\7E\2\2\u02c2\u02c3\7J\2\2\u02c3\u00a8\3\2\2\2\u02c4\u02c5"+
"\7E\2\2\u02c5\u02c6\7C\2\2\u02c6\u02c7\7U\2\2\u02c7\u02c8\7V\2\2\u02c8"+
"\u00aa\3\2\2\2\u02c9\u02ca\7?\2\2\u02ca\u00ac\3\2\2\2\u02cb\u02cc\7>\2"+
"\2\u02cc\u02d3\7@\2\2\u02cd\u02ce\7#\2\2\u02ce\u02d3\7?\2\2\u02cf\u02d0"+
"\7>\2\2\u02d0\u02d1\7?\2\2\u02d1\u02d3\7@\2\2\u02d2\u02cb\3\2\2\2\u02d2"+
"\u02cd\3\2\2\2\u02d2\u02cf\3\2\2\2\u02d3\u00ae\3\2\2\2\u02d4\u02d5\7>"+
"\2\2\u02d5\u00b0\3\2\2\2\u02d6\u02d7\7>\2\2\u02d7\u02d8\7?\2\2\u02d8\u00b2"+
"\3\2\2\2\u02d9\u02da\7@\2\2\u02da\u00b4\3\2\2\2\u02db\u02dc\7@\2\2\u02dc"+
"\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\u00ba\3\2\2\2\u02e2\u02e3\7,\2\2\u02e3\u00bc"+
"\3\2\2\2\u02e4\u02e5\7\61\2\2\u02e5\u00be\3\2\2\2\u02e6\u02e7\7\'\2\2"+
"\u02e7\u00c0\3\2\2\2\u02e8\u02e9\7~\2\2\u02e9\u02ea\7~\2\2\u02ea\u00c2"+
"\3\2\2\2\u02eb\u02f1\7)\2\2\u02ec\u02f0\n\2\2\2\u02ed\u02ee\7)\2\2\u02ee"+
"\u02f0\7)\2\2\u02ef\u02ec\3\2\2\2\u02ef\u02ed\3\2\2\2\u02f0\u02f3\3\2"+
"\2\2\u02f1\u02ef\3\2\2\2\u02f1\u02f2\3\2\2\2\u02f2\u02f4\3\2\2\2\u02f3"+
"\u02f1\3\2\2\2\u02f4\u02f5\7)\2\2\u02f5\u00c4\3\2\2\2\u02f6\u02f8\5\u00d3"+
"j\2\u02f7\u02f6\3\2\2\2\u02f8\u02f9\3\2\2\2\u02f9\u02f7\3\2\2\2\u02f9"+
"\u02fa\3\2\2\2\u02fa\u00c6\3\2\2\2\u02fb\u02fd\5\u00d3j\2\u02fc\u02fb"+
"\3\2\2\2\u02fd\u02fe\3\2\2\2\u02fe\u02fc\3\2\2\2\u02fe\u02ff\3\2\2\2\u02ff"+
"\u0300\3\2\2\2\u0300\u0304\7\60\2\2\u0301\u0303\5\u00d3j\2\u0302\u0301"+
"\3\2\2\2\u0303\u0306\3\2\2\2\u0304\u0302\3\2\2\2\u0304\u0305\3\2\2\2\u0305"+
"\u0326\3\2\2\2\u0306\u0304\3\2\2\2\u0307\u0309\7\60\2\2\u0308\u030a\5"+
"\u00d3j\2\u0309\u0308\3\2\2\2\u030a\u030b\3\2\2\2\u030b\u0309\3\2\2\2"+
"\u030b\u030c\3\2\2\2\u030c\u0326\3\2\2\2\u030d\u030f\5\u00d3j\2\u030e"+
"\u030d\3\2\2\2\u030f\u0310\3\2\2\2\u0310\u030e\3\2\2\2\u0310\u0311\3\2"+
"\2\2\u0311\u0319\3\2\2\2\u0312\u0316\7\60\2\2\u0313\u0315\5\u00d3j\2\u0314"+
"\u0313\3\2\2\2\u0315\u0318\3\2\2\2\u0316\u0314\3\2\2\2\u0316\u0317\3\2"+
"\2\2\u0317\u031a\3\2\2\2\u0318\u0316\3\2\2\2\u0319\u0312\3\2\2\2\u0319"+
"\u031a\3\2\2\2\u031a\u031b\3\2\2\2\u031b\u031c\5\u00d1i\2\u031c\u0326"+
"\3\2\2\2\u031d\u031f\7\60\2\2\u031e\u0320\5\u00d3j\2\u031f\u031e\3\2\2"+
"\2\u0320\u0321\3\2\2\2\u0321\u031f\3\2\2\2\u0321\u0322\3\2\2\2\u0322\u0323"+
"\3\2\2\2\u0323\u0324\5\u00d1i\2\u0324\u0326\3\2\2\2\u0325\u02fc\3\2\2"+
"\2\u0325\u0307\3\2\2\2\u0325\u030e\3\2\2\2\u0325\u031d\3\2\2\2\u0326\u00c8"+
"\3\2\2\2\u0327\u032a\5\u00d5k\2\u0328\u032a\7a\2\2\u0329\u0327\3\2\2\2"+
"\u0329\u0328\3\2\2\2\u032a\u0330\3\2\2\2\u032b\u032f\5\u00d5k\2\u032c"+
"\u032f\5\u00d3j\2\u032d\u032f\t\3\2\2\u032e\u032b\3\2\2\2\u032e\u032c"+
"\3\2\2\2\u032e\u032d\3\2\2\2\u032f\u0332\3\2\2\2\u0330\u032e\3\2\2\2\u0330"+
"\u0331\3\2\2\2\u0331\u00ca\3\2\2\2\u0332\u0330\3\2\2\2\u0333\u0337\5\u00d3"+
"j\2\u0334\u0338\5\u00d5k\2\u0335\u0338\5\u00d3j\2\u0336\u0338\t\3\2\2"+
"\u0337\u0334\3\2\2\2\u0337\u0335\3\2\2\2\u0337\u0336\3\2\2\2\u0338\u0339"+
"\3\2\2\2\u0339\u0337\3\2\2\2\u0339\u033a\3\2\2\2\u033a\u00cc\3\2\2\2\u033b"+
"\u0340\7$\2\2\u033c\u033f\n\4\2\2\u033d\u033f\7$\2\2\u033e\u033c\3\2\2"+
"\2\u033e\u033d\3\2\2\2\u033f\u0342\3\2\2\2\u0340\u033e\3\2\2\2\u0340\u0341"+
"\3\2\2\2\u0341\u0343\3\2\2\2\u0342\u0340\3\2\2\2\u0343\u0344\7$\2\2\u0344"+
"\u00ce\3\2\2\2\u0345\u034b\7b\2\2\u0346\u034a\n\5\2\2\u0347\u0348\7b\2"+
"\2\u0348\u034a\7b\2\2\u0349\u0346\3\2\2\2\u0349\u0347\3\2\2\2\u034a\u034d"+
"\3\2\2\2\u034b\u0349\3\2\2\2\u034b\u034c\3\2\2\2\u034c\u034e\3\2\2\2\u034d"+
"\u034b\3\2\2\2\u034e\u034f\7b\2\2\u034f\u00d0\3\2\2\2\u0350\u0352\7G\2"+
"\2\u0351\u0353\t\6\2\2\u0352\u0351\3\2\2\2\u0352\u0353\3\2\2\2\u0353\u0355"+
"\3\2\2\2\u0354\u0356\5\u00d3j\2\u0355\u0354\3\2\2\2\u0356\u0357\3\2\2"+
"\2\u0357\u0355\3\2\2\2\u0357\u0358\3\2\2\2\u0358\u00d2\3\2\2\2\u0359\u035a"+
"\t\7\2\2\u035a\u00d4\3\2\2\2\u035b\u035c\t\b\2\2\u035c\u00d6\3\2\2\2\u035d"+
"\u035e\7/\2\2\u035e\u035f\7/\2\2\u035f\u0363\3\2\2\2\u0360\u0362\n\t\2"+
"\2\u0361\u0360\3\2\2\2\u0362\u0365\3\2\2\2\u0363\u0361\3\2\2\2\u0363\u0364"+
"\3\2\2\2\u0364\u0367\3\2\2\2\u0365\u0363\3\2\2\2\u0366\u0368\7\17\2\2"+
"\u0367\u0366\3\2\2\2\u0367\u0368\3\2\2\2\u0368\u036a\3\2\2\2\u0369\u036b"+
"\7\f\2\2\u036a\u0369\3\2\2\2\u036a\u036b\3\2\2\2\u036b\u036c\3\2\2\2\u036c"+
"\u036d\bl\2\2\u036d\u00d8\3\2\2\2\u036e\u036f\7\61\2\2\u036f\u0370\7,"+
"\2\2\u0370\u0375\3\2\2\2\u0371\u0374\5\u00d9m\2\u0372\u0374\13\2\2\2\u0373"+
"\u0371\3\2\2\2\u0373\u0372\3\2\2\2\u0374\u0377\3\2\2\2\u0375\u0376\3\2"+
"\2\2\u0375\u0373\3\2\2\2\u0376\u0378\3\2\2\2\u0377\u0375\3\2\2\2\u0378"+
"\u0379\7,\2\2\u0379\u037a\7\61\2\2\u037a\u037b\3\2\2\2\u037b\u037c\bm"+
"\2\2\u037c\u00da\3\2\2\2\u037d\u037f\t\n\2\2\u037e\u037d\3\2\2\2\u037f"+
"\u0380\3\2\2\2\u0380\u037e\3\2\2\2\u0380\u0381\3\2\2\2\u0381\u0382\3\2"+
"\2\2\u0382\u0383\bn\2\2\u0383\u00dc\3\2\2\2\u0384\u0385\13\2\2\2\u0385"+
"\u00de\3\2\2\2 \2\u02d2\u02ef\u02f1\u02f9\u02fe\u0304\u030b\u0310\u0316"+
"\u0319\u0321\u0325\u0329\u032e\u0330\u0337\u0339\u033e\u0340\u0349\u034b"+
"\u0352\u0357\u0363\u0367\u036a\u0373\u0375\u0380\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -5,37 +5,27 @@
*/
package org.elasticsearch.xpack.sql.plan;
import java.util.Objects;
import org.elasticsearch.common.Strings;
import org.elasticsearch.xpack.sql.tree.Location;
import java.util.Objects;
public class TableIdentifier {
private final String index, type;
private final String index;
private final Location location;
public TableIdentifier(Location location, String index, String type) {
public TableIdentifier(Location location, String index) {
this.location = location;
this.index = index;
this.type = type;
}
public String index() {
return index;
}
public String type() {
return type;
}
public boolean hasType() {
return Strings.hasText(type);
}
@Override
public int hashCode() {
return Objects.hash(index, type);
return Objects.hash(index);
}
@Override
@ -49,8 +39,7 @@ public class TableIdentifier {
}
TableIdentifier other = (TableIdentifier) obj;
return Objects.equals(index, other.index)
&& Objects.equals(type, other.type);
return Objects.equals(index, other.index);
}
public Location location() {
@ -62,8 +51,6 @@ public class TableIdentifier {
StringBuilder builder = new StringBuilder();
builder.append("[index=");
builder.append(index);
builder.append(", type=");
builder.append(type);
builder.append("]");
return builder.toString();
}

View File

@ -5,13 +5,8 @@
*/
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.analysis.catalog.EsType;
import org.elasticsearch.xpack.sql.analysis.catalog.EsIndex;
import org.elasticsearch.xpack.sql.expression.Attribute;
import org.elasticsearch.xpack.sql.expression.NestedFieldAttribute;
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.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.stream.Collectors.toList;
import static org.elasticsearch.xpack.sql.util.CollectionUtils.combine;
public class CatalogTable extends LeafPlan {
private final EsType type;
private final EsIndex index;
private final List<Attribute> attrs;
public CatalogTable(Location location, EsType type) {
public CatalogTable(Location location, EsIndex index) {
super(location);
this.type = type;
attrs = flatten(location, type.mapping()).collect(toList());
this.index = index;
attrs = flatten(location, index.mapping()).collect(toList());
}
private static Stream<Attribute> flatten(Location location, Map<String, DataType> mapping) {
@ -62,8 +61,8 @@ public class CatalogTable extends LeafPlan {
});
}
public EsType type() {
return type;
public EsIndex index() {
return index;
}
@Override
@ -78,7 +77,7 @@ public class CatalogTable extends LeafPlan {
@Override
public int hashCode() {
return Objects.hash(type);
return Objects.hash(index);
}
@Override
@ -92,11 +91,11 @@ public class CatalogTable extends LeafPlan {
}
CatalogTable other = (CatalogTable) obj;
return Objects.equals(type, other.type);
return Objects.equals(index, other.index);
}
@Override
public String nodeString() {
return nodeName() + "[" + type + "]" + StringUtils.limitedToString(attrs);
return nodeName() + "[" + index + "]" + StringUtils.limitedToString(attrs);
}
}

View File

@ -5,11 +5,6 @@
*/
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.expression.Attribute;
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.DataTypes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import static java.util.Arrays.asList;
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);
this.index = index;
this.type = type;
}
public String index() {
return index;
}
public String type() {
return type;
}
@Override
public List<Attribute> output() {
return asList(new RootFieldAttribute(location(), "column", DataTypes.KEYWORD),
@ -52,7 +46,7 @@ public class ShowColumns extends Command {
@Override
protected RowSetCursor execute(SqlSession session) {
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<>();
fillInRows(mapping, null, rows);
@ -75,7 +69,7 @@ public class ShowColumns extends Command {
@Override
public int hashCode() {
return Objects.hash(index, type);
return Objects.hash(index);
}
@Override
@ -89,7 +83,6 @@ public class ShowColumns extends Command {
}
ShowColumns other = (ShowColumns) obj;
return Objects.equals(index, other.index)
&& Objects.equals(type, other.type);
return Objects.equals(index, other.index);
}
}

View File

@ -5,7 +5,7 @@
*/
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.RootFieldAttribute;
import org.elasticsearch.xpack.sql.session.RowSetCursor;
@ -19,47 +19,42 @@ import java.util.List;
import java.util.Objects;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
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);
this.index = index;
this.pattern = pattern;
}
public String index() {
return index;
}
public String pattern() {
return pattern;
}
@Override
public List<Attribute> output() {
return asList(new RootFieldAttribute(location(), "index", DataTypes.KEYWORD),
new RootFieldAttribute(location(), "type", DataTypes.KEYWORD));
return asList(new RootFieldAttribute(location(), "table", DataTypes.KEYWORD));
}
@Override
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
Collections.sort(types, comparing(EsType::index).thenComparing(EsType::name));
Collections.sort(indices, comparing(EsIndex::name));
return Rows.of(output(), types.stream()
.map(t -> asList(t.index(), t.name()))
return Rows.of(output(), indices.stream()
.map(t -> singletonList(t.name()))
.collect(toList()));
}
@Override
public int hashCode() {
return Objects.hash(index, pattern);
return Objects.hash(pattern);
}
@Override
@ -73,7 +68,6 @@ public class ShowTables extends Command {
}
ShowTables other = (ShowTables) obj;
return Objects.equals(index, other.index)
&& Objects.equals(pattern, other.pattern);
return Objects.equals(pattern, other.pattern);
}
}
}

View File

@ -19,30 +19,25 @@ import java.util.Objects;
public class EsQueryExec extends LeafExec {
private final String index, type;
private final String index;
private final List<Attribute> output;
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);
this.index = index;
this.type = type;
this.output = output;
this.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() {
return index;
}
public String type() {
return type;
}
public QueryContainer queryContainer() {
return queryContainer;
@ -56,12 +51,12 @@ public class EsQueryExec extends LeafExec {
@Override
public void execute(SqlSession session, ActionListener<RowSetCursor> listener) {
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
public int hashCode() {
return Objects.hash(index, type, queryContainer, output);
return Objects.hash(index, queryContainer, output);
}
@Override
@ -76,13 +71,12 @@ public class EsQueryExec extends LeafExec {
EsQueryExec other = (EsQueryExec) obj;
return Objects.equals(index, other.index)
&& Objects.equals(type, other.type)
&& Objects.equals(queryContainer, other.queryContainer)
&& Objects.equals(output, other.output);
}
@Override
public String nodeString() {
return nodeName() + "[" + index + "/" + type + "," + queryContainer + "]";
return nodeName() + "[" + index + "," + queryContainer + "]";
}
}

View File

@ -5,9 +5,6 @@
*/
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.plan.logical.Aggregate;
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.util.ReflectionUtils;
import java.util.Arrays;
import java.util.List;
class Mapper extends RuleExecutor<PhysicalPlan> {
public PhysicalPlan map(LogicalPlan plan) {
@ -91,7 +91,7 @@ class Mapper extends RuleExecutor<PhysicalPlan> {
if (p instanceof CatalogTable) {
CatalogTable c = (CatalogTable) p;
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) {

View File

@ -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());
return new EsQueryExec(exec.location(), exec.index(), exec.type(), project.output(), clone);
return new EsQueryExec(exec.location(), exec.index(), project.output(), clone);
}
return project;
}
@ -323,7 +323,7 @@ class QueryFolder extends RuleExecutor<PhysicalPlan> {
if (!aliases.isEmpty()) {
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;
}

View File

@ -10,7 +10,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.common.Strings;
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.search.SearchHitRowSetCursor;
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 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.tokenizeToStringArray;
import static org.elasticsearch.xpack.sql.util.StringUtils.EMPTY;
public class JdbcServer extends AbstractSqlServer {
@ -100,35 +98,29 @@ public class JdbcServer extends AbstractSqlServer {
}
public MetaTableResponse metaTable(MetaTableRequest req) {
String[] split = splitToIndexAndType(req.pattern());
String index = split[0];
String type = split[1];
String indexPattern = hasText(index) ? StringUtils.jdbcToEsPattern(index) : "*";
String indexPattern = hasText(req.pattern()) ? StringUtils.jdbcToEsPattern(req.pattern()) : "*";
Collection<EsType> types = executor.catalog().listTypes(indexPattern, type);
return new MetaTableResponse(types.stream()
.map(t -> t.index() + "." + t.name())
Collection<EsIndex> indices = executor.catalog().listIndices(indexPattern);
return new MetaTableResponse(indices.stream()
.map(EsIndex::name)
.collect(toList()));
}
public MetaColumnResponse metaColumn(MetaColumnRequest req) {
String[] split = splitToIndexAndType(req.tablePattern());
String index = split[0];
String type = split[1];
String indexPattern = Strings.hasText(index) ? StringUtils.jdbcToEsPattern(index) : "*";
String pattern = Strings.hasText(req.tablePattern()) ? StringUtils.jdbcToEsPattern(req.tablePattern()) : "*";
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;
List<MetaColumnInfo> resp = new ArrayList<>();
for (EsType esType : types) {
for (EsIndex esIndex : indices) {
int pos = 0;
for (Entry<String, DataType> entry : esType.mapping().entrySet()) {
for (Entry<String, DataType> entry : esIndex.mapping().entrySet()) {
pos++;
if (columnMatcher == null || columnMatcher.matcher(entry.getKey()).matches()) {
String name = entry.getKey();
String table = esType.index() + "." + esType.name();
String table = esIndex.name();
JDBCType tp = entry.getValue().sqlType();
int size = entry.getValue().precision();
resp.add(new MetaColumnInfo(table, name, tp, size, pos));
@ -149,6 +141,7 @@ public class JdbcServer extends AbstractSqlServer {
.build()
);
//NOCOMMIT: this should be pushed down to the TransportSqlAction to hook up pagination
executor.sql(sqlCfg, req.query, wrap(c -> {
long stop = System.currentTimeMillis();
String requestId = EMPTY;
@ -167,17 +160,4 @@ public class JdbcServer extends AbstractSqlServer {
public void queryPage(QueryPageRequest req, ActionListener<Response> listener) {
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), ""};
}
}

View File

@ -60,10 +60,6 @@ public class TransportSqlAction extends HandledTransportAction<SqlRequest, SqlRe
String sessionId = request.sessionId();
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 {
if (sessionId == null) {
if (!Strings.hasText(query)) {
@ -71,6 +67,11 @@ public class TransportSqlAction extends HandledTransportAction<SqlRequest, SqlRe
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 -> {
String id = generateId();
SESSIONS.put(id, c);

View File

@ -39,7 +39,7 @@ public class SqlSettings {
}
public DateTimeZone timeZone() {
return DateTimeZone.forID(TIMEZONE_ID);
return DateTimeZone.forID(timeZoneId());
}
public int pageSize() {