diff -Nru adql-1.3/debian/changelog adql-1.4/debian/changelog --- adql-1.3/debian/changelog 2017-03-15 14:11:02.000000000 +0000 +++ adql-1.4/debian/changelog 2018-03-21 13:25:27.000000000 +0000 @@ -1,3 +1,22 @@ +adql (1.4-1) unstable; urgency=low + + * Fix d/watch + * New upstream version 1.4 + * Drop Remove-unneeded-import-of-tap.data.DataReadException.patch + * Import unit tests for version 1.4 + + -- Ole Streicher Wed, 21 Mar 2018 14:25:27 +0100 + +adql (1.3-5) unstable; urgency=medium + + * Update VCS fields to use salsa.d.o + * Test: Compare only the first 8 digits in string comparison (Closes: #893193) + * Push Standards-Version to 4.1.3. Change URLs to https + * Push compat to 11 + * Add d/u/metadata + + -- Ole Streicher Wed, 21 Mar 2018 13:11:57 +0100 + adql (1.3-4) unstable; urgency=low * Add libpostgresql-jdbc-java to test dependencies diff -Nru adql-1.3/debian/compat adql-1.4/debian/compat --- adql-1.3/debian/compat 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/compat 2018-03-21 12:20:17.000000000 +0000 @@ -1 +1 @@ -9 \ No newline at end of file +11 diff -Nru adql-1.3/debian/control adql-1.4/debian/control --- adql-1.3/debian/control 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/control 2018-03-21 12:20:17.000000000 +0000 @@ -3,7 +3,7 @@ Priority: optional Maintainer: Debian Astro Team Uploaders: Ole Streicher -Build-Depends: ant, debhelper (>= 9), dh-exec, javahelper (>= 0.40) +Build-Depends: ant, debhelper (>= 11), dh-exec, javahelper (>= 0.40) Build-Depends-Indep: ant-optional, default-jdk, default-jdk-doc, @@ -11,10 +11,10 @@ junit4, libpostgresql-jdbc-java, libpostgresql-jdbc-java-doc -Standards-Version: 3.9.8 -Homepage: http://cdsportal.u-strasbg.fr/adqltuto/index.html -Vcs-Git: https://anonscm.debian.org/cgit/debian-astro/packages/adql.git -Vcs-Browser: https://anonscm.debian.org/cgit/debian-astro/packages/adql.git +Standards-Version: 4.1.3 +Homepage: https://cdsportal.u-strasbg.fr/adqltuto/index.html +Vcs-Git: https://salsa.debian.org/debian-astro-team/adql.git +Vcs-Browser: https://salsa.debian.org/debian-astro-team/adql Package: adql-java Architecture: all diff -Nru adql-1.3/debian/copyright adql-1.4/debian/copyright --- adql-1.3/debian/copyright 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/copyright 2018-03-21 12:20:17.000000000 +0000 @@ -1,6 +1,6 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: ADQL Library -Source: http://cdsportal.u-strasbg.fr/adqltuto/download?file=sources +Source: https://cdsportal.u-strasbg.fr/adqltuto/download?file=sources Files: * Copyright: 2011-2015 UDS/Centre de Données astronomiques de Strasbourg (CDS) diff -Nru adql-1.3/debian/patches/Add-unit-tests.patch adql-1.4/debian/patches/Add-unit-tests.patch --- adql-1.3/debian/patches/Add-unit-tests.patch 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/patches/Add-unit-tests.patch 2018-03-21 13:25:27.000000000 +0000 @@ -2,306 +2,58 @@ Date: Fri, 24 Feb 2017 14:47:48 +0100 Subject: Add unit tests +These unit tests were taken from + +https://github.com/gmantele/taplib/tree/tapLib-2.1/test/adql --- - test/adql/TestADQLQuery.java | 127 ++++ - test/adql/TestIN.java | 95 +++ - test/adql/TestIdentifierField.java | 25 + - test/adql/db/TestDBChecker.java | 740 +++++++++++++++++++++++ - test/adql/db/TestFunctionDef.java | 312 ++++++++++ - test/adql/db/TestSTCS.java | 536 ++++++++++++++++ - test/adql/parser/TestADQLParser.java | 43 ++ - test/adql/query/from/TestCrossJoin.java | 95 +++ - test/adql/query/from/TestInnerJoin.java | 158 +++++ - test/adql/translator/TestPgSphereTranslator.java | 332 ++++++++++ - test/testtools/CommandExecute.java | 51 ++ - test/testtools/DBTools.java | 136 +++++ - test/testtools/MD5Checksum.java | 46 ++ - 13 files changed, 2696 insertions(+) - create mode 100644 test/adql/TestADQLQuery.java - create mode 100644 test/adql/TestIN.java - create mode 100644 test/adql/TestIdentifierField.java + test/adql/db/TestDBChecker.java | 917 +++++++++++++++++++++ + test/adql/db/TestFunctionDef.java | 372 +++++++++ + test/adql/db/TestSTCS.java | 536 ++++++++++++ + test/adql/db/subquery_test_tables.xml | 301 +++++++ + test/adql/parser/TestADQLParser.java | 308 +++++++ + test/adql/parser/TestIdentifierItem.java | 34 + + test/adql/parser/TestUnknownTypes.java | 163 ++++ + test/adql/query/TestADQLObjectPosition.java | 140 ++++ + test/adql/query/TestADQLQuery.java | 240 ++++++ + test/adql/query/TestIdentifierField.java | 25 + + test/adql/query/constraint/TestIN.java | 95 +++ + test/adql/query/from/TestCrossJoin.java | 95 +++ + test/adql/query/from/TestInnerJoin.java | 158 ++++ + test/adql/query/from/TestSQLServer_InnerJoin.java | 159 ++++ + .../function/geometry/TestCentroidFunction.java | 28 + + test/adql/search/TestSimpleReplaceHandler.java | 121 +++ + test/adql/translator/TestJDBCTranslator.java | 136 +++ + test/adql/translator/TestPgSphereTranslator.java | 350 ++++++++ + test/adql/translator/TestPostgreSQLTranslator.java | 62 ++ + test/adql/translator/TestSQLServerTranslator.java | 86 ++ + 20 files changed, 4326 insertions(+) create mode 100644 test/adql/db/TestDBChecker.java create mode 100644 test/adql/db/TestFunctionDef.java create mode 100644 test/adql/db/TestSTCS.java + create mode 100644 test/adql/db/subquery_test_tables.xml create mode 100644 test/adql/parser/TestADQLParser.java + create mode 100644 test/adql/parser/TestIdentifierItem.java + create mode 100644 test/adql/parser/TestUnknownTypes.java + create mode 100644 test/adql/query/TestADQLObjectPosition.java + create mode 100644 test/adql/query/TestADQLQuery.java + create mode 100644 test/adql/query/TestIdentifierField.java + create mode 100644 test/adql/query/constraint/TestIN.java create mode 100644 test/adql/query/from/TestCrossJoin.java create mode 100644 test/adql/query/from/TestInnerJoin.java + create mode 100644 test/adql/query/from/TestSQLServer_InnerJoin.java + create mode 100644 test/adql/query/operand/function/geometry/TestCentroidFunction.java + create mode 100644 test/adql/search/TestSimpleReplaceHandler.java + create mode 100644 test/adql/translator/TestJDBCTranslator.java create mode 100644 test/adql/translator/TestPgSphereTranslator.java - create mode 100644 test/testtools/CommandExecute.java - create mode 100644 test/testtools/DBTools.java - create mode 100644 test/testtools/MD5Checksum.java + create mode 100644 test/adql/translator/TestPostgreSQLTranslator.java + create mode 100644 test/adql/translator/TestSQLServerTranslator.java -diff --git a/test/adql/TestADQLQuery.java b/test/adql/TestADQLQuery.java -new file mode 100644 -index 0000000..54a704e ---- /dev/null -+++ b/test/adql/TestADQLQuery.java -@@ -0,0 +1,127 @@ -+package adql; -+ -+import static org.junit.Assert.assertEquals; -+ -+import java.util.ArrayList; -+import java.util.Iterator; -+import java.util.List; -+ -+import org.junit.Before; -+import org.junit.Test; -+ -+import adql.query.ADQLObject; -+import adql.query.ADQLOrder; -+import adql.query.ADQLQuery; -+import adql.query.ClauseADQL; -+import adql.query.ClauseConstraints; -+import adql.query.ClauseSelect; -+import adql.query.SelectItem; -+import adql.query.constraint.Comparison; -+import adql.query.constraint.ComparisonOperator; -+import adql.query.constraint.ConstraintsGroup; -+import adql.query.from.ADQLTable; -+import adql.query.operand.ADQLColumn; -+import adql.query.operand.Concatenation; -+import adql.query.operand.NumericConstant; -+import adql.query.operand.Operation; -+import adql.query.operand.OperationType; -+import adql.query.operand.StringConstant; -+import adql.query.operand.WrappedOperand; -+import adql.search.IReplaceHandler; -+import adql.search.ISearchHandler; -+import adql.search.SearchColumnHandler; -+import adql.search.SimpleReplaceHandler; -+ -+public class TestADQLQuery { -+ private ADQLQuery query = null; -+ private List columns = new ArrayList(8); -+ private List typeObjColumns = new ArrayList(3); -+ -+ @Before -+ public void setUp(){ -+ query = new ADQLQuery(); -+ columns.clear(); -+ typeObjColumns.clear(); -+ -+ columns.add(new ADQLColumn("O", "nameObj")); // 0 = O.nameObj -+ columns.add(new ADQLColumn("O", "typeObj")); // 1 = O.typeObj -+ columns.add(new ADQLColumn("O", "ra")); // 2 = O.ra -+ columns.add(new ADQLColumn("O", "dec")); // 3 = O.dec -+ columns.add(new ADQLColumn("ra")); // 4 = ra -+ columns.add(new ADQLColumn("dec")); // 5 = dec -+ columns.add(new ADQLColumn("typeObj")); // 6 = typeObj -+ columns.add(new ADQLColumn("typeObj")); // 7 = typeObj -+ -+ typeObjColumns.add(columns.get(1)); -+ typeObjColumns.add(columns.get(6)); -+ typeObjColumns.add(columns.get(7)); -+ -+ // SELECT: -+ ClauseSelect select = query.getSelect(); -+ Concatenation concatObj = new Concatenation(); -+ concatObj.add(columns.get(0)); // O.nameObj -+ concatObj.add(new StringConstant(" (")); -+ concatObj.add(columns.get(1)); // O.typeObj -+ concatObj.add(new StringConstant(")")); -+ select.add(new SelectItem(new WrappedOperand(concatObj), "Nom objet")); -+ select.add(columns.get(2)); // O.ra -+ select.add(columns.get(3)); // O.dec -+ -+ // FROM: -+ ADQLTable table = new ADQLTable("truc.ObsCore"); -+ table.setAlias("O"); -+ // table.setJoin(new ADQLJoin(JoinType.INNER, new ADQLTable("VO"))); -+ query.setFrom(table); -+ -+ // WHERE: -+ ClauseConstraints where = query.getWhere(); -+ // ra/dec > 1 -+ where.add(new Comparison(new Operation(columns.get(4), OperationType.DIV, columns.get(5)), ComparisonOperator.GREATER_THAN, new NumericConstant("1"))); -+ ConstraintsGroup constOr = new ConstraintsGroup(); -+ // AND (typeObj == 'Star' -+ constOr.add(new Comparison(columns.get(6), ComparisonOperator.EQUAL, new StringConstant("Star"))); -+ // OR typeObj LIKE 'Galaxy*') -+ constOr.add("OR", new Comparison(columns.get(7), ComparisonOperator.LIKE, new StringConstant("Galaxy*"))); -+ where.add("AND", constOr); -+ -+ // ORDER BY: -+ ClauseADQL orderBy = query.getOrderBy(); -+ orderBy.add(new ADQLOrder(1, true)); -+ } -+ -+ @Test -+ public void testADQLQuery(){ -+ assertEquals("SELECT (O.nameObj || ' (' || O.typeObj || ')') AS Nom objet , O.ra , O.dec\nFROM truc.ObsCore AS O\nWHERE ra/dec > 1 AND (typeObj = 'Star' OR typeObj LIKE 'Galaxy*')\nORDER BY 1 DESC", query.toADQL()); -+ } -+ -+ @Test -+ public void testSearch(){ -+ ISearchHandler sHandler = new SearchColumnHandler(false); -+ Iterator results = query.search(sHandler); -+ assertEquals(columns.size(), sHandler.getNbMatch()); -+ for(ADQLColumn expectedCol : columns) -+ assertEquals(expectedCol, results.next()); -+ } -+ -+ @Test -+ public void testReplace(){ -+ IReplaceHandler sHandler = new SimpleReplaceHandler(false, false){ -+ @Override -+ protected boolean match(ADQLObject obj){ -+ return (obj instanceof ADQLColumn) && (((ADQLColumn)obj).getColumnName().equalsIgnoreCase("typeObj")); -+ } -+ -+ @Override -+ public ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException{ -+ return new ADQLColumn("NewTypeObj"); -+ } -+ }; -+ sHandler.searchAndReplace(query); -+ assertEquals(typeObjColumns.size(), sHandler.getNbMatch()); -+ assertEquals(sHandler.getNbMatch(), sHandler.getNbReplacement()); -+ Iterator results = sHandler.iterator(); -+ for(ADQLColumn expectedCol : typeObjColumns) -+ assertEquals(expectedCol, results.next()); -+ assertEquals("SELECT (O.nameObj || ' (' || NewTypeObj || ')') AS Nom objet , O.ra , O.dec\nFROM truc.ObsCore AS O\nWHERE ra/dec > 1 AND (NewTypeObj = 'Star' OR NewTypeObj LIKE 'Galaxy*')\nORDER BY 1 DESC", query.toADQL()); -+ } -+} -diff --git a/test/adql/TestIN.java b/test/adql/TestIN.java -new file mode 100644 -index 0000000..d3ad2f2 ---- /dev/null -+++ b/test/adql/TestIN.java -@@ -0,0 +1,95 @@ -+package adql; -+ -+import static org.junit.Assert.assertEquals; -+import static org.junit.Assert.fail; -+ -+import java.util.Iterator; -+ -+import org.junit.BeforeClass; -+import org.junit.Test; -+ -+import adql.query.ADQLList; -+import adql.query.ADQLObject; -+import adql.query.ADQLOrder; -+import adql.query.ADQLQuery; -+import adql.query.ClauseSelect; -+import adql.query.constraint.In; -+import adql.query.from.ADQLTable; -+import adql.query.operand.ADQLColumn; -+import adql.query.operand.ADQLOperand; -+import adql.query.operand.StringConstant; -+import adql.search.IReplaceHandler; -+import adql.search.SimpleReplaceHandler; -+import adql.translator.ADQLTranslator; -+import adql.translator.PostgreSQLTranslator; -+ -+public class TestIN { -+ -+ private static ADQLTranslator translator = null; -+ -+ @BeforeClass -+ public static void setUpBeforeClass(){ -+ translator = new PostgreSQLTranslator(); -+ } -+ -+ @Test -+ public void testIN(){ -+ // Test with a simple list of values (here, string constants): -+ In myIn = new In(new ADQLColumn("typeObj"), new ADQLOperand[]{new StringConstant("galaxy"),new StringConstant("star"),new StringConstant("planet"),new StringConstant("nebula")}, true); -+ // check the ADQL: -+ assertEquals("typeObj NOT IN ('galaxy' , 'star' , 'planet' , 'nebula')", myIn.toADQL()); -+ // check the SQL translation: -+ try{ -+ assertEquals(myIn.toADQL(), translator.translate(myIn)); -+ }catch(Exception ex){ -+ ex.printStackTrace(); -+ fail("This test should have succeeded because the IN statement is correct and theoretically well supported by the POSTGRESQL translator!"); -+ } -+ -+ // Test with a sub-query: -+ ADQLQuery subQuery = new ADQLQuery(); -+ -+ ClauseSelect select = subQuery.getSelect(); -+ select.setDistinctColumns(true); -+ select.setLimit(10); -+ select.add(new ADQLColumn("typeObj")); -+ -+ subQuery.setFrom(new ADQLTable("Objects")); -+ -+ ADQLList orderBy = subQuery.getOrderBy(); -+ orderBy.add(new ADQLOrder(1)); -+ -+ myIn.setSubQuery(subQuery); -+ // check the ADQL: -+ assertEquals("typeObj NOT IN (SELECT DISTINCT TOP 10 typeObj\nFROM Objects\nORDER BY 1 ASC)", myIn.toADQL()); -+ // check the SQL translation: -+ try{ -+ assertEquals("typeObj NOT IN (SELECT DISTINCT typeObj AS \"typeObj\"\nFROM Objects\nORDER BY 1 ASC\nLimit 10)", translator.translate(myIn)); -+ }catch(Exception ex){ -+ ex.printStackTrace(); -+ fail("This test should have succeeded because the IN statement is correct and theoretically well supported by the POSTGRESQL translator!"); -+ } -+ -+ // Test after replacement inside this IN statement: -+ IReplaceHandler sHandler = new SimpleReplaceHandler(true){ -+ -+ @Override -+ public boolean match(ADQLObject obj){ -+ return (obj instanceof ADQLColumn) && ((ADQLColumn)obj).getColumnName().equals("typeObj"); -+ } -+ -+ @Override -+ public ADQLObject getReplacer(ADQLObject objToReplace){ -+ return new ADQLColumn("type"); -+ } -+ }; -+ sHandler.searchAndReplace(myIn); -+ assertEquals(2, sHandler.getNbMatch()); -+ assertEquals(sHandler.getNbMatch(), sHandler.getNbReplacement()); -+ Iterator results = sHandler.iterator(); -+ while(results.hasNext()) -+ assertEquals("typeObj", results.next().toADQL()); -+ assertEquals("type NOT IN (SELECT DISTINCT TOP 10 type\nFROM Objects\nORDER BY 1 ASC)", myIn.toADQL()); -+ } -+ -+} -diff --git a/test/adql/TestIdentifierField.java b/test/adql/TestIdentifierField.java -new file mode 100644 -index 0000000..c4c5fc2 ---- /dev/null -+++ b/test/adql/TestIdentifierField.java -@@ -0,0 +1,25 @@ -+package adql; -+ -+import static org.junit.Assert.assertFalse; -+import static org.junit.Assert.assertTrue; -+ -+import org.junit.Test; -+ -+import adql.query.IdentifierField; -+ -+public class TestIdentifierField { -+ -+ @Test -+ public void testIsCaseSensitive(){ -+ byte b = 0x00; -+ assertFalse(IdentifierField.SCHEMA.isCaseSensitive(b)); -+ b = IdentifierField.SCHEMA.setCaseSensitive(b, true); -+ assertTrue(IdentifierField.SCHEMA.isCaseSensitive(b)); -+ } -+ -+ /*@Test -+ public void testSetCaseSensitive(){ -+ fail("Not yet implemented"); -+ }*/ -+ -+} diff --git a/test/adql/db/TestDBChecker.java b/test/adql/db/TestDBChecker.java new file mode 100644 -index 0000000..3f9924a +index 0000000..3e675ae --- /dev/null +++ b/test/adql/db/TestDBChecker.java -@@ -0,0 +1,740 @@ +@@ -0,0 +1,917 @@ +package adql.db; + +import static org.junit.Assert.assertEquals; @@ -336,6 +88,7 @@ +import adql.query.operand.function.UserDefinedFunction; +import adql.search.SimpleSearchHandler; +import adql.translator.ADQLTranslator; ++import adql.translator.PostgreSQLTranslator; +import adql.translator.TranslationException; + +public class TestDBChecker { @@ -346,7 +99,7 @@ + public static void setUpBeforeClass() throws Exception{ + tables = new ArrayList(); + -+ DefaultDBTable fooTable = new DefaultDBTable("foo"); ++ DefaultDBTable fooTable = new DefaultDBTable(null, "aschema", "foo"); + DBColumn col = new DefaultDBColumn("colS", new DBType(DBDatatype.VARCHAR), fooTable); + fooTable.addColumn(col); + col = new DefaultDBColumn("colI", new DBType(DBDatatype.INTEGER), fooTable); @@ -355,6 +108,12 @@ + fooTable.addColumn(col); + + tables.add(fooTable); ++ ++ DefaultDBTable fooTable2 = new DefaultDBTable(null, null, "foo2"); ++ col = new DefaultDBColumn("oid", new DBType(DBDatatype.BIGINT), fooTable2); ++ fooTable2.addColumn(col); ++ ++ tables.add(fooTable2); + } + + @AfterClass @@ -367,9 +126,133 @@ + public void tearDown() throws Exception{} + + @Test -+ public void testNumericOrStringValueExpressionPrimary(){ -+ ADQLParser parser = new ADQLParser(); -+ try{ ++ public void testSplitTableName(){ ++ String[] names = DefaultDBTable.splitTableName("foo"); ++ String[] expected = new String[]{null,null,"foo"}; ++ assertEquals(expected.length, names.length); ++ for(int i = 0; i < names.length; i++) ++ assertEquals(expected[i], names[i]); ++ ++ names = DefaultDBTable.splitTableName("aschema.foo"); ++ expected = new String[]{null,"aschema","foo"}; ++ assertEquals(expected.length, names.length); ++ for(int i = 0; i < names.length; i++) ++ assertEquals(expected[i], names[i]); ++ ++ names = DefaultDBTable.splitTableName("acat.aschema.foo"); ++ expected = new String[]{"acat","aschema","foo"}; ++ assertEquals(expected.length, names.length); ++ for(int i = 0; i < names.length; i++) ++ assertEquals(expected[i], names[i]); ++ ++ names = DefaultDBTable.splitTableName("weird.acat.aschema.foo"); ++ expected = new String[]{"weird.acat","aschema","foo"}; ++ assertEquals(expected.length, names.length); ++ for(int i = 0; i < names.length; i++) ++ assertEquals(expected[i], names[i]); ++ } ++ ++ @Test ++ public void testClauseADQLWithNameNull(){ ++ /* The name of an ADQLClause is got in DBChecker by SearchColumnOutsideGroupByHandler.goInto(...) ++ * and possibly in other locations in the future. If this name is NULL, no NullPointerException ++ * should be thrown. ++ * ++ * This issue can be tested by creating a ConstraintsGroup (i.e. in a constraints location like WHERE or JOIN...ON, ++ * a constraint (or more) between parenthesis). */ ++ ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList(0))); ++ try{ ++ parser.parseQuery("SELECT * FROM foo WHERE (colI BETWEEN 1 AND 10)"); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail(); ++ } ++ } ++ ++ @Test ++ public void testGroupByWithQualifiedColName(){ ++ ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList(0))); ++ try{ ++ // Not qualified column name: ++ parser.parseQuery("SELECT colI, COUNT(*) AS cnt FROM foo GROUP BY colI"); ++ // Qualified with the table name: ++ parser.parseQuery("SELECT foo.colI, COUNT(*) AS cnt FROM foo GROUP BY foo.colI"); ++ // Qualified with the table alias: ++ parser.parseQuery("SELECT f.colI, COUNT(*) AS cnt FROM foo AS f GROUP BY f.colI"); ++ // With the SELECT item alias: ++ parser.parseQuery("SELECT colI AS mycol, COUNT(*) AS cnt FROM foo GROUP BY mycol"); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail(); ++ } ++ } ++ ++ @Test ++ public void testQualifiedName(){ ++ ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList(0))); ++ try{ ++ // Tests with a table whose the schema is specified: ++ parser.parseQuery("SELECT * FROM foo;"); ++ parser.parseQuery("SELECT * FROM aschema.foo;"); ++ parser.parseQuery("SELECT foo.* FROM foo;"); ++ parser.parseQuery("SELECT aschema.foo.* FROM foo;"); ++ parser.parseQuery("SELECT aschema.foo.* FROM aschema.foo;"); ++ parser.parseQuery("SELECT \"colS\" FROM foo;"); ++ parser.parseQuery("SELECT foo.\"colS\" FROM foo;"); ++ parser.parseQuery("SELECT foo.\"colS\" FROM aschema.\"foo\";"); ++ parser.parseQuery("SELECT \"aschema\".\"foo\".\"colS\" FROM foo;"); ++ ++ // Tests with a table without schema: ++ parser.parseQuery("SELECT * FROM foo2;"); ++ parser.parseQuery("SELECT foo2.* FROM foo2;"); ++ parser.parseQuery("SELECT foo2.* FROM \"foo2\";"); ++ parser.parseQuery("SELECT \"foo2\".* FROM \"foo2\";"); ++ parser.parseQuery("SELECT oid FROM foo2;"); ++ parser.parseQuery("SELECT \"oid\" FROM \"foo2\";"); ++ parser.parseQuery("SELECT foo2.oid FROM foo2;"); ++ parser.parseQuery("SELECT \"foo2\".\"oid\" FROM \"foo2\";"); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail(); ++ } ++ ++ // If no schema is specified, then the table is not part of a schema and so, there is no reason a table with a fake schema prefix should work: ++ try{ ++ parser.parseQuery("SELECT * FROM noschema.foo2;"); ++ fail("The table \"foo2\" has no schema specified and so, is not part of a schema. A fake schema prefix should then be forbidden!"); ++ }catch(ParseException pe){} ++ try{ ++ parser.parseQuery("SELECT noschema.foo2.* FROM foo2;"); ++ fail("The table \"foo2\" has no schema specified and so, is not part of a schema. A fake schema prefix should then be forbidden!"); ++ }catch(ParseException pe){} ++ } ++ ++ @Test ++ public void testColRefWithDottedAlias(){ ++ ADQLParser parser = new ADQLParser(new DBChecker(tables)); ++ try{ ++ // ORDER BY ++ ADQLQuery adql = parser.parseQuery("SELECT colI AS \"col.I\" FROM aschema.foo ORDER BY \"col.I\""); ++ assertNotNull(adql); ++ assertEquals("SELECT \"aschema\".\"foo\".\"colI\" AS \"col.I\"\nFROM \"aschema\".\"foo\"\nORDER BY \"col.I\" ASC", (new PostgreSQLTranslator()).translate(adql)); ++ ++ // GROUP BY ++ adql = parser.parseQuery("SELECT colI AS \"col.I\" FROM aschema.foo GROUP BY \"col.I\""); ++ assertNotNull(adql); ++ assertEquals("SELECT \"aschema\".\"foo\".\"colI\" AS \"col.I\"\nFROM \"aschema\".\"foo\"\nGROUP BY \"col.I\"", (new PostgreSQLTranslator()).translate(adql)); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail(); ++ }catch(TranslationException te){ ++ te.printStackTrace(); ++ fail(); ++ } ++ } ++ ++ @Test ++ public void testNumericOrStringValueExpressionPrimary(){ ++ ADQLParser parser = new ADQLParser(); ++ try{ + assertNotNull(parser.parseQuery("SELECT 'toto' FROM foo;")); + assertNotNull(parser.parseQuery("SELECT ('toto') FROM foo;")); + assertNotNull(parser.parseQuery("SELECT (('toto')) FROM foo;")); @@ -385,6 +268,9 @@ + assertNotNull(parser.parseQuery("SELECT toto FROM foo;")); + assertNotNull(parser.parseQuery("SELECT toto * 3 FROM foo;")); + assertNotNull(parser.parseQuery("SELECT toto || 'blabla' FROM foo;")); ++ assertNotNull(parser.parseQuery("SELECT 'toto' || 1 FROM foo;")); ++ assertNotNull(parser.parseQuery("SELECT 1 || 'toto' FROM foo;")); ++ assertNotNull(parser.parseQuery("SELECT 'toto' || (-1) FROM foo;")); + }catch(ParseException pe){ + pe.printStackTrace(); + fail(); @@ -394,15 +280,15 @@ + fail(); + }catch(ParseException pe){} + try{ -+ parser.parseQuery("SELECT ABS(('toto' || 'blabla')) FROM foo;"); ++ parser.parseQuery("SELECT 'toto' || -1 FROM foo;"); + fail(); + }catch(ParseException pe){} + try{ -+ parser.parseQuery("SELECT 'toto' || 1 FROM foo;"); ++ parser.parseQuery("SELECT -1 || 'toto' FROM foo;"); + fail(); + }catch(ParseException pe){} + try{ -+ parser.parseQuery("SELECT 1 || 'toto' FROM foo;"); ++ parser.parseQuery("SELECT ABS(('toto' || 'blabla')) FROM foo;"); + fail(); + }catch(ParseException pe){} + try{ @@ -459,6 +345,30 @@ + assertEquals("Unresolved function: \"toto('blabla')\"! No UDF has been defined or found with the signature: toto(STRING).", ex.getErrors().next().getMessage()); + } + ++ // Test but with at least one column parameter: ++ try{ ++ parser.parseQuery("SELECT toto(colS) FROM foo;"); ++ fail("This query contains an unknown UDF signature (the fct toto is declared with no parameter): this test should have failed!"); ++ }catch(ParseException e){ ++ assertTrue(e instanceof UnresolvedIdentifiersException); ++ UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e; ++ assertEquals(1, ex.getNbErrors()); ++ assertEquals("Unresolved function: \"toto(colS)\"! No UDF has been defined or found with the signature: toto(STRING).", ex.getErrors().next().getMessage()); ++ } ++ ++ // Test but with at least one unknown column parameter: ++ try{ ++ parser.parseQuery("SELECT toto(whatami) FROM foo;"); ++ fail("This query contains an unknown UDF signature (the fct toto is declared with no parameter): this test should have failed!"); ++ }catch(ParseException e){ ++ assertTrue(e instanceof UnresolvedIdentifiersException); ++ UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e; ++ assertEquals(2, ex.getNbErrors()); ++ Iterator errors = ex.getErrors(); ++ assertEquals("Unknown column \"whatami\" !", errors.next().getMessage()); ++ assertEquals("Unresolved function: \"toto(whatami)\"! No UDF has been defined or found with the signature: toto(param1).", errors.next().getMessage()); ++ } ++ + // Test with a UDF whose the class is specified ; the corresponding object in the ADQL tree must be replace by an instance of this class: + udfs = new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("txt", new DBType(DBDatatype.VARCHAR))})}; + udfs[0].setUDFClass(UDFToto.class); @@ -619,7 +529,7 @@ + assertTrue(pe instanceof UnresolvedIdentifiersException); + UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe; + assertEquals(1, ex.getNbErrors()); -+ assertEquals("Coordinate system \"fk5 geocenter\" (= \"FK5 GEOCENTER SPHERICAL2\") not allowed in this implementation.", ex.getErrors().next().getMessage()); ++ assertEquals("Coordinate system \"fk5 geocenter\" (= \"FK5 GEOCENTER SPHERICAL2\") not allowed in this implementation. Allowed coordinate systems are: fk4 geocenter *, galactic * spherical2, icrs * *", ex.getErrors().next().getMessage()); + } + try{ + parser.parseQuery("SELECT Region('not(position fk5 heliocenter 1 2)') FROM foo;"); @@ -628,7 +538,7 @@ + assertTrue(pe instanceof UnresolvedIdentifiersException); + UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe; + assertEquals(1, ex.getNbErrors()); -+ assertEquals("Coordinate system \"FK5 HELIOCENTER\" (= \"FK5 HELIOCENTER SPHERICAL2\") not allowed in this implementation.", ex.getErrors().next().getMessage()); ++ assertEquals("Coordinate system \"FK5 HELIOCENTER\" (= \"FK5 HELIOCENTER SPHERICAL2\") not allowed in this implementation. Allowed coordinate systems are: fk4 geocenter *, galactic * spherical2, icrs * *", ex.getErrors().next().getMessage()); + } + + // Test with a coordinate system while none is allowed: @@ -649,8 +559,8 @@ + UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe; + assertEquals(2, ex.getNbErrors()); + Iterator itErrors = ex.getErrors(); -+ assertEquals("Coordinate system \"ICRS SPHERICAL2\" (= \"ICRS UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation.", itErrors.next().getMessage()); -+ assertEquals("Coordinate system \"icrs\" (= \"ICRS UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation.", itErrors.next().getMessage()); ++ assertEquals("Coordinate system \"ICRS SPHERICAL2\" (= \"ICRS UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation. No coordinate system is allowed!", itErrors.next().getMessage()); ++ assertEquals("Coordinate system \"icrs\" (= \"ICRS UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation. No coordinate system is allowed!", itErrors.next().getMessage()); + } + try{ + parser.parseQuery("SELECT Region('not(position fk4 1 2)') FROM foo;"); @@ -659,7 +569,7 @@ + assertTrue(pe instanceof UnresolvedIdentifiersException); + UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe; + assertEquals(1, ex.getNbErrors()); -+ assertEquals("Coordinate system \"FK4\" (= \"FK4 UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation.", ex.getErrors().next().getMessage()); ++ assertEquals("Coordinate system \"FK4\" (= \"FK4 UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation. No coordinate system is allowed!", ex.getErrors().next().getMessage()); + } + } + @@ -731,22 +641,16 @@ + fail("This query contains a concatenation between 2 strings: this test should have succeeded!"); + } + try{ -+ parser.parseQuery("SELECT colI || 'blabla' FROM foo;"); -+ fail("This query contains a concatenation between an integer and a string: this test should have failed!"); ++ assertNotNull(parser.parseQuery("SELECT colI || 'blabla' FROM foo;")); + }catch(ParseException e){ -+ assertTrue(e instanceof UnresolvedIdentifiersException); -+ UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e; -+ assertEquals(1, ex.getNbErrors()); -+ assertEquals("Type mismatch! A string value was expected instead of \"colI\".", ex.getErrors().next().getMessage()); ++ e.printStackTrace(); ++ fail("This query contains a concatenation between a column (whatever its type) and a string: this test should have succeeded!"); + } + try{ -+ parser.parseQuery("SELECT colG || 'blabla' FROM foo;"); -+ fail("This query contains a concatenation between a geometry and a string: this test should have failed!"); ++ assertNotNull(parser.parseQuery("SELECT colG || 'blabla' FROM foo;")); + }catch(ParseException e){ -+ assertTrue(e instanceof UnresolvedIdentifiersException); -+ UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e; -+ assertEquals(1, ex.getNbErrors()); -+ assertEquals("Type mismatch! A string value was expected instead of \"colG\".", ex.getErrors().next().getMessage()); ++ e.printStackTrace(); ++ fail("This query contains a concatenation between a column (whatever its type) and a string: this test should have succeeded!"); + } + + // Test the expected type - GEOMETRY - generated by the parser: @@ -882,6 +786,31 @@ + assertEquals("Type mismatch! A numeric value was expected instead of \"titi()\".", ex.getErrors().next().getMessage()); + } + ++ // Try with functions wrapped on 2 levels: ++ // i.e. fct1('blabla', fct2(fct3('blabla'))) ++ FunctionDef[] complexFcts = new FunctionDef[3]; ++ complexFcts[0] = new FunctionDef("fct1", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("str", new DBType(DBDatatype.VARCHAR)),new FunctionParam("num", new DBType(DBDatatype.INTEGER))}); ++ complexFcts[1] = new FunctionDef("fct2", new DBType(DBDatatype.INTEGER), new FunctionParam[]{new FunctionParam("str", new DBType(DBDatatype.VARCHAR))}); ++ complexFcts[2] = new FunctionDef("fct3", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("str", new DBType(DBDatatype.VARCHAR))}); ++ parser = new ADQLParser(new DBChecker(tables, Arrays.asList(complexFcts))); ++ // With parameters of the good type: ++ try{ ++ assertNotNull(parser.parseQuery("SELECT fct1('blabla', fct2(fct3('blabla'))) FROM foo")); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail("Types are matching: this test should have succeeded!"); ++ } ++ // With parameters of the bad type: ++ try{ ++ parser.parseQuery("SELECT fct2(fct1('blabla', fct3('blabla'))) FROM foo"); ++ fail("Parameters types are not matching: the parsing should have failed!"); ++ }catch(ParseException pe){ ++ assertEquals(UnresolvedIdentifiersException.class, pe.getClass()); ++ assertEquals(1, ((UnresolvedIdentifiersException)pe).getNbErrors()); ++ ParseException innerPe = ((UnresolvedIdentifiersException)pe).getErrors().next(); ++ assertEquals("Unresolved function: \"fct1('blabla', fct3('blabla'))\"! No UDF has been defined or found with the signature: fct1(STRING, STRING).", innerPe.getMessage()); ++ } ++ + // CLEAR ALL UDFs AND ALLOW UNKNOWN FUNCTION: + parser = new ADQLParser(new DBChecker(tables, null)); + @@ -1044,10 +973,10 @@ +} diff --git a/test/adql/db/TestFunctionDef.java b/test/adql/db/TestFunctionDef.java new file mode 100644 -index 0000000..c3d738a +index 0000000..6445887 --- /dev/null +++ b/test/adql/db/TestFunctionDef.java -@@ -0,0 +1,312 @@ +@@ -0,0 +1,372 @@ +package adql.db; + +import static org.junit.Assert.assertEquals; @@ -1055,11 +984,13 @@ +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + ++import org.junit.AfterClass; +import org.junit.Test; + +import adql.db.DBType.DBDatatype; +import adql.db.FunctionDef.FunctionParam; +import adql.parser.ParseException; ++import adql.query.operand.ADQLColumn; +import adql.query.operand.ADQLOperand; +import adql.query.operand.NumericConstant; +import adql.query.operand.StringConstant; @@ -1069,6 +1000,11 @@ + +public class TestFunctionDef { + ++ @AfterClass ++ public static void tearDownAfterClass() throws Exception{ ++ DBType.DBDatatype.UNKNOWN.setCustomType(null); ++ } ++ + @Test + public void testIsString(){ + for(DBDatatype type : DBDatatype.values()){ @@ -1109,8 +1045,10 @@ + case POINT: + case REGION: + case CLOB: ++ case UNKNOWN: + assertFalse(new FunctionDef("foo", new DBType(type)).isNumeric); + break; ++ case UNKNOWN_NUMERIC: + default: + assertTrue(new FunctionDef("foo", new DBType(type)).isNumeric); + } @@ -1183,6 +1121,20 @@ + fail("Wrong type parsing!"); + } + ++ // TYPE WITH SPACES AND/OR PARAMETER test: ++ try{ ++ assertEquals("foo() -> DOUBLE", FunctionDef.parse("foo() -> double precision").toString()); ++ assertEquals("foo(bar DOUBLE)", FunctionDef.parse("foo(bar DOUBLE Precision )").toString()); ++ assertEquals("foo() -> VARCHAR", FunctionDef.parse("foo() -> character varying").toString()); ++ assertEquals("foo(bar VARBINARY)", FunctionDef.parse("foo(bar bit varying)").toString()); ++ assertEquals("foo(bar VARCHAR(12))", FunctionDef.parse("foo(bar varchar (12))").toString()); ++ assertEquals("foo(bar VARCHAR(12))", FunctionDef.parse("foo(bar character varying (12))").toString()); ++ assertEquals("foo() -> DOUBLE", FunctionDef.parse("foo() -> double precision (2)").toString()); ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("Wrong type parsing!"); ++ } ++ + // WRONG string definitions: + try{ + FunctionDef.parse("123()"); @@ -1220,18 +1172,26 @@ + assertEquals("Wrong syntax for the 1-th parameter: \"param\"! Expected syntax: \"( (, )*)\", where =\"[a-zA-Z]+[a-zA-Z0-9_]*\", should be one of the types described in the UPLOAD section of the TAP documentation. Examples of good syntax: \"()\", \"(param INTEGER)\", \"(param1 INTEGER, param2 DOUBLE)\"", ex.getMessage()); + } + try{ -+ FunctionDef.parse("foo()->aType"); -+ fail("Wrong (return) type!"); ++ FunctionDef fct = FunctionDef.parse("foo()->aType"); ++ assertTrue(fct.isUnknown); ++ assertFalse(fct.isString); ++ assertFalse(fct.isNumeric); ++ assertFalse(fct.isGeometry); ++ assertEquals("?aType?", fct.returnType.type.toString()); + }catch(Exception ex){ -+ assertTrue(ex instanceof ParseException); -+ assertEquals("Unknown return type: \"aType\"!", ex.getMessage()); ++ ex.printStackTrace(System.err); ++ fail("Unknown types MUST be allowed!"); + } + try{ -+ FunctionDef.parse("foo()->aType(10)"); -+ fail("Wrong (return) type!"); ++ FunctionDef fct = FunctionDef.parse("foo()->aType(10)"); ++ assertTrue(fct.isUnknown); ++ assertFalse(fct.isString); ++ assertFalse(fct.isNumeric); ++ assertFalse(fct.isGeometry); ++ assertEquals("?aType(10)?", fct.returnType.type.toString()); + }catch(Exception ex){ -+ assertTrue(ex instanceof ParseException); -+ assertEquals("Unknown return type: \"aType(10)\"!", ex.getMessage()); ++ ex.printStackTrace(System.err); ++ fail("Unknown types MUST be allowed!"); + } + try{ + FunctionDef.parse("foo() -> "); @@ -1255,18 +1215,35 @@ + assertEquals(WRONG_PARAM_SYNTAX, ex.getMessage()); + } + try{ -+ FunctionDef.parse("foo(param1 aType)"); -+ fail("Wrong parameter type!"); ++ FunctionDef fct = FunctionDef.parse("foo(param1 aType)"); ++ assertTrue(fct.getParam(0).type.isUnknown()); ++ assertFalse(fct.getParam(0).type.isString()); ++ assertFalse(fct.getParam(0).type.isNumeric()); ++ assertFalse(fct.getParam(0).type.isGeometry()); ++ assertEquals("?aType?", fct.getParam(0).type.toString()); + }catch(Exception ex){ -+ assertTrue(ex instanceof ParseException); -+ assertEquals("Unknown type for the parameter \"param1\": \"aType\"!", ex.getMessage()); ++ ex.printStackTrace(System.err); ++ fail("Unknown types MUST be allowed!"); + } + try{ -+ FunctionDef.parse("foo(param1 aType(10))"); -+ fail("Wrong parameter type!"); ++ FunctionDef fct = FunctionDef.parse("foo(param1 aType(10))"); ++ assertTrue(fct.getParam(0).type.isUnknown()); ++ assertFalse(fct.getParam(0).type.isString()); ++ assertFalse(fct.getParam(0).type.isNumeric()); ++ assertFalse(fct.getParam(0).type.isGeometry()); ++ assertEquals("?aType(10)?", fct.getParam(0).type.toString()); + }catch(Exception ex){ -+ assertTrue(ex instanceof ParseException); -+ assertEquals("Unknown type for the parameter \"param1\": \"aType(10)\"!", ex.getMessage()); ++ ex.printStackTrace(System.err); ++ fail("Unknown types MUST be allowed!"); ++ } ++ try{ ++ FunctionDef fct = FunctionDef.parse("INTERSECTION(region1 region, region2 region) -> region"); ++ assertEquals(DBType.DBDatatype.REGION, fct.getParam(0).type.type); ++ assertEquals(DBType.DBDatatype.REGION, fct.getParam(1).type.type); ++ assertEquals(DBType.DBDatatype.REGION, fct.returnType.type); ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("Impossible to parse this REGION based FunctionDef! (see console for more details)"); + } + } + @@ -1284,7 +1261,7 @@ + // TEST :: With a function having the same name, but a different return type: [EQUAL} + assertEquals(0, def1.compareTo(new FunctionDef("fct1", new DBType(DBDatatype.INTEGER)))); + -+ // TEST :: With a function having the same name, but 2 parameters: [LESS (4 characters: ø against 1010)] ++ // TEST :: With a function having the same name, but 2 parameters: [LESS (6 characters: ø against 100100)] + assertEquals(-6, def1.compareTo(new FunctionDef("fct1", new DBType(DBDatatype.INTEGER), new FunctionParam[]{new FunctionParam("foo", new DBType(DBDatatype.INTEGER)),new FunctionParam("foo", new DBType(DBDatatype.INTEGER))}))); + + // DEFINITION 1 :: fct1(foo1 CHAR(12), foo2 DOUBLE) -> VARCHAR @@ -1357,12 +1334,24 @@ + e.printStackTrace(); + fail(); + } ++ ++ // Test with an UNKNOWN numeric type: ++ // TEST :: "fct0(foo)", where foo is a simple UNKNOWN [EQUAL] ++ FunctionDef def0 = new FunctionDef("fct0", null, new FunctionParam[]{new FunctionParam("whatever", new DBType(DBDatatype.VARCHAR))}); ++ DefaultDBColumn dbcol = new DefaultDBColumn("foo", new DefaultDBTable("toto")); ++ dbcol.setDatatype(new DBType(DBDatatype.UNKNOWN)); ++ ADQLColumn col = new ADQLColumn("foo"); ++ col.setDBLink(dbcol); ++ assertEquals(0, def0.compareTo(new DefaultUDF("fct0", new ADQLOperand[]{col}))); ++ // TEST :: "fct0(foo)", where foo is an UNKNOWN NUMERIC [LESS] ++ dbcol.setDatatype(new DBType(DBDatatype.UNKNOWN_NUMERIC)); ++ assertEquals(-1, def0.compareTo(new DefaultUDF("fct0", new ADQLOperand[]{col}))); + } + +} diff --git a/test/adql/db/TestSTCS.java b/test/adql/db/TestSTCS.java new file mode 100644 -index 0000000..8ff7646 +index 0000000..2f7698d --- /dev/null +++ b/test/adql/db/TestSTCS.java @@ -0,0 +1,536 @@ @@ -1734,7 +1723,7 @@ + fail(); + }catch(Exception e){ + assertTrue(e instanceof ParseException); -+ assertEquals("Incorrect syntax: \"HOME\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage()); ++ assertEquals("Incorrect syntax: \"HOME\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage()); + } + + // With wrong reference position: @@ -1743,7 +1732,7 @@ + fail(); + }catch(Exception e){ + assertTrue(e instanceof ParseException); -+ assertEquals("Incorrect syntax: \"HOME SPHERICAL2\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage()); ++ assertEquals("Incorrect syntax: \"HOME SPHERICAL2\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage()); + } + + // With a cartesian flavor: @@ -1782,7 +1771,7 @@ + fail(); + }catch(Exception e){ + assertTrue(e instanceof ParseException); -+ assertEquals("Incorrect syntax: \"icrsGeocentercarteSIAN2\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage()); ++ assertEquals("Incorrect syntax: \"icrsGeocentercarteSIAN2\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage()); + } + } + @@ -1886,7 +1875,7 @@ + fail(); + }catch(Exception ex){ + assertTrue(ex instanceof ParseException); -+ assertTrue(ex.getMessage().startsWith("Incorrect syntax: a coordinates pair (2 numerics separated by one or more spaces) was expected! Expected syntax: \"CIRCLE \", where coordPair=\" \", radius=\"\" and coordSys=\"[(ECLIPTIC|FK4|FK5|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.")); ++ assertTrue(ex.getMessage().startsWith("Incorrect syntax: a coordinates pair (2 numerics separated by one or more spaces) was expected! Expected syntax: \"CIRCLE \", where coordPair=\" \", radius=\"\" and coordSys=\"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.")); + } + + // TEST WITH EITHER A WRONG NUMERIC (L in lower case instead of 1) OR A MISSING OPENING PARENTHESIS: @@ -1902,16 +1891,324 @@ + } + } +} +diff --git a/test/adql/db/subquery_test_tables.xml b/test/adql/db/subquery_test_tables.xml +new file mode 100644 +index 0000000..526ef6e +--- /dev/null ++++ b/test/adql/db/subquery_test_tables.xml +@@ -0,0 +1,301 @@ ++ ++ ++ ++ public ++ ++ table1 ++ ++ oid ++ ++ meta.id;meta.main ++ ++ BIGINT ++ indexed ++ ++ ++ ra ++ deg ++ pos.eq.ra;meta.main ++ ++ DOUBLE ++ indexed ++ ++ ++ dec ++ Angle[deg] ++ pos.eq.dec;meta.main ++ ++ DOUBLE ++ indexed ++ ++ ++ h_m ++ mag ++ phot.mag;em.IR.H ++ ++ REAL ++ ++ ++ j_m ++ mag ++ phot.mag;em.IR.J ++ ++ REAL ++ ++ ++ k_m ++ mag ++ phot.mag;em.IR.K ++ ++ REAL ++ ++
++ ++ table2 ++ ++ oid2 ++ ++ meta.id;meta.main ++ ++ BIGINT ++ indexed ++ ++ ++ ra ++ deg ++ pos.eq.ra;meta.main ++ ++ DOUBLE ++ indexed ++ ++ ++ ra_error ++ mas ++ stat.error;pos.eq.ra ++ ++ DOUBLE ++ ++ ++ dec ++ deg ++ pos.eq.dec;meta.main ++ ++ DOUBLE ++ indexed ++ ++ ++ dec_error ++ mas ++ stat.error;pos.eq.dec ++ ++ DOUBLE ++ ++ ++ parallax ++ mas ++ pos.parallax ++ ++ DOUBLE ++ indexed ++ ++ ++ parallax_error ++ mas ++ stat.error;pos.parallax ++ ++ DOUBLE ++ indexed ++ ++ ++ magnitude ++ mag ++ phot.mag;stat.mean;em.opt ++ ++ DOUBLE ++ indexed ++ ++ ++ pmdec ++ mas/year ++ pos.pm;pos.eq.dec ++ ++ DOUBLE ++ indexed ++ ++ ++ pmdec_error ++ mas/year ++ stat.error;pos.pm;pos.eq.dec ++ ++ DOUBLE ++ ++ ++ pmra ++ mas/year ++ pos.pm;pos.eq.ra ++ ++ DOUBLE ++ indexed ++ ++ ++ pmra_error ++ mas/year ++ stat.error;pos.pm;pos.eq.ra ++ ++ DOUBLE ++ ++
++ ++ table3 ++ ++ oid ++ ++ meta.id ++ ++ BIGINT ++ ++ ++ oid2 ++ ++ ++ meta.id ++ ++ BIGINT ++ ++
++
++ ++ tap_schema ++ ++ tables ++ ++ description ++ VARCHAR ++ ++ ++ schema_name ++ VARCHAR ++ ++ ++ size ++ INTEGER ++ ++ ++ table_name ++ VARCHAR ++ ++ ++ table_type ++ VARCHAR ++ ++ ++ utype ++ VARCHAR ++ ++
++ ++ columns ++ ++ column_name ++ VARCHAR ++ ++ ++ datatype ++ VARCHAR ++ ++ ++ description ++ VARCHAR ++ ++ ++ indexed ++ INTEGER ++ ++ ++ principal ++ INTEGER ++ ++ ++ schema_name ++ VARCHAR ++ ++ ++ size ++ INTEGER ++ ++ ++ std ++ INTEGER ++ ++ ++ table_name ++ VARCHAR ++ ++ ++ ucd ++ VARCHAR ++ ++ ++ unit ++ VARCHAR ++ ++ ++ utype ++ VARCHAR ++ ++
++ ++ keys ++ ++ description ++ VARCHAR ++ ++ ++ from_table ++ VARCHAR ++ ++ ++ key_id ++ VARCHAR ++ ++ ++ target_table ++ VARCHAR ++ ++ ++ utype ++ VARCHAR ++ ++
++ ++ schemas ++ ++ description ++ VARCHAR ++ ++ ++ schema_name ++ VARCHAR ++ ++ ++ utype ++ VARCHAR ++ ++
++ ++ key_columns ++ ++ from_column ++ VARCHAR ++ ++ ++ key_id ++ VARCHAR ++ ++ ++ target_column ++ VARCHAR ++ ++
++
++
diff --git a/test/adql/parser/TestADQLParser.java b/test/adql/parser/TestADQLParser.java new file mode 100644 -index 0000000..10837d5 +index 0000000..3ccfff9 --- /dev/null +++ b/test/adql/parser/TestADQLParser.java -@@ -0,0 +1,43 @@ +@@ -0,0 +1,308 @@ +package adql.parser; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.After; @@ -1921,6 +2218,8 @@ +import org.junit.Test; + +import adql.query.ADQLQuery; ++import adql.query.from.ADQLJoin; ++import adql.query.from.ADQLTable; +import adql.query.operand.StringConstant; + +public class TestADQLParser { @@ -1931,58 +2230,1318 @@ + @AfterClass + public static void tearDownAfterClass() throws Exception{} + -+ @Before -+ public void setUp() throws Exception{} ++ @Before ++ public void setUp() throws Exception{} ++ ++ @After ++ public void tearDown() throws Exception{} ++ ++ @Test ++ public void testColumnReference(){ ++ ADQLParser parser = new ADQLParser(); ++ try{ ++ // ORDER BY ++ parser.parseQuery("SELECT * FROM cat ORDER BY oid;"); ++ parser.parseQuery("SELECT * FROM cat ORDER BY oid ASC;"); ++ parser.parseQuery("SELECT * FROM cat ORDER BY oid DESC;"); ++ parser.parseQuery("SELECT * FROM cat ORDER BY 1;"); ++ parser.parseQuery("SELECT * FROM cat ORDER BY 1 ASC;"); ++ parser.parseQuery("SELECT * FROM cat ORDER BY 1 DESC;"); ++ // GROUP BY ++ parser.parseQuery("SELECT * FROM cat GROUP BY oid;"); ++ parser.parseQuery("SELECT * FROM cat GROUP BY cat.oid;"); ++ // JOIN ... USING(...) ++ parser.parseQuery("SELECT * FROM cat JOIN cat2 USING(oid);"); ++ }catch(Exception e){ ++ e.printStackTrace(System.err); ++ fail("These ADQL queries are strictly correct! No error should have occured. (see stdout for more details)"); ++ } ++ ++ try{ ++ // ORDER BY ++ parser.parseQuery("SELECT * FROM cat ORDER BY cat.oid;"); ++ fail("A qualified column name is forbidden in ORDER BY! This test should have failed."); ++ }catch(Exception e){ ++ assertEquals(ParseException.class, e.getClass()); ++ assertEquals(" Encountered \".\". Was expecting one of: \",\" \";\" \"ASC\" \"DESC\" ", e.getMessage()); ++ } ++ ++ // Query reported as in error before the bug correction: ++ try{ ++ parser.parseQuery("SELECT TOP 10 browndwarfs.cat.jmag FROM browndwarfs.cat ORDER BY browndwarfs.cat.jmag"); ++ fail("A qualified column name is forbidden in ORDER BY! This test should have failed."); ++ }catch(Exception e){ ++ assertEquals(ParseException.class, e.getClass()); ++ assertEquals(" Encountered \".\". Was expecting one of: \",\" \";\" \"ASC\" \"DESC\" ", e.getMessage()); ++ } ++ ++ try{ ++ // GROUP BY with a SELECT item index ++ parser.parseQuery("SELECT * FROM cat GROUP BY 1;"); ++ fail("A SELECT item index is forbidden in GROUP BY! This test should have failed."); ++ }catch(Exception e){ ++ assertEquals(ParseException.class, e.getClass()); ++ assertEquals(" Encountered \"1\". Was expecting one of: \"\\\"\" ", e.getMessage()); ++ } ++ ++ try{ ++ // JOIN ... USING(...) ++ parser.parseQuery("SELECT * FROM cat JOIN cat2 USING(cat.oid);"); ++ fail("A qualified column name is forbidden in USING(...)! This test should have failed."); ++ }catch(Exception e){ ++ assertEquals(ParseException.class, e.getClass()); ++ assertEquals(" Encountered \".\". Was expecting one of: \")\" \",\" ", e.getMessage()); ++ } ++ ++ try{ ++ // JOIN ... USING(...) ++ parser.parseQuery("SELECT * FROM cat JOIN cat2 USING(1);"); ++ fail("A column index is forbidden in USING(...)! This test should have failed."); ++ }catch(Exception e){ ++ assertEquals(ParseException.class, e.getClass()); ++ assertEquals(" Encountered \"1\". Was expecting one of: \"\\\"\" ", e.getMessage()); ++ } ++ } ++ ++ @Test ++ public void testDelimitedIdentifiersWithDot(){ ++ ADQLParser parser = new ADQLParser(); ++ try{ ++ ADQLQuery query = parser.parseQuery("SELECT * FROM \"B/avo.rad/catalog\";"); ++ assertEquals("B/avo.rad/catalog", query.getFrom().getTables().get(0).getTableName()); ++ }catch(Exception e){ ++ e.printStackTrace(System.err); ++ fail("The ADQL query is strictly correct! No error should have occured. (see stdout for more details)"); ++ } ++ } ++ ++ @Test ++ public void testJoinTree(){ ++ ADQLParser parser = new ADQLParser(); ++ try{ ++ String[] queries = new String[]{"SELECT * FROM aTable A JOIN aSecondTable B ON A.id = B.id JOIN aThirdTable C ON B.id = C.id;","SELECT * FROM aTable A NATURAL JOIN aSecondTable B NATURAL JOIN aThirdTable C;"}; ++ for(String q : queries){ ++ ADQLQuery query = parser.parseQuery(q); ++ ++ assertTrue(query.getFrom() instanceof ADQLJoin); ++ ++ ADQLJoin join = ((ADQLJoin)query.getFrom()); ++ assertTrue(join.getLeftTable() instanceof ADQLJoin); ++ assertTrue(join.getRightTable() instanceof ADQLTable); ++ assertEquals("aThirdTable", ((ADQLTable)join.getRightTable()).getTableName()); ++ ++ join = (ADQLJoin)join.getLeftTable(); ++ assertTrue(join.getLeftTable() instanceof ADQLTable); ++ assertEquals("aTable", ((ADQLTable)join.getLeftTable()).getTableName()); ++ assertTrue(join.getRightTable() instanceof ADQLTable); ++ assertEquals("aSecondTable", ((ADQLTable)join.getRightTable()).getTableName()); ++ } ++ }catch(Exception e){ ++ e.printStackTrace(System.err); ++ fail("The ADQL query is strictly correct! No error should have occured. (see stdout for more details)"); ++ } ++ } ++ ++ @Test ++ public void test(){ ++ ADQLParser parser = new ADQLParser(); ++ try{ ++ ADQLQuery query = parser.parseQuery("SELECT 'truc''machin' 'bidule' --- why not a comment now ^^\n'FIN' FROM foo;"); ++ assertNotNull(query); ++ assertEquals("truc'machinbiduleFIN", ((StringConstant)(query.getSelect().get(0).getOperand())).getValue()); ++ assertEquals("'truc''machinbiduleFIN'", query.getSelect().get(0).getOperand().toADQL()); ++ }catch(Exception ex){ ++ fail("String litteral concatenation is perfectly legal according to the ADQL standard."); ++ } ++ ++ // With a comment ending the query ++ try{ ++ ADQLQuery query = parser.parseQuery("SELECT TOP 1 * FROM ivoa.ObsCore -- comment"); ++ assertNotNull(query); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("String litteral concatenation is perfectly legal according to the ADQL standard."); ++ } ++ } ++ ++ @Test ++ public void testIncorrectCharacter(){ ++ /* An identifier must be written only with digits, an underscore or ++ * regular latin characters: */ ++ try{ ++ (new ADQLParser()).parseQuery("select gr\u00e9gory FROM aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().startsWith("Incorrect character encountered at l.1, c.10:")); ++ } ++ ++ // But in a string, delimited identifier or a comment, it is fine: ++ try{ ++ (new ADQLParser()).parseQuery("select 'grégory' FROM aTable"); ++ (new ADQLParser()).parseQuery("select \"grégory\" FROM aTable"); ++ (new ADQLParser()).parseQuery("select * FROM aTable -- a comment by Grégory"); ++ }catch(Throwable t){ ++ fail("This error should never occurs because all these queries have an accentuated character but at a correct place."); ++ } ++ } ++ ++ @Test ++ public void testMultipleSpacesInOrderAndGroupBy(){ ++ try{ ++ ADQLParser parser = new ADQLParser(); ++ ++ // Single space: ++ parser.parseQuery("select * from aTable ORDER BY aCol"); ++ parser.parseQuery("select * from aTable GROUP BY aCol"); ++ ++ // More than one space: ++ parser.parseQuery("select * from aTable ORDER BY aCol"); ++ parser.parseQuery("select * from aTable GROUP BY aCol"); ++ ++ // With any other space character: ++ parser.parseQuery("select * from aTable ORDER\tBY aCol"); ++ parser.parseQuery("select * from aTable ORDER\nBY aCol"); ++ parser.parseQuery("select * from aTable ORDER \t\nBY aCol"); ++ ++ parser.parseQuery("select * from aTable GROUP\tBY aCol"); ++ parser.parseQuery("select * from aTable GROUP\nBY aCol"); ++ parser.parseQuery("select * from aTable GROUP \t\nBY aCol"); ++ }catch(Throwable t){ ++ t.printStackTrace(); ++ fail("Having multiple space characters between the ORDER/GROUP and the BY keywords should not generate any parsing error."); ++ } ++ } ++ ++ @Test ++ public void testADQLReservedWord(){ ++ ADQLParser parser = new ADQLParser(); ++ ++ final String hintAbs = "\n(HINT: \"abs\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)"; ++ final String hintPoint = "\n(HINT: \"point\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)"; ++ final String hintExists = "\n(HINT: \"exists\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)"; ++ final String hintLike = "\n(HINT: \"LIKE\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)"; ++ ++ /* TEST AS A COLUMN/TABLE/SCHEMA NAME... */ ++ // ...with a numeric function name (but no param): ++ try{ ++ parser.parseQuery("select abs from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintAbs)); ++ } ++ // ...with a geometric function name (but no param): ++ try{ ++ parser.parseQuery("select point from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintPoint)); ++ } ++ // ...with an ADQL function name (but no param): ++ try{ ++ parser.parseQuery("select exists from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintExists)); ++ } ++ // ...with an ADQL syntax item: ++ try{ ++ parser.parseQuery("select LIKE from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintLike)); ++ } ++ ++ /* TEST AS AN ALIAS... */ ++ // ...with a numeric function name (but no param): ++ try{ ++ parser.parseQuery("select aCol AS abs from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintAbs)); ++ } ++ // ...with a geometric function name (but no param): ++ try{ ++ parser.parseQuery("select aCol AS point from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintPoint)); ++ } ++ // ...with an ADQL function name (but no param): ++ try{ ++ parser.parseQuery("select aCol AS exists from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintExists)); ++ } ++ // ...with an ADQL syntax item: ++ try{ ++ parser.parseQuery("select aCol AS LIKE from aTable"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintLike)); ++ } ++ ++ /* TEST AT THE END OF THE QUERY (AND IN A WHERE) */ ++ try{ ++ parser.parseQuery("select aCol from aTable WHERE toto = abs"); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith(hintAbs)); ++ } ++ } ++ ++ @Test ++ public void testSQLReservedWord(){ ++ ADQLParser parser = new ADQLParser(); ++ ++ try{ ++ parser.parseQuery("SELECT rows FROM aTable"); ++ fail("\"ROWS\" is an SQL reserved word. This query should not pass."); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith("\n(HINT: \"rows\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)")); ++ } ++ ++ try{ ++ parser.parseQuery("SELECT CASE WHEN aCol = 2 THEN 'two' ELSE 'smth else' END as str FROM aTable"); ++ fail("ADQL does not support the CASE syntax. This query should not pass."); ++ }catch(Throwable t){ ++ assertEquals(ParseException.class, t.getClass()); ++ assertTrue(t.getMessage().endsWith("\n(HINT: \"CASE\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)")); ++ } ++ } ++ ++} +diff --git a/test/adql/parser/TestIdentifierItem.java b/test/adql/parser/TestIdentifierItem.java +new file mode 100644 +index 0000000..9c0575f +--- /dev/null ++++ b/test/adql/parser/TestIdentifierItem.java +@@ -0,0 +1,34 @@ ++package adql.parser; ++ ++import static adql.parser.ADQLParserConstants.DELIMITED_IDENTIFIER; ++import static adql.parser.ADQLParserConstants.REGULAR_IDENTIFIER; ++import static org.junit.Assert.assertEquals; ++ ++import org.junit.Before; ++import org.junit.BeforeClass; ++import org.junit.Test; ++ ++import adql.parser.IdentifierItems.IdentifierItem; ++ ++public class TestIdentifierItem { ++ ++ @BeforeClass ++ public static void setUpBeforeClass() throws Exception{} ++ ++ @Before ++ public void setUp() throws Exception{} ++ ++ @Test ++ public void testIdentifierItem(){ ++ /* A regular identifier (with no special characters) should be returned ++ * as provided: */ ++ IdentifierItem identifier = new IdentifierItem(new Token(REGULAR_IDENTIFIER, "m50"), false); ++ assertEquals("m50", identifier.toString()); ++ ++ /* Ensure doubled double quotes are escaped ++ * (i.e. considered as a single double quote): */ ++ identifier = new IdentifierItem(new Token(DELIMITED_IDENTIFIER, "m50\"\""), true); ++ assertEquals("m50\"", identifier.toString()); ++ } ++ ++} +diff --git a/test/adql/parser/TestUnknownTypes.java b/test/adql/parser/TestUnknownTypes.java +new file mode 100644 +index 0000000..2116da0 +--- /dev/null ++++ b/test/adql/parser/TestUnknownTypes.java +@@ -0,0 +1,163 @@ ++package adql.parser; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertFalse; ++import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.assertNull; ++import static org.junit.Assert.assertTrue; ++import static org.junit.Assert.fail; ++ ++import java.util.Arrays; ++import java.util.Collection; ++ ++import org.junit.After; ++import org.junit.AfterClass; ++import org.junit.Before; ++import org.junit.BeforeClass; ++import org.junit.Test; ++ ++import adql.db.DBChecker; ++import adql.db.DBColumn; ++import adql.db.DBTable; ++import adql.db.DBType; ++import adql.db.DBType.DBDatatype; ++import adql.db.DefaultDBColumn; ++import adql.db.DefaultDBTable; ++import adql.db.FunctionDef; ++import adql.query.ADQLQuery; ++ ++public class TestUnknownTypes { ++ ++ @BeforeClass ++ public static void setUpBeforeClass() throws Exception{} ++ ++ @AfterClass ++ public static void tearDownAfterClass() throws Exception{ ++ DBType.DBDatatype.UNKNOWN.setCustomType(null); ++ } ++ ++ @Before ++ public void setUp() throws Exception{} ++ ++ @After ++ public void tearDown() throws Exception{} ++ ++ public void testForFctDef(){ ++ // Test with the return type: ++ try{ ++ FunctionDef fct = FunctionDef.parse("foo()->aType"); ++ assertTrue(fct.isUnknown()); ++ assertFalse(fct.isString()); ++ assertFalse(fct.isNumeric()); ++ assertFalse(fct.isGeometry()); ++ assertEquals("?aType?", fct.returnType.type.toString()); ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("Unknown types MUST be allowed!"); ++ } ++ ++ // Test with a parameter type: ++ try{ ++ FunctionDef fct = FunctionDef.parse("foo(param1 aType)"); ++ assertTrue(fct.getParam(0).type.isUnknown()); ++ assertFalse(fct.getParam(0).type.isString()); ++ assertFalse(fct.getParam(0).type.isNumeric()); ++ assertFalse(fct.getParam(0).type.isGeometry()); ++ assertEquals("?aType?", fct.getParam(0).type.toString()); ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("Unknown types MUST be allowed!"); ++ } ++ } ++ ++ @Test ++ public void testForColumns(){ ++ final String QUERY_TXT = "SELECT FOO(C1), FOO(C2), FOO(C4), C1, C2, C3, C4 FROM T1"; ++ ++ try{ ++ // Create the parser: ++ ADQLParser parser = new ADQLParser(); ++ ++ // Create table/column metadata: ++ DefaultDBTable table1 = new DefaultDBTable("T1"); ++ table1.addColumn(new DefaultDBColumn("C1", table1)); ++ table1.addColumn(new DefaultDBColumn("C2", new DBType(DBDatatype.UNKNOWN), table1)); ++ table1.addColumn(new DefaultDBColumn("C3", new DBType(DBDatatype.VARCHAR), table1)); ++ table1.addColumn(new DefaultDBColumn("C4", new DBType(DBDatatype.UNKNOWN_NUMERIC), table1)); ++ Collection tList = Arrays.asList(new DBTable[]{table1}); ++ ++ // Check the type of the column T1.C1: ++ DBColumn col = table1.getColumn("C1", true); ++ assertNotNull(col); ++ assertNull(col.getDatatype()); ++ ++ // Check the type of the column T1.C2: ++ col = table1.getColumn("C2", true); ++ assertNotNull(col); ++ assertNotNull(col.getDatatype()); ++ assertTrue(col.getDatatype().isUnknown()); ++ assertFalse(col.getDatatype().isNumeric()); ++ assertFalse(col.getDatatype().isString()); ++ assertFalse(col.getDatatype().isGeometry()); ++ assertEquals("UNKNOWN", col.getDatatype().toString()); ++ ++ // Check the type of the column T1.C4: ++ col = table1.getColumn("C4", true); ++ assertNotNull(col); ++ assertNotNull(col.getDatatype()); ++ assertTrue(col.getDatatype().isUnknown()); ++ assertTrue(col.getDatatype().isNumeric()); ++ assertFalse(col.getDatatype().isString()); ++ assertFalse(col.getDatatype().isGeometry()); ++ assertEquals("UNKNOWN_NUMERIC", col.getDatatype().toString()); ++ ++ // Define a UDF, and allow all geometrical functions and coordinate systems: ++ FunctionDef udf1 = FunctionDef.parse("FOO(x INTEGER) -> INTEGER"); ++ Collection udfList = Arrays.asList(new FunctionDef[]{udf1}); ++ Collection geoList = null; ++ Collection csList = null; ++ ++ // Create the Query checker: ++ QueryChecker checker = new DBChecker(tList, udfList, geoList, csList); ++ ++ // Parse the query: ++ ADQLQuery pq = parser.parseQuery(QUERY_TXT); ++ ++ // Check the parsed query: ++ checker.check(pq); ++ ++ /* Ensure the type of every ADQLColumn is as expected: */ ++ // isNumeric() = true for FOO(C1), but false for the others ++ assertTrue(pq.getSelect().get(0).getOperand().isNumeric()); ++ assertFalse(pq.getSelect().get(0).getOperand().isString()); ++ assertFalse(pq.getSelect().get(0).getOperand().isGeometry()); ++ // isNumeric() = true for FOO(C2), but false for the others ++ assertTrue(pq.getSelect().get(1).getOperand().isNumeric()); ++ assertFalse(pq.getSelect().get(1).getOperand().isString()); ++ assertFalse(pq.getSelect().get(1).getOperand().isGeometry()); ++ // isNumeric() = true for FOO(C4), but false for the others ++ assertTrue(pq.getSelect().get(2).getOperand().isNumeric()); ++ assertFalse(pq.getSelect().get(2).getOperand().isString()); ++ assertFalse(pq.getSelect().get(2).getOperand().isGeometry()); ++ // isNumeric() = isString() = isGeometry() for C1 ++ assertTrue(pq.getSelect().get(3).getOperand().isNumeric()); ++ assertTrue(pq.getSelect().get(3).getOperand().isString()); ++ assertTrue(pq.getSelect().get(3).getOperand().isGeometry()); ++ // isNumeric() = isString() = isGeometry() for C2 ++ assertTrue(pq.getSelect().get(4).getOperand().isNumeric()); ++ assertTrue(pq.getSelect().get(4).getOperand().isString()); ++ assertTrue(pq.getSelect().get(4).getOperand().isGeometry()); ++ // isString() = true for C3, but false for the others ++ assertFalse(pq.getSelect().get(5).getOperand().isNumeric()); ++ assertTrue(pq.getSelect().get(5).getOperand().isString()); ++ assertFalse(pq.getSelect().get(5).getOperand().isGeometry()); ++ // isString() = true for C4, but false for the others ++ assertTrue(pq.getSelect().get(6).getOperand().isNumeric()); ++ assertFalse(pq.getSelect().get(6).getOperand().isString()); ++ assertFalse(pq.getSelect().get(6).getOperand().isGeometry()); ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("The construction, configuration and usage of the parser are correct. Nothing should have failed here. (see console for more details)"); ++ } ++ } ++} +diff --git a/test/adql/query/TestADQLObjectPosition.java b/test/adql/query/TestADQLObjectPosition.java +new file mode 100644 +index 0000000..a03b24c +--- /dev/null ++++ b/test/adql/query/TestADQLObjectPosition.java +@@ -0,0 +1,140 @@ ++package adql.query; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.fail; ++ ++import java.util.Iterator; ++import java.util.List; ++ ++import org.junit.Before; ++import org.junit.Test; ++ ++import adql.parser.ADQLParser; ++import adql.parser.ParseException; ++import adql.query.constraint.Comparison; ++import adql.query.from.ADQLJoin; ++import adql.query.from.ADQLTable; ++import adql.query.operand.ADQLColumn; ++import adql.query.operand.ADQLOperand; ++import adql.query.operand.function.ADQLFunction; ++import adql.search.SimpleSearchHandler; ++ ++public class TestADQLObjectPosition { ++ ++ private ADQLParser parser = new ADQLParser(); ++ ++ @Before ++ public void setUp(){ ++ ++ } ++ ++ @Test ++ public void testPositionInAllClauses(){ ++ try{ ++ ADQLQuery query = parser.parseQuery("SELECT truc, bidule.machin, toto(truc, chose) AS \"super\" FROM foo JOIN bidule USING(id) WHERE truc > 12.5 AND bidule.machin < 5 GROUP BY chose HAVING try > 0 ORDER BY chouetteAlors"); ++ ++ Iterator results = query.search(new SimpleSearchHandler(true){ ++ @Override ++ protected boolean match(ADQLObject obj){ ++ return obj.getPosition() == null; ++ } ++ }); ++ if (results.hasNext()){ ++ System.err.println("OBJECT WITH NO DEFINED POSITION:"); ++ while(results.hasNext()) ++ System.err.println(" * " + results.next().toADQL()); ++ fail("At least one item of the generated ADQL tree does not have a position information! (see System.err for more details)"); ++ } ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail("No error should have occured here: the ADQL query is syntactically correct!"); ++ } ++ } ++ ++ private void assertEquality(final TextPosition expected, final TextPosition realPos){ ++ assertEquals(expected.beginLine, realPos.beginLine); ++ assertEquals(expected.beginColumn, realPos.beginColumn); ++ assertEquals(expected.endLine, realPos.endLine); ++ assertEquals(expected.endColumn, realPos.endColumn); ++ } ++ ++ @Test ++ public void testPositionAccuracy(){ ++ try{ ++ ADQLQuery query = parser.parseQuery("SELECT TOP 1000 oid FROM foo JOIN bar USING(oid)\nWHERE foo || toto = 'truc'\n AND 2 > 1+0 GROUP BY oid HAVING COUNT(oid) > 10\n\tORDER BY 1 DESC"); ++ // Test SELECT ++ assertEquality(new TextPosition(1, 1, 1, 20), query.getSelect().getPosition()); ++ // Test ADQLColumn (here: "oid") ++ assertEquality(new TextPosition(1, 17, 1, 20), query.getSelect().get(0).getPosition()); ++ // Test FROM & ADQLJoin ++ /* NB: The clause FROM is the only one which is not a list but a single item of type FromContent (JOIN or table). ++ * That's why, it is not possible to get its exact starting position ('FROM') ; the starting position is ++ * the one of the first table of the clause FROM. */ ++ assertEquality(new TextPosition(1, 26, 1, 49), query.getFrom().getPosition()); ++ // Test ADQLTable ++ List tables = query.getFrom().getTables(); ++ assertEquality(new TextPosition(1, 26, 1, 29), tables.get(0).getPosition()); ++ assertEquality(new TextPosition(1, 35, 1, 38), tables.get(1).getPosition()); ++ // Test the join condition: ++ Iterator itCol = ((ADQLJoin)query.getFrom()).getJoinedColumns(); ++ assertEquality(new TextPosition(1, 45, 1, 48), itCol.next().getPosition()); ++ // Test WHERE ++ assertEquality(new TextPosition(2, 1, 3, 18), query.getWhere().getPosition()); ++ // Test COMPARISON = CONSTRAINT ++ Comparison comp = (Comparison)(query.getWhere().get(0)); ++ assertEquality(new TextPosition(2, 7, 2, 27), comp.getPosition()); ++ // Test left operand = concatenation: ++ ADQLOperand operand = comp.getLeftOperand(); ++ assertEquality(new TextPosition(2, 7, 2, 18), operand.getPosition()); ++ Iterator itObj = operand.adqlIterator(); ++ // foo ++ assertEquality(new TextPosition(2, 7, 2, 10), itObj.next().getPosition()); ++ // toto ++ assertEquality(new TextPosition(2, 14, 2, 18), itObj.next().getPosition()); ++ // Test right operand = string: ++ operand = comp.getRightOperand(); ++ assertEquality(new TextPosition(2, 21, 2, 27), operand.getPosition()); ++ // Test COMPARISON > CONSTRAINT: ++ comp = (Comparison)(query.getWhere().get(1)); ++ assertEquality(new TextPosition(3, 11, 3, 18), comp.getPosition()); ++ // Test left operand = numeric: ++ operand = comp.getLeftOperand(); ++ assertEquality(new TextPosition(3, 11, 3, 12), operand.getPosition()); ++ // Test right operand = operation: ++ operand = comp.getRightOperand(); ++ assertEquality(new TextPosition(3, 15, 3, 18), operand.getPosition()); ++ itObj = operand.adqlIterator(); ++ // 1 ++ assertEquality(new TextPosition(3, 15, 3, 16), itObj.next().getPosition()); ++ // 0 ++ assertEquality(new TextPosition(3, 17, 3, 18), itObj.next().getPosition()); ++ // Test GROUP BY ++ assertEquality(new TextPosition(3, 19, 3, 31), query.getGroupBy().getPosition()); ++ // oid ++ assertEquality(new TextPosition(3, 28, 3, 31), query.getGroupBy().get(0).getPosition()); ++ // Test HAVING ++ assertEquality(new TextPosition(3, 32, 3, 54), query.getHaving().getPosition()); ++ // Test COMPARISON > CONSTRAINT: ++ comp = (Comparison)(query.getHaving().get(0)); ++ assertEquality(new TextPosition(3, 39, 3, 54), comp.getPosition()); ++ // Test left operand = COUNT function: ++ operand = comp.getLeftOperand(); ++ assertEquality(new TextPosition(3, 39, 3, 49), operand.getPosition()); ++ // Test parameter = ADQLColumn oid: ++ assertEquality(new TextPosition(3, 45, 3, 48), ((ADQLFunction)operand).getParameter(0).getPosition()); ++ // Test right operand = operation: ++ operand = comp.getRightOperand(); ++ assertEquality(new TextPosition(3, 52, 3, 54), operand.getPosition()); ++ // Test ORDER BY ++ assertEquality(new TextPosition(4, 9, 4, 24), query.getOrderBy().getPosition()); ++ // Test column index: ++ assertEquality(new TextPosition(4, 18, 4, 19), query.getOrderBy().get(0).getPosition()); ++ ++ }catch(ParseException pe){ ++ System.err.println("ERROR IN THE ADQL QUERY AT " + pe.getPosition()); ++ pe.printStackTrace(); ++ fail("No error should have occured here: the ADQL query is syntactically correct!"); ++ } ++ } ++ ++} +diff --git a/test/adql/query/TestADQLQuery.java b/test/adql/query/TestADQLQuery.java +new file mode 100644 +index 0000000..272622e +--- /dev/null ++++ b/test/adql/query/TestADQLQuery.java +@@ -0,0 +1,240 @@ ++package adql.query; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNull; ++import static org.junit.Assert.fail; ++ ++import java.util.ArrayList; ++import java.util.Iterator; ++import java.util.List; ++ ++import org.junit.Before; ++import org.junit.Test; ++ ++import adql.db.DBType; ++import adql.db.DBType.DBDatatype; ++import adql.db.FunctionDef; ++import adql.query.constraint.Comparison; ++import adql.query.constraint.ComparisonOperator; ++import adql.query.constraint.ConstraintsGroup; ++import adql.query.from.ADQLTable; ++import adql.query.operand.ADQLColumn; ++import adql.query.operand.ADQLOperand; ++import adql.query.operand.Concatenation; ++import adql.query.operand.NumericConstant; ++import adql.query.operand.Operation; ++import adql.query.operand.OperationType; ++import adql.query.operand.StringConstant; ++import adql.query.operand.WrappedOperand; ++import adql.query.operand.function.DefaultUDF; ++import adql.query.operand.function.MathFunction; ++import adql.query.operand.function.MathFunctionType; ++import adql.query.operand.function.SQLFunction; ++import adql.query.operand.function.SQLFunctionType; ++import adql.query.operand.function.geometry.BoxFunction; ++import adql.query.operand.function.geometry.CentroidFunction; ++import adql.query.operand.function.geometry.CircleFunction; ++import adql.query.operand.function.geometry.GeometryFunction; ++import adql.query.operand.function.geometry.GeometryFunction.GeometryValue; ++import adql.query.operand.function.geometry.PointFunction; ++import adql.query.operand.function.geometry.PolygonFunction; ++import adql.query.operand.function.geometry.RegionFunction; ++import adql.search.IReplaceHandler; ++import adql.search.ISearchHandler; ++import adql.search.SearchColumnHandler; ++import adql.search.SimpleReplaceHandler; ++ ++public class TestADQLQuery { ++ private ADQLQuery query = null; ++ private List columns = new ArrayList(8); ++ private List typeObjColumns = new ArrayList(3); ++ ++ @Before ++ public void setUp(){ ++ query = new ADQLQuery(); ++ columns.clear(); ++ typeObjColumns.clear(); ++ ++ columns.add(new ADQLColumn("O", "nameObj")); // 0 = O.nameObj ++ columns.add(new ADQLColumn("O", "typeObj")); // 1 = O.typeObj ++ columns.add(new ADQLColumn("O", "ra")); // 2 = O.ra ++ columns.add(new ADQLColumn("O", "dec")); // 3 = O.dec ++ columns.add(new ADQLColumn("ra")); // 4 = ra ++ columns.add(new ADQLColumn("dec")); // 5 = dec ++ columns.add(new ADQLColumn("typeObj")); // 6 = typeObj ++ columns.add(new ADQLColumn("typeObj")); // 7 = typeObj ++ ++ typeObjColumns.add(columns.get(1)); ++ typeObjColumns.add(columns.get(6)); ++ typeObjColumns.add(columns.get(7)); ++ ++ // SELECT: ++ ClauseSelect select = query.getSelect(); ++ Concatenation concatObj = new Concatenation(); ++ concatObj.add(columns.get(0)); // O.nameObj ++ concatObj.add(new StringConstant(" (")); ++ concatObj.add(columns.get(1)); // O.typeObj ++ concatObj.add(new StringConstant(")")); ++ select.add(new SelectItem(new WrappedOperand(concatObj), "Nom objet")); ++ select.add(columns.get(2)); // O.ra ++ select.add(columns.get(3)); // O.dec ++ ++ // FROM: ++ ADQLTable table = new ADQLTable("truc.ObsCore"); ++ table.setAlias("O"); ++ // table.setJoin(new ADQLJoin(JoinType.INNER, new ADQLTable("VO"))); ++ query.setFrom(table); ++ ++ // WHERE: ++ ClauseConstraints where = query.getWhere(); ++ // ra/dec > 1 ++ where.add(new Comparison(new Operation(columns.get(4), OperationType.DIV, columns.get(5)), ComparisonOperator.GREATER_THAN, new NumericConstant("1"))); ++ ConstraintsGroup constOr = new ConstraintsGroup(); ++ // AND (typeObj == 'Star' ++ constOr.add(new Comparison(columns.get(6), ComparisonOperator.EQUAL, new StringConstant("Star"))); ++ // OR typeObj LIKE 'Galaxy*') ++ constOr.add("OR", new Comparison(columns.get(7), ComparisonOperator.LIKE, new StringConstant("Galaxy*"))); ++ where.add("AND", constOr); ++ ++ // ORDER BY: ++ ClauseADQL orderBy = query.getOrderBy(); ++ orderBy.add(new ADQLOrder(1, true)); ++ } ++ ++ @Test ++ public void testADQLQuery(){ ++ assertEquals("SELECT (O.nameObj || ' (' || O.typeObj || ')') AS Nom objet , O.ra , O.dec\nFROM truc.ObsCore AS O\nWHERE ra/dec > 1 AND (typeObj = 'Star' OR typeObj LIKE 'Galaxy*')\nORDER BY 1 DESC", query.toADQL()); ++ } ++ ++ @Test ++ public void testSearch(){ ++ ISearchHandler sHandler = new SearchColumnHandler(false); ++ Iterator results = query.search(sHandler); ++ assertEquals(columns.size(), sHandler.getNbMatch()); ++ for(ADQLColumn expectedCol : columns) ++ assertEquals(expectedCol, results.next()); ++ } ++ ++ @Test ++ public void testReplace(){ ++ IReplaceHandler sHandler = new SimpleReplaceHandler(false, false){ ++ @Override ++ protected boolean match(ADQLObject obj){ ++ return (obj instanceof ADQLColumn) && (((ADQLColumn)obj).getColumnName().equalsIgnoreCase("typeObj")); ++ } ++ ++ @Override ++ public ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException{ ++ return new ADQLColumn("NewTypeObj"); ++ } ++ }; ++ sHandler.searchAndReplace(query); ++ assertEquals(typeObjColumns.size(), sHandler.getNbMatch()); ++ assertEquals(sHandler.getNbMatch(), sHandler.getNbReplacement()); ++ Iterator results = sHandler.iterator(); ++ for(ADQLColumn expectedCol : typeObjColumns) ++ assertEquals(expectedCol, results.next()); ++ assertEquals("SELECT (O.nameObj || ' (' || NewTypeObj || ')') AS Nom objet , O.ra , O.dec\nFROM truc.ObsCore AS O\nWHERE ra/dec > 1 AND (NewTypeObj = 'Star' OR NewTypeObj LIKE 'Galaxy*')\nORDER BY 1 DESC", query.toADQL()); ++ } ++ ++ @Test ++ public void testTypeResultingColumns(){ ++ ADQLQuery query = new ADQLQuery(); ++ query.setFrom(new ADQLTable("foo")); ++ ClauseSelect select = new ClauseSelect(); ++ query.setSelect(select); ++ ++ // Test with a numeric constant: ++ select.add(new NumericConstant(2.3)); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.UNKNOWN_NUMERIC, query.getResultingColumns()[0].getDatatype().type); ++ ++ // Test with a math operation: ++ select.clear(); ++ select.add(new Operation(new Operation(new NumericConstant(2), OperationType.MULT, new NumericConstant(3.14)), OperationType.DIV, new NumericConstant(5))); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.UNKNOWN_NUMERIC, query.getResultingColumns()[0].getDatatype().type); ++ ++ // Test with a math function: ++ try{ ++ select.clear(); ++ select.add(new MathFunction(MathFunctionType.SQRT, new ADQLColumn("col1"))); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.UNKNOWN_NUMERIC, query.getResultingColumns()[0].getDatatype().type); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("The mathematical function SQRT is well defined. This error should have occurred."); ++ } ++ ++ // Test with an aggregation function: ++ select.clear(); ++ select.add(new SQLFunction(SQLFunctionType.SUM, new ADQLColumn("col1"))); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.UNKNOWN_NUMERIC, query.getResultingColumns()[0].getDatatype().type); ++ ++ // Test with a string constant: ++ select.clear(); ++ select.add(new StringConstant("blabla")); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.VARCHAR, query.getResultingColumns()[0].getDatatype().type); ++ ++ // Test with a concatenation: ++ select.clear(); ++ Concatenation concat = new Concatenation(); ++ concat.add(new StringConstant("super ")); ++ concat.add(new ADQLColumn("foo", "col")); ++ select.add(concat); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.VARCHAR, query.getResultingColumns()[0].getDatatype().type); ++ ++ // Test with a POINT: ++ try{ ++ select.clear(); ++ select.add(new PointFunction(new StringConstant(""), new ADQLColumn("ra"), new ADQLColumn("dec"))); ++ select.add(new CentroidFunction(new GeometryValue(new ADQLColumn("aRegion")))); ++ assertEquals(2, query.getResultingColumns().length); ++ for(int i = 0; i < 2; i++) ++ assertEquals(DBDatatype.POINT, query.getResultingColumns()[i].getDatatype().type); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("The POINT function is well defined. This error should have occurred."); ++ } ++ ++ // Test with a REGION (CIRCLE, BOX, POLYGON and REGION functions): ++ try{ ++ select.clear(); ++ select.add(new CircleFunction(new StringConstant(""), new ADQLColumn("ra"), new ADQLColumn("dec"), new NumericConstant(1))); ++ select.add(new BoxFunction(new StringConstant(""), new ADQLColumn("ra"), new ADQLColumn("dec"), new NumericConstant(10), new NumericConstant(20))); ++ ADQLOperand[] points = new ADQLOperand[6]; ++ points[0] = new ADQLColumn("point1"); ++ points[1] = new ADQLColumn("point2"); ++ points[2] = new ADQLColumn("point3"); ++ points[3] = new ADQLColumn("point4"); ++ points[4] = new ADQLColumn("point5"); ++ points[5] = new ADQLColumn("point6"); ++ select.add(new PolygonFunction(new StringConstant(""), points)); ++ select.add(new RegionFunction(new StringConstant("CIRCLE '' ra dec 2.3"))); ++ assertEquals(4, query.getResultingColumns().length); ++ for(int i = 0; i < 4; i++) ++ assertEquals(DBDatatype.REGION, query.getResultingColumns()[i].getDatatype().type); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("The geometrical functions are well defined. This error should have occurred."); ++ } ++ ++ // Test with a UDF having no definition: ++ select.clear(); ++ select.add(new DefaultUDF("foo", new ADQLOperand[0])); ++ assertEquals(1, query.getResultingColumns().length); ++ assertNull(query.getResultingColumns()[0].getDatatype()); ++ ++ // Test with a UDF having a definition: ++ select.clear(); ++ DefaultUDF udf = new DefaultUDF("foo", new ADQLOperand[0]); ++ udf.setDefinition(new FunctionDef("foo", new DBType(DBDatatype.INTEGER))); ++ select.add(udf); ++ assertEquals(1, query.getResultingColumns().length); ++ assertEquals(DBDatatype.INTEGER, query.getResultingColumns()[0].getDatatype().type); ++ ++ } ++} +diff --git a/test/adql/query/TestIdentifierField.java b/test/adql/query/TestIdentifierField.java +new file mode 100644 +index 0000000..2885d10 +--- /dev/null ++++ b/test/adql/query/TestIdentifierField.java +@@ -0,0 +1,25 @@ ++package adql.query; ++ ++import static org.junit.Assert.assertFalse; ++import static org.junit.Assert.assertTrue; ++ ++import org.junit.Test; ++ ++import adql.query.IdentifierField; ++ ++public class TestIdentifierField { ++ ++ @Test ++ public void testIsCaseSensitive(){ ++ byte b = 0x00; ++ assertFalse(IdentifierField.SCHEMA.isCaseSensitive(b)); ++ b = IdentifierField.SCHEMA.setCaseSensitive(b, true); ++ assertTrue(IdentifierField.SCHEMA.isCaseSensitive(b)); ++ } ++ ++ /*@Test ++ public void testSetCaseSensitive(){ ++ fail("Not yet implemented"); ++ }*/ ++ ++} +diff --git a/test/adql/query/constraint/TestIN.java b/test/adql/query/constraint/TestIN.java +new file mode 100644 +index 0000000..ab385db +--- /dev/null ++++ b/test/adql/query/constraint/TestIN.java +@@ -0,0 +1,95 @@ ++package adql.query.constraint; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.fail; ++ ++import java.util.Iterator; ++ ++import org.junit.BeforeClass; ++import org.junit.Test; ++ ++import adql.query.ADQLList; ++import adql.query.ADQLObject; ++import adql.query.ADQLOrder; ++import adql.query.ADQLQuery; ++import adql.query.ClauseSelect; ++import adql.query.constraint.In; ++import adql.query.from.ADQLTable; ++import adql.query.operand.ADQLColumn; ++import adql.query.operand.ADQLOperand; ++import adql.query.operand.StringConstant; ++import adql.search.IReplaceHandler; ++import adql.search.SimpleReplaceHandler; ++import adql.translator.ADQLTranslator; ++import adql.translator.PostgreSQLTranslator; ++ ++public class TestIN { ++ ++ private static ADQLTranslator translator = null; ++ ++ @BeforeClass ++ public static void setUpBeforeClass(){ ++ translator = new PostgreSQLTranslator(); ++ } ++ ++ @Test ++ public void testIN(){ ++ // Test with a simple list of values (here, string constants): ++ In myIn = new In(new ADQLColumn("typeObj"), new ADQLOperand[]{new StringConstant("galaxy"),new StringConstant("star"),new StringConstant("planet"),new StringConstant("nebula")}, true); ++ // check the ADQL: ++ assertEquals("typeObj NOT IN ('galaxy' , 'star' , 'planet' , 'nebula')", myIn.toADQL()); ++ // check the SQL translation: ++ try{ ++ assertEquals(myIn.toADQL(), translator.translate(myIn)); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded because the IN statement is correct and theoretically well supported by the POSTGRESQL translator!"); ++ } ++ ++ // Test with a sub-query: ++ ADQLQuery subQuery = new ADQLQuery(); ++ ++ ClauseSelect select = subQuery.getSelect(); ++ select.setDistinctColumns(true); ++ select.setLimit(10); ++ select.add(new ADQLColumn("typeObj")); ++ ++ subQuery.setFrom(new ADQLTable("Objects")); ++ ++ ADQLList orderBy = subQuery.getOrderBy(); ++ orderBy.add(new ADQLOrder(1)); ++ ++ myIn.setSubQuery(subQuery); ++ // check the ADQL: ++ assertEquals("typeObj NOT IN (SELECT DISTINCT TOP 10 typeObj\nFROM Objects\nORDER BY 1 ASC)", myIn.toADQL()); ++ // check the SQL translation: ++ try{ ++ assertEquals("typeObj NOT IN (SELECT DISTINCT typeObj AS \"typeObj\"\nFROM Objects\nORDER BY 1 ASC\nLimit 10)", translator.translate(myIn)); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded because the IN statement is correct and theoretically well supported by the POSTGRESQL translator!"); ++ } ++ ++ // Test after replacement inside this IN statement: ++ IReplaceHandler sHandler = new SimpleReplaceHandler(true){ ++ ++ @Override ++ public boolean match(ADQLObject obj){ ++ return (obj instanceof ADQLColumn) && ((ADQLColumn)obj).getColumnName().equals("typeObj"); ++ } ++ ++ @Override ++ public ADQLObject getReplacer(ADQLObject objToReplace){ ++ return new ADQLColumn("type"); ++ } ++ }; ++ sHandler.searchAndReplace(myIn); ++ assertEquals(2, sHandler.getNbMatch()); ++ assertEquals(sHandler.getNbMatch(), sHandler.getNbReplacement()); ++ Iterator results = sHandler.iterator(); ++ while(results.hasNext()) ++ assertEquals("typeObj", results.next().toADQL()); ++ assertEquals("type NOT IN (SELECT DISTINCT TOP 10 type\nFROM Objects\nORDER BY 1 ASC)", myIn.toADQL()); ++ } ++ ++} +diff --git a/test/adql/query/from/TestCrossJoin.java b/test/adql/query/from/TestCrossJoin.java +new file mode 100644 +index 0000000..ce440bc +--- /dev/null ++++ b/test/adql/query/from/TestCrossJoin.java +@@ -0,0 +1,95 @@ ++package adql.query.from; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.fail; ++ ++import java.util.List; ++ ++import org.junit.AfterClass; ++import org.junit.Before; ++import org.junit.Test; ++ ++import adql.db.DBColumn; ++import adql.db.DBType; ++import adql.db.DBType.DBDatatype; ++import adql.db.DefaultDBColumn; ++import adql.db.DefaultDBTable; ++import adql.db.SearchColumnList; ++import adql.query.IdentifierField; ++ ++public class TestCrossJoin { ++ ++ private ADQLTable tableA, tableB; ++ ++ @AfterClass ++ public static void tearDownAfterClass() throws Exception{} ++ ++ @Before ++ public void setUp() throws Exception{ ++ /* SET THE TABLES AND COLUMNS NEEDED FOR THE TEST */ ++ // Describe the available table: ++ DefaultDBTable metaTableA = new DefaultDBTable("A"); ++ metaTableA.setADQLSchemaName("public"); ++ DefaultDBTable metaTableB = new DefaultDBTable("B"); ++ metaTableB.setADQLSchemaName("public"); ++ ++ // Describe its columns: ++ metaTableA.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableA)); ++ metaTableA.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableA)); ++ metaTableB.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableB)); ++ metaTableB.addColumn(new DefaultDBColumn("txtb", new DBType(DBDatatype.VARCHAR), metaTableB)); ++ ++ // Build the ADQL tables: ++ tableA = new ADQLTable("A"); ++ tableA.setDBLink(metaTableA); ++ tableB = new ADQLTable("B"); ++ tableB.setDBLink(metaTableB); ++ } ++ ++ @Test ++ public void testGetDBColumns(){ ++ try{ ++ ADQLJoin join = new CrossJoin(tableA, tableB); ++ SearchColumnList joinColumns = join.getDBColumns(); ++ assertEquals(4, joinColumns.size()); ++ ++ // check column A.id and B.id ++ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(2, lstFound.size()); ++ // A.id ++ assertNotNull(lstFound.get(0).getTable()); ++ assertEquals("A", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ // B.id ++ assertNotNull(lstFound.get(1).getTable()); ++ assertEquals("B", lstFound.get(1).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(1).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check column A.txta ++ lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotNull(lstFound.get(0).getTable()); ++ assertEquals("A", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check column B.txtb ++ lstFound = joinColumns.search(null, null, null, "txtb", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotNull(lstFound.get(0).getTable()); ++ assertEquals("B", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "B", "txtb", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "A", "txtb", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded!"); ++ } ++ } ++} +diff --git a/test/adql/query/from/TestInnerJoin.java b/test/adql/query/from/TestInnerJoin.java +new file mode 100644 +index 0000000..57c4f87 +--- /dev/null ++++ b/test/adql/query/from/TestInnerJoin.java +@@ -0,0 +1,158 @@ ++package adql.query.from; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.fail; ++ ++import java.util.ArrayList; ++import java.util.List; ++ ++import org.junit.Before; ++import org.junit.Test; ++ ++import adql.db.DBColumn; ++import adql.db.DBCommonColumn; ++import adql.db.DBType; ++import adql.db.DBType.DBDatatype; ++import adql.db.DefaultDBColumn; ++import adql.db.DefaultDBTable; ++import adql.db.SearchColumnList; ++import adql.query.IdentifierField; ++import adql.query.operand.ADQLColumn; ++ ++public class TestInnerJoin { ++ ++ private ADQLTable tableA, tableB, tableC; ++ ++ @Before ++ public void setUp() throws Exception{ ++ /* SET THE TABLES AND COLUMNS NEEDED FOR THE TEST */ ++ // Describe the available table: ++ DefaultDBTable metaTableA = new DefaultDBTable("A"); ++ metaTableA.setADQLSchemaName("public"); ++ DefaultDBTable metaTableB = new DefaultDBTable("B"); ++ metaTableB.setADQLSchemaName("public"); ++ DefaultDBTable metaTableC = new DefaultDBTable("C"); ++ metaTableC.setADQLSchemaName("public"); ++ ++ // Describe its columns: ++ metaTableA.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableA)); ++ metaTableA.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableA)); ++ metaTableB.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableB)); ++ metaTableB.addColumn(new DefaultDBColumn("txtb", new DBType(DBDatatype.VARCHAR), metaTableB)); ++ metaTableC.addColumn(new DefaultDBColumn("Id", new DBType(DBDatatype.VARCHAR), metaTableC)); ++ metaTableC.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableC)); ++ metaTableC.addColumn(new DefaultDBColumn("txtc", new DBType(DBDatatype.VARCHAR), metaTableC)); ++ ++ // Build the ADQL tables: ++ tableA = new ADQLTable("A"); ++ tableA.setDBLink(metaTableA); ++ tableB = new ADQLTable("B"); ++ tableB.setDBLink(metaTableB); ++ tableC = new ADQLTable("C"); ++ tableC.setDBLink(metaTableC); ++ } ++ ++ @Test ++ public void testGetDBColumns(){ ++ // Test NATURAL JOIN 1: ++ try{ ++ ADQLJoin join = new InnerJoin(tableA, tableB); ++ SearchColumnList joinColumns = join.getDBColumns(); ++ assertEquals(3, joinColumns.size()); ++ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(1, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ lstFound = joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ lstFound = joinColumns.search(null, "public", "B", "txtb", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded!"); ++ } ++ ++ // Test NATURAL JOIN 2: ++ try{ ++ ADQLJoin join = new InnerJoin(tableA, tableC); ++ SearchColumnList joinColumns = join.getDBColumns(); ++ assertEquals(3, joinColumns.size()); ++ ++ // check id (column common to table A and C only): ++ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check txta (column common to table A and C only): ++ lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check txtc (only for table C) ++ lstFound = joinColumns.search(null, null, null, "txtc", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotNull(lstFound.get(0).getTable()); ++ assertEquals("C", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded!"); ++ } ++ ++ // Test with a USING("id"): ++ try{ ++ List usingList = new ArrayList(1); ++ usingList.add(new ADQLColumn("id")); ++ ADQLJoin join = new InnerJoin(tableA, tableC, usingList); ++ SearchColumnList joinColumns = join.getDBColumns(); ++ assertEquals(4, joinColumns.size()); ++ ++ // check id (column common to table A and C only): ++ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check A.txta and C.txta: ++ lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(2, lstFound.size()); ++ // A.txta ++ assertNotNull(lstFound.get(0).getTable()); ++ assertEquals("A", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ // C.txta ++ assertNotNull(lstFound.get(1).getTable()); ++ assertEquals("C", lstFound.get(1).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(1).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "txta", IdentifierField.getFullCaseSensitive(true)).size()); + -+ @After -+ public void tearDown() throws Exception{} ++ // check txtc (only for table C): ++ lstFound = joinColumns.search(null, null, null, "txtc", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotNull(lstFound.get(0).getTable()); ++ assertEquals("C", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "txtc", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "A", "txtc", IdentifierField.getFullCaseSensitive(true)).size()); + -+ @Test -+ public void test(){ -+ ADQLParser parser = new ADQLParser(); -+ try{ -+ ADQLQuery query = parser.parseQuery("SELECT 'truc''machin' 'bidule' -- why not a comment now ^^\n'FIN' FROM foo;"); -+ assertNotNull(query); -+ assertEquals("truc'machinbiduleFIN", ((StringConstant)(query.getSelect().get(0).getOperand())).getValue()); -+ assertEquals("'truc''machinbiduleFIN'", query.getSelect().get(0).getOperand().toADQL()); + }catch(Exception ex){ -+ fail("String litteral concatenation is perfectly legal according to the ADQL standard."); ++ ex.printStackTrace(); ++ fail("This test should have succeeded!"); + } + } + +} -diff --git a/test/adql/query/from/TestCrossJoin.java b/test/adql/query/from/TestCrossJoin.java +diff --git a/test/adql/query/from/TestSQLServer_InnerJoin.java b/test/adql/query/from/TestSQLServer_InnerJoin.java new file mode 100644 -index 0000000..ce440bc +index 0000000..70be938 --- /dev/null -+++ b/test/adql/query/from/TestCrossJoin.java -@@ -0,0 +1,95 @@ ++++ b/test/adql/query/from/TestSQLServer_InnerJoin.java +@@ -0,0 +1,159 @@ +package adql.query.from; + +import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + ++import java.util.ArrayList; +import java.util.List; + -+import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import adql.db.DBColumn; ++import adql.db.DBCommonColumn; +import adql.db.DBType; +import adql.db.DBType.DBDatatype; +import adql.db.DefaultDBColumn; +import adql.db.DefaultDBTable; +import adql.db.SearchColumnList; +import adql.query.IdentifierField; ++import adql.query.operand.ADQLColumn; + -+public class TestCrossJoin { -+ -+ private ADQLTable tableA, tableB; ++public class TestSQLServer_InnerJoin { + -+ @AfterClass -+ public static void tearDownAfterClass() throws Exception{} ++ private ADQLTable tableA, tableB, tableC; + + @Before + public void setUp() throws Exception{ @@ -1992,236 +3551,439 @@ + metaTableA.setADQLSchemaName("public"); + DefaultDBTable metaTableB = new DefaultDBTable("B"); + metaTableB.setADQLSchemaName("public"); ++ DefaultDBTable metaTableC = new DefaultDBTable("C"); ++ metaTableC.setADQLSchemaName("public"); + + // Describe its columns: + metaTableA.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableA)); + metaTableA.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableA)); + metaTableB.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableB)); + metaTableB.addColumn(new DefaultDBColumn("txtb", new DBType(DBDatatype.VARCHAR), metaTableB)); ++ metaTableC.addColumn(new DefaultDBColumn("Id", new DBType(DBDatatype.VARCHAR), metaTableC)); ++ metaTableC.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableC)); ++ metaTableC.addColumn(new DefaultDBColumn("txtc", new DBType(DBDatatype.VARCHAR), metaTableC)); + + // Build the ADQL tables: + tableA = new ADQLTable("A"); + tableA.setDBLink(metaTableA); + tableB = new ADQLTable("B"); + tableB.setDBLink(metaTableB); ++ tableC = new ADQLTable("C"); ++ tableC.setDBLink(metaTableC); + } + + @Test + public void testGetDBColumns(){ ++ // Test NATURAL JOIN 1: + try{ -+ ADQLJoin join = new CrossJoin(tableA, tableB); ++ ADQLJoin join = new SQLServer_InnerJoin(tableA, tableB); + SearchColumnList joinColumns = join.getDBColumns(); -+ assertEquals(4, joinColumns.size()); ++ assertEquals(3, joinColumns.size()); ++ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ lstFound = joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ lstFound = joinColumns.search(null, "public", "B", "txtb", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded!"); ++ } + -+ // check column A.id and B.id ++ // Test NATURAL JOIN 2: ++ try{ ++ ADQLJoin join = new SQLServer_InnerJoin(tableA, tableC); ++ SearchColumnList joinColumns = join.getDBColumns(); ++ assertEquals(3, joinColumns.size()); ++ ++ // check id (only the column of table A should be found): + List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(2, lstFound.size()); -+ // A.id ++ assertEquals(1, lstFound.size()); ++ assertNotEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check txta (only the column of table A should be found): ++ lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotEquals(DBCommonColumn.class, lstFound.get(0).getClass()); ++ assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "C", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ ++ // check txtc (only for table C) ++ lstFound = joinColumns.search(null, null, null, "txtc", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); + assertNotNull(lstFound.get(0).getTable()); -+ assertEquals("A", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("C", lstFound.get(0).getTable().getADQLName()); + assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("This test should have succeeded!"); ++ } ++ ++ // Test with a USING("id"): ++ try{ ++ List usingList = new ArrayList(1); ++ usingList.add(new ADQLColumn("id")); ++ ADQLJoin join = new SQLServer_InnerJoin(tableA, tableC, usingList); ++ SearchColumnList joinColumns = join.getDBColumns(); ++ assertEquals(4, joinColumns.size()); ++ ++ // check id (only the column of table A should be found): ++ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); ++ assertEquals(1, lstFound.size()); ++ assertNotEquals(DBCommonColumn.class, lstFound.get(0).getClass()); + assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ // B.id -+ assertNotNull(lstFound.get(1).getTable()); -+ assertEquals("B", lstFound.get(1).getTable().getADQLName()); -+ assertEquals("public", lstFound.get(1).getTable().getADQLSchemaName()); -+ assertEquals(1, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); + assertEquals(0, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); + -+ // check column A.txta ++ // check A.txta and C.txta: + lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); ++ assertEquals(2, lstFound.size()); ++ // A.txta + assertNotNull(lstFound.get(0).getTable()); + assertEquals("A", lstFound.get(0).getTable().getADQLName()); + assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); + assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ // C.txta ++ assertNotNull(lstFound.get(1).getTable()); ++ assertEquals("C", lstFound.get(1).getTable().getADQLName()); ++ assertEquals("public", lstFound.get(1).getTable().getADQLSchemaName()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "txta", IdentifierField.getFullCaseSensitive(true)).size()); + assertEquals(0, joinColumns.search(null, "public", "B", "txta", IdentifierField.getFullCaseSensitive(true)).size()); + -+ // check column B.txtb -+ lstFound = joinColumns.search(null, null, null, "txtb", IdentifierField.getFullCaseSensitive(true)); ++ // check txtc (only for table C): ++ lstFound = joinColumns.search(null, null, null, "txtc", IdentifierField.getFullCaseSensitive(true)); + assertEquals(1, lstFound.size()); + assertNotNull(lstFound.get(0).getTable()); -+ assertEquals("B", lstFound.get(0).getTable().getADQLName()); ++ assertEquals("C", lstFound.get(0).getTable().getADQLName()); + assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); -+ assertEquals(1, joinColumns.search(null, "public", "B", "txtb", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "A", "txtb", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(1, joinColumns.search(null, "public", "C", "txtc", IdentifierField.getFullCaseSensitive(true)).size()); ++ assertEquals(0, joinColumns.search(null, "public", "A", "txtc", IdentifierField.getFullCaseSensitive(true)).size()); + + }catch(Exception ex){ + ex.printStackTrace(); + fail("This test should have succeeded!"); + } + } ++ +} -diff --git a/test/adql/query/from/TestInnerJoin.java b/test/adql/query/from/TestInnerJoin.java +diff --git a/test/adql/query/operand/function/geometry/TestCentroidFunction.java b/test/adql/query/operand/function/geometry/TestCentroidFunction.java new file mode 100644 -index 0000000..57c4f87 +index 0000000..ee17950 --- /dev/null -+++ b/test/adql/query/from/TestInnerJoin.java -@@ -0,0 +1,158 @@ -+package adql.query.from; ++++ b/test/adql/query/operand/function/geometry/TestCentroidFunction.java +@@ -0,0 +1,28 @@ ++package adql.query.operand.function.geometry; ++ ++import static org.junit.Assert.assertFalse; ++import static org.junit.Assert.assertTrue; ++import static org.junit.Assert.fail; ++ ++import org.junit.Test; ++ ++import adql.query.operand.NumericConstant; ++import adql.query.operand.StringConstant; ++import adql.query.operand.function.geometry.GeometryFunction.GeometryValue; ++ ++public class TestCentroidFunction { ++ ++ @Test ++ public void testIsGeometry(){ ++ try{ ++ CentroidFunction centfc = new CentroidFunction(new GeometryValue(new CircleFunction(new StringConstant("ICRS"), new NumericConstant(128.23), new NumericConstant(0.53), new NumericConstant(2)))); ++ assertTrue(centfc.isGeometry()); ++ assertFalse(centfc.isNumeric()); ++ assertFalse(centfc.isString()); ++ }catch(Throwable t){ ++ t.printStackTrace(System.err); ++ fail("An error occured while building a simple CentroidFunction! (see the console for more details)"); ++ } ++ } ++ ++} +diff --git a/test/adql/search/TestSimpleReplaceHandler.java b/test/adql/search/TestSimpleReplaceHandler.java +new file mode 100644 +index 0000000..785fddf +--- /dev/null ++++ b/test/adql/search/TestSimpleReplaceHandler.java +@@ -0,0 +1,121 @@ ++package adql.search; + +import static org.junit.Assert.assertEquals; -+import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + -+import java.util.ArrayList; -+import java.util.List; ++import org.junit.Before; ++import org.junit.Test; ++ ++import adql.parser.ADQLParser; ++import adql.query.ADQLObject; ++import adql.query.ADQLQuery; ++import adql.query.operand.function.DefaultUDF; ++import adql.query.operand.function.MathFunction; ++import adql.query.operand.function.MathFunctionType; ++ ++public class TestSimpleReplaceHandler { ++ ++ @Before ++ public void setUp() throws Exception{} ++ ++ @Test ++ public void testReplaceRecursiveMatch(){ ++ /* WHY THIS TEST? ++ * ++ * When a match item had also a match item inside it (e.g. function parameter or sub-query), ++ * both matched items (e.g. the parent and the child) must be replaced. ++ * ++ * However, if the parent is replaced first, the reference of the new parent is lost by the SimpleReplaceHandler and so, ++ * the replacement of the child will be performed on the former parent. Thus, after the whole process, ++ * in the final ADQL query, the replacement of the child won't be visible since the former parent is ++ * not referenced any more. ++ */ ++ ++ String testQuery = "SELECT SQRT(ABS(81)) FROM myTable"; ++ try{ ++ // Parse the query: ++ ADQLQuery query = (new ADQLParser()).parseQuery(testQuery); ++ ++ // Check it is as expected, before the replacements: ++ assertEquals(testQuery, query.toADQL().replaceAll("\\n", " ")); ++ ++ // Create a replace handler: ++ SimpleReplaceHandler replaceHandler = new SimpleReplaceHandler(){ ++ @Override ++ protected boolean match(ADQLObject obj){ ++ return obj instanceof MathFunction; ++ } ++ ++ @Override ++ protected ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException{ ++ return new DefaultUDF("foo", ((MathFunction)objToReplace).getParameters()); ++ } ++ }; ++ ++ // Apply the replacement of all mathematical functions by a dumb UDF: ++ replaceHandler.searchAndReplace(query); ++ assertEquals(2, replaceHandler.getNbMatch()); ++ assertEquals(replaceHandler.getNbMatch(), replaceHandler.getNbReplacement()); ++ assertEquals("SELECT foo(foo(81)) FROM myTable", query.toADQL().replaceAll("\\n", " ")); ++ ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("No error should have occured here since nothing is wrong in the ADQL query used for the test. See the stack trace in the console for more details."); ++ } ++ ++ } ++ ++ @Test ++ public void testWrappingReplacement(){ ++ /* WHY THIS TEST? ++ * ++ * In case you just want to wrap a matched object, you replace it by the wrapping object initialized ++ * with the matched object. ++ * ++ * In a first version, the replacement was done and then the ReplaceHandler was going inside the new object to replace ++ * other matching objects. But of course, it will find again the first matched object and will wrap it again, and so on ++ * indefinitely => "nasty" infinite loop. ++ * ++ * So, the replacement of the matched objects should be always done after having looked inside it. ++ */ ++ ++ String testQuery = "SELECT foo(bar(123)) FROM myTable"; ++ try{ ++ // Parse the query: ++ ADQLQuery query = (new ADQLParser()).parseQuery(testQuery); ++ ++ // Check it is as expected, before the replacements: ++ assertEquals(testQuery, query.toADQL().replaceAll("\\n", " ")); ++ ++ // Create a replace handler: ++ SimpleReplaceHandler replaceHandler = new SimpleReplaceHandler(){ ++ @Override ++ protected boolean match(ADQLObject obj){ ++ return obj instanceof DefaultUDF && ((DefaultUDF)obj).getName().toLowerCase().matches("(foo|bar)"); ++ } ++ ++ @Override ++ protected ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException{ ++ try{ ++ return new MathFunction(MathFunctionType.ROUND, (DefaultUDF)objToReplace); ++ }catch(Exception e){ ++ e.printStackTrace(System.err); ++ fail("No error should have occured here since nothing is wrong in the ADQL query used for the test. See the stack trace in the console for more details."); ++ return null; ++ } ++ } ++ }; ++ ++ // Apply the wrapping: ++ replaceHandler.searchAndReplace(query); ++ assertEquals(2, replaceHandler.getNbMatch()); ++ assertEquals(replaceHandler.getNbMatch(), replaceHandler.getNbReplacement()); ++ assertEquals("SELECT ROUND(foo(ROUND(bar(123)))) FROM myTable", query.toADQL().replaceAll("\\n", " ")); ++ ++ }catch(Exception ex){ ++ ex.printStackTrace(System.err); ++ fail("No error should have occured here since nothing is wrong in the ADQL query used for the test. See the stack trace in the console for more details."); ++ } ++ } ++ ++} +diff --git a/test/adql/translator/TestJDBCTranslator.java b/test/adql/translator/TestJDBCTranslator.java +new file mode 100644 +index 0000000..577b11f +--- /dev/null ++++ b/test/adql/translator/TestJDBCTranslator.java +@@ -0,0 +1,136 @@ ++package adql.translator; ++ ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.fail; ++ ++import org.junit.Before; ++import org.junit.Test; ++ ++import adql.db.DBType; ++import adql.db.STCS.Region; ++import adql.parser.ParseException; ++import adql.query.IdentifierField; ++import adql.query.operand.StringConstant; ++import adql.query.operand.function.geometry.AreaFunction; ++import adql.query.operand.function.geometry.BoxFunction; ++import adql.query.operand.function.geometry.CentroidFunction; ++import adql.query.operand.function.geometry.CircleFunction; ++import adql.query.operand.function.geometry.ContainsFunction; ++import adql.query.operand.function.geometry.DistanceFunction; ++import adql.query.operand.function.geometry.ExtractCoord; ++import adql.query.operand.function.geometry.ExtractCoordSys; ++import adql.query.operand.function.geometry.IntersectsFunction; ++import adql.query.operand.function.geometry.PointFunction; ++import adql.query.operand.function.geometry.PolygonFunction; ++import adql.query.operand.function.geometry.RegionFunction; ++ ++public class TestJDBCTranslator { ++ ++ @Before ++ public void setUp() throws Exception{} ++ ++ @Test ++ public void testTranslateStringConstant(){ ++ JDBCTranslator tr = new AJDBCTranslator(); ++ ++ /* Ensure the translation from ADQL to SQL of strings is correct ; ++ * particularly, ' should be escaped otherwise it would mean the end of a string in SQL ++ *(the way to escape a such character is by doubling the character '): */ ++ try{ ++ assertEquals("'SQL''s translation'", tr.translate(new StringConstant("SQL's translation"))); ++ }catch(TranslationException e){ ++ e.printStackTrace(System.err); ++ fail("There should have been no problem to translate a StringConstant object into SQL."); ++ } ++ } + -+import org.junit.Before; -+import org.junit.Test; ++ public final static class AJDBCTranslator extends JDBCTranslator { + -+import adql.db.DBColumn; -+import adql.db.DBCommonColumn; -+import adql.db.DBType; -+import adql.db.DBType.DBDatatype; -+import adql.db.DefaultDBColumn; -+import adql.db.DefaultDBTable; -+import adql.db.SearchColumnList; -+import adql.query.IdentifierField; -+import adql.query.operand.ADQLColumn; ++ @Override ++ public String translate(ExtractCoord extractCoord) throws TranslationException{ ++ return null; ++ } + -+public class TestInnerJoin { ++ @Override ++ public String translate(ExtractCoordSys extractCoordSys) throws TranslationException{ ++ return null; ++ } + -+ private ADQLTable tableA, tableB, tableC; ++ @Override ++ public String translate(AreaFunction areaFunction) throws TranslationException{ ++ return null; ++ } + -+ @Before -+ public void setUp() throws Exception{ -+ /* SET THE TABLES AND COLUMNS NEEDED FOR THE TEST */ -+ // Describe the available table: -+ DefaultDBTable metaTableA = new DefaultDBTable("A"); -+ metaTableA.setADQLSchemaName("public"); -+ DefaultDBTable metaTableB = new DefaultDBTable("B"); -+ metaTableB.setADQLSchemaName("public"); -+ DefaultDBTable metaTableC = new DefaultDBTable("C"); -+ metaTableC.setADQLSchemaName("public"); ++ @Override ++ public String translate(CentroidFunction centroidFunction) throws TranslationException{ ++ return null; ++ } + -+ // Describe its columns: -+ metaTableA.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableA)); -+ metaTableA.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableA)); -+ metaTableB.addColumn(new DefaultDBColumn("id", new DBType(DBDatatype.VARCHAR), metaTableB)); -+ metaTableB.addColumn(new DefaultDBColumn("txtb", new DBType(DBDatatype.VARCHAR), metaTableB)); -+ metaTableC.addColumn(new DefaultDBColumn("Id", new DBType(DBDatatype.VARCHAR), metaTableC)); -+ metaTableC.addColumn(new DefaultDBColumn("txta", new DBType(DBDatatype.VARCHAR), metaTableC)); -+ metaTableC.addColumn(new DefaultDBColumn("txtc", new DBType(DBDatatype.VARCHAR), metaTableC)); ++ @Override ++ public String translate(DistanceFunction fct) throws TranslationException{ ++ return null; ++ } + -+ // Build the ADQL tables: -+ tableA = new ADQLTable("A"); -+ tableA.setDBLink(metaTableA); -+ tableB = new ADQLTable("B"); -+ tableB.setDBLink(metaTableB); -+ tableC = new ADQLTable("C"); -+ tableC.setDBLink(metaTableC); -+ } ++ @Override ++ public String translate(ContainsFunction fct) throws TranslationException{ ++ return null; ++ } + -+ @Test -+ public void testGetDBColumns(){ -+ // Test NATURAL JOIN 1: -+ try{ -+ ADQLJoin join = new InnerJoin(tableA, tableB); -+ SearchColumnList joinColumns = join.getDBColumns(); -+ assertEquals(3, joinColumns.size()); -+ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); -+ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(1, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ lstFound = joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ lstFound = joinColumns.search(null, "public", "B", "txtb", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ }catch(Exception ex){ -+ ex.printStackTrace(); -+ fail("This test should have succeeded!"); ++ @Override ++ public String translate(IntersectsFunction fct) throws TranslationException{ ++ return null; + } + -+ // Test NATURAL JOIN 2: -+ try{ -+ ADQLJoin join = new InnerJoin(tableA, tableC); -+ SearchColumnList joinColumns = join.getDBColumns(); -+ assertEquals(3, joinColumns.size()); ++ @Override ++ public String translate(PointFunction point) throws TranslationException{ ++ return null; ++ } + -+ // check id (column common to table A and C only): -+ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); -+ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(1, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ @Override ++ public String translate(CircleFunction circle) throws TranslationException{ ++ return null; ++ } + -+ // check txta (column common to table A and C only): -+ lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); -+ assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(1, joinColumns.search(null, "public", "C", "txta", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ @Override ++ public String translate(BoxFunction box) throws TranslationException{ ++ return null; ++ } + -+ // check txtc (only for table C) -+ lstFound = joinColumns.search(null, null, null, "txtc", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ assertNotNull(lstFound.get(0).getTable()); -+ assertEquals("C", lstFound.get(0).getTable().getADQLName()); -+ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); ++ @Override ++ public String translate(PolygonFunction polygon) throws TranslationException{ ++ return null; ++ } + -+ }catch(Exception ex){ -+ ex.printStackTrace(); -+ fail("This test should have succeeded!"); ++ @Override ++ public String translate(RegionFunction region) throws TranslationException{ ++ return null; + } + -+ // Test with a USING("id"): -+ try{ -+ List usingList = new ArrayList(1); -+ usingList.add(new ADQLColumn("id")); -+ ADQLJoin join = new InnerJoin(tableA, tableC, usingList); -+ SearchColumnList joinColumns = join.getDBColumns(); -+ assertEquals(4, joinColumns.size()); ++ @Override ++ public boolean isCaseSensitive(IdentifierField field){ ++ return false; ++ } + -+ // check id (column common to table A and C only): -+ List lstFound = joinColumns.search(null, null, null, "id", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ assertEquals(DBCommonColumn.class, lstFound.get(0).getClass()); -+ assertEquals(1, joinColumns.search(null, "public", "A", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(1, joinColumns.search(null, "public", "C", "id", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "B", "id", IdentifierField.getFullCaseSensitive(true)).size()); ++ @Override ++ public DBType convertTypeFromDB(int dbmsType, String rawDbmsTypeName, String dbmsTypeName, String[] typeParams){ ++ return null; ++ } + -+ // check A.txta and C.txta: -+ lstFound = joinColumns.search(null, null, null, "txta", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(2, lstFound.size()); -+ // A.txta -+ assertNotNull(lstFound.get(0).getTable()); -+ assertEquals("A", lstFound.get(0).getTable().getADQLName()); -+ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); -+ assertEquals(1, joinColumns.search(null, "public", "A", "txta", IdentifierField.getFullCaseSensitive(true)).size()); -+ // C.txta -+ assertNotNull(lstFound.get(1).getTable()); -+ assertEquals("C", lstFound.get(1).getTable().getADQLName()); -+ assertEquals("public", lstFound.get(1).getTable().getADQLSchemaName()); -+ assertEquals(1, joinColumns.search(null, "public", "C", "txta", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "B", "txta", IdentifierField.getFullCaseSensitive(true)).size()); ++ @Override ++ public String convertTypeToDB(DBType type){ ++ return null; ++ } + -+ // check txtc (only for table C): -+ lstFound = joinColumns.search(null, null, null, "txtc", IdentifierField.getFullCaseSensitive(true)); -+ assertEquals(1, lstFound.size()); -+ assertNotNull(lstFound.get(0).getTable()); -+ assertEquals("C", lstFound.get(0).getTable().getADQLName()); -+ assertEquals("public", lstFound.get(0).getTable().getADQLSchemaName()); -+ assertEquals(1, joinColumns.search(null, "public", "C", "txtc", IdentifierField.getFullCaseSensitive(true)).size()); -+ assertEquals(0, joinColumns.search(null, "public", "A", "txtc", IdentifierField.getFullCaseSensitive(true)).size()); ++ @Override ++ public Region translateGeometryFromDB(Object jdbcColValue) throws ParseException{ ++ return null; ++ } + -+ }catch(Exception ex){ -+ ex.printStackTrace(); -+ fail("This test should have succeeded!"); ++ @Override ++ public Object translateGeometryToDB(Region region) throws ParseException{ ++ return null; + } ++ + } + +} diff --git a/test/adql/translator/TestPgSphereTranslator.java b/test/adql/translator/TestPgSphereTranslator.java new file mode 100644 -index 0000000..2f34471 +index 0000000..346ed80 --- /dev/null +++ b/test/adql/translator/TestPgSphereTranslator.java -@@ -0,0 +1,332 @@ +@@ -0,0 +1,350 @@ +package adql.translator; + +import static org.junit.Assert.assertEquals; @@ -2243,6 +4005,12 @@ +import adql.db.DBType.DBDatatype; +import adql.db.STCS.Region; +import adql.parser.ParseException; ++import adql.query.operand.NumericConstant; ++import adql.query.operand.StringConstant; ++import adql.query.operand.function.geometry.CentroidFunction; ++import adql.query.operand.function.geometry.CircleFunction; ++import adql.query.operand.function.geometry.GeometryFunction; ++import adql.query.operand.function.geometry.GeometryFunction.GeometryValue; + +public class TestPgSphereTranslator { + @@ -2259,6 +4027,18 @@ + public void tearDown() throws Exception{} + + @Test ++ public void testTranslateCentroidFunction(){ ++ try{ ++ PgSphereTranslator translator = new PgSphereTranslator(); ++ CentroidFunction centfc = new CentroidFunction(new GeometryValue(new CircleFunction(new StringConstant("ICRS"), new NumericConstant(128.23), new NumericConstant(0.53), new NumericConstant(2)))); ++ assertEquals("center(scircle(spoint(radians(128.23),radians(0.53)),radians(2)))", translator.translate(centfc)); ++ }catch(Throwable t){ ++ t.printStackTrace(System.err); ++ fail("An error occured while building a simple CentroidFunction! (see the console for more details)"); ++ } ++ } ++ ++ @Test + public void testConvertTypeFromDB(){ + PgSphereTranslator translator = new PgSphereTranslator(); + @@ -2554,254 +4334,163 @@ + } + +} -diff --git a/test/testtools/CommandExecute.java b/test/testtools/CommandExecute.java +diff --git a/test/adql/translator/TestPostgreSQLTranslator.java b/test/adql/translator/TestPostgreSQLTranslator.java new file mode 100644 -index 0000000..2e78978 +index 0000000..01fef8e --- /dev/null -+++ b/test/testtools/CommandExecute.java -@@ -0,0 +1,51 @@ -+package testtools; -+ -+import java.io.BufferedReader; -+import java.io.InputStreamReader; -+ -+/** -+ * Let's execute any shell command (even with pipes and redirections). -+ * -+ * @author Grégory Mantelet (ARI) -+ * @version 2.0 (09/2014) -+ */ -+public final class CommandExecute { -+ -+ /** -+ * SINGLETON CLASS. -+ * No instance of this class can be created. -+ */ -+ private CommandExecute(){} -+ -+ /** -+ * Execute the given command (which may include pipe(s) and/or redirection(s)). -+ * -+ * @param command Command to execute in the shell. -+ * -+ * @return The string returned by the execution of the command. -+ */ -+ public final static String execute(final String command){ -+ -+ String[] shellCmd = new String[]{"/bin/sh","-c",command}; -+ -+ StringBuffer output = new StringBuffer(); -+ -+ Process p; -+ try{ -+ p = Runtime.getRuntime().exec(shellCmd); -+ p.waitFor(); -+ BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); -+ -+ String line = ""; -+ while((line = reader.readLine()) != null){ -+ output.append(line + "\n"); -+ } ++++ b/test/adql/translator/TestPostgreSQLTranslator.java +@@ -0,0 +1,62 @@ ++package adql.translator; + -+ }catch(Exception e){ -+ e.printStackTrace(); -+ } ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.fail; + -+ return output.toString(); ++import org.junit.Before; ++import org.junit.Test; + -+ } -+} -diff --git a/test/testtools/DBTools.java b/test/testtools/DBTools.java -new file mode 100644 -index 0000000..ba542f9 ---- /dev/null -+++ b/test/testtools/DBTools.java -@@ -0,0 +1,136 @@ -+package testtools; ++import adql.query.operand.NumericConstant; ++import adql.query.operand.function.MathFunction; ++import adql.query.operand.function.MathFunctionType; + -+import java.sql.Connection; -+import java.sql.DriverManager; -+import java.sql.ResultSet; -+import java.sql.SQLException; -+import java.sql.Statement; -+import java.util.HashMap; -+ -+public final class DBTools { -+ -+ public static int count = 0; -+ -+ public final static void main(final String[] args) throws Throwable{ -+ for(int i = 0; i < 3; i++){ -+ Thread t = new Thread(new Runnable(){ -+ @Override -+ public void run(){ -+ count++; -+ try{ -+ Connection conn = DBTools.createConnection("postgresql", "127.0.0.1", null, "gmantele", "gmantele", "pwd"); -+ System.out.println("Start - " + count + ": "); -+ String query = "SELECT * FROM gums.smc WHERE magg BETWEEN " + (15 + count) + " AND " + (20 + count) + ";"; -+ System.out.println(query); -+ ResultSet rs = DBTools.select(conn, query); -+ try{ -+ rs.last(); -+ System.out.println("Nb rows: " + rs.getRow()); -+ }catch(SQLException e){ -+ e.printStackTrace(); -+ } -+ if (DBTools.closeConnection(conn)) -+ System.out.println("[DEBUG] Connection closed!"); -+ }catch(DBToolsException e){ -+ e.printStackTrace(); -+ } -+ System.out.println("End - " + count); -+ count--; ++public class TestPostgreSQLTranslator { ++ ++ @Before ++ public void setUp() throws Exception{} ++ ++ @Test ++ public void testTranslateMathFunction(){ ++ // Check that all math functions, except PI, operates a cast to their DOUBLE/REAL parameters: ++ PostgreSQLTranslator trans = new PostgreSQLTranslator(); ++ MathFunctionType[] types = MathFunctionType.values(); ++ NumericConstant num = new NumericConstant("1.234"), prec = new NumericConstant("2"); ++ for(MathFunctionType type : types){ ++ try{ ++ switch(type){ ++ case PI: ++ assertEquals("PI()", trans.translate(new MathFunction(type))); ++ break; ++ case RAND: ++ assertEquals("random()", trans.translate(new MathFunction(type))); ++ assertEquals("random()", trans.translate(new MathFunction(type, num))); ++ break; ++ case LOG: ++ assertEquals("ln(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num))); ++ break; ++ case LOG10: ++ assertEquals("log(10, CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num))); ++ break; ++ case TRUNCATE: ++ assertEquals("trunc(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num))); ++ assertEquals("trunc(CAST(1.234 AS numeric), 2)", trans.translate(new MathFunction(type, num, prec))); ++ break; ++ case ROUND: ++ assertEquals("round(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num))); ++ assertEquals("round(CAST(1.234 AS numeric), 2)", trans.translate(new MathFunction(type, num, prec))); ++ break; ++ default: ++ if (type.nbMaxParams() == 1 || type.nbMinParams() == 1) ++ assertEquals(type + "(CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num))); ++ if (type.nbMaxParams() == 2) ++ assertEquals(type + "(CAST(1.234 AS numeric), CAST(1.234 AS numeric))", trans.translate(new MathFunction(type, num, num))); ++ break; + } -+ }); -+ t.start(); ++ }catch(Exception ex){ ++ ex.printStackTrace(); ++ fail("Translation exception for the type \"" + type + "\": " + ex.getMessage()); ++ } + } + } + -+ public static class DBToolsException extends Exception { ++} +diff --git a/test/adql/translator/TestSQLServerTranslator.java b/test/adql/translator/TestSQLServerTranslator.java +new file mode 100644 +index 0000000..ed605d8 +--- /dev/null ++++ b/test/adql/translator/TestSQLServerTranslator.java +@@ -0,0 +1,86 @@ ++package adql.translator; + -+ private static final long serialVersionUID = 1L; ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.fail; + -+ public DBToolsException(){ -+ super(); -+ } ++import java.util.ArrayList; ++import java.util.List; + -+ public DBToolsException(String message, Throwable cause){ -+ super(message, cause); -+ } ++import org.junit.Before; ++import org.junit.Test; + -+ public DBToolsException(String message){ -+ super(message); -+ } ++import adql.db.DBChecker; ++import adql.db.DBTable; ++import adql.db.DefaultDBColumn; ++import adql.db.DefaultDBTable; ++import adql.parser.ADQLParser; ++import adql.parser.ParseException; ++import adql.parser.SQLServer_ADQLQueryFactory; ++import adql.query.ADQLQuery; + -+ public DBToolsException(Throwable cause){ -+ super(cause); -+ } ++public class TestSQLServerTranslator { + -+ } ++ private List tables = null; + -+ public final static HashMap VALUE_JDBC_DRIVERS = new HashMap(4); -+ static{ -+ VALUE_JDBC_DRIVERS.put("oracle", "oracle.jdbc.OracleDriver"); -+ VALUE_JDBC_DRIVERS.put("postgresql", "org.postgresql.Driver"); -+ VALUE_JDBC_DRIVERS.put("mysql", "com.mysql.jdbc.Driver"); -+ VALUE_JDBC_DRIVERS.put("sqlite", "org.sqlite.JDBC"); ++ @Before ++ public void setUp() throws Exception{ ++ tables = new ArrayList(2); ++ DefaultDBTable t = new DefaultDBTable("aTable"); ++ t.addColumn(new DefaultDBColumn("id", t)); ++ t.addColumn(new DefaultDBColumn("name", t)); ++ t.addColumn(new DefaultDBColumn("aColumn", t)); ++ tables.add(t); ++ t = new DefaultDBTable("anotherTable"); ++ t.addColumn(new DefaultDBColumn("id", t)); ++ t.addColumn(new DefaultDBColumn("name", t)); ++ t.addColumn(new DefaultDBColumn("anotherColumn", t)); ++ tables.add(t); + } + -+ private DBTools(){} -+ -+ public final static Connection createConnection(String dbms, final String server, final String port, final String dbName, final String user, final String passwd) throws DBToolsException{ -+ // 1. Resolve the DBMS and get its JDBC driver: -+ if (dbms == null) -+ throw new DBToolsException("Missing DBMS (expected: oracle, postgresql, mysql or sqlite)!"); -+ dbms = dbms.toLowerCase(); -+ String jdbcDriver = VALUE_JDBC_DRIVERS.get(dbms); -+ if (jdbcDriver == null) -+ throw new DBToolsException("Unknown DBMS (\"" + dbms + "\")!"); -+ -+ // 2. Load the JDBC driver: -+ try{ -+ Class.forName(jdbcDriver); -+ }catch(ClassNotFoundException e){ -+ throw new DBToolsException("Impossible to load the JDBC driver: " + e.getMessage(), e); -+ } ++ @Test ++ public void testNaturalJoin(){ ++ final String adqlquery = "SELECT id, name, aColumn, anotherColumn FROM aTable A NATURAL JOIN anotherTable B;"; + -+ // 3. Establish the connection: -+ Connection connection = null; + try{ -+ connection = DriverManager.getConnection("jdbc:" + dbms + ":" + ((server != null && server.trim().length() > 0) ? "//" + server + ((port != null && port.trim().length() > 0) ? (":" + port) : "") + "/" : "") + dbName, user, passwd); -+ }catch(SQLException e){ -+ throw new DBToolsException("Connection failed: " + e.getMessage(), e); -+ } ++ ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery); ++ SQLServerTranslator translator = new SQLServerTranslator(); + -+ if (connection == null) -+ throw new DBToolsException("Failed to make connection!"); ++ // Test the FROM part: ++ assertEquals("\"aTable\" AS \"a\" INNER JOIN \"anotherTable\" AS \"b\" ON \"a\".\"id\"=\"b\".\"id\" AND \"a\".\"name\"=\"b\".\"name\"", translator.translate(query.getFrom())); + -+ return connection; -+ } ++ // Test the SELECT part (in order to ensure the usual common columns (due to NATURAL) are actually translated as columns of the first joined table): ++ assertEquals("SELECT \"a\".\"id\" AS \"id\" , \"a\".\"name\" AS \"name\" , \"a\".\"aColumn\" AS \"aColumn\" , \"b\".\"anotherColumn\" AS \"anotherColumn\"", translator.translate(query.getSelect())); + -+ public final static boolean closeConnection(final Connection conn) throws DBToolsException{ -+ try{ -+ if (conn != null && !conn.isClosed()){ -+ conn.close(); -+ try{ -+ Thread.sleep(200); -+ }catch(InterruptedException e){ -+ System.err.println("WARNING: can't wait/sleep before testing the connection close status! [" + e.getMessage() + "]"); -+ } -+ return conn.isClosed(); -+ }else -+ return true; -+ }catch(SQLException e){ -+ throw new DBToolsException("Closing connection failed: " + e.getMessage(), e); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)"); ++ }catch(TranslationException te){ ++ te.printStackTrace(); ++ fail("No error was expected from this translation. (see the console for more details)"); + } + } + -+ public final static ResultSet select(final Connection conn, final String selectQuery) throws DBToolsException{ -+ if (conn == null || selectQuery == null || selectQuery.trim().length() == 0) -+ throw new DBToolsException("One parameter is missing!"); ++ @Test ++ public void testJoinWithUSING(){ ++ final String adqlquery = "SELECT B.id, name, aColumn, anotherColumn FROM aTable A JOIN anotherTable B USING(name);"; + + try{ -+ Statement stmt = conn.createStatement(); -+ return stmt.executeQuery(selectQuery); -+ }catch(SQLException e){ -+ throw new DBToolsException("Can't execute the given SQL query: " + e.getMessage(), e); -+ } -+ } ++ ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery); ++ SQLServerTranslator translator = new SQLServerTranslator(); + -+} -diff --git a/test/testtools/MD5Checksum.java b/test/testtools/MD5Checksum.java -new file mode 100644 -index 0000000..d4941c5 ---- /dev/null -+++ b/test/testtools/MD5Checksum.java -@@ -0,0 +1,46 @@ -+package testtools; -+ -+import java.io.ByteArrayInputStream; -+import java.io.InputStream; -+import java.security.MessageDigest; -+ -+public class MD5Checksum { -+ -+ public static byte[] createChecksum(InputStream input) throws Exception{ -+ byte[] buffer = new byte[1024]; -+ MessageDigest complete = MessageDigest.getInstance("MD5"); -+ int numRead; -+ -+ do{ -+ numRead = input.read(buffer); -+ if (numRead > 0){ -+ complete.update(buffer, 0, numRead); -+ } -+ }while(numRead != -1); -+ return complete.digest(); -+ } ++ // Test the FROM part: ++ assertEquals("\"aTable\" AS \"a\" INNER JOIN \"anotherTable\" AS \"b\" ON \"a\".\"name\"=\"b\".\"name\"", translator.translate(query.getFrom())); + -+ // see this How-to for a faster way to convert -+ // a byte array to a HEX string -+ public static String getMD5Checksum(InputStream input) throws Exception{ -+ byte[] b = createChecksum(input); -+ String result = ""; ++ // Test the SELECT part (in order to ensure the usual common columns (due to USING) are actually translated as columns of the first joined table): ++ assertEquals("SELECT \"b\".\"id\" AS \"id\" , \"a\".\"name\" AS \"name\" , \"a\".\"aColumn\" AS \"aColumn\" , \"b\".\"anotherColumn\" AS \"anotherColumn\"", translator.translate(query.getSelect())); + -+ for(int i = 0; i < b.length; i++){ -+ result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1); ++ }catch(ParseException pe){ ++ pe.printStackTrace(); ++ fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)"); ++ }catch(TranslationException te){ ++ te.printStackTrace(); ++ fail("No error was expected from this translation. (see the console for more details)"); + } -+ return result; -+ } -+ -+ public static String getMD5Checksum(final String content) throws Exception{ -+ return getMD5Checksum(new ByteArrayInputStream(content.getBytes())); + } + -+ public static void main(String args[]){ -+ try{ -+ System.out.println(getMD5Checksum("Blabla et Super blabla")); -+ }catch(Exception e){ -+ e.printStackTrace(); -+ } -+ } +} diff -Nru adql-1.3/debian/patches/Fix-test.patch adql-1.4/debian/patches/Fix-test.patch --- adql-1.3/debian/patches/Fix-test.patch 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/patches/Fix-test.patch 2018-03-21 13:25:27.000000000 +0000 @@ -13,10 +13,10 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/adql/db/TestDBChecker.java b/test/adql/db/TestDBChecker.java -index 3f9924a..ae4d165 100644 +index 3e675ae..cca6d20 100644 --- a/test/adql/db/TestDBChecker.java +++ b/test/adql/db/TestDBChecker.java -@@ -566,7 +566,7 @@ public class TestDBChecker { +@@ -718,7 +718,7 @@ public class TestDBChecker { fail("Geometrical UDFs are not allowed for the moment in the ADQL language: this test should have failed!"); }catch(ParseException e1){ assertTrue(e1 instanceof ParseException); diff -Nru adql-1.3/debian/patches/Remove-unneeded-import-of-tap.data.DataReadException.patch adql-1.4/debian/patches/Remove-unneeded-import-of-tap.data.DataReadException.patch --- adql-1.3/debian/patches/Remove-unneeded-import-of-tap.data.DataReadException.patch 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/patches/Remove-unneeded-import-of-tap.data.DataReadException.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -From: Ole Streicher -Date: Sat, 17 Dec 2016 18:13:50 +0100 -Subject: Remove unneeded import of tap.data.DataReadException - ---- - src/adql/translator/JDBCTranslator.java | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/src/adql/translator/JDBCTranslator.java b/src/adql/translator/JDBCTranslator.java -index 0ba1b0d..a93eb9e 100644 ---- a/src/adql/translator/JDBCTranslator.java -+++ b/src/adql/translator/JDBCTranslator.java -@@ -23,7 +23,6 @@ import java.util.ArrayList; - import java.util.HashMap; - import java.util.Iterator; - --import tap.data.DataReadException; - import adql.db.DBColumn; - import adql.db.DBTable; - import adql.db.DBType; -@@ -873,7 +872,6 @@ public abstract class JDBCTranslator implements ADQLTranslator { - * {@link #convertTypeFromDB(int, String, String, String[])}. So the value should always - * be of the expected type and format. However, if it turns out that the type is wrong - * and that the conversion is finally impossible, this function SHOULD throw a -- * {@link DataReadException}. - *

- * - * @param jdbcColValue A JDBC column value (returned by ResultSet.getObject(int)). diff -Nru adql-1.3/debian/patches/series adql-1.4/debian/patches/series --- adql-1.3/debian/patches/series 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/patches/series 2018-03-21 13:25:27.000000000 +0000 @@ -1,5 +1,5 @@ -Remove-unneeded-import-of-tap.data.DataReadException.patch Add-unit-tests.patch Add-build.xml.patch Fix-ant-build.patch Fix-test.patch +Test-Compare-only-the-first-8-digits-in-string-comparison.patch diff -Nru adql-1.3/debian/patches/Test-Compare-only-the-first-8-digits-in-string-comparison.patch adql-1.4/debian/patches/Test-Compare-only-the-first-8-digits-in-string-comparison.patch --- adql-1.3/debian/patches/Test-Compare-only-the-first-8-digits-in-string-comparison.patch 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/debian/patches/Test-Compare-only-the-first-8-digits-in-string-comparison.patch 2018-03-21 13:25:27.000000000 +0000 @@ -0,0 +1,36 @@ +From: Ole Streicher +Date: Wed, 21 Mar 2018 13:00:21 +0100 +Subject: Test: Compare only the first 8 digits in string comparison + +In TestPgSphereTranslator, two strings are compared +containing (double) floating point numbers. These numbers are slightly +different with different Java versions. To overcome this, only the +first eight fractional digits are compared. + +Closes: #893193 +--- + test/adql/translator/TestPgSphereTranslator.java | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/test/adql/translator/TestPgSphereTranslator.java b/test/adql/translator/TestPgSphereTranslator.java +index 346ed80..2d09fc3 100644 +--- a/test/adql/translator/TestPgSphereTranslator.java ++++ b/test/adql/translator/TestPgSphereTranslator.java +@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue; + import static org.junit.Assert.fail; + + import java.sql.Types; ++import java.util.regex.Pattern; + + import org.junit.After; + import org.junit.AfterClass; +@@ -315,7 +316,8 @@ public class TestPgSphereTranslator { + pgo = (PGobject)translator.translateGeometryToDB(r); + assertNotNull(pgo); + assertEquals("spoly", pgo.getType()); +- assertEquals("{(46.2d,0.0d),(46.176942336483876d,0.2341083864193539d),(46.108655439013546d,0.4592201188381077d),(45.99776353476305d,0.6666842796235226d),(45.848528137423855d,0.8485281374238569d),(45.666684279623524d,0.9977635347630542d),(45.45922011883811d,1.1086554390135441d),(45.23410838641935d,1.1769423364838765d),(45.0d,1.2d),(44.76589161358065d,1.1769423364838765d),(44.54077988116189d,1.1086554390135441d),(44.333315720376476d,0.9977635347630543d),(44.151471862576145d,0.848528137423857d),(44.00223646523695d,0.6666842796235226d),(43.891344560986454d,0.4592201188381073d),(43.823057663516124d,0.23410838641935325d),(43.8d,-9.188564877424678E-16d),(43.823057663516124d,-0.23410838641935505d),(43.891344560986454d,-0.45922011883810904d),(44.00223646523695d,-0.6666842796235241d),(44.151471862576145d,-0.8485281374238584d),(44.333315720376476d,-0.9977635347630555d),(44.540779881161896d,-1.108655439013545d),(44.76589161358065d,-1.176942336483877d),(45.0d,-1.2d),(45.23410838641936d,-1.1769423364838758d),(45.45922011883811d,-1.1086554390135428d),(45.666684279623524d,-0.9977635347630521d),(45.84852813742386d,-0.8485281374238541d),(45.99776353476306d,-0.6666842796235192d),(46.108655439013546d,-0.45922011883810354d),(46.176942336483876d,-0.23410838641934922d)}", pgo.getValue()); ++ Pattern fp8 = Pattern.compile("(\\.\\d{8})\\d+d"); ++ assertEquals("{(46.2d,0.0d),(46.17694233d,0.23410838d),(46.10865543d,0.45922011d),(45.99776353d,0.66668427d),(45.84852813d,0.84852813d),(45.66668427d,0.99776353d),(45.45922011d,1.10865543d),(45.23410838d,1.17694233d),(45.0d,1.2d),(44.76589161d,1.17694233d),(44.54077988d,1.10865543d),(44.33331572d,0.99776353d),(44.15147186d,0.84852813d),(44.00223646d,0.66668427d),(43.89134456d,0.45922011d),(43.82305766d,0.23410838d),(43.8d,-9.188564877424678E-16d),(43.82305766d,-0.23410838d),(43.89134456d,-0.45922011d),(44.00223646d,-0.66668427d),(44.15147186d,-0.84852813d),(44.33331572d,-0.99776353d),(44.54077988d,-1.10865543d),(44.76589161d,-1.17694233d),(45.0d,-1.2d),(45.23410838d,-1.17694233d),(45.45922011d,-1.10865543d),(45.66668427d,-0.99776353d),(45.84852813d,-0.84852813d),(45.99776353d,-0.66668427d),(46.10865543d,-0.45922011d),(46.17694233d,-0.23410838d)}", fp8.matcher(pgo.getValue()).replaceAll("$1d")); + + // BOX + r = new Region(null, new double[]{45,0}, 1.2, 5); diff -Nru adql-1.3/debian/upstream/metadata adql-1.4/debian/upstream/metadata --- adql-1.3/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/debian/upstream/metadata 2018-03-21 12:20:17.000000000 +0000 @@ -0,0 +1,3 @@ +Bug-Database: https://github.com/gmantele/taplib/issues +Name: ADQL +Repository: https://github.com/gmantele/taplib diff -Nru adql-1.3/debian/watch adql-1.4/debian/watch --- adql-1.3/debian/watch 2017-03-14 13:40:07.000000000 +0000 +++ adql-1.4/debian/watch 2018-03-21 12:48:54.000000000 +0000 @@ -1,2 +1,2 @@ version=3 -https://github.com/gmantele/taplib/releases/latest .+/adql-(.*)_src.jar debian jh_repack +https://github.com/gmantele/taplib/releases/ .*/adql-(.*)_src.jar debian jh_repack diff -Nru adql-1.3/META-INF/MANIFEST.MF adql-1.4/META-INF/MANIFEST.MF --- adql-1.3/META-INF/MANIFEST.MF 2015-05-04 09:50:28.000000000 +0000 +++ adql-1.4/META-INF/MANIFEST.MF 2018-02-26 15:18:18.000000000 +0000 @@ -1,4 +1,4 @@ Manifest-Version: 1.0 -Ant-Version: Apache Ant 1.8.4 -Created-By: 1.7.0_51-b13 (Oracle Corporation) +Ant-Version: Apache Ant 1.9.6 +Created-By: 1.7.0_151-b01 (Oracle Corporation) diff -Nru adql-1.3/src/adql/db/DBChecker.java adql-1.4/src/adql/db/DBChecker.java --- adql-1.3/src/adql/db/DBChecker.java 2015-05-04 09:24:46.000000000 +0000 +++ adql-1.4/src/adql/db/DBChecker.java 2018-01-12 13:49:48.000000000 +0000 @@ -2,22 +2,22 @@ /* * This file is part of ADQLLibrary. - * + * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . - * - * Copyright 2011,2013-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), - * Astronomisches Rechen Institut (ARI) + * + * Copyright 2011-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institut (ARI) */ import java.lang.reflect.Constructor; @@ -27,6 +27,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Stack; @@ -42,6 +43,7 @@ import adql.query.ADQLIterator; import adql.query.ADQLObject; import adql.query.ADQLQuery; +import adql.query.ClauseADQL; import adql.query.ClauseSelect; import adql.query.ColumnReference; import adql.query.IdentifierField; @@ -76,33 +78,33 @@ *
  • Check whether all used coordinate systems are supported
  • *
  • Check that types of columns and UDFs match with their context
  • * - * + * *

    Check tables and columns

    *

    * In addition to check the existence of tables and columns referenced in the query, * this checked will also attach database metadata on these references ({@link ADQLTable} * and {@link ADQLColumn} instances when they are resolved. *

    - * + * *

    These information are:

    *
      *
    • the corresponding {@link DBTable} or {@link DBColumn} (see getter and setter for DBLink in {@link ADQLTable} and {@link ADQLColumn})
    • *
    • the link between an {@link ADQLColumn} and its {@link ADQLTable}
    • *
    - * + * *

    Note: * Knowing DB metadata of {@link ADQLTable} and {@link ADQLColumn} is particularly useful for the translation of the ADQL query to SQL, * because the ADQL name of columns and tables can be replaced in SQL by their DB name, if different. This mapping is done automatically * by {@link adql.translator.JDBCTranslator}. *

    - * + * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (05/2015) + * @version 1.4 (11/2017) */ public class DBChecker implements QueryChecker { /** List of all available tables ({@link DBTable}). */ - protected SearchTableList lstTables; + protected SearchTableApi lstTables; /**

    List of all allowed geometrical functions (i.e. CONTAINS, REGION, POINT, COORD2, ...).

    *

    @@ -149,7 +151,7 @@ /* ************ */ /** *

    Builds a {@link DBChecker} with an empty list of tables.

    - * + * *

    Verifications done by this object after creation:

    *
      *
    • Existence of tables and columns: NO (even unknown or fake tables and columns are allowed)
    • @@ -164,7 +166,7 @@ /** *

      Builds a {@link DBChecker} with the given list of known tables.

      - * + * *

      Verifications done by this object after creation:

      *
        *
      • Existence of tables and columns: OK
      • @@ -172,7 +174,7 @@ *
      • Support of geometrical functions: NO (all valid geometrical functions are allowed)
      • *
      • Support of coordinate systems: NO (all valid coordinate systems are allowed)
      • *
      - * + * * @param tables List of all available tables. */ public DBChecker(final Collection tables){ @@ -181,7 +183,7 @@ /** *

      Builds a {@link DBChecker} with the given list of known tables and with a restricted list of user defined functions.

      - * + * *

      Verifications done by this object after creation:

      *
        *
      • Existence of tables and columns: OK
      • @@ -189,13 +191,13 @@ *
      • Support of geometrical functions: NO (all valid geometrical functions are allowed)
      • *
      • Support of coordinate systems: NO (all valid coordinate systems are allowed)
      • *
      - * + * * @param tables List of all available tables. * @param allowedUdfs List of all allowed user defined functions. * If NULL, no verification will be done (and so, all UDFs are allowed). * If empty list, no "unknown" (or UDF) is allowed. * Note: match with items of this list are done case insensitively. - * + * * @since 1.3 */ public DBChecker(final Collection tables, final Collection allowedUdfs){ @@ -215,7 +217,9 @@ tmp[cnt++] = udf; } // make a copy of the array: - this.allowedUdfs = Arrays.copyOf(tmp, cnt, FunctionDef[].class); + this.allowedUdfs = new FunctionDef[cnt]; + System.arraycopy(tmp, 0, this.allowedUdfs, 0, cnt); + tmp = null; // sort the values: Arrays.sort(this.allowedUdfs); @@ -224,7 +228,7 @@ /** *

      Builds a {@link DBChecker} with the given list of known tables and with a restricted list of user defined functions.

      - * + * *

      Verifications done by this object after creation:

      *
        *
      • Existence of tables and columns: OK
      • @@ -232,7 +236,7 @@ *
      • Support of geometrical functions: OK
      • *
      • Support of coordinate systems: OK
      • *
      - * + * * @param tables List of all available tables. * @param allowedGeoFcts List of all allowed geometrical functions (i.e. CONTAINS, POINT, UNION, CIRCLE, COORD1). * If NULL, no verification will be done (and so, all geometries are allowed). @@ -245,7 +249,7 @@ * For instance: "ICRS (GEOCENTER|heliocenter) *". * If the given list is NULL, no verification will be done (and so, all coordinate systems are allowed). * If it is empty, no coordinate system is allowed (except the default values - generally expressed by an empty string: ''). - * + * * @since 1.3 */ public DBChecker(final Collection tables, final Collection allowedGeoFcts, final Collection allowedCoordSys) throws ParseException{ @@ -254,7 +258,7 @@ /** *

      Builds a {@link DBChecker}.

      - * + * *

      Verifications done by this object after creation:

      *
        *
      • Existence of tables and columns: OK
      • @@ -262,7 +266,7 @@ *
      • Support of geometrical functions: OK
      • *
      • Support of coordinate systems: OK
      • *
      - * + * * @param tables List of all available tables. * @param allowedUdfs List of all allowed user defined functions. * If NULL, no verification will be done (and so, all UDFs are allowed). @@ -279,7 +283,7 @@ * For instance: "ICRS (GEOCENTER|heliocenter) *". * If the given list is NULL, no verification will be done (and so, all coordinate systems are allowed). * If it is empty, no coordinate system is allowed (except the default values - generally expressed by an empty string: ''). - * + * * @since 1.3 */ public DBChecker(final Collection tables, final Collection allowedUdfs, final Collection allowedGeoFcts, final Collection allowedCoordSys) throws ParseException{ @@ -297,11 +301,11 @@ /** * Transform the given collection of string elements in a sorted array. * Only non-NULL and non-empty strings are kept. - * + * * @param items Items to copy and sort. - * + * * @return A sorted array containing all - except NULL and empty strings - items of the given collection. - * + * * @since 1.3 */ protected final static String[] specialSort(final Collection items){ @@ -318,7 +322,8 @@ } // Make an adjusted array copy: - String[] copy = Arrays.copyOf(tmp, cnt); + String[] copy = new String[cnt]; + System.arraycopy(tmp, 0, copy, 0, cnt); // Sort the values: Arrays.sort(copy); @@ -331,19 +336,20 @@ /* ****** */ /** *

      Sets the list of all available tables.

      - * + * *

      Note: - * Only if the given collection is NOT an instance of {@link SearchTableList}, - * the collection will be copied inside a new {@link SearchTableList}, otherwise it is used as provided. + * Only if the given collection is NOT an implementation of + * {@link SearchTableApi}, the collection will be copied inside a new + * {@link SearchTableList}, otherwise it is used as provided. *

      - * + * * @param tables List of {@link DBTable}s. */ public final void setTables(final Collection tables){ if (tables == null) lstTables = new SearchTableList(); - else if (tables instanceof SearchTableList) - lstTables = (SearchTableList)tables; + else if (tables instanceof SearchTableApi) + lstTables = (SearchTableApi)tables; else lstTables = new SearchTableList(tables); } @@ -353,16 +359,16 @@ /* ************* */ /** *

      Check all the columns, tables and UDFs references inside the given query.

      - * + * *

      * Note: This query has already been parsed ; thus it is already syntactically correct. * Only the consistency with the published tables, columns and all the defined UDFs must be checked. *

      - * + * * @param query The query to check. - * + * * @throws ParseException An {@link UnresolvedIdentifiersException} if some tables or columns can not be resolved. - * + * * @see #check(ADQLQuery, Stack) */ @Override @@ -372,7 +378,7 @@ /** *

      Process several (semantic) verifications in the given ADQL query.

      - * + * *

      Main verifications done in this function:

      *
        *
      1. Existence of DB items (tables and columns)
      2. @@ -381,17 +387,17 @@ *
      3. Support of every encountered geometries (functions, coordinate systems and STC-S expressions)
      4. *
      5. Consistency of types still unknown (because the syntactic parser could not yet resolve them)
      6. *
      - * + * * @param query The query to check. * @param fathersList List of all columns available in the father queries and that should be accessed in sub-queries. * Each item of this stack is a list of columns available in each father-level query. * Note: this parameter is NULL if this function is called with the root/father query as parameter. - * + * * @throws UnresolvedIdentifiersException An {@link UnresolvedIdentifiersException} if one or several of the above listed tests have detected * some semantic errors (i.e. unresolved table, columns, function). - * + * * @since 1.2 - * + * * @see #checkDBItems(ADQLQuery, Stack, UnresolvedIdentifiersException) * @see #checkSubQueries(ADQLQuery, Stack, SearchColumnList, UnresolvedIdentifiersException) * @see #checkUDFs(ADQLQuery, UnresolvedIdentifiersException) @@ -428,26 +434,26 @@ /** *

      Check DB items (tables and columns) used in the given ADQL query.

      - * + * *

      Operations done in this function:

      *
        *
      1. Resolve all found tables
      2. *
      3. Get the whole list of all available columns Note: this list is returned by this function.
      4. *
      5. Resolve all found columns
      6. *
      - * + * * @param query Query in which the existence of DB items must be checked. * @param fathersList List of all columns available in the father queries and that should be accessed in sub-queries. * Each item of this stack is a list of columns available in each father-level query. * Note: this parameter is NULL if this function is called with the root/father query as parameter. * @param errors List of errors to complete in this function each time an unknown table or column is encountered. - * + * * @return List of all columns available in the given query. - * + * * @see #resolveTables(ADQLQuery, Stack, UnresolvedIdentifiersException) * @see FromContent#getDBColumns() * @see #resolveColumns(ADQLQuery, Stack, Map, SearchColumnList, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected SearchColumnList checkDBItems(final ADQLQuery query, final Stack fathersList, final UnresolvedIdentifiersException errors){ @@ -470,29 +476,54 @@ } /** - *

      Search all table references inside the given query, resolve them against the available tables, and if there is only one match, - * attach the matching metadata to them.

      - * + * Search all table references inside the given query, resolve them against + * the available tables, and if there is only one match, attach the matching + * metadata to them. + * * Management of sub-query tables *

      - * If a table is not a DB table reference but a sub-query, this latter is first checked (using {@link #check(ADQLQuery, Stack)} ; - * but the father list must not contain tables of the given query, because on the same level) and then corresponding table metadata - * are generated (using {@link #generateDBTable(ADQLQuery, String)}) and attached to it. + * If a table is not a DB table reference but a sub-query, this latter is + * first checked (using {@link #check(ADQLQuery, Stack)} ; but the father + * list must not contain tables of the given query, because on the same + * level) and then corresponding table metadata are generated (using + * {@link #generateDBTable(ADQLQuery, String)}) and attached to it. *

      - * + * * Management of "{table}.*" in the SELECT clause *

      - * For each of this SELECT item, this function tries to resolve the table name. If only one match is found, the corresponding ADQL table object - * is got from the list of resolved tables and attached to this SELECT item (thus, the joker item will also have the good metadata, - * particularly if the referenced table is a sub-query). + * For each of this SELECT item, this function tries to resolve the table + * name. If only one match is found, the corresponding ADQL table object + * is got from the list of resolved tables and attached to this SELECT item + * (thus, the joker item will also have the good metadata, particularly if + * the referenced table is a sub-query). *

      - * - * @param query Query in which the existence of tables must be checked. - * @param fathersList List of all columns available in the father queries and that should be accessed in sub-queries. - * Each item of this stack is a list of columns available in each father-level query. - * Note: this parameter is NULL if this function is called with the root/father query as parameter. - * @param errors List of errors to complete in this function each time an unknown table or column is encountered. - * + * + * Table alias + *

      + * When a simple table (i.e. not a sub-query) is aliased, the metadata of + * this table will be wrapped inside a {@link DBTableAlias} in order to + * keep the original metadata but still declare use the table with the + * alias instead of its original name. The original name will be used + * only when translating the corresponding FROM item ; the rest of the time + * (i.e. for references when using a column), the alias name must be used. + *

      + *

      + * In order to avoid unpredictable behavior at execution of the SQL query, + * the alias will be put in lower case if not defined between double + * quotes. + *

      + * + * @param query Query in which the existence of tables must be + * checked. + * @param fathersList List of all columns available in the father queries + * and that should be accessed in sub-queries. + * Each item of this stack is a list of columns + * available in each father-level query. + * Note: this parameter is NULL if this function is + * called with the root/father query as parameter. + * @param errors List of errors to complete in this function each + * time an unknown table or column is encountered. + * * @return An associative map of all the resolved tables. */ protected Map resolveTables(final ADQLQuery query, final Stack fathersList, final UnresolvedIdentifiersException errors){ @@ -515,8 +546,9 @@ dbTable = generateDBTable(table.getSubQuery(), table.getAlias()); }else{ dbTable = resolveTable(table); - if (table.hasAlias()) - dbTable = dbTable.copy(null, table.getAlias()); + // wrap this table metadata if an alias should be used: + if (dbTable != null && table.hasAlias()) + dbTable = new DBTableAlias(dbTable, (table.isCaseSensitive(IdentifierField.ALIAS) ? table.getAlias() : table.getAlias().toLowerCase())); } // link with the matched DBTable: @@ -542,7 +574,7 @@ // first, try to resolve the table by table alias: if (table.getTableName() != null && table.getSchemaName() == null){ - ArrayList tables = query.getFrom().getTablesByAlias(table.getTableName(), table.isCaseSensitive(IdentifierField.TABLE)); + List tables = query.getFrom().getTablesByAlias(table.getTableName(), table.isCaseSensitive(IdentifierField.TABLE)); if (tables.size() == 1) dbTable = tables.get(0).getDBLink(); } @@ -563,22 +595,22 @@ /** * Resolve the given table, that's to say search for the corresponding {@link DBTable}. - * + * * @param table The table to resolve. - * + * * @return The corresponding {@link DBTable} if found, null otherwise. - * + * * @throws ParseException An {@link UnresolvedTableException} if the given table can't be resolved. */ protected DBTable resolveTable(final ADQLTable table) throws ParseException{ - ArrayList tables = lstTables.search(table); + List tables = lstTables.search(table); // good if only one table has been found: if (tables.size() == 1) return tables.get(0); // but if more than one: ambiguous table name ! else if (tables.size() > 1) - throw new UnresolvedTableException(table, tables.get(0).getADQLSchemaName() + "." + tables.get(0).getADQLName(), tables.get(1).getADQLSchemaName() + "." + tables.get(1).getADQLName()); + throw new UnresolvedTableException(table, (tables.get(0).getADQLSchemaName() == null ? "" : tables.get(0).getADQLSchemaName() + ".") + tables.get(0).getADQLName(), (tables.get(1).getADQLSchemaName() == null ? "" : tables.get(1).getADQLSchemaName() + ".") + tables.get(1).getADQLName()); // otherwise (no match): unknown table ! else throw new UnresolvedTableException(table); @@ -587,7 +619,7 @@ /** *

      Search all column references inside the given query, resolve them thanks to the given tables' metadata, * and if there is only one match, attach the matching metadata to them.

      - * + * * Management of selected columns' references *

      * A column reference is not only a direct reference to a table column using a column name. @@ -599,7 +631,7 @@ * These references are also checked, in a second step, in this function. Thus, column metadata are * also attached to them, as common columns. *

      - * + * * @param query Query in which the existence of tables must be checked. * @param fathersList List of all columns available in the father queries and that should be accessed in sub-queries. * Each item of this stack is a list of columns available in each father-level query. @@ -612,7 +644,7 @@ ISearchHandler sHandler; // Check the existence of all columns: - sHandler = new SearchColumnHandler(); + sHandler = new SearchColumnOutsideGroupByHandler(); sHandler.search(query); for(ADQLObject result : sHandler){ try{ @@ -627,12 +659,30 @@ } } + // Check the GROUP BY items: + ClauseSelect select = query.getSelect(); + sHandler = new SearchColumnHandler(); + sHandler.search(query.getGroupBy()); + for(ADQLObject result : sHandler){ + try{ + ADQLColumn adqlColumn = (ADQLColumn)result; + // resolve the column: + DBColumn dbColumn = checkGroupByItem(adqlColumn, select, list); + // link with the matched DBColumn: + if (dbColumn != null){ + adqlColumn.setDBLink(dbColumn); + adqlColumn.setAdqlTable(mapTables.get(dbColumn.getTable())); + } + }catch(ParseException pe){ + errors.addException(pe); + } + } + // Check the correctness of all column references (= references to selected columns): /* Note: no need to provide the father tables when resolving column references, - * because no father column can be used in ORDER BY and/or GROUP BY. */ + * because no father column can be used in ORDER BY. */ sHandler = new SearchColReferenceHandler(); sHandler.search(query); - ClauseSelect select = query.getSelect(); for(ADQLObject result : sHandler){ try{ ColumnReference colRef = (ColumnReference)result; @@ -650,26 +700,26 @@ /** *

      Resolve the given column, that's to say search for the corresponding {@link DBColumn}.

      - * + * *

      * The third parameter is used only if this function is called inside a sub-query. In this case, * the column is tried to be resolved with the first list (dbColumns). If no match is found, * the resolution is tried with the father columns list (fathersList). *

      - * + * * @param column The column to resolve. * @param dbColumns List of all available {@link DBColumn}s. * @param fathersList List of all columns available in the father queries and that should be accessed in sub-queries. * Each item of this stack is a list of columns available in each father-level query. * Note: this parameter is NULL if this function is called with the root/father query as parameter. - * + * * @return The corresponding {@link DBColumn} if found. Otherwise an exception is thrown. - * + * * @throws ParseException An {@link UnresolvedColumnException} if the given column can't be resolved * or an {@link UnresolvedTableException} if its table reference can't be resolved. */ protected DBColumn resolveColumn(final ADQLColumn column, final SearchColumnList dbColumns, Stack fathersList) throws ParseException{ - ArrayList foundColumns = dbColumns.search(column); + List foundColumns = dbColumns.search(column); // good if only one column has been found: if (foundColumns.size() == 1) @@ -693,18 +743,50 @@ } /** + * Check whether the given column corresponds to a selected item's alias or to an existing column. + * + * @param col The column to check. + * @param select The SELECT clause of the ADQL query. + * @param dbColumns The list of all available columns. + * + * @return The corresponding {@link DBColumn} if this column corresponds to an existing column, + * NULL otherwise. + * + * @throws ParseException An {@link UnresolvedColumnException} if the given column can't be resolved + * or an {@link UnresolvedTableException} if its table reference can't be resolved. + * + * @see ClauseSelect#searchByAlias(String) + * @see #resolveColumn(ADQLColumn, SearchColumnList, Stack) + * + * @since 1.4 + */ + protected DBColumn checkGroupByItem(final ADQLColumn col, final ClauseSelect select, final SearchColumnList dbColumns) throws ParseException{ + /* If the column name is not qualified, it may be a SELECT-item's alias. + * So, try resolving the name as an alias. + * If it fails, perform the normal column resolution.*/ + if (col.getTableName() == null){ + List founds = select.searchByAlias(col.getColumnName(), col.isCaseSensitive(IdentifierField.COLUMN)); + if (founds.size() == 1) + return null; + else if (founds.size() > 1) + throw new UnresolvedColumnException(col, founds.get(0).getAlias(), founds.get(1).getAlias()); + } + return resolveColumn(col, dbColumns, null); + } + + /** * Check whether the given column reference corresponds to a selected item (column or an expression with an alias) * or to an existing column. - * + * * @param colRef The column reference which must be checked. * @param select The SELECT clause of the ADQL query. * @param dbColumns The list of all available columns. - * + * * @return The corresponding {@link DBColumn} if this reference is actually the name of a column, null otherwise. - * + * * @throws ParseException An {@link UnresolvedColumnException} if the given column can't be resolved * or an {@link UnresolvedTableException} if its table reference can't be resolved. - * + * * @see ClauseSelect#searchByAlias(String) * @see #resolveColumn(ADQLColumn, SearchColumnList, Stack) */ @@ -720,18 +802,16 @@ }else throw new ParseException("Column index out of bounds: " + index + " (must be between 1 and " + select.size() + ") !", colRef.getPosition()); }else{ - ADQLColumn col = new ADQLColumn(colRef.getColumnName()); + ADQLColumn col = new ADQLColumn(null, colRef.getColumnName()); col.setCaseSensitive(colRef.isCaseSensitive()); col.setPosition(colRef.getPosition()); // search among the select_item aliases: - if (col.getTableName() == null){ - ArrayList founds = select.searchByAlias(colRef.getColumnName(), colRef.isCaseSensitive()); - if (founds.size() == 1) - return null; - else if (founds.size() > 1) - throw new UnresolvedColumnException(col, founds.get(0).getAlias(), founds.get(1).getAlias()); - } + List founds = select.searchByAlias(colRef.getColumnName(), colRef.isCaseSensitive()); + if (founds.size() == 1) + return null; + else if (founds.size() > 1) + throw new UnresolvedColumnException(col, founds.get(0).getAlias(), founds.get(1).getAlias()); // check the corresponding column: return resolveColumn(col, dbColumns, null); @@ -741,12 +821,12 @@ /** * Generate a {@link DBTable} corresponding to the given sub-query with the given table name. * This {@link DBTable} will contain all {@link DBColumn} returned by {@link ADQLQuery#getResultingColumns()}. - * + * * @param subQuery Sub-query in which the specified table must be searched. * @param tableName Name of the table to search. - * + * * @return The corresponding {@link DBTable} if the table has been found in the given sub-query, null otherwise. - * + * * @throws ParseException Can be used to explain why the table has not been found. Note: not used by default. */ public static DBTable generateDBTable(final ADQLQuery subQuery, final String tableName) throws ParseException{ @@ -766,7 +846,7 @@ /** *

      Search all UDFs (User Defined Functions) inside the given query, and then * check their signature against the list of allowed UDFs.

      - * + * *

      Note: * When more than one allowed function match, the function is considered as correct * and no error is added. @@ -776,10 +856,10 @@ * then need to cast some parameters to help the parser identifying the right function. * But the type-casting ability is not yet possible in ADQL. *

      - * + * * @param query Query in which UDFs must be checked. * @param errors List of errors to complete in this function each time a UDF does not match to any of the allowed UDFs. - * + * * @since 1.3 */ protected void checkUDFs(final ADQLQuery query, final UnresolvedIdentifiersException errors){ @@ -810,30 +890,32 @@ * for a later resolution try. */ for(ADQLObject result : sHandler){ udf = (UserDefinedFunction)result; - // search for a match: - match = binSearch.search(udf, allowedUdfs); - // if no match... - if (match < 0){ - // ...if the type of all parameters is resolved, add an error (no match is possible): - if (isAllParamTypesResolved(udf)) - errors.addException(new UnresolvedFunctionException(udf)); // TODO Add the ADQLOperand position! - // ...otherwise, try to resolved it later (when other UDFs will be mostly resolved): - else - toResolveLater.add(udf); + // if the type of not all parameters are resolved, postpone the resolution: + if (!isAllParamTypesResolved(udf)) + toResolveLater.add(udf); + // otherwise: + else{ + // search for a match: + match = binSearch.search(udf, allowedUdfs); + // if no match... + if (match < 0) + errors.addException(new UnresolvedFunctionException(udf)); + // if there is a match, metadata may be attached (particularly if the function is built automatically by the syntactic parser): + else if (udf instanceof DefaultUDF) + ((DefaultUDF)udf).setDefinition(allowedUdfs[match]); } - // if there is a match, metadata may be attached (particularly if the function is built automatically by the syntactic parser): - else if (udf instanceof DefaultUDF) - ((DefaultUDF)udf).setDefinition(allowedUdfs[match]); } // Try to resolve UDFs whose some parameter types are depending of other UDFs: - for(int i = 0; i < toResolveLater.size(); i++){ + /* Note: we need to iterate from the end in order to resolve first the most wrapped functions + * (e.g. fct1(fct2(...)) ; fct2 must be resolved before fct1). */ + for(int i = toResolveLater.size() - 1; i >= 0; i--){ udf = toResolveLater.get(i); // search for a match: match = binSearch.search(udf, allowedUdfs); // if no match, add an error: if (match < 0) - errors.addException(new UnresolvedFunctionException(udf)); // TODO Add the ADQLOperand position! + errors.addException(new UnresolvedFunctionException(udf)); // otherwise, metadata may be attached (particularly if the function is built automatically by the syntactic parser): else if (udf instanceof DefaultUDF) ((DefaultUDF)udf).setDefinition(allowedUdfs[match]); @@ -847,23 +929,23 @@ /** *

      Tell whether the type of all parameters of the given ADQL function * is resolved.

      - * + * *

      A parameter type may not be resolved for 2 main reasons:

      *
        *
      • the parameter is a column, but this column has not been successfully resolved. Thus its type is still unknown.
      • *
      • the parameter is a UDF, but this UDF has not been already resolved. Thus, as for the column, its return type is still unknown. * But it could be known later if the UDF is resolved later ; a second try should be done afterwards.
      • *
      - * + * * @param fct ADQL function whose the parameters' type should be checked. - * + * * @return true if the type of all parameters is known, false otherwise. - * + * * @since 1.3 */ protected final boolean isAllParamTypesResolved(final ADQLFunction fct){ for(ADQLOperand op : fct.getParameters()){ - if (op.isNumeric() == op.isString()) + if (op.isGeometry() == op.isNumeric() && op.isNumeric() == op.isString()) return false; } return true; @@ -875,7 +957,7 @@ /** *

      Check all geometries.

      - * + * *

      Operations done in this function:

      *
        *
      1. Check that all geometrical functions are supported
      2. @@ -883,14 +965,14 @@ *
      3. Check all STC-S expressions (only in {@link RegionFunction} for the moment) and * Apply the 2 previous checks on them
      4. *
      - * + * * @param query Query in which geometries must be checked. * @param errors List of errors to complete in this function each time a geometry item is not supported. - * + * * @see #resolveGeometryFunctions(ADQLQuery, BinarySearch, UnresolvedIdentifiersException) * @see #resolveCoordinateSystems(ADQLQuery, UnresolvedIdentifiersException) * @see #resolveSTCSExpressions(ADQLQuery, BinarySearch, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected void checkGeometries(final ADQLQuery query, final UnresolvedIdentifiersException errors){ @@ -916,12 +998,12 @@ /** * Search for all geometrical functions and check whether they are allowed. - * + * * @param query Query in which geometrical functions must be checked. * @param errors List of errors to complete in this function each time a geometrical function is not supported. - * + * * @see #checkGeometryFunction(String, ADQLFunction, BinarySearch, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected void resolveGeometryFunctions(final ADQLQuery query, final BinarySearch binSearch, final UnresolvedIdentifiersException errors){ @@ -937,12 +1019,12 @@ /** *

      Check whether the specified geometrical function is allowed by this implementation.

      - * + * *

      Note: * If the list of allowed geometrical functions is empty, this function will always add an errors to the given list. * Indeed, it means that no geometrical function is allowed and so that the specified function is automatically not supported. *

      - * + * * @param fctName Name of the geometrical function to test. * @param fct The function instance being or containing the geometrical function to check. Note: this function can be the function to test or a function embedding the function under test (i.e. RegionFunction). * @param binSearch The object to use in order to search a function name inside the list of allowed functions. @@ -950,7 +1032,7 @@ * this object is its compare function which must be overridden and tells how to compare the item * to search and the items of the array (basically, a non-case-sensitive comparison between 2 strings). * @param errors List of errors to complete in this function each time a geometrical function is not supported. - * + * * @since 1.3 */ protected void checkGeometryFunction(final String fctName, final ADQLFunction fct, final BinarySearch binSearch, final UnresolvedIdentifiersException errors){ @@ -963,18 +1045,18 @@ /** *

      Search all explicit coordinate system declarations, check their syntax and whether they are allowed by this implementation.

      - * + * *

      Note: * "explicit" means here that all {@link StringConstant} instances. Only coordinate systems expressed as string can * be parsed and so checked. So if a coordinate system is specified by a column, no check can be done at this stage... * it will be possible to perform such test only at the execution. *

      - * + * * @param query Query in which coordinate systems must be checked. * @param errors List of errors to complete in this function each time a coordinate system has a wrong syntax or is not supported. - * + * * @see #checkCoordinateSystem(StringConstant, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected void resolveCoordinateSystems(final ADQLQuery query, final UnresolvedIdentifiersException errors){ @@ -986,13 +1068,13 @@ /** * Parse and then check the coordinate system contained in the given {@link StringConstant} instance. - * + * * @param adqlCoordSys The {@link StringConstant} object containing the coordinate system to check. * @param errors List of errors to complete in this function each time a coordinate system has a wrong syntax or is not supported. - * + * * @see STCS#parseCoordSys(String) * @see #checkCoordinateSystem(adql.db.STCS.CoordSys, ADQLOperand, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected void checkCoordinateSystem(final StringConstant adqlCoordSys, final UnresolvedIdentifiersException errors){ @@ -1000,42 +1082,55 @@ try{ checkCoordinateSystem(STCS.parseCoordSys(coordSysStr), adqlCoordSys, errors); }catch(ParseException pe){ - errors.addException(new ParseException(pe.getMessage())); // TODO Missing object position! + errors.addException(new ParseException(pe.getMessage(), adqlCoordSys.getPosition())); } } /** - * Check whether the given coordinate system is allowed by this implementation. - * + * Check whether the given coordinate system is allowed by this implementation. + * * @param coordSys Coordinate system to test. * @param operand The operand representing or containing the coordinate system under test. * @param errors List of errors to complete in this function each time a coordinate system is not supported. - * + * * @since 1.3 */ protected void checkCoordinateSystem(final CoordSys coordSys, final ADQLOperand operand, final UnresolvedIdentifiersException errors){ - if (coordSysRegExp != null && coordSys != null && !coordSys.toFullSTCS().matches(coordSysRegExp)) - errors.addException(new ParseException("Coordinate system \"" + ((operand instanceof StringConstant) ? ((StringConstant)operand).getValue() : coordSys.toString()) + "\" (= \"" + coordSys.toFullSTCS() + "\") not allowed in this implementation.")); // TODO Missing object position! + List of accepted coordinate systems + if (coordSysRegExp != null && coordSys != null && !coordSys.toFullSTCS().matches(coordSysRegExp)){ + StringBuffer buf = new StringBuffer(); + if (allowedCoordSys != null){ + for(String cs : allowedCoordSys){ + if (buf.length() > 0) + buf.append(", "); + buf.append(cs); + } + } + if (buf.length() == 0) + buf.append("No coordinate system is allowed!"); + else + buf.insert(0, "Allowed coordinate systems are: "); + errors.addException(new ParseException("Coordinate system \"" + ((operand instanceof StringConstant) ? ((StringConstant)operand).getValue() : coordSys.toString()) + "\" (= \"" + coordSys.toFullSTCS() + "\") not allowed in this implementation. " + buf.toString(), operand.getPosition())); + } } /** *

      Search all STC-S expressions inside the given query, parse them (and so check their syntax) and then determine * whether the declared coordinate system and the expressed region are allowed in this implementation.

      - * + * *

      Note: * In the current ADQL language definition, STC-S expressions can be found only as only parameter of the REGION function. *

      - * + * * @param query Query in which STC-S expressions must be checked. * @param binSearch The object to use in order to search a region name inside the list of allowed functions/regions. * It is able to perform a binary search inside a sorted array of String objects. The interest of * this object is its compare function which must be overridden and tells how to compare the item * to search and the items of the array (basically, a non-case-sensitive comparison between 2 strings). * @param errors List of errors to complete in this function each time the STC-S syntax is wrong or each time the declared coordinate system or region is not supported. - * + * * @see STCS#parseRegion(String) * @see #checkRegion(adql.db.STCS.Region, RegionFunction, BinarySearch, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected void resolveSTCSExpressions(final ADQLQuery query, final BinarySearch binSearch, final UnresolvedIdentifiersException errors){ @@ -1057,29 +1152,29 @@ // check whether the regions (this one + the possible inner ones) and the coordinate systems are allowed: checkRegion(region, (RegionFunction)result, binSearch, errors); }catch(ParseException pe){ - errors.addException(new ParseException(pe.getMessage())); // TODO Missing object position! + errors.addException(new ParseException(pe.getMessage(), result.getPosition())); } } } /** *

      Check the given region.

      - * + * *

      The following points are checked in this function:

      *
        *
      • whether the coordinate system is allowed
      • *
      • whether the type of region is allowed
      • *
      • whether the inner regions are correct (here this function is called recursively on each inner region).
      • *
      - * + * * @param r The region to check. * @param fct The REGION function containing the region to check. * @param errors List of errors to complete in this function if the given region or its inner regions are not supported. - * + * * @see #checkCoordinateSystem(adql.db.STCS.CoordSys, ADQLOperand, UnresolvedIdentifiersException) * @see #checkGeometryFunction(String, ADQLFunction, BinarySearch, UnresolvedIdentifiersException) * @see #checkRegion(adql.db.STCS.Region, RegionFunction, BinarySearch, UnresolvedIdentifiersException) - * + * * @since 1.3 */ protected void checkRegion(final Region r, final RegionFunction fct, final BinarySearch binSearch, final UnresolvedIdentifiersException errors){ @@ -1112,13 +1207,13 @@ /** *

      Search all operands whose the type is not yet known and try to resolve it now * and to check whether it matches the type expected by the syntactic parser.

      - * + * *

      * Only two operands may have an unresolved type: columns and user defined functions. * Indeed, their type can be resolved only if the list of available columns and UDFs is known, * and if columns and UDFs used in the query are resolved successfully. *

      - * + * *

      * When an operand type is still unknown, they will own the three kinds of type and * so this function won't raise an error: it is thus automatically on the expected type. @@ -1126,17 +1221,17 @@ * that means the item/operand has not been resolved in the previous steps and so that * an error about this item has already been raised. *

      - * + * *

      Important note: * This function does not check the types exactly, but just roughly by considering only three categories: * string, numeric and geometry. *

      - * + * * @param query Query in which unknown types must be resolved and checked. * @param errors List of errors to complete in this function each time a types does not match to the expected one. - * + * * @see UnknownType - * + * * @since 1.3 */ protected void checkTypes(final ADQLQuery query, final UnresolvedIdentifiersException errors){ @@ -1152,17 +1247,17 @@ case 'G': case 'g': if (!unknown.isGeometry()) - errors.addException(new ParseException("Type mismatch! A geometry was expected instead of \"" + unknown.toADQL() + "\".")); // TODO Add the ADQLOperand position! + errors.addException(new ParseException("Type mismatch! A geometry was expected instead of \"" + unknown.toADQL() + "\".", result.getPosition())); break; case 'N': case 'n': if (!unknown.isNumeric()) - errors.addException(new ParseException("Type mismatch! A numeric value was expected instead of \"" + unknown.toADQL() + "\".")); // TODO Add the ADQLOperand position! + errors.addException(new ParseException("Type mismatch! A numeric value was expected instead of \"" + unknown.toADQL() + "\".", result.getPosition())); break; case 'S': case 's': if (!unknown.isString()) - errors.addException(new ParseException("Type mismatch! A string value was expected instead of \"" + unknown.toADQL() + "\".")); // TODO Add the ADQLOperand position! + errors.addException(new ParseException("Type mismatch! A string value was expected instead of \"" + unknown.toADQL() + "\".", result.getPosition())); break; } } @@ -1175,7 +1270,7 @@ /** *

      Search all sub-queries found in the given query but not in the clause FROM. * These sub-queries are then checked using {@link #check(ADQLQuery, Stack)}.

      - * + * * Fathers stack *

      * Each time a sub-query must be checked with {@link #check(ADQLQuery, Stack)}, @@ -1188,15 +1283,15 @@ * This modification of the given stack is just the execution time of this function. * Before returning, this function removes the last item of the stack. *

      - * - * + * + * * @param query Query in which sub-queries must be checked. * @param fathersList List of all columns available in the father queries and that should be accessed in sub-queries. * Each item of this stack is a list of columns available in each father-level query. * Note: this parameter is NULL if this function is called with the root/father query as parameter. * @param availableColumns List of all columns resolved in the given query. * @param errors List of errors to complete in this function each time a semantic error is encountered. - * + * * @since 1.3 */ protected void checkSubQueries(final ADQLQuery query, Stack fathersList, final SearchColumnList availableColumns, final UnresolvedIdentifiersException errors){ @@ -1229,9 +1324,29 @@ /* *************** */ /* SEARCH HANDLERS */ /* *************** */ + + /** + * Lets searching all {@link ADQLColumn} in the given object, EXCEPT in the GROUP BY clause. + * + *

      + * {@link ADQLColumn}s of the GROUP BY may be aliases and so, they can not be checked + * exactly as a normal column. + *

      + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (05/2017) + * @since 1.4 + */ + private static class SearchColumnOutsideGroupByHandler extends SearchColumnHandler { + @Override + protected boolean goInto(final ADQLObject obj){ + return !(obj instanceof ClauseADQL && ((ClauseADQL)obj).getName() != null && ((ClauseADQL)obj).getName().equalsIgnoreCase("GROUP BY")) && super.goInto(obj); + } + } + /** * Lets searching all tables. - * + * * @author Grégory Mantelet (CDS) * @version 1.0 (07/2011) */ @@ -1244,7 +1359,7 @@ /** * Lets searching all wildcards. - * + * * @author Grégory Mantelet (CDS) * @version 1.0 (09/2011) */ @@ -1257,7 +1372,7 @@ /** * Lets searching column references. - * + * * @author Grégory Mantelet (CDS) * @version 1.0 (11/2011) */ @@ -1270,12 +1385,12 @@ /** *

      Lets searching subqueries in every clause except the FROM one (hence the modification of the {@link #goInto(ADQLObject)}.

      - * + * *

      * Note: The function {@link #addMatch(ADQLObject, ADQLIterator)} has been modified in order to * not have the root search object (here: the main query) in the list of results. *

      - * + * * @author Grégory Mantelet (ARI) * @version 1.2 (12/2013) * @since 1.2 @@ -1300,7 +1415,7 @@ /** * Let searching user defined functions. - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (10/2014) * @since 1.3 @@ -1314,11 +1429,11 @@ /** *

      Let replacing every {@link DefaultUDF}s whose a {@link FunctionDef} is set by their corresponding {@link UserDefinedFunction} class.

      - * + * *

      Important note: * If the replacer can not be created using the class returned by {@link FunctionDef#getUDFClass()}, no replacement is performed. *

      - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (02/2015) * @since 1.3 @@ -1359,7 +1474,7 @@ /** * Let searching geometrical functions. - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (10/2014) * @since 1.3 @@ -1374,12 +1489,12 @@ /** *

      Let searching all ADQL objects whose the type was not known while checking the syntax of the ADQL query. * These objects are {@link ADQLColumn}s and {@link UserDefinedFunction}s.

      - * + * *

      Important note: * Only {@link UnknownType} instances having an expected type equals to 'S' (or 's' ; for string) or 'N' (or 'n' ; for numeric) * are kept by this handler. Others are ignored. *

      - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (10/2014) * @since 1.3 @@ -1398,7 +1513,7 @@ /** * Let searching all explicit declaration of coordinate systems. * So, only {@link StringConstant} objects will be returned. - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (10/2014) * @since 1.3 @@ -1421,7 +1536,7 @@ /** * Let searching all {@link RegionFunction}s. - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (10/2014) * @since 1.3 @@ -1439,23 +1554,23 @@ /** *

      Implement the binary search algorithm over a sorted array.

      - * + * *

      * The only difference with the standard implementation of Java is * that this object lets perform research with a different type * of object than the types of array items. *

      - * + * *

      * For that reason, the "compare" function must always be implemented. *

      - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (10/2014) - * + * * @param Type of items stored in the array. * @param Type of the item to search. - * + * * @since 1.3 */ protected static abstract class BinarySearch< T, S > { @@ -1463,16 +1578,16 @@ /** *

      Search the given item in the given array.

      - * + * *

      * In case the given object matches to several items of the array, * this function will return the smallest index, pointing thus to the first * of all matches. *

      - * + * * @param searchItem Object for which a corresponding array item must be searched. * @param array Array in which the given object must be searched. - * + * * @return The array index of the first item of all matches. */ public int search(final S searchItem, final T[] array){ @@ -1483,7 +1598,7 @@ m = s + ((e - s) / 2); // compare the fct with the middle item of the array: comp = compare(searchItem, array[m]); - // if the fct is after, trigger the inspection of the right part of the array: + // if the fct is after, trigger the inspection of the right part of the array: if (comp > 0) s = m + 1; // otherwise, the left part: @@ -1498,10 +1613,10 @@ /** * Compare the search item and the array item. - * + * * @param searchItem Item whose a corresponding value must be found in the array. * @param arrayItem An item of the array. - * + * * @return Negative value if searchItem is less than arrayItem, 0 if they are equals, or a positive value if searchItem is greater. */ protected abstract int compare(final S searchItem, final T arrayItem); diff -Nru adql-1.3/src/adql/db/DBColumn.java adql-1.4/src/adql/db/DBColumn.java --- adql-1.3/src/adql/db/DBColumn.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/db/DBColumn.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2011,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2011-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -29,12 +29,12 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (07/2016) */ public interface DBColumn { /** - * Gets the name of this column which must be used in an ADQL query. + * Gets the name of this column (without any prefix and double-quotes). * * @return Its ADQL name. */ diff -Nru adql-1.3/src/adql/db/DBTableAlias.java adql-1.4/src/adql/db/DBTableAlias.java --- adql-1.3/src/adql/db/DBTableAlias.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/db/DBTableAlias.java 2017-11-30 15:04:26.000000000 +0000 @@ -0,0 +1,77 @@ +package adql.db; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ADQLLibrary. If not, see . + * + * Copyright 2017 - Astronomisches Rechen Institut (ARI) + */ + +/** + * This {@link DBTable} wraps another {@link DBTable} with a different ADQL and + * DB name. + * + *

      + * This wrapper aims to represent in the metadata the aliasing of a table. + * This table should not be part of any schema, in ADQL but also in SQL...it is + * just an alias of an existing table. + *

      + * + *

      + * All columns of the origin table are completely copied into this + * {@link DBTable} thanks to {@link DBColumn#copy(String, String, DBTable)}, + * with the same ADQL and DB name but a different parent table (this one is + * used of the original one). + *

      + * + *

      Note: + * The origin table is still available thanks to the function + * {@link #getOriginTable()}. + *

      + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (11/2017) + * @since 1.4 + */ +public class DBTableAlias extends DefaultDBTable { + + /** Wrapped table. */ + protected final DBTable originTable; + + /** + * Wrap the given table under the given ADQL/DB name. + * + * @param originTable The table to wrap/alias. + * @param tableAlias The alias name. + */ + public DBTableAlias(final DBTable originTable, final String tableAlias){ + super(null, null, tableAlias); + + this.originTable = originTable; + + for(DBColumn col : originTable) + addColumn(col.copy(col.getDBName(), col.getADQLName(), this)); + } + + /** + * Get the aliased/wrapped table. + * + * @return The aliased table. + */ + public DBTable getOriginTable(){ + return originTable; + } + +} diff -Nru adql-1.3/src/adql/db/DBTable.java adql-1.4/src/adql/db/DBTable.java --- adql-1.3/src/adql/db/DBTable.java 2015-02-19 17:28:18.000000000 +0000 +++ adql-1.4/src/adql/db/DBTable.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -29,12 +29,12 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (09/2014) + * @version 1.4 (07/2016) */ public interface DBTable extends Iterable { /** - * Gets the name of this table which must be used in an ADQL query. + * Gets the name of this table (without any prefix and double-quotes). * * @return Its ADQL name. */ diff -Nru adql-1.3/src/adql/db/DBType.java adql-1.4/src/adql/db/DBType.java --- adql-1.3/src/adql/db/DBType.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/db/DBType.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,11 +16,10 @@ * You should have received a copy of the GNU Lesser General Public License * along with TAPLibrary. If not, see . * - * Copyright 2014 - Astronomisches Rechen Institut (ARI) + * Copyright 2014-2016 - Astronomisches Rechen Institut (ARI) */ /** - * *

      * Describe a full column type as it is described in the IVOA document of TAP. * Thus, this object contains 2 attributes: type (or datatype) and length (or size). @@ -30,9 +29,9 @@ * *

      All datatypes declared in the IVOA recommendation document of TAP are listed in an enumeration type: {@link DBDatatype}. * It is used to set the attribute type/datatype of this class.

      - * + * * @author Grégory Mantelet (ARI) - * @version 1.3 (10/2014) + * @version 1.4 (07/2016) * @since 1.3 */ public class DBType { @@ -41,11 +40,53 @@ * List of all datatypes declared in the IVOA recommendation of TAP (in the section UPLOAD). * * @author Grégory Mantelet (ARI) - * @version 1.3 (10/2014) + * @version 1.4 (07/2016) * @since 1.3 */ public static enum DBDatatype{ - SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, BINARY, VARBINARY, CHAR, VARCHAR, BLOB, CLOB, TIMESTAMP, POINT, REGION; + SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, BINARY, VARBINARY, CHAR, VARCHAR, BLOB, CLOB, TIMESTAMP, POINT, REGION, + /** Type to use when the precise datatype is unknown. + * @since 1.4 */ + UNKNOWN, + /**

      Type to use when the type is known as numeric but there is no precise datatype + * (e.g. double, float, integer, ...).

      + *

      It is particularly used when creating a {@link DefaultDBColumn} from an ADQL function + * or operation while listing resulting columns of a sub-query.

      + *

      This type is similar to {@link #UNKNOWN}.

      + * @since 1.4 */ + UNKNOWN_NUMERIC; + + /** String to return when {@link #toString()} is called. + * @since 1.4*/ + private String strExp = this.name(); + + @Override + public String toString(){ + return strExp; + } + + /** + *

      This function lets define the name of the type as provided + * ONLY FOR {@link #UNKNOWN} and {@link #UNKNOWN_NUMERIC} {@link DBDatatype}s.

      + * + *

      Important: + * If this {@link DBDatatype} is not {@link #UNKNOWN} or {@link #UNKNOWN_NUMERIC} this function has no effect. + * But if the given name is NULL or empty, no custom type will be set ; instead the default value (i.e. name of + * the unknown enum item) will be returned. + *

      + * + * @param typeName User type name. + * + * @since 1.4 + */ + public void setCustomType(final String typeName){ + if ((this == UNKNOWN || this == UNKNOWN_NUMERIC)){ + if (typeName != null && typeName.trim().length() > 0) + strExp = "?" + typeName.trim() + "?"; + else + strExp = this.name(); + } + } } /** Special value in case no length/size is specified. */ @@ -79,6 +120,25 @@ this.length = length; } + /** + *

      Tells whether this type is a numeric.

      + * + *

      Concerned types: + * {@link DBDatatype#SMALLINT SMALLINT}, {@link DBDatatype#INTEGER INTEGER}, {@link DBDatatype#BIGINT BIGINT}, + * {@link DBDatatype#REAL REAL}, {@link DBDatatype#DOUBLE DOUBLE}, {@link DBDatatype#BINARY BINARY}, + * {@link DBDatatype#VARBINARY VARBINARY} and {@link DBDatatype#BLOB BLOB}. + *

      + * + *

      Important note: + * Since {@link DBDatatype#UNKNOWN UNKNOWN} is an unresolved type, it can potentially be anything. + * But, in order to avoid incorrect operation while expecting a numeric although the type is unknown + * and is in fact not really a numeric, this function will return false if the type is + * {@link DBDatatype#UNKNOWN UNKNOWN} BUT true if + * {@link DBDatatype#UNKNOWN_NUMERIC UNKNOWN_NUMERIC}. + *

      + * + * @return true if this type is a numeric, false otherwise. + */ public boolean isNumeric(){ switch(type){ case SMALLINT: @@ -91,12 +151,29 @@ case BINARY: case VARBINARY: case BLOB: + case UNKNOWN_NUMERIC: return true; default: return false; } } + /** + *

      Tells whether this type is a list of bytes.

      + * + *

      Concerned types: + * {@link DBDatatype#BINARY BINARY}, {@link DBDatatype#VARBINARY VARBINARY} and {@link DBDatatype#BLOB BLOB}. + *

      + * + *

      Important note: + * Since {@link DBDatatype#UNKNOWN UNKNOWN} is an unresolved type, it can potentially be anything. + * But, in order to avoid incorrect operation while expecting a binary although the type is unknown + * and is in fact not really a binary, this function will return false if the type is + * {@link DBDatatype#UNKNOWN UNKNOWN} or {@link DBDatatype#UNKNOWN_NUMERIC UNKNOWN_NUMERIC}. + *

      + * + * @return true if this type is a binary, false otherwise. + */ public boolean isBinary(){ switch(type){ case BINARY: @@ -108,6 +185,23 @@ } } + /** + *

      Tells whether this type is about characters.

      + * + *

      Concerned types: + * {@link DBDatatype#CHAR CHAR}, {@link DBDatatype#VARCHAR VARCHAR}, {@link DBDatatype#CLOB CLOB} + * and {@link DBDatatype#TIMESTAMP TIMESTAMP}. + *

      + * + *

      Important note: + * Since {@link DBDatatype#UNKNOWN UNKNOWN} is an unresolved type, it can potentially be anything. + * But, in order to avoid incorrect operation while expecting a string although the type is unknown + * and is in fact not really a string, this function will return false if the type is + * {@link DBDatatype#UNKNOWN UNKNOWN} or {@link DBDatatype#UNKNOWN_NUMERIC UNKNOWN_NUMERIC} + *

      + * + * @return true if this type is a string, false otherwise. + */ public boolean isString(){ switch(type){ case CHAR: @@ -120,13 +214,59 @@ } } + /** + *

      Tells whether this type is a geometrical region.

      + * + *

      Concerned types: + * {@link DBDatatype#POINT POINT} and {@link DBDatatype#REGION REGION}. + *

      + * + *

      Important note: + * Since {@link DBDatatype#UNKNOWN UNKNOWN} is an unresolved type, it can potentially be anything. + * But, in order to avoid incorrect operation while expecting a geometry although the type is unknown + * and is in fact not really a geometry, this function will return false if the type is + * {@link DBDatatype#UNKNOWN UNKNOWN} or {@link DBDatatype#UNKNOWN_NUMERIC UNKNOWN_NUMERIC}. + *

      + * + * @return true if this type is a geometry, false otherwise. + */ public boolean isGeometry(){ return (type == DBDatatype.POINT || type == DBDatatype.REGION); } + /** + *

      Tell whether this type has been resolved or not.

      + * + *

      Concerned types: + * {@link DBDatatype#UNKNOWN UNKNOWN} and {@link DBDatatype#UNKNOWN_NUMERIC UNKNOWN_NUMERIC}. + *

      + * + * @return true if this type has NOT been resolved, false otherwise. + * + * @since 1.4 + */ + public boolean isUnknown(){ + return type == DBDatatype.UNKNOWN || type == DBDatatype.UNKNOWN_NUMERIC; + } + + /** + *

      Tell whether this {@link DBType} is compatible with the given one.

      + * + *

      + * Two {@link DBType}s are said compatible if they are both binary, numeric, geometric or string. + * If one of the two types is {@link DBDatatype#UNKNOWN unknown} or {@link DBDatatype#UNKNOWN_NUMERIC unknown_numeric}, + * this function will consider them as compatible and will return true. + *

      + * + * @param t The type to compare to. + * + * @return true if this type is compatible with the given one, false otherwise. + */ public boolean isCompatible(final DBType t){ if (t == null) return false; + else if (isUnknown() || t.isUnknown()) + return true; else if (isBinary() == t.isBinary()) return (type == DBDatatype.BLOB && t.type == DBDatatype.BLOB) || (type != DBDatatype.BLOB && t.type != DBDatatype.BLOB); else if (isNumeric() == t.isNumeric()) diff -Nru adql-1.3/src/adql/db/DefaultDBColumn.java adql-1.4/src/adql/db/DefaultDBColumn.java --- adql-1.3/src/adql/db/DefaultDBColumn.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/db/DefaultDBColumn.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012,2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -24,7 +24,7 @@ * Default implementation of {@link DBColumn}. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (08/2015) */ public class DefaultDBColumn implements DBColumn { @@ -96,9 +96,11 @@ * @param dbName Database column name. * Only the column name is expected. Contrary to {@link DefaultDBTable}, * if a whole column reference is given, no split will be done. + * REQUIRED parameter: it must be not NULL. * @param adqlName Column name used in ADQL queries. * Only the column name is expected. Contrary to {@link DefaultDBTable}, * if a whole column reference is given, no split will be done. + * If NULL, it will be set to dbName. * @param type Type of the column. * Note: there is no default value. Consequently if this parameter is NULL, * the type should be considered as unknown. It means that any comparison with @@ -108,8 +110,13 @@ * @since 1.3 */ public DefaultDBColumn(final String dbName, final String adqlName, final DBType type, final DBTable table){ + + if (dbName == null || dbName.length() == 0) + throw new NullPointerException("Missing DB name!"); + this.dbName = dbName; - this.adqlName = adqlName; + this.adqlName = (adqlName == null) ? dbName : adqlName; + this.type = type; this.table = table; } diff -Nru adql-1.3/src/adql/db/DefaultDBTable.java adql-1.4/src/adql/db/DefaultDBTable.java --- adql-1.3/src/adql/db/DefaultDBTable.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/db/DefaultDBTable.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -29,7 +29,7 @@ * Default implementation of {@link DBTable}. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (11/2014) + * @version 1.4 (08/2015) */ public class DefaultDBTable implements DBTable { @@ -107,10 +107,13 @@ * * @param dbCatName Database catalog name. * @param adqlCatName Catalog name used in ADQL queries. + * If NULL, it will be set to dbCatName. * @param dbSchemName Database schema name. * @param adqlSchemName Schema name used in ADQL queries. + * If NULL, it will be set to dbSchemName. * @param dbName Database table name. * @param adqlName Table name used in ADQL queries. + * If NULL, it will be set to dbName. */ public DefaultDBTable(final String dbCatName, final String adqlCatName, final String dbSchemName, final String adqlSchemName, final String dbName, final String adqlName){ @@ -118,13 +121,13 @@ throw new NullPointerException("Missing DB name !"); this.dbName = dbName; - this.adqlName = adqlName; + this.adqlName = (adqlName == null) ? dbName : adqlName; dbSchemaName = dbSchemName; - adqlSchemaName = adqlSchemName; + adqlSchemaName = (adqlSchemName == null) ? dbSchemName : adqlSchemName; dbCatalogName = dbCatName; - adqlCatalogName = adqlCatName; + adqlCatalogName = (adqlCatName == null) ? dbCatName : adqlCatName; } @Override diff -Nru adql-1.3/src/adql/db/exception/UnresolvedFunctionException.java adql-1.4/src/adql/db/exception/UnresolvedFunctionException.java --- adql-1.3/src/adql/db/exception/UnresolvedFunctionException.java 2015-05-04 09:23:40.000000000 +0000 +++ adql-1.4/src/adql/db/exception/UnresolvedFunctionException.java 2017-11-03 17:18:00.000000000 +0000 @@ -20,13 +20,14 @@ */ import adql.parser.ParseException; +import adql.query.TextPosition; import adql.query.operand.function.ADQLFunction; /** * Exception thrown when a function can not be resolved by the library. * * @author Grégory Mantelet (ARI) - * @version 1.3 (05/2015) + * @version 1.4 (08/2015) * @since 1.3 */ public class UnresolvedFunctionException extends ParseException { @@ -41,7 +42,19 @@ * @param message Description of the error. */ public UnresolvedFunctionException(final String message){ - super(message); + this(message, (TextPosition)null); + } + + /** + * Build the exception with just a message. + * + * @param message Description of the error. + * @param pos Position of the unresolved function inside the ADQL query. + * + * @since 1.4 + */ + public UnresolvedFunctionException(final String message, final TextPosition pos){ + super(message, pos); functionInError = null; } @@ -52,7 +65,7 @@ * @param fct The unresolved function. */ public UnresolvedFunctionException(final ADQLFunction fct){ - super("Unresolved function: \"" + fct.toADQL() + "\"! No UDF has been defined or found with the signature: " + getFctSignature(fct) + "."); // TODO Add the position of the function in the ADQL query! + super("Unresolved function: \"" + fct.toADQL() + "\"! No UDF has been defined or found with the signature: " + getFctSignature(fct) + ".", fct.getPosition()); functionInError = fct; } @@ -64,7 +77,7 @@ * @param fct The unresolved function. */ public UnresolvedFunctionException(final String message, final ADQLFunction fct){ - super(message); // TODO Add the position of the function in the ADQL query! + super(message, (fct == null) ? null : fct.getPosition()); functionInError = fct; } @@ -87,7 +100,8 @@ * *

      Note 1: * A parameter type can be either "NUMERIC", "STRING" or "GEOMETRY". In order to be the most generic has possible, - * no more precision about a type is returned here. If the parameter is none of these type kinds, "???" is returned. + * no more precision about a type is returned here. If the parameter is none of these type kinds, "param" suffixed + * by the parameter index (e.g. "param1") is returned. *

      * *

      Note 2: @@ -105,14 +119,16 @@ StringBuffer buf = new StringBuffer(fct.getName().toLowerCase()); buf.append('('); for(int i = 0; i < fct.getNbParameters(); i++){ - if (fct.getParameter(i).isNumeric()) + if (fct.getParameter(i).isNumeric() && fct.getParameter(i).isString() && fct.getParameter(i).isGeometry()) + buf.append("param").append(i + 1); + else if (fct.getParameter(i).isNumeric()) buf.append("NUMERIC"); else if (fct.getParameter(i).isString()) buf.append("STRING"); else if (fct.getParameter(i).isGeometry()) buf.append("GEOMETRY"); else - buf.append("???"); + buf.append("param").append(i + 1); if ((i + 1) < fct.getNbParameters()) buf.append(", "); diff -Nru adql-1.3/src/adql/db/exception/UnresolvedIdentifiersException.java adql-1.4/src/adql/db/exception/UnresolvedIdentifiersException.java --- adql-1.3/src/adql/db/exception/UnresolvedIdentifiersException.java 2015-05-04 09:22:36.000000000 +0000 +++ adql-1.4/src/adql/db/exception/UnresolvedIdentifiersException.java 2017-11-03 17:18:00.000000000 +0000 @@ -38,7 +38,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (04/2015) + * @version 1.4 (06/2015) * * @see DBChecker */ @@ -66,16 +66,16 @@ exceptions.add(pe); if (pe instanceof UnresolvedColumnException){ String colName = ((UnresolvedColumnException)pe).getColumnName(); - if (colName != null && !colName.trim().isEmpty()) + if (colName != null && colName.trim().length() > 0) addIdentifierName(colName + " " + pe.getPosition()); }else if (pe instanceof UnresolvedTableException){ String tableName = ((UnresolvedTableException)pe).getTableName(); - if (tableName != null && !tableName.trim().isEmpty()) + if (tableName != null && tableName.trim().length() > 0) addIdentifierName(tableName + " " + pe.getPosition()); }else if (pe instanceof UnresolvedFunctionException){ String fctName = (((UnresolvedFunctionException)pe).getFunction() == null) ? null : ((UnresolvedFunctionException)pe).getFunction().getName() + "(...)"; - if (fctName != null && !fctName.trim().isEmpty()) - addIdentifierName(fctName /*+ " " + pe.getPosition()*/); // TODO Add the position of the function in the ADQL query! + if (fctName != null && fctName.trim().length() > 0) + addIdentifierName(fctName + " " + pe.getPosition()); }else if (pe instanceof UnresolvedIdentifiersException) addIdentifierName(((UnresolvedIdentifiersException)pe).unresolvedIdentifiers); } @@ -87,7 +87,7 @@ * @param name Name (or description) of the identifier to add. */ private final void addIdentifierName(final String name){ - if (name != null && !name.trim().isEmpty()){ + if (name != null && name.trim().length() > 0){ if (unresolvedIdentifiers == null) unresolvedIdentifiers = ""; else diff -Nru adql-1.3/src/adql/db/exception/UnresolvedJoinException.java adql-1.4/src/adql/db/exception/UnresolvedJoinException.java --- adql-1.3/src/adql/db/exception/UnresolvedJoinException.java 2015-05-04 09:23:28.000000000 +0000 +++ adql-1.4/src/adql/db/exception/UnresolvedJoinException.java 2017-11-03 17:18:00.000000000 +0000 @@ -26,8 +26,8 @@ * This exception is thrown when a table between 2 tables can not be resolved, * and particularly because of the join condition (i.e. column names not found, ...). * - * @author Grégory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de - * @version 1.3 (05/2015) + * @author Grégory Mantelet (ARI) + * @version 1.4 (06/2015) * @since 1.2 */ public class UnresolvedJoinException extends ParseException { @@ -53,4 +53,15 @@ super(message, errorPosition); } + /** + * Set the position of the invalid JOIN. + * + * @param pos Position of the concerned JOIN inside the ADQL query. + * + * @since 1.4 + */ + public void setPosition(final TextPosition pos){ + this.position = pos; + } + } diff -Nru adql-1.3/src/adql/db/FunctionDef.java adql-1.4/src/adql/db/FunctionDef.java --- adql-1.3/src/adql/db/FunctionDef.java 2015-02-11 15:43:28.000000000 +0000 +++ adql-1.4/src/adql/db/FunctionDef.java 2017-11-03 17:18:00.000000000 +0000 @@ -49,7 +49,7 @@ *

      * * @author Grégory Mantelet (ARI) - * @version 1.3 (02/2015) + * @version 1.4 (08/2015) * * @since 1.3 */ @@ -59,7 +59,7 @@ /** Rough regular expression for a function return type or a parameter type. * The exact type is not checked here ; just the type name syntax is tested, not its value. * This regular expression allows a type to have exactly one parameter (which is generally the length of a character or binary string. */ - protected final static String typeRegExp = "([a-zA-Z]+[0-9a-zA-Z]*)(\\(\\s*([0-9]+)\\s*\\))?"; + protected final static String typeRegExp = "([a-zA-Z_]+[ 0-9a-zA-Z_]*)(\\(\\s*([0-9]+)\\s*\\))?"; /** Rough regular expression for a function parameters' list. */ protected final static String fctParamsRegExp = "\\s*[^,]+\\s*(,\\s*[^,]+\\s*)*"; /** Rough regular expression for a function parameter: a name (see {@link #regularIdentifierRegExp}) and a type (see {@link #typeRegExp}). */ @@ -86,6 +86,14 @@ protected final boolean isNumeric; /** Indicate whether the return type is a geometry. */ protected final boolean isGeometry; + /** Indicate whether the return type is an unknown type. + *

      Note: + * If true, {@link #isString}, {@link #isNumeric} + * and {@link #isGeometry} are false. Otherwise, + * at least one of these attributes is set to true. + *

      + * @since 1.4 */ + protected final boolean isUnknown; /** Total number of parameters. */ public final int nbParams; @@ -122,7 +130,7 @@ *

      This definition is composed of two items: the name and the type of the parameter.

      * * @author Grégory Mantelet (ARI) - * @version 1.3 (10/2014) + * @version 1.4 (07/2015) * @since 1.3 */ public static final class FunctionParam { @@ -135,15 +143,13 @@ * Create a function parameter. * * @param paramName Name of the parameter to create. MUST NOT be NULL - * @param paramType Type of the parameter to create. MUST NOT be NULL + * @param paramType Type of the parameter to create. If NULL, an {@link DBDatatype#UNKNOWN UNKNOWN} type will be created and set instead. */ public FunctionParam(final String paramName, final DBType paramType){ if (paramName == null) throw new NullPointerException("Missing name! The function parameter can not be created."); - if (paramType == null) - throw new NullPointerException("Missing type! The function parameter can not be created."); this.name = paramName; - this.type = paramType; + this.type = (paramType == null) ? new DBType(DBDatatype.UNKNOWN) : paramType; } } @@ -193,13 +199,11 @@ this.nbParams = (params == null) ? 0 : params.length; // Set the return type; - this.returnType = returnType; - if (returnType != null){ - isNumeric = returnType.isNumeric(); - isString = returnType.isString(); - isGeometry = returnType.isGeometry(); - }else - isNumeric = isString = isGeometry = false; + this.returnType = (returnType != null) ? returnType : new DBType(DBDatatype.UNKNOWN); + isUnknown = this.returnType.isUnknown(); + isNumeric = this.returnType.isNumeric(); + isString = this.returnType.isString(); + isGeometry = this.returnType.isGeometry(); // Serialize in Strings (serializedForm and compareForm) this function definition: StringBuffer bufSer = new StringBuffer(name), bufCmp = new StringBuffer(name.toLowerCase()); @@ -245,6 +249,20 @@ } /** + *

      Tell whether this function returns an unknown type.

      + * + *

      + * If this function returns true, {@link #isNumeric()}, {@link #isString()} and {@link #isGeometry()} + * MUST ALL return false. Otherwise, one of these 3 last functions MUST return true. + *

      + * + * @return true if this function returns an unknown/unresolved/unsupported type, false otherwise. + */ + public final boolean isUnknown(){ + return isUnknown; + } + + /** * Get the number of parameters required by this function. * * @return Number of required parameters. @@ -330,10 +348,12 @@ *
      {fctName}([{param1Name} {param1Type}, ...])[ -> {returnType}]
      * *

      - * Allowed parameter types and return types should be one the types listed by the UPLOAD section of the TAP recommendation document. - * These types are listed in the enumeration object {@link DBType}. + * This function must be able to parse functions as defined by TAPRegExt (section 2.3). + * Hence, allowed parameter types and return types should be one of the types listed by the UPLOAD section of the TAP recommendation document. + * These types are listed in the enumeration object {@link DBDatatype}. * However, other types should be accepted like the common database types...but it should be better to not rely on that - * since the conversion of those types to TAP types should not be exactly what is expected. + * since the conversion of those types to TAP types should not be exactly what is expected (because depending from the used DBMS); + * a default interpretation of database types is nevertheless processed by this parser. *

      * * @param strDefinition Serialized function definition to parse. @@ -357,8 +377,10 @@ DBType returnType = null; if (m.group(3) != null){ returnType = parseType(m.group(5), (m.group(7) == null) ? DBType.NO_LENGTH : Integer.parseInt(m.group(7))); - if (returnType == null) - throw new ParseException("Unknown return type: \"" + m.group(4).trim() + "\"!"); + if (returnType == null){ + returnType = new DBType(DBDatatype.UNKNOWN); + returnType.type.setCustomType(m.group(4)); + } } // Get the parameters, if any: @@ -384,10 +406,11 @@ paramType = parseType(m.group(2), (m.group(4) == null) ? DBType.NO_LENGTH : Integer.parseInt(m.group(4))); // ...build the parameter definition object: - if (paramType == null) - throw new ParseException("Unknown type for the parameter \"" + m.group(1) + "\": \"" + m.group(2) + ((m.group(3) == null) ? "" : m.group(3)) + "\"!"); - else - params[i] = new FunctionParam(m.group(1), paramType); + if (paramType == null){ + paramType = new DBType(DBDatatype.UNKNOWN); + paramType.type.setCustomType(m.group(2) + ((m.group(3) == null) ? "" : m.group(3))); + } + params[i] = new FunctionParam(m.group(1), paramType); }else // note: should never happen because we have already check the syntax of the whole parameters list before parsing each individual parameter. throw new ParseException("Wrong syntax for the " + (i + 1) + "-th parameter: \"" + paramsSplit[i].trim() + "\"! Expected syntax: \"( (, )*)\", where =\"[a-zA-Z]+[a-zA-Z0-9_]*\", should be one of the types described in the UPLOAD section of the TAP documentation. Examples of good syntax: \"()\", \"(param INTEGER)\", \"(param1 INTEGER, param2 DOUBLE)\""); @@ -405,17 +428,22 @@ * * @param datatype String representation of a datatype. * Note: This string must not contain the length parameter or any other parameter. - * These latter should have been separated from the datatype before calling this function. + * These latter should have been separated from the datatype before calling this function. + * It can however contain space(s) in first, last or intern position.
      * @param length Length of this datatype. * Note: This length will be used only for binary (BINARY and VARBINARY) * and character (CHAR and VARCHAR) types. * - * @return The object representation of the specified datatype. + * @return The object representation of the specified datatype + * or NULL if the specified datatype can not be resolved. */ private static DBType parseType(String datatype, int length){ if (datatype == null) return null; + // Remove leading and trailing spaces and replace each inner serie of spaces by just one space: + datatype = datatype.trim().replaceAll(" +", " "); + try{ // Try to find a corresponding DBType item: DBDatatype dbDatatype = DBDatatype.valueOf(datatype.toUpperCase()); @@ -434,31 +462,29 @@ }catch(IllegalArgumentException iae){ // If there's no corresponding DBType item, try to find a match among the most used DB types: datatype = datatype.toLowerCase(); - if (datatype.equals("bool") || datatype.equals("boolean") || datatype.equals("short")) + if (datatype.equals("bool") || datatype.equals("boolean") || datatype.equals("short") || datatype.equals("int2") || datatype.equals("smallserial") || datatype.equals("serial2")) return new DBType(DBDatatype.SMALLINT); - else if (datatype.equals("int2")) - return new DBType(DBDatatype.SMALLINT); - else if (datatype.equals("int") || datatype.equals("int4")) + else if (datatype.equals("int") || datatype.equals("int4") || datatype.equals("serial") || datatype.equals("serial4")) return new DBType(DBDatatype.INTEGER); - else if (datatype.equals("long") || datatype.equals("number") || datatype.equals("bigint") || datatype.equals("int8")) + else if (datatype.equals("long") || datatype.equals("number") || datatype.equals("int8") || datatype.equals("bigserial") || datatype.equals("bigserial8")) return new DBType(DBDatatype.BIGINT); else if (datatype.equals("float") || datatype.equals("float4")) return new DBType(DBDatatype.REAL); - else if (datatype.equals("numeric") || datatype.equals("float8")) + else if (datatype.equals("numeric") || datatype.equals("float8") || datatype.equals("double precision")) return new DBType(DBDatatype.DOUBLE); - else if (datatype.equals("byte") || datatype.equals("raw")) + else if (datatype.equals("bit") || datatype.equals("byte") || datatype.equals("raw")) return new DBType(DBDatatype.BINARY, length); - else if (datatype.equals("unsignedByte")) + else if (datatype.equals("unsignedByte") || datatype.equals("bit varying") || datatype.equals("varbit")) return new DBType(DBDatatype.VARBINARY, length); else if (datatype.equals("character")) return new DBType(DBDatatype.CHAR, length); - else if (datatype.equals("string") || datatype.equals("varchar2")) + else if (datatype.equals("string") || datatype.equals("varchar2") || datatype.equals("character varying")) return new DBType(DBDatatype.VARCHAR, length); else if (datatype.equals("bytea")) return new DBType(DBDatatype.BLOB); else if (datatype.equals("text")) return new DBType(DBDatatype.CLOB); - else if (datatype.equals("date") || datatype.equals("time")) + else if (datatype.equals("date") || datatype.equals("time") || datatype.equals("timetz") || datatype.equals("timestamptz")) return new DBType(DBDatatype.TIMESTAMP); else if (datatype.equals("position")) return new DBType(DBDatatype.POINT); @@ -489,7 +515,7 @@ * not part of a function signature. *

      * - *

      The notion of "greater" and "less" are defined here according to the three following test steps:

      + *

      The notions of "greater" and "less" are defined here according to the three following test steps:

      *
        *
      1. Name test: if the name of both function are equals, next steps are evaluated, otherwise the standard string comparison (case insensitive) result is returned.
      2. *
      3. Parameters test: parameters are compared individually. Each time parameters (at the same position in both functions) are equals the next parameter can be tested, @@ -503,10 +529,19 @@ * returned. Otherwise a negative value will be returned, or 0 if the number of parameters is the same.
      4. *
      * + *

      Note: + * If one of the tested types (i.e. parameters types) is unknown, the match should return 0 (i.e. equality). + * The notion of "unknown" is different in function of the tested item. A {@link DBType} is unknown if its function + * {@link DBType#isUnknown()} returns true ; thus, its other functions such as {@link DBType#isNumeric()} will + * return false. On the contrary, an {@link ADQLOperand} does not have any isUnknown() + * function. However, when the type of a such is unknown, all its functions isNumeric(), isString() and isGeometry() return + * true. + *

      + * * @param fct ADQL function item to compare with this function definition. * * @return A positive value if this function definition is "greater" than the given {@link ADQLFunction}, - * 0 if they are perfectly matching, + * 0 if they are perfectly matching or one of the tested types (i.e. parameters types) is unknown, * or a negative value if this function definition is "less" than the given {@link ADQLFunction}. */ public int compareTo(final ADQLFunction fct){ @@ -519,7 +554,11 @@ // If equals, compare the parameters' type: if (comp == 0){ for(int i = 0; comp == 0 && i < nbParams && i < fct.getNbParameters(); i++){ - if (params[i].type.isNumeric() == fct.getParameter(i).isNumeric()){ + // if one of the types is unknown, the comparison should return true: + if (params[i].type.isUnknown() || (fct.getParameter(i).isNumeric() && fct.getParameter(i).isString() && fct.getParameter(i).isGeometry())) + comp = 0; + // otherwise, just compare each kind of type for an exact match: + else if (params[i].type.isNumeric() == fct.getParameter(i).isNumeric()){ if (params[i].type.isString() == fct.getParameter(i).isString()){ if (params[i].type.isGeometry() == fct.getParameter(i).isGeometry()) comp = 0; diff -Nru adql-1.3/src/adql/db/SearchColumnList.java adql-1.4/src/adql/db/SearchColumnList.java --- adql-1.3/src/adql/db/SearchColumnList.java 2015-02-10 16:56:12.000000000 +0000 +++ adql-1.4/src/adql/db/SearchColumnList.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -46,7 +47,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (02/2015) + * @version 1.4 (09/2017) */ public class SearchColumnList extends TextualSearchList { private static final long serialVersionUID = 1L; @@ -55,10 +56,10 @@ private boolean distinct = false; /** Case-sensitive dictionary of table aliases. (tableAlias <-> TableName) */ - private final HashMap tableAliases = new HashMap(); + private final Map tableAliases = new HashMap(); /** Case-insensitive dictionary of table aliases. (tablealias <-> List<TableName>) */ - private final HashMap> mapAliases = new HashMap>(); + private final Map> mapAliases = new HashMap>(); /* ************ */ /* CONSTRUCTORS */ @@ -122,7 +123,7 @@ if (tableAlias != null && tableName != null){ tableAliases.put(tableAlias, tableName); - ArrayList aliases = mapAliases.get(tableAlias.toLowerCase()); + List aliases = mapAliases.get(tableAlias.toLowerCase()); if (aliases == null){ aliases = new ArrayList(); mapAliases.put(tableAlias.toLowerCase(), aliases); @@ -139,7 +140,7 @@ public final void removeTableAlias(final String tableAlias){ tableAliases.remove(tableAlias); - ArrayList aliases = mapAliases.get(tableAlias.toLowerCase()); + List aliases = mapAliases.get(tableAlias.toLowerCase()); if (aliases != null){ aliases.remove(tableAlias); if (aliases.isEmpty()) @@ -171,7 +172,7 @@ * * @see TextualSearchList#get(String) */ - public ArrayList search(final String columnName){ + public List search(final String columnName){ return get(columnName); } @@ -187,7 +188,7 @@ * * @see #search(String, String, String, String, byte) */ - public final ArrayList search(final String catalog, final String schema, final String table, final String column){ + public final List search(final String catalog, final String schema, final String table, final String column){ return search(catalog, schema, table, column, (byte)0); } @@ -200,7 +201,7 @@ * * @see #search(String, String, String, String, byte) */ - public ArrayList search(final ADQLColumn column){ + public List search(final ADQLColumn column){ return search(column.getCatalogName(), column.getSchemaName(), column.getTableName(), column.getColumnName(), column.getCaseSensitive()); } @@ -217,15 +218,15 @@ * * @see IdentifierField */ - public ArrayList search(final String catalog, final String schema, final String table, final String column, final byte caseSensitivity){ + public List search(final String catalog, final String schema, final String table, final String column, final byte caseSensitivity){ - ArrayList tmpResult = get(column, IdentifierField.COLUMN.isCaseSensitive(caseSensitivity)); + List tmpResult = get(column, IdentifierField.COLUMN.isCaseSensitive(caseSensitivity)); /* WITH TABLE PREFIX */ if (table != null){ /* 1. Figure out the table alias */ String tableName = null; - ArrayList aliasMatches = null; + List aliasMatches = null; // Case sensitive => tableName is set , aliasMatches = null if (IdentifierField.TABLE.isCaseSensitive(caseSensitivity)){ @@ -284,7 +285,10 @@ } // test the schema name: - if (schema != null && matchTable.getADQLSchemaName() != null){ + if (schema != null){ + // No schema name (<=> no schema), then this table can not be a good match: + if (matchTable.getADQLSchemaName() == null) + continue; if (IdentifierField.SCHEMA.isCaseSensitive(caseSensitivity)){ if (!matchTable.getADQLSchemaName().equals(schema)) continue; @@ -295,6 +299,9 @@ // test the catalog name: if (catalog != null){ + // No catalog name (<=> no catalog), then this table can not be a good match: + if (matchTable.getADQLCatalogName() == null) + continue; if (IdentifierField.CATALOG.isCaseSensitive(caseSensitivity)){ if (!matchTable.getADQLCatalogName().equals(catalog)) continue; diff -Nru adql-1.3/src/adql/db/SearchTableApi.java adql-1.4/src/adql/db/SearchTableApi.java --- adql-1.3/src/adql/db/SearchTableApi.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/db/SearchTableApi.java 2017-11-03 17:18:00.000000000 +0000 @@ -0,0 +1,47 @@ +package adql.db; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ADQLLibrary. If not, see . + * + * Copyright 2017 - Astronomisches Rechen Institut (ARI) + */ + +import java.util.List; + +import adql.query.from.ADQLTable; + +/** + * Simple interface about a class which allows to search for a specified + * {@link ADQLTable}. + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (09/2017) + * @since 1.4 + * + * @see SearchTableList + */ +public interface SearchTableApi { + + /** + * Searches all {@link DBTable} elements corresponding to the given {@link ADQLTable} (case insensitive). + * + * @param table An {@link ADQLTable}. + * + * @return The list of all corresponding {@link DBTable} elements. + */ + public List search(final ADQLTable table); + +} \ No newline at end of file diff -Nru adql-1.3/src/adql/db/SearchTableList.java adql-1.4/src/adql/db/SearchTableList.java --- adql-1.3/src/adql/db/SearchTableList.java 2015-02-10 16:55:54.000000000 +0000 +++ adql-1.4/src/adql/db/SearchTableList.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,12 +16,13 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS) * Astronomisches Rechen Institut (ARI) */ import java.util.ArrayList; import java.util.Collection; +import java.util.List; import adql.query.IdentifierField; import adql.query.from.ADQLTable; @@ -36,9 +37,9 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (02/2015) + * @version 1.4 (09/2017) */ -public class SearchTableList extends TextualSearchList { +public class SearchTableList extends TextualSearchList implements SearchTableApi { private static final long serialVersionUID = 1L; /** Indicates whether multiple occurrences are allowed. */ @@ -105,7 +106,7 @@ * * @see TextualSearchList#get(String) */ - public ArrayList search(final String tableName){ + public List search(final String tableName){ return get(tableName); } @@ -120,7 +121,7 @@ * * @see #search(String, String, String, byte) */ - public final ArrayList search(final String catalog, final String schema, final String table){ + public final List search(final String catalog, final String schema, final String table){ return search(catalog, schema, table, (byte)0); } @@ -133,7 +134,8 @@ * * @see #search(String, String, String, byte) */ - public ArrayList search(final ADQLTable table){ + @Override + public List search(final ADQLTable table){ return search(table.getCatalogName(), table.getSchemaName(), table.getTableName(), table.getCaseSensitive()); } @@ -149,31 +151,35 @@ * * @see IdentifierField */ - public ArrayList search(final String catalog, final String schema, final String table, final byte caseSensitivity){ - ArrayList tmpResult = get(table, IdentifierField.TABLE.isCaseSensitive(caseSensitivity)); + public List search(final String catalog, final String schema, final String table, final byte caseSensitivity){ + List tmpResult = get(table, IdentifierField.TABLE.isCaseSensitive(caseSensitivity)); if (schema != null){ - ArrayList result = new ArrayList(); + List result = new ArrayList(); for(DBTable match : tmpResult){ - if (match.getADQLSchemaName() != null){ - if (IdentifierField.SCHEMA.isCaseSensitive(caseSensitivity)){ - if (!match.getADQLSchemaName().equals(schema)) + // No schema name (<=> no schema), then this table can not be a good match: + if (match.getADQLSchemaName() == null) + continue; + if (IdentifierField.SCHEMA.isCaseSensitive(caseSensitivity)){ + if (!match.getADQLSchemaName().equals(schema)) + continue; + }else{ + if (!match.getADQLSchemaName().equalsIgnoreCase(schema)) + continue; + } + + if (catalog != null){ + // No catalog name (<=> no catalog), then this table can not be a good match: + if (match.getADQLCatalogName() == null) + continue; + if (IdentifierField.CATALOG.isCaseSensitive(caseSensitivity)){ + if (!match.getADQLCatalogName().equals(catalog)) continue; }else{ - if (!match.getADQLSchemaName().equalsIgnoreCase(schema)) + if (!match.getADQLCatalogName().equalsIgnoreCase(catalog)) continue; } - - if (catalog != null && match.getADQLCatalogName() != null){ - if (IdentifierField.CATALOG.isCaseSensitive(caseSensitivity)){ - if (!match.getADQLCatalogName().equals(catalog)) - continue; - }else{ - if (!match.getADQLCatalogName().equalsIgnoreCase(catalog)) - continue; - } - } } result.add(match); diff -Nru adql-1.3/src/adql/db/STCS.java adql-1.4/src/adql/db/STCS.java --- adql-1.3/src/adql/db/STCS.java 2015-04-22 17:03:20.000000000 +0000 +++ adql-1.4/src/adql/db/STCS.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2014 - Astronomisches Rechen Institut (ARI) + * Copyright 2014-2017 - Astronomisches Rechen Institut (ARI) */ import java.util.ArrayList; @@ -78,7 +78,7 @@ *

      * * @author Grégory Mantelet (ARI) - * @version 1.3 (12/2014) + * @version 1.4 (04/2017) * @since 1.3 */ public final class STCS { @@ -143,11 +143,11 @@ *

      * * @author Grégory Mantelet (ARI) - * @version 1.3 (10/2014) + * @version 1.4 (04/2017) * @since 1.3 */ public static enum Frame{ - ECLIPTIC, FK4, FK5, GALACTIC, ICRS, UNKNOWNFRAME; + ECLIPTIC, FK4, FK5, J2000, GALACTIC, ICRS, UNKNOWNFRAME; /** Default value for a frame: {@link #UNKNOWNFRAME}. */ public static final Frame DEFAULT = UNKNOWNFRAME; @@ -1329,7 +1329,7 @@ * @param expectedSyntax Description of the good syntax expected. This description is used only to write the * {@link ParseException} in case other non-space characters are found among the remaining characters. * - * @throws ParseException If other non-space characters remains. + * @throws ParseException If other non-space characters remains. */ private void end(final String expectedSyntax) throws ParseException{ // Skip all spaces: @@ -1346,7 +1346,7 @@ } /** - * Tool function which skip all next space characters until the next meaningful characters. + * Tool function which skip all next space characters until the next meaningful characters. */ private void skipSpaces(){ while(pos < stcs.length() && Character.isWhitespace(stcs.charAt(pos))) @@ -1395,7 +1395,7 @@ if (nextToken().matches(numericRegExp)) return Double.parseDouble(token); else - throw new ParseException("a numeric was expected!", new TextPosition(1, pos - token.length(), 1, pos)); // TODO Check the begin and end! + throw new ParseException("a numeric was expected!", new TextPosition(1, pos - token.length(), 1, pos)); } /** @@ -1415,7 +1415,7 @@ if (pe instanceof EOEException) throw pe; else - throw new ParseException("a coordinates pair (2 numerics separated by one or more spaces) was expected!", new TextPosition(1, startPos, 1, pos)); // TODO Check the begin and end! + throw new ParseException("a coordinates pair (2 numerics separated by one or more spaces) was expected!", new TextPosition(1, startPos, 1, pos)); } } diff -Nru adql-1.3/src/adql/parser/adqlGrammar.jj adql-1.4/src/adql/parser/adqlGrammar.jj --- adql-1.3/src/adql/parser/adqlGrammar.jj 2015-03-13 18:21:20.000000000 +0000 +++ adql-1.4/src/adql/parser/adqlGrammar.jj 2018-01-12 13:50:16.000000000 +0000 @@ -14,19 +14,24 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institute (ARI) */ /* -* This JavaCC file implements the BNF definition of ADQL v2.0 (IVOA Recommendation 30 Oct 2008 - http://www.ivoa.net/Documents/cover/ADQL-20081030.html). -* To generate the parser with this file use JavaCC. This .jj file has been successfully tested with JavaCC 5.0. -* -* The generated parser checks the syntax of the given ADQL query and generates an object representation but no coherence with any database is done. -* If the syntax is not conform to the ADQL definition an error message is printed else it will be the message "Correct syntax". +* This JavaCC file implements the BNF definition of ADQL v2.0 +* (IVOA Recommendation 30 Oct 2008 - http://www.ivoa.net/Documents/cover/ADQL-20081030.html). +* +* To generate the parser with this file use JavaCC. This .jj file has been +* successfully tested with JavaCC 6.0. +* +* The generated parser checks the syntax of the given ADQL query and generates +* an object representation but no coherence with any database is done. +* If the syntax is not conform to the ADQL definition an error message is +* printed else it will be the message "Correct syntax". * * Author: Grégory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de -* Version: 1.3 (10/2014) +* Version: 1.4 (01/2018) */ /* ########### */ @@ -35,7 +40,7 @@ options { STATIC = false; IGNORE_CASE = true; - DEBUG_PARSER = false; + DEBUG_PARSER = true; } /* ########## */ @@ -74,22 +79,37 @@ import adql.translator.TranslationException; /** -*

      Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.

      +* Parses an ADQL query thanks to the {@link ADQLParser#Query()} function. * -*

      This parser is able, thanks to a {@link QueryChecker} object, to check each ADQLQuery just after its generation. -* It could be used to check the consistency between the ADQL query to parse and the "database" on which the query must be executed. -* By default, there is no {@link QueryChecker}. Thus you must extend {@link QueryChecker} to check semantically all generated ADQLQuery objects.

      +*

      +* This parser is able, thanks to a {@link QueryChecker} object, to check each +* {@link ADQLQuery} just after its generation. It could be used to check the +* consistency between the ADQL query to parse and the "database" on which the +* query must be executed. By default, there is no {@link QueryChecker}. Thus +* you must extend {@link QueryChecker} to check semantically all generated +* ADQLQuery objects. +*

      * -*

      To create an object representation of the given ADQL query, this parser uses a {@link ADQLQueryFactory} object. So if you want customize some object (ie. CONTAINS) of this representation -* you just have to extend the corresponding default object (ie. ContainsFunction) and to extend the corresponding function of {@link ADQLQueryFactory} (ie. createContains(...)).

      +*

      +* To create an object representation of the given ADQL query, this parser uses +* a {@link ADQLQueryFactory} object. So if you want customize some object +* (ie. CONTAINS) of this representation you just have to extend the +* corresponding default object (ie. ContainsFunction) and to extend the +* corresponding function of {@link ADQLQueryFactory} +* (ie. createContains(...)). +*

      * -*

      WARNING: To modify this class it's strongly encouraged to modify the .jj file in the section between PARSER_BEGIN and PARSER_END and to re-compile it with JavaCC.

      +*

      WARNING: +* To modify this class it's strongly encouraged to modify the .jj file in the +* section between PARSER_BEGIN and PARSER_END and to re-compile +* it with JavaCC. +*

      * * @see QueryChecker * @see ADQLQueryFactory * * @author Grégory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de -* @version 1.3 (10/2014) +* @version 1.4 (01/2018) */ public class ADQLParser { @@ -99,13 +119,16 @@ /** The stack of queries (because there may be some sub-queries). */ private Stack stackQuery = new Stack(); - /** The object representation of the ADQL query to parse. (ONLY USED DURING THE PARSING, else it is always null). */ + /** The object representation of the ADQL query to parse. + * (ONLY USED DURING THE PARSING, else it is always null). */ private ADQLQuery query = null; - /** Checks each ADQLQuery (sub-query or not) just after their generation. */ + /** Checks each {@link ADQLQuery} (sub-query or not) just after their + * generation. */ private QueryChecker queryChecker = null; - /** The first token of a table/column name. This token is extracted by {@link #Identifier()}. */ + /** The first token of a table/column name. This token is extracted by + * {@link #Identifier()}. */ private Token currentIdentifierToken = null; /** @@ -113,13 +136,16 @@ */ public ADQLParser(){ this(new java.io.ByteArrayInputStream("".getBytes())); + setDebug(false); } /** - * Builds an ADQL parser without a query to parse but with a QueryChecker and a ADQLQueryFactory. + * Builds an ADQL parser without a query to parse but with a + * {@link QueryChecker} and a {@link ADQLQueryFactory}. * - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(QueryChecker checker, ADQLQueryFactory factory) { this(); @@ -131,18 +157,21 @@ } /** - * Builds an ADQL parser without a query to parse but with a QueryChecker. + * Builds an ADQL parser without a query to parse but with a + * {@link QueryChecker}. * - * @param checker The object to use to check each ADQLQuery. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(QueryChecker checker) { this(checker, null); } /** - * Builds an ADQL parser without a query to parse but with a ADQLQueryFactory. + * Builds an ADQL parser without a query to parse but with a + * {@link ADQLQueryFactory}. * - * @param factory The object to use to build an object representation of the given ADQL query. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(ADQLQueryFactory factory) { this((QueryChecker)null, factory); @@ -152,11 +181,15 @@ * Builds a parser with a stream containing the query to parse. * * @param stream The stream in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory) { this(stream); + setDebug(false); + + setDebug(false); queryChecker = checker; @@ -168,7 +201,7 @@ * Builds a parser with a stream containing the query to parse. * * @param stream The stream in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(java.io.InputStream stream, QueryChecker checker) { this(stream, checker, null); @@ -178,7 +211,8 @@ * Builds a parser with a stream containing the query to parse. * * @param stream The stream in which the ADQL query to parse is given. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory) { this(stream, (QueryChecker)null, factory); @@ -187,13 +221,15 @@ /** * Builds a parser with a stream containing the query to parse. * - * @param stream The stream in which the ADQL query to parse is given. - * @param encoding The supplied encoding. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param stream The stream in which the ADQL query to parse is given. + * @param encoding The supplied encoding. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory) { this(stream, encoding); + setDebug(false); queryChecker = checker; @@ -204,9 +240,9 @@ /** * Builds a parser with a stream containing the query to parse. * - * @param stream The stream in which the ADQL query to parse is given. - * @param encoding The supplied encoding. - * @param checker The object to use to check each ADQLQuery. + * @param stream The stream in which the ADQL query to parse is given. + * @param encoding The supplied encoding. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker) { this(stream, encoding, checker, null); @@ -215,9 +251,10 @@ /** * Builds a parser with a stream containing the query to parse. * - * @param stream The stream in which the ADQL query to parse is given. - * @param encoding The supplied encoding. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param stream The stream in which the ADQL query to parse is given. + * @param encoding The supplied encoding. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.InputStream stream, String encoding, ADQLQueryFactory factory) { this(stream, encoding, null, factory); @@ -226,12 +263,16 @@ /** * Builds a parser with a reader containing the query to parse. * - * @param reader The reader in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param reader The reader in which the ADQL query to parse is given. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory) { this(reader); + setDebug(false); + + setDebug(false); queryChecker = checker; @@ -242,8 +283,8 @@ /** * Builds a parser with a reader containing the query to parse. * - * @param reader The reader in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. + * @param reader The reader in which the ADQL query to parse is given. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(java.io.Reader reader, QueryChecker checker) { this(reader, checker, null); @@ -253,7 +294,8 @@ * Builds a parser with a reader containing the query to parse. * * @param reader The reader in which the ADQL query to parse is given. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.Reader reader, ADQLQueryFactory factory) { this(reader, null, factory); @@ -262,12 +304,16 @@ /** * Builds a parser with another token manager. * - * @param tm The manager which associates a token to a numeric code. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param tm The manager which associates a token to a numeric code. + * @param checker The object to use to check each {@link ADQLQuery }. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker, ADQLQueryFactory factory) { this(tm); + setDebug(false); + + setDebug(false); queryChecker = checker; @@ -278,8 +324,8 @@ /** * Builds a parser with another token manager. * - * @param tm The manager which associates a token to a numeric code. - * @param checker The object to use to check each ADQLQuery. + * @param tm The manager which associates a token to a numeric code. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker) { this(tm, checker, null); @@ -288,17 +334,20 @@ /** * Builds a parser with another token manager. * - * @param tm The manager which associates a token to a numeric code. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param tm The manager which associates a token to a numeric code. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(ADQLParserTokenManager tm, ADQLQueryFactory factory) { this(tm, null, factory); } /** - * Parses the query given at the creation of this parser or in the ReInit functions. + * Parses the query given at the creation of this parser or in the + * ReInit functions. * - * @return The object representation of the given ADQL query. + * @return The object representation of the given ADQL query. + * * @throws ParseException If there is at least one syntactic error. * * @see ADQLParser#Query() @@ -306,14 +355,20 @@ public final ADQLQuery parseQuery() throws ParseException { stackQuery.clear(); query = null; - return Query(); + try { + return Query(); + }catch(TokenMgrError tme) { + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** * Parses the query given in parameter. * - * @param q The ADQL query to parse. - * @return The object representation of the given ADQL query. + * @param q The ADQL query to parse. + * + * @return The object representation of the given ADQL query. + * * @throws ParseException If there is at least one syntactic error. * * @see ADQLParser#ReInit(java.io.InputStream) @@ -324,14 +379,20 @@ stackQuery.clear(); query = null; ReInit(new java.io.ByteArrayInputStream(q.getBytes())); - return Query(); + try { + return Query(); + }catch(TokenMgrError tme) { + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** * Parses the query contained in the stream given in parameter. * - * @param stream The stream which contains the ADQL query to parse. - * @return The object representation of the given ADQL query. + * @param stream The stream which contains the ADQL query to parse. + * + * @return The object representation of the given ADQL query. + * * @throws ParseException If there is at least one syntactic error. * * @see ADQLParser#ReInit(java.io.InputStream) @@ -342,7 +403,11 @@ stackQuery.clear(); query = null; ReInit(stream); - return Query(); + try { + return Query(); + }catch(TokenMgrError tme) { + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } public final void setDebug(boolean debug){ @@ -376,11 +441,23 @@ } /** - *

      Gets the specified ADQL query and parses the given ADQL query. The SQL translation is then printed if the syntax is correct.

      - *

      ONLY the syntax is checked: the query is NOT EXECUTED !

      - *

      Supplied parameters are:

      • [-debug] -url http://...
      • [-debug] -file ...
      • [-debug] -query SELECT...

      + * Gets the specified ADQL query and parses the given ADQL query. The SQL + * translation is then printed if the syntax is correct. + * + *

      + * ONLY the syntax is checked: the query is NOT EXECUTED ! + *

      + * + *

      Supplied parameters are: + *

        + *
      • [-debug] -url http://...
      • + *
      • [-debug] -file ...
      • + *
      • [-debug] -query SELECT...
      • + *
      + *

      * * @param args + * @throws Exception */ public static final void main(String[] args) throws Exception { @@ -426,7 +503,7 @@ try{ - if (file == null || file.isEmpty()) + if (file == null || file.length()==0) parser = new ADQLParser(System.in); else if (file.matches(urlRegex)) parser = new ADQLParser((new java.net.URL(file)).openStream()); @@ -486,6 +563,20 @@ /* ******************** */ SKIP : { < " " | "\t" | "\n" | "\r" | "\r\n" > } +/* ************************************************************************** */ +/* Reserved SQL words */ +/* */ +/* NOTE: */ +/* This list is the one provided by the ADQL-2.0 standard after removal of */ +/* all ADQL used words (e.g. SELECT, AS, LIKE, AVG, ABS, COS, POINT). */ +/* (see ParseException.initialise(Token, int[][], String[]) for more */ +/* details) */ +/* ************************************************************************** */ + +TOKEN : { + < SQL_RESERVED_WORD: ("ABSOLUTE"|"ACTION"|"ADD"|"ALLOCATE"|"ALTER"|"ANY"|"ARE"|"ASSERTION"|"AT"|"AUTHORIZATION"|"BEGIN"|"BIT"|"BIT_LENGTH"|"BOTH"|"CASCADE"|"CASCADED"|"CASE"|"CAST"|"CATALOG"|"CHAR"|"CHARACTER"|"CHAR_LENGTH"|"CHARACTER_LENGTH"|"CHECK"|"CLOSE"|"COALESCE"|"COLLATE"|"COLLATION"|"COLUMN"|"COMMIT"|"CONNECT"|"CONNECTION"|"CONSTRAINT"|"CONSTRAINTS"|"CONTINUE"|"CONVERT"|"CORRESPONDING"|"CREATE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_USER"|"CURSOR"|"DATE"|"DAY"|"DEALLOCATE"|"DECIMAL"|"DECLARE"|"DEFAULT"|"DEFERRABLE"|"DEFERRED"|"DELETE"|"DESCRIBE"|"DESCRIPTOR"|"DIAGNOSTICS"|"DISCONNECT"|"DOMAIN"|"DOUBLE"|"DROP"|"ELSE"|"END"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXCEPTION"|"EXEC"|"EXECUTE"|"EXTERNAL"|"EXTRACT"|"FALSE"|"FETCH"|"FIRST"|"FLOAT"|"FOR"|"FOREIGN"|"FOUND"|"GET"|"GLOBAL"|"GO"|"GOTO"|"GRANT"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"INDICATOR"|"INITIALLY"|"INPUT"|"INSENSITIVE"|"INSERT"|"INT"|"INTEGER"|"INTERSECT"|"INTERVAL"|"INTO"|"ISOLATION"|"KEY"|"LANGUAGE"|"LAST"|"LEADING"|"LEVEL"|"LOCAL"|"LOWER"|"MATCH"|"MINUTE"|"MODULE"|"MONTH"|"NAMES"|"NATIONAL"|"NCHAR"|"NEXT"|"NO"|"NULLIF"|"NUMERIC"|"OCTET_LENGTH"|"OF"|"ONLY"|"OPEN"|"OPTION"|"OUTPUT"|"OVERLAPS"|"PAD"|"PARTIAL"|"POSITION"|"PRECISION"|"PREPARE"|"PRESERVE"|"PRIMARY"|"PRIOR"|"PRIVILEGES"|"PROCEDURE"|"PUBLIC"|"READ"|"REAL"|"REFERENCES"|"RELATIVE"|"RESTRICT"|"REVOKE"|"ROLLBACK"|"ROWS"|"SCHEMA"|"SCROLL"|"SECOND"|"SECTION"|"SESSION"|"SESSION_USER"|"SET"|"SIZE"|"SMALLINT"|"SOME"|"SPACE"|"SQL"|"SQLCODE"|"SQLERROR"|"SQLSTATE"|"SUBSTRING"|"SYSTEM_USER"|"TABLE"|"TEMPORARY"|"THEN"|"TIME"|"TIMESTAMP"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSACTION"|"TRANSLATE"|"TRANSLATION"|"TRIM"|"TRUE"|"UNION"|"UNIQUE"|"UNKNOWN"|"UPDATE"|"UPPER"|"USAGE"|"USER"|"VALUE"|"VALUES"|"VARCHAR"|"VARYING"|"VIEW"|"WHEN"|"WHENEVER"|"WITH"|"WORK"|"WRITE"|"YEAR"|"ZONE") > +} + /* *********** */ /* Punctuation */ /* *********** */ @@ -566,9 +657,10 @@ /* Other clauses' tokens */ /* ********************* */ TOKEN : { - < GROUP_BY: "GROUP BY" > + < BY: "BY" > +| < GROUP: "GROUP" > | < HAVING: "HAVING" > -| < ORDER_BY: "ORDER BY" > +| < ORDER: "ORDER" > | < ASC: "ASC" > | < DESC: "DESC" > } @@ -642,9 +734,7 @@ /* ******* */ /* Comment */ /* ******* */ - MORE : { < ()+ >: WithinComment } - SKIP : { < "\n" | "\r" | "\r\n" >: DEFAULT } - MORE : { < ~[] > } +SKIP : { < (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > } /* ****** */ /* String */ @@ -700,7 +790,7 @@ } } -ADQLQuery QueryExpression(): {} { +ADQLQuery QueryExpression(): {TextPosition endPos = null;} { { try{ // create the query: @@ -711,12 +801,15 @@ } } Select() - From() - [Where()] - [GroupBy()] - [Having()] - [OrderBy()] + From() {endPos = query.getFrom().getPosition();} + [Where() {endPos = query.getWhere().getPosition();}] + [GroupBy() {endPos = query.getGroupBy().getPosition();}] + [Having() {endPos = query.getHaving().getPosition();}] + [OrderBy() {endPos = query.getOrderBy().getPosition();}] { + // set the position of the query: + query.setPosition(new TextPosition(query.getSelect().getPosition(), endPos)); + // get the previous query (!= null if the current query is a sub-query): ADQLQuery previousQuery = stackQuery.pop(); if (stackQuery.isEmpty()) @@ -728,13 +821,16 @@ } } -ADQLQuery SubQueryExpression(): {ADQLQuery q = null;} { - q=QueryExpression() - {return q;} +ADQLQuery SubQueryExpression(): {ADQLQuery q = null; Token start, end;} { + start= q=QueryExpression() end= + { + q.setPosition(new TextPosition(start, end)); + return q; + } } -void Select(): {ClauseSelect select = query.getSelect(); SelectItem item=null; Token t = null;} { - [t= {select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT"));}] [ t= { @@ -748,11 +844,20 @@ item=SelectItem() {select.add(item);} ( item=SelectItem() {select.add(item);})* + { + TextPosition lastItemPos = query.getSelect().get(query.getSelect().size()-1).getPosition(); + select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn)); } } -SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null;} { +SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null; SelectItem item; Token starToken;} { ( - ( {return new SelectAllColumns(query);} ) + ( starToken= + { + item = new SelectAllColumns(query); + item.setPosition(new TextPosition(starToken)); + return item; + } + ) |LOOKAHEAD(7) ( id=Identifier() { identifiers.append(id); } @@ -762,10 +867,13 @@ id=Identifier() { identifiers.append(id); } )? )? - + starToken= { - try{; - return new SelectAllColumns( queryFactory.createTable(identifiers, null) ); + try{ + item = new SelectAllColumns( queryFactory.createTable(identifiers, null) ); + TextPosition firstPos = identifiers.get(0).position; + item.setPosition(new TextPosition(firstPos.beginLine, firstPos.beginColumn, starToken.endLine, (starToken.endColumn < 0) ? -1 : (starToken.endColumn + 1))); + return item; }catch(Exception ex) { throw generateParseException(ex); } @@ -773,14 +881,16 @@ ) | - (op=ValueExpression()( label=Identifier())?) + (op=ValueExpression()[[] label=Identifier()]) ) { try{ - SelectItem item = queryFactory.createSelectItem(op, (label==null)?null:label.identifier); - if (label != null) + item = queryFactory.createSelectItem(op, (label==null)?null:label.identifier); + if (label != null){ item.setCaseSensitive(label.caseSensitivity); + item.setPosition(new TextPosition(op.getPosition(), label.position)); + }else item.setPosition(new TextPosition(op.getPosition())); return item; }catch(Exception ex){ throw generateParseException(ex); @@ -791,29 +901,45 @@ void From():{FromContent content = null, content2 = null;}{ try{ content=TableRef() - ( content2=TableRef() { content = queryFactory.createJoin(JoinType.CROSS, content, content2); } )* + ( content2=TableRef() + { + TextPosition startPos = content.getPosition(), endPos = content2.getPosition(); + content = queryFactory.createJoin(JoinType.CROSS, content, content2); + content.setPosition(new TextPosition(startPos, endPos)); + } + )* { query.setFrom(content); } }catch(Exception ex){ throw generateParseException(ex); } } -void Where(): {ClauseConstraints where = query.getWhere(); ADQLConstraint condition;} { - ConditionsList(where) +void Where(): {ClauseConstraints where = query.getWhere(); ADQLConstraint condition; Token start;} { + start= ConditionsList(where) + { + TextPosition endPosition = where.getPosition(); + where.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn)); + } } -void GroupBy(): {ClauseADQL groupBy = query.getGroupBy(); ColumnReference colRef = null;} { - colRef=ColumnRef() { groupBy.add(colRef); } - ( colRef=ColumnRef() { groupBy.add(colRef); } )* +void GroupBy(): {ClauseADQL groupBy = query.getGroupBy(); ADQLColumn colRef = null; Token start;} { + start= colRef=Column() { groupBy.add(colRef); } + ( colRef=Column() { groupBy.add(colRef); } )* + { groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn)); } } -void Having(): {ClauseConstraints having = query.getHaving();} { - ConditionsList(having) +void Having(): {ClauseConstraints having = query.getHaving(); Token start;} { + start= ConditionsList(having) + { + TextPosition endPosition = having.getPosition(); + having.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn)); + } } -void OrderBy(): {ClauseADQL orderBy = query.getOrderBy(); ADQLOrder order = null;} { - order=OrderItem() {orderBy.add(order);} +void OrderBy(): {ClauseADQL orderBy = query.getOrderBy(); ADQLOrder order = null; Token start;} { + start= order=OrderItem() {orderBy.add(order);} ( order=OrderItem() {orderBy.add(order);} )* + { orderBy.setPosition(new TextPosition(start, token)); } } /* *************************** */ @@ -871,31 +997,18 @@ } } -ColumnReference ColumnRef(): {IdentifierItems identifiers = null; Token ind = null;}{ - ( identifiers=ColumnName() | ind= ) - { - try{ - ColumnReference colRef = null; - if (identifiers != null) - colRef = queryFactory.createColRef(identifiers); - else - colRef = queryFactory.createColRef(Integer.parseInt(ind.image), new TextPosition(ind)); - return colRef; - }catch(Exception ex){ - throw generateParseException(ex); - } - } -} - -ADQLOrder OrderItem(): {IdentifierItems identifiers = null; Token ind = null, desc = null;}{ - (identifiers=ColumnName() | ind=) ( | desc=)? +ADQLOrder OrderItem(): {IdentifierItem identifier = null; Token ind = null, desc = null;}{ + (identifier=Identifier() | ind=) ( | desc=)? { try{ ADQLOrder order = null; - if (identifiers != null) - order = queryFactory.createOrder(identifiers, desc!=null); - else - order = queryFactory.createOrder(Integer.parseInt(ind.image), desc!=null, new TextPosition(ind)); + if (identifier != null){ + order = queryFactory.createOrder(identifier, desc!=null); + order.setPosition(identifier.position); + }else{ + order = queryFactory.createOrder(Integer.parseInt(ind.image), desc!=null); + order.setPosition(new TextPosition(ind)); + } return order; }catch(Exception ex){ throw generateParseException(ex); @@ -903,17 +1016,34 @@ } } -FromContent SimpleTableRef(): {IdentifierItem alias = null; IdentifierItems identifiers = null; ADQLQuery subQuery = null; FromContent content = null;} { +FromContent SimpleTableRef(): {IdentifierItem alias = null; IdentifierItems identifiers = null; ADQLQuery subQuery = null; FromContent content = null; Token start,end;} { try{ ( identifiers=TableName() [[] alias=Identifier()] - { return queryFactory.createTable(identifiers, alias); } + { + content = queryFactory.createTable(identifiers, alias); + if (alias == null) + content.setPosition(new TextPosition(identifiers.get(0).position, identifiers.get(identifiers.size()-1).position)); + else + content.setPosition(new TextPosition(identifiers.get(0).position, alias.position)); + return content; + } |LOOKAHEAD(2) subQuery=SubQueryExpression() [] alias=Identifier() - { return queryFactory.createTable(subQuery, alias); } + { + content = queryFactory.createTable(subQuery, alias); + if (alias == null) + content.setPosition(new TextPosition(subQuery.getPosition())); + else + content.setPosition(new TextPosition(subQuery.getPosition(), alias.position)); + return content; + } | - content=JoinedTable() - { return content; } + start= content=JoinedTable() end= + { + content.setPosition(new TextPosition(start, end)); + return content; + } ) }catch(Exception ex){ throw generateParseException(ex); @@ -933,24 +1063,36 @@ } -ADQLJoin JoinSpecification(FromContent leftTable): { boolean natural = false; JoinType type = JoinType.INNER; ClauseConstraints condition = new ClauseConstraints("ON"); ArrayList lstColumns=new ArrayList(); IdentifierItem id; FromContent rightTable;} { +ADQLJoin JoinSpecification(FromContent leftTable): { boolean natural = false; JoinType type = JoinType.INNER; ClauseConstraints condition = new ClauseConstraints("ON"); ArrayList lstColumns=new ArrayList(); IdentifierItem id; FromContent rightTable; ADQLJoin join; Token lastPar;} { try{ ( - {natural=true;} [ | (( {type = JoinType.OUTER_LEFT;}| {type = JoinType.OUTER_RIGHT;}| {type = JoinType.OUTER_FULL;}) [])] rightTable=TableRef() - { return queryFactory.createJoin(type, leftTable, rightTable); } + {natural=true;} [ | (( {type = JoinType.OUTER_LEFT;}| {type = JoinType.OUTER_RIGHT;}| {type = JoinType.OUTER_FULL;}) [])] rightTable=SimpleTableRef() + { + join = queryFactory.createJoin(type, leftTable, rightTable); + join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition())); + return join; + } | - [ | (( {type = JoinType.OUTER_LEFT;}| {type = JoinType.OUTER_RIGHT;}| {type = JoinType.OUTER_FULL;}) [])] rightTable=TableRef() + [ | (( {type = JoinType.OUTER_LEFT;}| {type = JoinType.OUTER_RIGHT;}| {type = JoinType.OUTER_FULL;}) [])] rightTable=SimpleTableRef() ( ConditionsList(condition) - { return queryFactory.createJoin(type, leftTable, rightTable, condition); } + { + join = queryFactory.createJoin(type, leftTable, rightTable, condition); + join.setPosition(new TextPosition(leftTable.getPosition(), condition.getPosition())); + return join; + } | id=Identifier() { lstColumns.add( queryFactory.createColumn(id) ); } ( id=Identifier() { lstColumns.add( queryFactory.createColumn(id) ); } - )* - { return queryFactory.createJoin(type, leftTable, rightTable, lstColumns); } + )* lastPar= + { + join = queryFactory.createJoin(type, leftTable, rightTable, lstColumns); + join.setPosition(new TextPosition(leftTable.getPosition().beginLine, leftTable.getPosition().beginColumn, lastPar.endLine, (lastPar.endColumn < 0) ? -1 : (lastPar.endColumn + 1))); + return join; + } ) ) }catch(Exception ex){ @@ -961,73 +1103,128 @@ /* ****** */ /* STRING */ /* ****** */ -String String(): {Token t; String str="";} { - (t= {str += t.image.substring(1,t.image.length()-1).replaceAll("''", "'");})+ - {return str;} +StringConstant String(): {Token t, start=null; String str=""; StringConstant cst;} { + (t= + { + str += t.image.substring(1, t.image.length()-1).replaceAll("''", "'"); + if (start == null) + start = t; + } + )+ + { + try{ + cst = queryFactory.createStringConstant(str); + cst.setPosition(new TextPosition(start, t)); + return cst; + }catch(Exception ex){ + throw generateParseException(ex); + } + } } /* ************* */ /* NUMERIC TYPES */ /* ************* */ -String UnsignedNumeric(): {Token t;} { +NumericConstant UnsignedNumeric(): {Token t; NumericConstant cst;} { (t= | t= | t=) - {return t.image;} + { try{ + cst = queryFactory.createNumericConstant(t.image); + cst.setPosition(new TextPosition(t)); + return cst; + }catch(Exception ex){ + throw generateParseException(ex); + } + } } -String UnsignedFloat(): {Token t;} { +NumericConstant UnsignedFloat(): {Token t; NumericConstant cst;} { (t= | t=) - {return t.image;} + { + try{ + cst = queryFactory.createNumericConstant(t.image); + cst.setPosition(new TextPosition(t)); + return cst; + }catch(Exception ex){ + throw generateParseException(ex); + } + } } -String SignedInteger(): {Token sign=null, number;} { +NumericConstant SignedInteger(): {Token sign=null, number; NumericConstant cst;} { ((sign=|sign=)? number=) - {return ((sign==null)?"":sign.image)+number.image;} + { + try{ + if (sign == null){ cst = queryFactory.createNumericConstant(number.image); + cst.setPosition(new TextPosition(number)); + }else{ cst = queryFactory.createNumericConstant(sign.image+number.image); + cst.setPosition(new TextPosition(sign, number)); + } + return cst; + }catch(Exception ex){ + throw generateParseException(ex); + } + } } /* *********** */ /* EXPRESSIONS */ /* *********** */ -ADQLOperand NumericValueExpressionPrimary(): {String expr; ADQLColumn column; ADQLOperand op;} { +ADQLOperand NumericValueExpressionPrimary(): {ADQLColumn column; ADQLOperand op; Token left, right;} { try{ (// unsigned_value_specification - expr=UnsignedNumeric() {return queryFactory.createNumericConstant(expr);} + op=UnsignedNumeric() {return op;} // column_reference | column=Column() {column.setExpectedType('N'); return column;} // set_function_specification | op=SqlFunction() {return op;} // LEFT_PAR value_expression RIGHT_PAR - | ( op=NumericExpression() ) {return queryFactory.createWrappedOperand(op);}) + | (left= op=NumericExpression() right=) { WrappedOperand wop = queryFactory.createWrappedOperand(op); wop.setPosition(new TextPosition(left, right)); return wop; }) }catch(Exception ex){ throw generateParseException(ex); } } -ADQLOperand StringValueExpressionPrimary(): {String expr; ADQLColumn column; ADQLOperand op;} { +ADQLOperand StringValueExpressionPrimary(): {StringConstant expr; ADQLColumn column; ADQLOperand op; Token left, right;} { try{ (// string - expr=String() {return queryFactory.createStringConstant(expr);} + expr=String() {return expr;} + // unsigned numeric + | op=UnsignedNumeric() {return op;} + // set_function_specification + | op=SqlFunction() {return op;} // column_reference - | column=Column() {column.setExpectedType('S'); return column;} + | column=Column() {column.setExpectedType('*'); return column;} // LEFT_PAR value_expression RIGHT_PAR - | ( (op=StringExpression()) ) {return queryFactory.createWrappedOperand(op);}) + | (left= (op=ValueExpression()) right=) { WrappedOperand wop = queryFactory.createWrappedOperand(op); wop.setPosition(new TextPosition(left, right)); return wop; }) }catch(Exception ex){ throw generateParseException(ex); } } -ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; } { +ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; Token left, right; } { try{ (LOOKAHEAD((|) | (Factor() (|||))) valueExpr=NumericExpression() | LOOKAHEAD( | (StringFactor() )) valueExpr=StringExpression() - | LOOKAHEAD() valueExpr=ValueExpression() { valueExpr = queryFactory.createWrappedOperand(valueExpr); } + | LOOKAHEAD() left= valueExpr=ValueExpression() right= { valueExpr = queryFactory.createWrappedOperand(valueExpr); ((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right)); } | LOOKAHEAD( ) valueExpr=UserDefinedFunction() - | valueExpr=GeometryValueFunction() + | LOOKAHEAD(2) valueExpr=GeometryValueFunction() | LOOKAHEAD(Column()) valueExpr=Column() | LOOKAHEAD(String()) valueExpr=StringFactor() - | valueExpr=Factor()) + | LOOKAHEAD(3) valueExpr=Factor() + + /* At this position in this switch, all possibilities (including + * Column()) have already been tested and failed. + * + * So, this final choice actually aims to throw an error set with the + * current token and with an error message implying that a column name + * was expected (which is generally the case in an ADQL query). + * + * Note: This choice will generally be reached if an unexpected ADQL/SQL + * word is ending the query. */ + | valueExpr=Column() ) {return valueExpr;} }catch(Exception ex){ throw generateParseException(ex); @@ -1041,7 +1238,9 @@ return leftOp; else{ try{ - return queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition())); + return operation; }catch(Exception ex){ throw generateParseException(ex); } @@ -1056,7 +1255,9 @@ return leftOp; else{ try{ - return queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition())); + return operation; }catch(Exception ex){ throw generateParseException(ex); } @@ -1064,16 +1265,22 @@ } } -ADQLOperand Factor(): {boolean negative = false;; ADQLOperand op;} { +ADQLOperand Factor(): {boolean negative = false; Token minusSign = null; ADQLOperand op;} { ( - ( | ( {negative = true;}))? + ( | (minusSign= {negative = true;}))? (LOOKAHEAD(2) op=NumericFunction() | op=NumericValueExpressionPrimary()) ) { if (negative){ try{ + TextPosition position = op.getPosition(); op = queryFactory.createNegativeOperand(op); + NegativeOperand negativeOp = (NegativeOperand)op; + if (minusSign != null) + negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, position.endLine, position.endColumn)); + else + negativeOp.setPosition(position); }catch(Exception ex){ throw generateParseException(ex); } @@ -1101,7 +1308,12 @@ ((Concatenation)leftOp).add(rightOp); } )* - { return leftOp; } + { + if (leftOp instanceof Concatenation){ + Concatenation concat = (Concatenation)leftOp; concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition())); + } + return leftOp; + } } ADQLOperand StringFactor(): {ADQLOperand op;} { @@ -1126,11 +1338,15 @@ /* ********************************** */ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint constraint = null; Token op = null; boolean notOp = false;} { try{ - [ {notOp = true;}] + [op= {notOp = true;}] constraint=Constraint() { - if (notOp) constraint = queryFactory.createNot(constraint); + if (notOp){ + TextPosition oldPos = constraint.getPosition(); constraint = queryFactory.createNot(constraint); + ((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn)); + } notOp = false; + if (clause instanceof ADQLConstraint) clause.add(constraint); else @@ -1141,8 +1357,13 @@ [ {notOp = true;}] constraint=Constraint() { - if (notOp) constraint = queryFactory.createNot(constraint); + if (notOp){ + TextPosition oldPos = constraint.getPosition(); + constraint = queryFactory.createNot(constraint); + ((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn)); + } notOp = false; + if (clause instanceof ADQLConstraint) clause.add(op.image, constraint); else @@ -1152,13 +1373,19 @@ }catch(Exception ex){ throw generateParseException(ex); } - {return clause;} + { + if (!clause.isEmpty()){ TextPosition start = clause.get(0).getPosition(); + TextPosition end = clause.get(clause.size()-1).getPosition(); + clause.setPosition(new TextPosition(start, end)); + } + return clause; + } } -ADQLConstraint Constraint(): {ADQLConstraint constraint = null;} { - (LOOKAHEAD(Predicate()) constraint=Predicate() +ADQLConstraint Constraint(): {ADQLConstraint constraint = null; Token start, end;} { + (LOOKAHEAD( | ValueExpression()) constraint=Predicate() | ( - + start= { try{ constraint = queryFactory.createGroupOfConstraints(); @@ -1167,19 +1394,39 @@ } } ConditionsList((ConstraintsGroup)constraint) - + end= + { ((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end)); } )) {return constraint;} } -ADQLConstraint Predicate(): {ADQLQuery q=null; ADQLColumn column=null; ADQLOperand strExpr1=null, strExpr2=null; ADQLOperand op; Token notToken = null; ADQLConstraint constraint = null;} { +ADQLConstraint Predicate(): {ADQLQuery q=null; ADQLColumn column=null; ADQLOperand strExpr1=null, strExpr2=null; ADQLOperand op; Token start, notToken = null, end; ADQLConstraint constraint = null;} { try{ // exists_predicate - (( q=SubQueryExpression()) {return queryFactory.createExists(q);} + ( + (start= q=SubQueryExpression() + { + Exists e = queryFactory.createExists(q); + e.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn)); + return e; + } + ) // null_predicate - | LOOKAHEAD(Column() )(column=Column() [notToken=] {return queryFactory.createIsNull((notToken!=null), column);}) + | LOOKAHEAD(Column() )(column=Column() [notToken=] end= + { + IsNull in = queryFactory.createIsNull((notToken!=null), column); + in.setPosition(new TextPosition(column.getPosition().beginLine, column.getPosition().beginColumn, end.endLine, (end.endColumn < 0) ? -1 : (end.endColumn + 1))); + return in; + } + ) // like_predicate - | LOOKAHEAD(StringExpression() [] ) (strExpr1=StringExpression() [notToken=] strExpr2=StringExpression() {return queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.LIKE:ComparisonOperator.NOTLIKE, strExpr2);}) + | LOOKAHEAD(StringExpression() [] ) (strExpr1=StringExpression() [notToken=] strExpr2=StringExpression() + { + Comparison comp = queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.LIKE:ComparisonOperator.NOTLIKE, strExpr2); + comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition())); + return comp; + } + ) | (op=ValueExpression() (// comparison_predicate (constraint=ComparisonEnd(op)) @@ -1188,7 +1435,8 @@ // in_predicate | constraint=InEnd(op) ) - )) + ) + ) }catch(Exception ex){ throw generateParseException(ex); } @@ -1199,39 +1447,49 @@ ((comp= | comp= | comp= | comp= | comp= | comp=) rightOp=ValueExpression()) { try{ - return queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp); + Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp); + comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition())); + return comparison; }catch(Exception ex){ throw generateParseException(ex); } } } -Between BetweenEnd(ADQLOperand leftOp): {Token notToken=null; ADQLOperand min, max;} { - [notToken=] min=ValueExpression() max=ValueExpression() +Between BetweenEnd(ADQLOperand leftOp): {Token start,notToken=null; ADQLOperand min, max;} { + [notToken=] start= min=ValueExpression() max=ValueExpression() { try{ - return queryFactory.createBetween((notToken!=null), leftOp, min, max); + Between bet = queryFactory.createBetween((notToken!=null), leftOp, min, max); + if (notToken != null) start = notToken; + bet.setPosition(new TextPosition(start.beginLine, start.beginColumn, max.getPosition().endLine, max.getPosition().endColumn)); + return bet; }catch(Exception ex){ throw generateParseException(ex); } } } -In InEnd(ADQLOperand leftOp): {Token not=null; ADQLQuery q = null; ADQLOperand item; Vector items = new Vector();} { - [not=] +In InEnd(ADQLOperand leftOp): {Token not=null, start; ADQLQuery q = null; ADQLOperand item; Vector items = new Vector();} { + [not=] start= (LOOKAHEAD(2) q=SubQueryExpression() | ( item=ValueExpression() {items.add(item);} ( item=ValueExpression() {items.add(item);})* )) { try{ - if (q != null) - return queryFactory.createIn(leftOp, q, not!=null); - else{ + In in; + start = (not!=null) ? not : start; + if (q != null){ + in = queryFactory.createIn(leftOp, q, not!=null); + in.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn)); + }else{ ADQLOperand[] list = new ADQLOperand[items.size()]; int i=0; for(ADQLOperand op : items) list[i++] = op; - return queryFactory.createIn(leftOp, list, not!=null); + in = queryFactory.createIn(leftOp, list, not!=null); + in.setPosition(new TextPosition(start.beginLine, start.beginColumn, list[list.length-1].getPosition().endLine, list[list.length-1].getPosition().endColumn)); } + return in; }catch(Exception ex){ throw generateParseException(ex); } @@ -1242,14 +1500,20 @@ /* ************* */ /* SQL FUNCTIONS */ /* ************* */ -SQLFunction SqlFunction(): {Token fct, all=null, distinct=null; ADQLOperand op=null; SQLFunction funct = null;}{ +SQLFunction SqlFunction(): {Token fct, all=null, distinct=null, end; ADQLOperand op=null; SQLFunction funct = null;}{ try{ ( - ( [distinct=] (all= | op=ValueExpression()) - { funct = queryFactory.createSQLFunction((all!=null)?SQLFunctionType.COUNT_ALL:SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); }) + (fct= [distinct=] (all= | op=ValueExpression()) end= + { + funct = queryFactory.createSQLFunction((all!=null)?SQLFunctionType.COUNT_ALL:SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); + funct.setPosition(new TextPosition(fct, end)); + }) | - ((fct= | fct= | fct= | fct=) [distinct=] op=ValueExpression() - { funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); }) + ((fct= | fct= | fct= | fct=) [distinct=] op=ValueExpression() end= + { + funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); + funct.setPosition(new TextPosition(fct, end)); + }) ) }catch(Exception ex){ throw generateParseException(ex); @@ -1266,22 +1530,22 @@ {return ops;} } -GeometryFunction GeometryFunction(): {Token t=null; GeometryValue gvf1, gvf2; GeometryValue gvp1, gvp2; GeometryFunction gf = null; PointFunction p1=null, p2=null; ADQLColumn col1 = null, col2 = null;} { +GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue gvf1, gvf2; GeometryValue gvp1, gvp2; GeometryFunction gf = null; PointFunction p1=null, p2=null; ADQLColumn col1 = null, col2 = null;} { try{ // predicate_geometry_function ( - ((t= | t=) gvf1=GeometryExpression() gvf2=GeometryExpression() + ((fct= | fct=) gvf1=GeometryExpression() gvf2=GeometryExpression() end= { - if (t.image.equalsIgnoreCase("contains")) + if (fct.image.equalsIgnoreCase("contains")) gf = queryFactory.createContains(gvf1, gvf2); else gf = queryFactory.createIntersects(gvf1, gvf2); }) // non_predicate_geometry_function - | ( gvf1=GeometryExpression() ) {gf = queryFactory.createArea(gvf1);} - | ( (p1=Point() {gf = queryFactory.createCoord1(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord1(col1);}) ) - | ( (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord2(col1);}) ) - | ( + | (fct= gvf1=GeometryExpression() end=) {gf = queryFactory.createArea(gvf1);} + | (fct= (p1=Point() {gf = queryFactory.createCoord1(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord1(col1);}) end=) + | (fct= (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord2(col1);}) end=) + | (fct= (p1=Point()|col1=Column()) { @@ -1300,7 +1564,7 @@ gvp2 = new GeometryValue(col2); } } - + end= {gf = queryFactory.createDistance(gvp1, gvp2);} ) ) @@ -1308,7 +1572,10 @@ throw generateParseException(ex); } - { return gf; } + { + gf.setPosition(new TextPosition(fct, end)); + return gf; + } } ADQLOperand CoordinateSystem(): { ADQLOperand coordSys=null;}{ @@ -1316,62 +1583,70 @@ { return coordSys; } } -GeometryFunction GeometryValueFunction(): {ADQLOperand coordSys; ADQLOperand width, height; ADQLOperand[] coords, tmp; Vector vCoords; ADQLOperand op=null; GeometryValue gvf = null; GeometryFunction gf = null;} { +GeometryFunction GeometryValueFunction(): {Token fct=null, end=null; ADQLOperand coordSys; ADQLOperand width, height; ADQLOperand[] coords, tmp; Vector vCoords; ADQLOperand op=null; GeometryValue gvf = null; GeometryFunction gf = null;} { try{ // BOX: - (( coordSys=CoordinateSystem() // coord_sys + ((fct= coordSys=CoordinateSystem() // coord_sys coords=Coordinates() // coordinates - width=NumericExpression() height=NumericExpression() ) + width=NumericExpression() height=NumericExpression() end=) {gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);} // CENTROID: - | ( gvf=GeometryExpression() ) {gf = queryFactory.createCentroid(gvf);} + | (fct= gvf=GeometryExpression() end=) {gf = queryFactory.createCentroid(gvf);} // CIRCLE: - | ( coordSys=CoordinateSystem() // coord_sys + | (fct= coordSys=CoordinateSystem() // coord_sys coords=Coordinates() // coordinates - width=NumericExpression() ) // radius + width=NumericExpression() end=) // radius {gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);} // POINT: | gf=Point() // POLYGON: - | ( coordSys=CoordinateSystem() // coord_sys + | (fct= coordSys=CoordinateSystem() // coord_sys { vCoords = new Vector(); } // coordinates tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);} tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);} tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);} ( tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);})* - ) + end=) { gf = queryFactory.createPolygon(coordSys, vCoords); } // REGION: - | ( op=StringExpression() ) {gf = queryFactory.createRegion(op);}) + | (fct= op=StringExpression() end=) {gf = queryFactory.createRegion(op);}) }catch(Exception ex){ throw generateParseException(ex); } - {return gf;} + { + if (fct != null && end != null) // = !(gf instanceof Point) + gf.setPosition(new TextPosition(fct, end)); + return gf; + } } -PointFunction Point(): {ADQLOperand coordSys; ADQLOperand[] coords;} { - coordSys=CoordinateSystem() // coord_sys - coords=Coordinates() // coordinates +PointFunction Point(): {Token start, end; ADQLOperand coordSys; ADQLOperand[] coords;} { + start= coordSys=CoordinateSystem() // coord_sys + coords=Coordinates() end= // coordinates { try{ - return queryFactory.createPoint(coordSys, coords[0], coords[1]); + PointFunction pf = queryFactory.createPoint(coordSys, coords[0], coords[1]); + pf.setPosition(new TextPosition(start, end)); + return pf; }catch(Exception ex){ throw generateParseException(ex); } } } -GeometryFunction ExtractCoordSys(): {GeometryValue gvf;} { - gvf=GeometryExpression() +GeometryFunction ExtractCoordSys(): {Token start, end; GeometryValue gvf;} { + start= gvf=GeometryExpression() end= { try{ - return queryFactory.createExtractCoordSys(gvf); + GeometryFunction gf = queryFactory.createExtractCoordSys(gvf); + gf.setPosition(new TextPosition(start, end)); + return gf; }catch(Exception ex){ throw generateParseException(ex); } @@ -1389,57 +1664,55 @@ {return fct;} } -MathFunction MathFunction(): {Token fct=null; ADQLOperand param1=null, param2=null; String integerValue = null;} { +MathFunction MathFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null; NumericConstant integerValue = null;} { try{ - ((fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() param2=NumericExpression() ) - | (fct= ) - | (fct= param1=NumericExpression() param2=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= (param1=NumericExpression())? ) - | (fct= param1=NumericExpression() ( integerValue=SignedInteger() {param2 = queryFactory.createNumericConstant(integerValue);})? ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ( integerValue=SignedInteger() {param2 = queryFactory.createNumericConstant(integerValue);})? )) + ((fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() param2=NumericExpression() end=) + | (fct= end=) + | (fct= param1=NumericExpression() param2=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= (param1=NumericExpression())? end=) + | (fct= param1=NumericExpression() ( param2=SignedInteger())? end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() ( param2=SignedInteger())? end=)) { - if (param1 != null) - return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); - else - return null; + MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); + mf.setPosition(new TextPosition(fct, end)); + return mf; } }catch(Exception ex){ throw generateParseException(ex); } } -MathFunction TrigFunction(): {Token fct=null; ADQLOperand param1=null, param2=null;} { - ((fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() param2=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() ) - | (fct= param1=NumericExpression() )) +MathFunction TrigFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null;} { + ((fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() param2=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=) + | (fct= param1=NumericExpression() end=)) { try{ - if (param1 != null) - return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); - else - return null; + MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); + mf.setPosition(new TextPosition(fct, end)); + return mf; }catch(Exception ex){ throw generateParseException(ex); } } } -UserDefinedFunction UserDefinedFunction(): {Token fct; Vector params = new Vector(); ADQLOperand op;} { - fct= (op=ValueExpression() {params.add(op);} ( op=ValueExpression() {params.add(op);})*)? +UserDefinedFunction UserDefinedFunction(): {Token fct, end; Vector params = new Vector(); ADQLOperand op;} { + fct= (op=ValueExpression() {params.add(op);} ( op=ValueExpression() {params.add(op);})*)? end= { //System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !"); try{ @@ -1447,9 +1720,10 @@ ADQLOperand[] parameters = new ADQLOperand[params.size()]; for(int i=0; i", "", + "", "\"(\"", "\")\"", "\".\"", @@ -252,9 +255,10 @@ "\"LIKE\"", "\"IN\"", "\"EXISTS\"", - "\"GROUP BY\"", + "\"BY\"", + "\"GROUP\"", "\"HAVING\"", - "\"ORDER BY\"", + "\"ORDER\"", "\"ASC\"", "\"DESC\"", "\"AVG\"", @@ -298,8 +302,6 @@ "\"COT\"", "\"SIN\"", "\"TAN\"", - "", - "", "", "\"\\\'\"", "", diff -Nru adql-1.3/src/adql/parser/ADQLParser.java adql-1.4/src/adql/parser/ADQLParser.java --- adql-1.3/src/adql/parser/ADQLParser.java 2015-03-13 18:21:20.000000000 +0000 +++ adql-1.4/src/adql/parser/ADQLParser.java 2018-01-12 13:50:30.000000000 +0000 @@ -1,3 +1,4 @@ +/* ADQLParser.java */ /* Generated By:JavaCC: Do not edit this line. ADQLParser.java */ package adql.parser; @@ -15,7 +16,6 @@ import adql.query.ClauseADQL; import adql.query.ClauseConstraints; import adql.query.ClauseSelect; -import adql.query.ColumnReference; import adql.query.SelectAllColumns; import adql.query.SelectItem; import adql.query.TextPosition; @@ -24,13 +24,21 @@ import adql.query.constraint.Comparison; import adql.query.constraint.ComparisonOperator; import adql.query.constraint.ConstraintsGroup; +import adql.query.constraint.Exists; import adql.query.constraint.In; +import adql.query.constraint.IsNull; +import adql.query.constraint.NotConstraint; import adql.query.from.ADQLJoin; import adql.query.from.FromContent; import adql.query.operand.ADQLColumn; import adql.query.operand.ADQLOperand; import adql.query.operand.Concatenation; +import adql.query.operand.NegativeOperand; +import adql.query.operand.NumericConstant; +import adql.query.operand.Operation; import adql.query.operand.OperationType; +import adql.query.operand.StringConstant; +import adql.query.operand.WrappedOperand; import adql.query.operand.function.ADQLFunction; import adql.query.operand.function.MathFunction; import adql.query.operand.function.MathFunctionType; @@ -44,22 +52,37 @@ import adql.translator.TranslationException; /** -*

      Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.

      -* -*

      This parser is able, thanks to a {@link QueryChecker} object, to check each ADQLQuery just after its generation. -* It could be used to check the consistency between the ADQL query to parse and the "database" on which the query must be executed. -* By default, there is no {@link QueryChecker}. Thus you must extend {@link QueryChecker} to check semantically all generated ADQLQuery objects.

      -* -*

      To create an object representation of the given ADQL query, this parser uses a {@link ADQLQueryFactory} object. So if you want customize some object (ie. CONTAINS) of this representation -* you just have to extend the corresponding default object (ie. ContainsFunction) and to extend the corresponding function of {@link ADQLQueryFactory} (ie. createContains(...)).

      -* -*

      WARNING: To modify this class it's strongly encouraged to modify the .jj file in the section between PARSER_BEGIN and PARSER_END and to re-compile it with JavaCC.

      +* Parses an ADQL query thanks to the {@link ADQLParser#Query()} function. +* +*

      +* This parser is able, thanks to a {@link QueryChecker} object, to check each +* {@link ADQLQuery} just after its generation. It could be used to check the +* consistency between the ADQL query to parse and the "database" on which the +* query must be executed. By default, there is no {@link QueryChecker}. Thus +* you must extend {@link QueryChecker} to check semantically all generated +* ADQLQuery objects. +*

      +* +*

      +* To create an object representation of the given ADQL query, this parser uses +* a {@link ADQLQueryFactory} object. So if you want customize some object +* (ie. CONTAINS) of this representation you just have to extend the +* corresponding default object (ie. ContainsFunction) and to extend the +* corresponding function of {@link ADQLQueryFactory} +* (ie. createContains(...)). +*

      +* +*

      WARNING: +* To modify this class it's strongly encouraged to modify the .jj file in the +* section between PARSER_BEGIN and PARSER_END and to re-compile +* it with JavaCC. +*

      * * @see QueryChecker * @see ADQLQueryFactory * * @author Grégory Mantelet (CDS;ARI) - gmantele@ari.uni-heidelberg.de -* @version 1.3 (10/2014) +* @version 1.4 (01/2018) */ public class ADQLParser implements ADQLParserConstants { @@ -69,13 +92,16 @@ /** The stack of queries (because there may be some sub-queries). */ private Stack stackQuery = new Stack(); - /** The object representation of the ADQL query to parse. (ONLY USED DURING THE PARSING, else it is always null). */ + /** The object representation of the ADQL query to parse. + * (ONLY USED DURING THE PARSING, else it is always null). */ private ADQLQuery query = null; - /** Checks each ADQLQuery (sub-query or not) just after their generation. */ + /** Checks each {@link ADQLQuery} (sub-query or not) just after their + * generation. */ private QueryChecker queryChecker = null; - /** The first token of a table/column name. This token is extracted by {@link #Identifier()}. */ + /** The first token of a table/column name. This token is extracted by + * {@link #Identifier()}. */ private Token currentIdentifierToken = null; /** @@ -83,13 +109,16 @@ */ public ADQLParser(){ this(new java.io.ByteArrayInputStream("".getBytes())); + setDebug(false); } /** - * Builds an ADQL parser without a query to parse but with a QueryChecker and a ADQLQueryFactory. + * Builds an ADQL parser without a query to parse but with a + * {@link QueryChecker} and a {@link ADQLQueryFactory}. * - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(QueryChecker checker, ADQLQueryFactory factory){ this(); @@ -101,18 +130,21 @@ } /** - * Builds an ADQL parser without a query to parse but with a QueryChecker. + * Builds an ADQL parser without a query to parse but with a + * {@link QueryChecker}. * - * @param checker The object to use to check each ADQLQuery. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(QueryChecker checker){ this(checker, null); } /** - * Builds an ADQL parser without a query to parse but with a ADQLQueryFactory. + * Builds an ADQL parser without a query to parse but with a + * {@link ADQLQueryFactory}. * - * @param factory The object to use to build an object representation of the given ADQL query. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(ADQLQueryFactory factory){ this((QueryChecker)null, factory); @@ -122,11 +154,15 @@ * Builds a parser with a stream containing the query to parse. * * @param stream The stream in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory){ this(stream); + setDebug(false); + + setDebug(false); queryChecker = checker; @@ -138,7 +174,7 @@ * Builds a parser with a stream containing the query to parse. * * @param stream The stream in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(java.io.InputStream stream, QueryChecker checker){ this(stream, checker, null); @@ -148,7 +184,8 @@ * Builds a parser with a stream containing the query to parse. * * @param stream The stream in which the ADQL query to parse is given. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory){ this(stream, (QueryChecker)null, factory); @@ -157,13 +194,15 @@ /** * Builds a parser with a stream containing the query to parse. * - * @param stream The stream in which the ADQL query to parse is given. - * @param encoding The supplied encoding. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param stream The stream in which the ADQL query to parse is given. + * @param encoding The supplied encoding. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory){ this(stream, encoding); + setDebug(false); queryChecker = checker; @@ -174,9 +213,9 @@ /** * Builds a parser with a stream containing the query to parse. * - * @param stream The stream in which the ADQL query to parse is given. - * @param encoding The supplied encoding. - * @param checker The object to use to check each ADQLQuery. + * @param stream The stream in which the ADQL query to parse is given. + * @param encoding The supplied encoding. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker){ this(stream, encoding, checker, null); @@ -185,9 +224,10 @@ /** * Builds a parser with a stream containing the query to parse. * - * @param stream The stream in which the ADQL query to parse is given. - * @param encoding The supplied encoding. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param stream The stream in which the ADQL query to parse is given. + * @param encoding The supplied encoding. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.InputStream stream, String encoding, ADQLQueryFactory factory){ this(stream, encoding, null, factory); @@ -196,12 +236,16 @@ /** * Builds a parser with a reader containing the query to parse. * - * @param reader The reader in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param reader The reader in which the ADQL query to parse is given. + * @param checker The object to use to check each {@link ADQLQuery}. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory){ this(reader); + setDebug(false); + + setDebug(false); queryChecker = checker; @@ -212,8 +256,8 @@ /** * Builds a parser with a reader containing the query to parse. * - * @param reader The reader in which the ADQL query to parse is given. - * @param checker The object to use to check each ADQLQuery. + * @param reader The reader in which the ADQL query to parse is given. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(java.io.Reader reader, QueryChecker checker){ this(reader, checker, null); @@ -223,7 +267,8 @@ * Builds a parser with a reader containing the query to parse. * * @param reader The reader in which the ADQL query to parse is given. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(java.io.Reader reader, ADQLQueryFactory factory){ this(reader, null, factory); @@ -232,12 +277,16 @@ /** * Builds a parser with another token manager. * - * @param tm The manager which associates a token to a numeric code. - * @param checker The object to use to check each ADQLQuery. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param tm The manager which associates a token to a numeric code. + * @param checker The object to use to check each {@link ADQLQuery }. + * @param factory The object to use to build an object representation + * of the given ADQL query. */ public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker, ADQLQueryFactory factory){ this(tm); + setDebug(false); + + setDebug(false); queryChecker = checker; @@ -248,8 +297,8 @@ /** * Builds a parser with another token manager. * - * @param tm The manager which associates a token to a numeric code. - * @param checker The object to use to check each ADQLQuery. + * @param tm The manager which associates a token to a numeric code. + * @param checker The object to use to check each {@link ADQLQuery}. */ public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker){ this(tm, checker, null); @@ -258,17 +307,20 @@ /** * Builds a parser with another token manager. * - * @param tm The manager which associates a token to a numeric code. - * @param factory The object to use to build an object representation of the given ADQL query. + * @param tm The manager which associates a token to a numeric code. + * @param factory The object to use to build an object representation of + * the given ADQL query. */ public ADQLParser(ADQLParserTokenManager tm, ADQLQueryFactory factory){ this(tm, null, factory); } /** - * Parses the query given at the creation of this parser or in the ReInit functions. + * Parses the query given at the creation of this parser or in the + * ReInit functions. + * + * @return The object representation of the given ADQL query. * - * @return The object representation of the given ADQL query. * @throws ParseException If there is at least one syntactic error. * * @see ADQLParser#Query() @@ -276,14 +328,20 @@ public final ADQLQuery parseQuery() throws ParseException{ stackQuery.clear(); query = null; - return Query(); + try{ + return Query(); + }catch(TokenMgrError tme){ + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** * Parses the query given in parameter. * - * @param q The ADQL query to parse. - * @return The object representation of the given ADQL query. + * @param q The ADQL query to parse. + * + * @return The object representation of the given ADQL query. + * * @throws ParseException If there is at least one syntactic error. * * @see ADQLParser#ReInit(java.io.InputStream) @@ -294,14 +352,20 @@ stackQuery.clear(); query = null; ReInit(new java.io.ByteArrayInputStream(q.getBytes())); - return Query(); + try{ + return Query(); + }catch(TokenMgrError tme){ + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } /** * Parses the query contained in the stream given in parameter. * - * @param stream The stream which contains the ADQL query to parse. - * @return The object representation of the given ADQL query. + * @param stream The stream which contains the ADQL query to parse. + * + * @return The object representation of the given ADQL query. + * * @throws ParseException If there is at least one syntactic error. * * @see ADQLParser#ReInit(java.io.InputStream) @@ -312,7 +376,11 @@ stackQuery.clear(); query = null; ReInit(stream); - return Query(); + try{ + return Query(); + }catch(TokenMgrError tme){ + throw new ParseException(tme.getMessage(), new TextPosition(tme.getErrorLine(), tme.getErrorColumn())); + } } public final void setDebug(boolean debug){ @@ -348,11 +416,23 @@ } /** - *

      Gets the specified ADQL query and parses the given ADQL query. The SQL translation is then printed if the syntax is correct.

      - *

      ONLY the syntax is checked: the query is NOT EXECUTED !

      - *

      Supplied parameters are:

      • [-debug] -url http://...
      • [-debug] -file ...
      • [-debug] -query SELECT...

      + * Gets the specified ADQL query and parses the given ADQL query. The SQL + * translation is then printed if the syntax is correct. + * + *

      + * ONLY the syntax is checked: the query is NOT EXECUTED ! + *

      + * + *

      Supplied parameters are: + *

        + *
      • [-debug] -url http://...
      • + *
      • [-debug] -file ...
      • + *
      • [-debug] -query SELECT...
      • + *
      + *

      * * @param args + * @throws Exception */ public static final void main(String[] args) throws Exception{ @@ -398,7 +478,7 @@ try{ - if (file == null || file.isEmpty()) + if (file == null || file.length() == 0) parser = new ADQLParser(System.in); else if (file.matches(urlRegex)) parser = new ADQLParser((new java.net.URL(file)).openStream()); @@ -470,1213 +550,598 @@ * @throws ParseException If the query syntax is incorrect. */ final public ADQLQuery Query() throws ParseException{ - ADQLQuery q = null; - q = QueryExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case 0: - jj_consume_token(0); - break; - case EOQ: - jj_consume_token(EOQ); - break; - default: - jj_la1[0] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - // check the query: - if (queryChecker != null) - queryChecker.check(q); - - { - if (true) - return q; - } - throw new Error("Missing return statement in function"); - } - - final public ADQLQuery QueryExpression() throws ParseException{ + trace_call("Query"); try{ - // create the query: - query = queryFactory.createQuery(); - stackQuery.push(query); - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - Select(); - From(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case WHERE: - Where(); - break; - default: - jj_la1[1] = jj_gen; - ; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case GROUP_BY: - GroupBy(); - break; - default: - jj_la1[2] = jj_gen; - ; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case HAVING: - Having(); - break; - default: - jj_la1[3] = jj_gen; - ; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ORDER_BY: - OrderBy(); - break; - default: - jj_la1[4] = jj_gen; - ; - } - // get the previous query (!= null if the current query is a sub-query): - ADQLQuery previousQuery = stackQuery.pop(); - if (stackQuery.isEmpty()) - query = null; - else - query = stackQuery.peek(); - - { - if (true) - return previousQuery; - } - throw new Error("Missing return statement in function"); - } - - final public ADQLQuery SubQueryExpression() throws ParseException{ - ADQLQuery q = null; - jj_consume_token(LEFT_PAR); - q = QueryExpression(); - jj_consume_token(RIGHT_PAR); - { - if (true) - return q; - } - throw new Error("Missing return statement in function"); - } - - final public void Select() throws ParseException{ - ClauseSelect select = query.getSelect(); - SelectItem item = null; - Token t = null; - jj_consume_token(SELECT); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case QUANTIFIER: - t = jj_consume_token(QUANTIFIER); - select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT")); - break; - default: - jj_la1[5] = jj_gen; - ; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case TOP: - jj_consume_token(TOP); - t = jj_consume_token(UNSIGNED_INTEGER); - try{ - select.setLimit(Integer.parseInt(t.image)); - }catch(NumberFormatException nfe){ - { - if (true) - throw new ParseException("[l." + t.beginLine + ";c." + t.beginColumn + "] The TOP limit (\u005c"" + t.image + "\u005c") isn't a regular unsigned integer !"); - } + ADQLQuery q = null; + q = QueryExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case 0:{ + jj_consume_token(0); + break; } - break; - default: - jj_la1[6] = jj_gen; - ; - } - item = SelectItem(); - select.add(item); - label_1: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; + case EOQ:{ + jj_consume_token(EOQ); break; + } default: - jj_la1[7] = jj_gen; - break label_1; + jj_la1[0] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); } - jj_consume_token(COMMA); - item = SelectItem(); - select.add(item); - } - } + // check the query: + if (queryChecker != null) + queryChecker.check(q); - final public SelectItem SelectItem() throws ParseException{ - IdentifierItems identifiers = new IdentifierItems(true); - IdentifierItem id = null, label = null; - ADQLOperand op = null; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ASTERISK: - jj_consume_token(ASTERISK); - { - if (true) - return new SelectAllColumns(query); - } - break; - default: - jj_la1[11] = jj_gen; - if (jj_2_1(7)){ - id = Identifier(); - jj_consume_token(DOT); - identifiers.append(id); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - id = Identifier(); - jj_consume_token(DOT); - identifiers.append(id); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - id = Identifier(); - jj_consume_token(DOT); - identifiers.append(id); - break; - default: - jj_la1[8] = jj_gen; - ; - } - break; - default: - jj_la1[9] = jj_gen; - ; - } - jj_consume_token(ASTERISK); - try{ - ; - { - if (true) - return new SelectAllColumns(queryFactory.createTable(identifiers, null)); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case PLUS: - case MINUS: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case BOX: - case CENTROID: - case CIRCLE: - case POINT: - case POLYGON: - case REGION: - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case COORDSYS: - case DISTANCE: - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - case STRING_LITERAL: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - op = ValueExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AS: - jj_consume_token(AS); - label = Identifier(); - break; - default: - jj_la1[10] = jj_gen; - ; - } - break; - default: - jj_la1[12] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - } - } - try{ - SelectItem item = queryFactory.createSelectItem(op, (label == null) ? null : label.identifier); - if (label != null) - item.setCaseSensitive(label.caseSensitivity); - { - if (true) - return item; - } - }catch(Exception ex){ { - if (true) - throw generateParseException(ex); + if ("" != null) + return q; } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Query"); } - throw new Error("Missing return statement in function"); } - final public void From() throws ParseException{ - FromContent content = null, content2 = null; + final public ADQLQuery QueryExpression() throws ParseException{ + trace_call("QueryExpression"); try{ - jj_consume_token(FROM); - content = TableRef(); - label_2: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; - break; - default: - jj_la1[13] = jj_gen; - break label_2; + TextPosition endPos = null; + try{ + // create the query: + query = queryFactory.createQuery(); + stackQuery.push(query); + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); } - jj_consume_token(COMMA); - content2 = TableRef(); - content = queryFactory.createJoin(JoinType.CROSS, content, content2); } - query.setFrom(content); - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - } - - final public void Where() throws ParseException{ - ClauseConstraints where = query.getWhere(); - ADQLConstraint condition; - jj_consume_token(WHERE); - ConditionsList(where); - } - - final public void GroupBy() throws ParseException{ - ClauseADQL groupBy = query.getGroupBy(); - ColumnReference colRef = null; - jj_consume_token(GROUP_BY); - colRef = ColumnRef(); - groupBy.add(colRef); - label_3: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; + Select(); + From(); + endPos = query.getFrom().getPosition(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case WHERE:{ + Where(); + endPos = query.getWhere().getPosition(); break; + } default: - jj_la1[14] = jj_gen; - break label_3; + jj_la1[1] = jj_gen;; } - jj_consume_token(COMMA); - colRef = ColumnRef(); - groupBy.add(colRef); - } - } - - final public void Having() throws ParseException{ - ClauseConstraints having = query.getHaving(); - jj_consume_token(HAVING); - ConditionsList(having); - } - - final public void OrderBy() throws ParseException{ - ClauseADQL orderBy = query.getOrderBy(); - ADQLOrder order = null; - jj_consume_token(ORDER_BY); - order = OrderItem(); - orderBy.add(order); - label_4: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case GROUP:{ + GroupBy(); + endPos = query.getGroupBy().getPosition(); break; + } default: - jj_la1[15] = jj_gen; - break label_4; + jj_la1[2] = jj_gen;; } - jj_consume_token(COMMA); - order = OrderItem(); - orderBy.add(order); - } - } - - /* *************************** */ - /* COLUMN AND TABLE REFERENCES */ - /* *************************** */ - final public IdentifierItem Identifier() throws ParseException{ - Token t; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case REGULAR_IDENTIFIER: - t = jj_consume_token(REGULAR_IDENTIFIER); - { - if (true) - return new IdentifierItem(t, false); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case HAVING:{ + Having(); + endPos = query.getHaving().getPosition(); + break; } - break; - case DELIMITED_IDENTIFIER: - t = jj_consume_token(DELIMITED_IDENTIFIER); - { - if (true) - return new IdentifierItem(t, true); + default: + jj_la1[3] = jj_gen;; + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ORDER:{ + OrderBy(); + endPos = query.getOrderBy().getPosition(); + break; } - break; - default: - jj_la1[16] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - throw new Error("Missing return statement in function"); - } + default: + jj_la1[4] = jj_gen;; + } + // set the position of the query: + query.setPosition(new TextPosition(query.getSelect().getPosition(), endPos)); - /** - * Extracts the name of a table with its possible catalog and schema prefixes. - * - * @return A {@link IdentifierItems} which contains at most three items: catalogName, schemaName and tableName. - */ - final public IdentifierItems TableName() throws ParseException{ - IdentifierItems identifiers = new IdentifierItems(true); - IdentifierItem id = null; - id = Identifier(); - identifiers.append(id); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DOT: - jj_consume_token(DOT); - id = Identifier(); - identifiers.append(id); - break; - default: - jj_la1[17] = jj_gen; - ; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DOT: - jj_consume_token(DOT); - id = Identifier(); - identifiers.append(id); - break; - default: - jj_la1[18] = jj_gen; - ; - } - { - if (true) - return identifiers; - } - throw new Error("Missing return statement in function"); - } + // get the previous query (!= null if the current query is a sub-query): + ADQLQuery previousQuery = stackQuery.pop(); + if (stackQuery.isEmpty()) + query = null; + else + query = stackQuery.peek(); - /** - * Extracts the name of a column with its possible catalog, schema and table prefixes. - * - * @return A {@link IdentifierItems} which contains at most four items: catalogName, schemaName, tableName and columnName. - */ - final public IdentifierItems ColumnName() throws ParseException{ - IdentifierItem id; - IdentifierItems table = null, identifiers = new IdentifierItems(false); - id = Identifier(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DOT: - jj_consume_token(DOT); - table = TableName(); - break; - default: - jj_la1[19] = jj_gen; - ; - } - identifiers.append(id); - if (table != null){ - for(int i = 0; i < table.size(); i++) - identifiers.append(table.get(i)); - } - { - if (true) - return identifiers; + { + if ("" != null) + return previousQuery; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("QueryExpression"); } - throw new Error("Missing return statement in function"); } - final public ADQLColumn Column() throws ParseException{ - IdentifierItems identifiers; - identifiers = ColumnName(); + final public ADQLQuery SubQueryExpression() throws ParseException{ + trace_call("SubQueryExpression"); try{ + ADQLQuery q = null; + Token start, end; + start = jj_consume_token(LEFT_PAR); + q = QueryExpression(); + end = jj_consume_token(RIGHT_PAR); + q.setPosition(new TextPosition(start, end)); { - if (true) - return queryFactory.createColumn(identifiers); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + if ("" != null) + return q; } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("SubQueryExpression"); } - throw new Error("Missing return statement in function"); } - final public ColumnReference ColumnRef() throws ParseException{ - IdentifierItems identifiers = null; - Token ind = null; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - identifiers = ColumnName(); - break; - case UNSIGNED_INTEGER: - ind = jj_consume_token(UNSIGNED_INTEGER); - break; - default: - jj_la1[20] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } + final public void Select() throws ParseException{ + trace_call("Select"); try{ - ColumnReference colRef = null; - if (identifiers != null) - colRef = queryFactory.createColRef(identifiers); - else - colRef = queryFactory.createColRef(Integer.parseInt(ind.image), new TextPosition(ind)); - { - if (true) - return colRef; + ClauseSelect select = query.getSelect(); + SelectItem item = null; + Token start, t = null; + start = jj_consume_token(SELECT); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case QUANTIFIER:{ + t = jj_consume_token(QUANTIFIER); + select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT")); + break; + } + default: + jj_la1[5] = jj_gen;; } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case TOP:{ + jj_consume_token(TOP); + t = jj_consume_token(UNSIGNED_INTEGER); + try{ + select.setLimit(Integer.parseInt(t.image)); + }catch(NumberFormatException nfe){ + { + if (true) + throw new ParseException("[l." + t.beginLine + ";c." + t.beginColumn + "] The TOP limit (\u005c"" + t.image + "\u005c") isn't a regular unsigned integer !"); + } + } + break; + } + default: + jj_la1[6] = jj_gen;; } - } - throw new Error("Missing return statement in function"); - } - - final public ADQLOrder OrderItem() throws ParseException{ - IdentifierItems identifiers = null; - Token ind = null, desc = null; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - identifiers = ColumnName(); - break; - case UNSIGNED_INTEGER: - ind = jj_consume_token(UNSIGNED_INTEGER); - break; - default: - jj_la1[21] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ASC: - case DESC: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ASC: - jj_consume_token(ASC); - break; - case DESC: - desc = jj_consume_token(DESC); + item = SelectItem(); + select.add(item); + label_1: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; break; + } default: - jj_la1[22] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[7] = jj_gen; + break label_1; } - break; - default: - jj_la1[23] = jj_gen; - ; - } - try{ - ADQLOrder order = null; - if (identifiers != null) - order = queryFactory.createOrder(identifiers, desc != null); - else - order = queryFactory.createOrder(Integer.parseInt(ind.image), desc != null, new TextPosition(ind)); - { - if (true) - return order; - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + jj_consume_token(COMMA); + item = SelectItem(); + select.add(item); } + TextPosition lastItemPos = query.getSelect().get(query.getSelect().size() - 1).getPosition(); + select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn)); + }finally{ + trace_return("Select"); } - throw new Error("Missing return statement in function"); } - final public FromContent SimpleTableRef() throws ParseException{ - IdentifierItem alias = null; - IdentifierItems identifiers = null; - ADQLQuery subQuery = null; - FromContent content = null; + final public SelectItem SelectItem() throws ParseException{ + trace_call("SelectItem"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - identifiers = TableName(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AS: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AS: - jj_consume_token(AS); - break; - default: - jj_la1[24] = jj_gen; - ; - } - alias = Identifier(); - break; - default: - jj_la1[25] = jj_gen; - ; - } + IdentifierItems identifiers = new IdentifierItems(true); + IdentifierItem id = null, label = null; + ADQLOperand op = null; + SelectItem item; + Token starToken; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ASTERISK:{ + starToken = jj_consume_token(ASTERISK); + item = new SelectAllColumns(query); + item.setPosition(new TextPosition(starToken)); { - if (true) - return queryFactory.createTable(identifiers, alias); + if ("" != null) + return item; } break; + } default: - jj_la1[27] = jj_gen; - if (jj_2_2(2)){ - subQuery = SubQueryExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AS: - jj_consume_token(AS); - break; + jj_la1[12] = jj_gen; + if (jj_2_1(7)){ + id = Identifier(); + jj_consume_token(DOT); + identifiers.append(id); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + id = Identifier(); + jj_consume_token(DOT); + identifiers.append(id); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + id = Identifier(); + jj_consume_token(DOT); + identifiers.append(id); + break; + } + default: + jj_la1[8] = jj_gen;; + } + break; + } default: - jj_la1[26] = jj_gen; - ; + jj_la1[9] = jj_gen;; } - alias = Identifier(); - { - if (true) - return queryFactory.createTable(subQuery, alias); + starToken = jj_consume_token(ASTERISK); + try{ + item = new SelectAllColumns(queryFactory.createTable(identifiers, null)); + TextPosition firstPos = identifiers.get(0).position; + item.setPosition(new TextPosition(firstPos.beginLine, firstPos.beginColumn, starToken.endLine, (starToken.endColumn < 0) ? -1 : (starToken.endColumn + 1))); + { + if ("" != null) + return item; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ case LEFT_PAR: - jj_consume_token(LEFT_PAR); - content = JoinedTable(); - jj_consume_token(RIGHT_PAR); - { - if (true) - return content; + case PLUS: + case MINUS: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case BOX: + case CENTROID: + case CIRCLE: + case POINT: + case POLYGON: + case REGION: + case CONTAINS: + case INTERSECTS: + case AREA: + case COORD1: + case COORD2: + case COORDSYS: + case DISTANCE: + case ABS: + case CEILING: + case DEGREES: + case EXP: + case FLOOR: + case LOG: + case LOG10: + case MOD: + case PI: + case POWER: + case RADIANS: + case RAND: + case ROUND: + case SQRT: + case TRUNCATE: + case ACOS: + case ASIN: + case ATAN: + case ATAN2: + case COS: + case COT: + case SIN: + case TAN: + case STRING_LITERAL: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = ValueExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AS: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AS:{ + jj_consume_token(AS); + break; + } + default: + jj_la1[10] = jj_gen;; + } + label = Identifier(); + break; + } + default: + jj_la1[11] = jj_gen;; } break; + } default: - jj_la1[28] = jj_gen; + jj_la1[13] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + try{ + item = queryFactory.createSelectItem(op, (label == null) ? null : label.identifier); + if (label != null){ + item.setCaseSensitive(label.caseSensitivity); + item.setPosition(new TextPosition(op.getPosition(), label.position)); + }else + item.setPosition(new TextPosition(op.getPosition())); + { + if ("" != null) + return item; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("SelectItem"); } - throw new Error("Missing return statement in function"); } - final public FromContent TableRef() throws ParseException{ - FromContent content; - content = SimpleTableRef(); - label_5: while(true){ - if (jj_2_3(2)){ - ; - }else{ - break label_5; + final public void From() throws ParseException{ + trace_call("From"); + try{ + FromContent content = null, content2 = null; + try{ + jj_consume_token(FROM); + content = TableRef(); + label_2: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; + break; + } + default: + jj_la1[14] = jj_gen; + break label_2; + } + jj_consume_token(COMMA); + content2 = TableRef(); + TextPosition startPos = content.getPosition(), + endPos = content2.getPosition(); + content = queryFactory.createJoin(JoinType.CROSS, content, content2); + content.setPosition(new TextPosition(startPos, endPos)); + } + query.setFrom(content); + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } - content = JoinSpecification(content); - } - { - if (true) - return content; + }finally{ + trace_return("From"); } - throw new Error("Missing return statement in function"); } - final public FromContent JoinedTable() throws ParseException{ - FromContent content; - content = SimpleTableRef(); - label_6: while(true){ - content = JoinSpecification(content); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NATURAL: - case INNER: - case RIGHT: - case LEFT: - case FULL: - case JOIN: - ; - break; - default: - jj_la1[29] = jj_gen; - break label_6; - } - } - { - if (true) - return content; + final public void Where() throws ParseException{ + trace_call("Where"); + try{ + ClauseConstraints where = query.getWhere(); + ADQLConstraint condition; + Token start; + start = jj_consume_token(WHERE); + ConditionsList(where); + TextPosition endPosition = where.getPosition(); + where.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn)); + }finally{ + trace_return("Where"); } - throw new Error("Missing return statement in function"); } - final public ADQLJoin JoinSpecification(FromContent leftTable) throws ParseException{ - boolean natural = false; - JoinType type = JoinType.INNER; - ClauseConstraints condition = new ClauseConstraints("ON"); - ArrayList lstColumns = new ArrayList(); - IdentifierItem id; - FromContent rightTable; - try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NATURAL: - jj_consume_token(NATURAL); - natural = true; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case INNER: - case RIGHT: - case LEFT: - case FULL: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case INNER: - jj_consume_token(INNER); - break; - case RIGHT: - case LEFT: - case FULL: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT: - jj_consume_token(LEFT); - type = JoinType.OUTER_LEFT; - break; - case RIGHT: - jj_consume_token(RIGHT); - type = JoinType.OUTER_RIGHT; - break; - case FULL: - jj_consume_token(FULL); - type = JoinType.OUTER_FULL; - break; - default: - jj_la1[30] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case OUTER: - jj_consume_token(OUTER); - break; - default: - jj_la1[31] = jj_gen; - ; - } - break; - default: - jj_la1[32] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - break; - default: - jj_la1[33] = jj_gen; - ; - } - jj_consume_token(JOIN); - rightTable = TableRef(); - { - if (true) - return queryFactory.createJoin(type, leftTable, rightTable); - } - break; - case INNER: - case RIGHT: - case LEFT: - case FULL: - case JOIN: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case INNER: - case RIGHT: - case LEFT: - case FULL: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case INNER: - jj_consume_token(INNER); - break; - case RIGHT: - case LEFT: - case FULL: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT: - jj_consume_token(LEFT); - type = JoinType.OUTER_LEFT; - break; - case RIGHT: - jj_consume_token(RIGHT); - type = JoinType.OUTER_RIGHT; - break; - case FULL: - jj_consume_token(FULL); - type = JoinType.OUTER_FULL; - break; - default: - jj_la1[34] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case OUTER: - jj_consume_token(OUTER); - break; - default: - jj_la1[35] = jj_gen; - ; - } - break; - default: - jj_la1[36] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - break; - default: - jj_la1[37] = jj_gen; - ; - } - jj_consume_token(JOIN); - rightTable = TableRef(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ON: - jj_consume_token(ON); - ConditionsList(condition); - { - if (true) - return queryFactory.createJoin(type, leftTable, rightTable, condition); - } - break; - case USING: - jj_consume_token(USING); - jj_consume_token(LEFT_PAR); - id = Identifier(); - lstColumns.add(queryFactory.createColumn(id)); - label_7: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; - break; - default: - jj_la1[38] = jj_gen; - break label_7; - } - jj_consume_token(COMMA); - id = Identifier(); - lstColumns.add(queryFactory.createColumn(id)); - } - jj_consume_token(RIGHT_PAR); - { - if (true) - return queryFactory.createJoin(type, leftTable, rightTable, lstColumns); - } - break; - default: - jj_la1[39] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + final public void GroupBy() throws ParseException{ + trace_call("GroupBy"); + try{ + ClauseADQL groupBy = query.getGroupBy(); + ADQLColumn colRef = null; + Token start; + start = jj_consume_token(GROUP); + jj_consume_token(BY); + colRef = Column(); + groupBy.add(colRef); + label_3: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; + break; } - break; - default: - jj_la1[40] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + default: + jj_la1[15] = jj_gen; + break label_3; + } + jj_consume_token(COMMA); + colRef = Column(); + groupBy.add(colRef); } + groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn)); + }finally{ + trace_return("GroupBy"); } - throw new Error("Missing return statement in function"); } - /* ****** */ - /* STRING */ - /* ****** */ - final public String String() throws ParseException{ - Token t; - String str = ""; - label_8: while(true){ - t = jj_consume_token(STRING_LITERAL); - str += t.image.substring(1, t.image.length() - 1).replaceAll("''", "'"); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case STRING_LITERAL: - ; - break; - default: - jj_la1[41] = jj_gen; - break label_8; - } - } - { - if (true) - return str; + final public void Having() throws ParseException{ + trace_call("Having"); + try{ + ClauseConstraints having = query.getHaving(); + Token start; + start = jj_consume_token(HAVING); + ConditionsList(having); + TextPosition endPosition = having.getPosition(); + having.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn)); + }finally{ + trace_return("Having"); } - throw new Error("Missing return statement in function"); } - /* ************* */ - /* NUMERIC TYPES */ - /* ************* */ - final public String UnsignedNumeric() throws ParseException{ - Token t; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case SCIENTIFIC_NUMBER: - t = jj_consume_token(SCIENTIFIC_NUMBER); - break; - case UNSIGNED_FLOAT: - t = jj_consume_token(UNSIGNED_FLOAT); - break; - case UNSIGNED_INTEGER: - t = jj_consume_token(UNSIGNED_INTEGER); - break; - default: - jj_la1[42] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - { - if (true) - return t.image; - } - throw new Error("Missing return statement in function"); - } - - final public String UnsignedFloat() throws ParseException{ - Token t; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case UNSIGNED_INTEGER: - t = jj_consume_token(UNSIGNED_INTEGER); - break; - case UNSIGNED_FLOAT: - t = jj_consume_token(UNSIGNED_FLOAT); - break; - default: - jj_la1[43] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - { - if (true) - return t.image; - } - throw new Error("Missing return statement in function"); - } - - final public String SignedInteger() throws ParseException{ - Token sign = null, number; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case PLUS: - case MINUS: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case PLUS: - sign = jj_consume_token(PLUS); - break; - case MINUS: - sign = jj_consume_token(MINUS); + final public void OrderBy() throws ParseException{ + trace_call("OrderBy"); + try{ + ClauseADQL orderBy = query.getOrderBy(); + ADQLOrder order = null; + Token start; + start = jj_consume_token(ORDER); + jj_consume_token(BY); + order = OrderItem(); + orderBy.add(order); + label_4: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; break; + } default: - jj_la1[44] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[16] = jj_gen; + break label_4; } - break; - default: - jj_la1[45] = jj_gen; - ; - } - number = jj_consume_token(UNSIGNED_INTEGER); - { - if (true) - return ((sign == null) ? "" : sign.image) + number.image; + jj_consume_token(COMMA); + order = OrderItem(); + orderBy.add(order); + } + orderBy.setPosition(new TextPosition(start, token)); + }finally{ + trace_return("OrderBy"); } - throw new Error("Missing return statement in function"); } - /* *********** */ - /* EXPRESSIONS */ - /* *********** */ - final public ADQLOperand NumericValueExpressionPrimary() throws ParseException{ - String expr; - ADQLColumn column; - ADQLOperand op; + /* *************************** */ + /* COLUMN AND TABLE REFERENCES */ + /* *************************** */ + final public IdentifierItem Identifier() throws ParseException{ + trace_call("Identifier"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - // unsigned_value_specification - expr = UnsignedNumeric(); - { - if (true) - return queryFactory.createNumericConstant(expr); - } - break; - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - column = Column(); - column.setExpectedType('N'); - { - if (true) - return column; - } - break; - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - op = SqlFunction(); + Token t; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case REGULAR_IDENTIFIER:{ + t = jj_consume_token(REGULAR_IDENTIFIER); { - if (true) - return op; + if ("" != null) + return new IdentifierItem(t, false); } break; - case LEFT_PAR: - jj_consume_token(LEFT_PAR); - op = NumericExpression(); - jj_consume_token(RIGHT_PAR); + } + case DELIMITED_IDENTIFIER:{ + t = jj_consume_token(DELIMITED_IDENTIFIER); { - if (true) - return queryFactory.createWrappedOperand(op); + if ("" != null) + return new IdentifierItem(t, true); } break; + } default: - jj_la1[46] = jj_gen; + jj_la1[17] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Identifier"); } - throw new Error("Missing return statement in function"); } - final public ADQLOperand StringValueExpressionPrimary() throws ParseException{ - String expr; - ADQLColumn column; - ADQLOperand op; + /** + * Extracts the name of a table with its possible catalog and schema prefixes. + * + * @return A {@link IdentifierItems} which contains at most three items: catalogName, schemaName and tableName. + */ + final public IdentifierItems TableName() throws ParseException{ + trace_call("TableName"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case STRING_LITERAL: - // string - expr = String(); - { - if (true) - return queryFactory.createStringConstant(expr); - } - break; - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - column = Column(); - column.setExpectedType('S'); - { - if (true) - return column; - } + IdentifierItems identifiers = new IdentifierItems(true); + IdentifierItem id = null; + id = Identifier(); + identifiers.append(id); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DOT:{ + jj_consume_token(DOT); + id = Identifier(); + identifiers.append(id); break; - case LEFT_PAR: - jj_consume_token(LEFT_PAR); - op = StringExpression(); - jj_consume_token(RIGHT_PAR); - { - if (true) - return queryFactory.createWrappedOperand(op); - } + } + default: + jj_la1[18] = jj_gen;; + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DOT:{ + jj_consume_token(DOT); + id = Identifier(); + identifiers.append(id); break; + } default: - jj_la1[47] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[19] = jj_gen;; } - }catch(Exception ex){ { - if (true) - throw generateParseException(ex); + if ("" != null) + return identifiers; } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("TableName"); } - throw new Error("Missing return statement in function"); } - final public ADQLOperand ValueExpression() throws ParseException{ - ADQLOperand valueExpr = null; + /** + * Extracts the name of a column with its possible catalog, schema and table prefixes. + * + * @return A {@link IdentifierItems} which contains at most four items: catalogName, schemaName, tableName and columnName. + */ + final public IdentifierItems ColumnName() throws ParseException{ + trace_call("ColumnName"); try{ - if (jj_2_4(2147483647)){ - valueExpr = NumericExpression(); - }else if (jj_2_5(2147483647)){ - valueExpr = StringExpression(); - }else if (jj_2_6(2147483647)){ - jj_consume_token(LEFT_PAR); - valueExpr = ValueExpression(); - jj_consume_token(RIGHT_PAR); - valueExpr = queryFactory.createWrappedOperand(valueExpr); - }else if (jj_2_7(2147483647)){ - valueExpr = UserDefinedFunction(); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case BOX: - case CENTROID: - case CIRCLE: - case POINT: - case POLYGON: - case REGION: - valueExpr = GeometryValueFunction(); - break; - default: - jj_la1[48] = jj_gen; - if (jj_2_8(2147483647)){ - valueExpr = Column(); - }else if (jj_2_9(2147483647)){ - valueExpr = StringFactor(); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case PLUS: - case MINUS: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case DISTANCE: - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - valueExpr = Factor(); - break; - default: - jj_la1[49] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - } + IdentifierItem id; + IdentifierItems table = null, + identifiers = new IdentifierItems(false); + id = Identifier(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DOT:{ + jj_consume_token(DOT); + table = TableName(); + break; } + default: + jj_la1[20] = jj_gen;; } - { - if (true) - return valueExpr; + identifiers.append(id); + if (table != null){ + for(int i = 0; i < table.size(); i++) + identifiers.append(table.get(i)); } - }catch(Exception ex){ { - if (true) - throw generateParseException(ex); + if ("" != null) + return identifiers; } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("ColumnName"); } - throw new Error("Missing return statement in function"); } - final public ADQLOperand NumericExpression() throws ParseException{ - Token sign = null; - ADQLOperand leftOp, rightOp = null; - leftOp = NumericTerm(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case PLUS: - case MINUS: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case PLUS: - sign = jj_consume_token(PLUS); - break; - case MINUS: - sign = jj_consume_token(MINUS); - break; - default: - jj_la1[50] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - rightOp = NumericExpression(); - break; - default: - jj_la1[51] = jj_gen; - ; - } - if (sign == null){ - if (true) - return leftOp; - }else{ + final public ADQLColumn Column() throws ParseException{ + trace_call("Column"); + try{ + IdentifierItems identifiers; + identifiers = ColumnName(); try{ { - if (true) - return queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + if ("" != null) + return queryFactory.createColumn(identifiers); } }catch(Exception ex){ { @@ -1684,43 +1149,66 @@ throw generateParseException(ex); } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Column"); } - throw new Error("Missing return statement in function"); } - final public ADQLOperand NumericTerm() throws ParseException{ - Token sign = null; - ADQLOperand leftOp, rightOp = null; - leftOp = Factor(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ASTERISK: - case DIVIDE: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ASTERISK: - sign = jj_consume_token(ASTERISK); - break; - case DIVIDE: - sign = jj_consume_token(DIVIDE); - break; - default: - jj_la1[52] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + final public ADQLOrder OrderItem() throws ParseException{ + trace_call("OrderItem"); + try{ + IdentifierItem identifier = null; + Token ind = null, desc = null; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + identifier = Identifier(); + break; } - rightOp = NumericTerm(); - break; - default: - jj_la1[53] = jj_gen; - ; - } - if (sign == null){ - if (true) - return leftOp; - }else{ + case UNSIGNED_INTEGER:{ + ind = jj_consume_token(UNSIGNED_INTEGER); + break; + } + default: + jj_la1[21] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ASC: + case DESC:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ASC:{ + jj_consume_token(ASC); + break; + } + case DESC:{ + desc = jj_consume_token(DESC); + break; + } + default: + jj_la1[22] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + } + default: + jj_la1[23] = jj_gen;; + } try{ + ADQLOrder order = null; + if (identifier != null){ + order = queryFactory.createOrder(identifier, desc != null); + order.setPosition(identifier.position); + }else{ + order = queryFactory.createOrder(Integer.parseInt(ind.image), desc != null); + order.setPosition(new TextPosition(ind)); + } { - if (true) - return queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + if ("" != null) + return order; } }catch(Exception ex){ { @@ -1728,1455 +1216,2550 @@ throw generateParseException(ex); } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("OrderItem"); } - throw new Error("Missing return statement in function"); } - final public ADQLOperand Factor() throws ParseException{ - boolean negative = false;; - ADQLOperand op; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case PLUS: - case MINUS: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case PLUS: - jj_consume_token(PLUS); - break; - case MINUS: - jj_consume_token(MINUS); - negative = true; + final public FromContent SimpleTableRef() throws ParseException{ + trace_call("SimpleTableRef"); + try{ + IdentifierItem alias = null; + IdentifierItems identifiers = null; + ADQLQuery subQuery = null; + FromContent content = null; + Token start, end; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + identifiers = TableName(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AS: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AS:{ + jj_consume_token(AS); + break; + } + default: + jj_la1[24] = jj_gen;; + } + alias = Identifier(); + break; + } + default: + jj_la1[25] = jj_gen;; + } + content = queryFactory.createTable(identifiers, alias); + if (alias == null) + content.setPosition(new TextPosition(identifiers.get(0).position, identifiers.get(identifiers.size() - 1).position)); + else + content.setPosition(new TextPosition(identifiers.get(0).position, alias.position)); + { + if ("" != null) + return content; + } break; + } default: - jj_la1[54] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[27] = jj_gen; + if (jj_2_2(2)){ + subQuery = SubQueryExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AS:{ + jj_consume_token(AS); + break; + } + default: + jj_la1[26] = jj_gen;; + } + alias = Identifier(); + content = queryFactory.createTable(subQuery, alias); + if (alias == null) + content.setPosition(new TextPosition(subQuery.getPosition())); + else + content.setPosition(new TextPosition(subQuery.getPosition(), alias.position)); + { + if ("" != null) + return content; + } + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR:{ + start = jj_consume_token(LEFT_PAR); + content = JoinedTable(); + end = jj_consume_token(RIGHT_PAR); + content.setPosition(new TextPosition(start, end)); + { + if ("" != null) + return content; + } + break; + } + default: + jj_la1[28] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } } - break; - default: - jj_la1[55] = jj_gen; - ; - } - if (jj_2_10(2)){ - op = NumericFunction(); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - op = NumericValueExpressionPrimary(); - break; - default: - jj_la1[56] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - } - if (negative){ - try{ - op = queryFactory.createNegativeOperand(op); }catch(Exception ex){ { if (true) throw generateParseException(ex); } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("SimpleTableRef"); } - - { - if (true) - return op; - } - throw new Error("Missing return statement in function"); } - final public ADQLOperand StringExpression() throws ParseException{ - ADQLOperand leftOp; - ADQLOperand rightOp = null; - leftOp = StringFactor(); - label_9: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case CONCAT: + final public FromContent TableRef() throws ParseException{ + trace_call("TableRef"); + try{ + FromContent content; + content = SimpleTableRef(); + label_5: while(true){ + if (jj_2_3(2)){ ; - break; - default: - jj_la1[57] = jj_gen; - break label_9; - } - jj_consume_token(CONCAT); - rightOp = StringFactor(); - if (!(leftOp instanceof Concatenation)){ - try{ - ADQLOperand temp = leftOp; - leftOp = queryFactory.createConcatenation(); - ((Concatenation)leftOp).add(temp); - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } + }else{ + break label_5; } + content = JoinSpecification(content); } - ((Concatenation)leftOp).add(rightOp); - } - { - if (true) - return leftOp; + { + if ("" != null) + return content; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("TableRef"); } - throw new Error("Missing return statement in function"); } - final public ADQLOperand StringFactor() throws ParseException{ - ADQLOperand op; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COORDSYS: - op = ExtractCoordSys(); - break; - default: - jj_la1[58] = jj_gen; - if (jj_2_11(2)){ - op = UserDefinedFunction(); - ((UserDefinedFunction)op).setExpectedType('S'); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case STRING_LITERAL: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - op = StringValueExpressionPrimary(); - break; - default: - jj_la1[59] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + final public FromContent JoinedTable() throws ParseException{ + trace_call("JoinedTable"); + try{ + FromContent content; + content = SimpleTableRef(); + label_6: while(true){ + content = JoinSpecification(content); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NATURAL: + case INNER: + case RIGHT: + case LEFT: + case FULL: + case JOIN:{ + ; + break; } + default: + jj_la1[29] = jj_gen; + break label_6; } - } - { - if (true) - return op; - } - throw new Error("Missing return statement in function"); - } - - final public GeometryValue GeometryExpression() throws ParseException{ - ADQLColumn col = null; - GeometryFunction gf = null; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - col = Column(); - break; - case BOX: - case CENTROID: - case CIRCLE: - case POINT: - case POLYGON: - case REGION: - gf = GeometryValueFunction(); - break; - default: - jj_la1[60] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - if (col != null){ - col.setExpectedType('G'); + } { - if (true) - return new GeometryValue(col); + if ("" != null) + return content; } - }else{ - if (true) - return new GeometryValue(gf); + throw new Error("Missing return statement in function"); + }finally{ + trace_return("JoinedTable"); } - throw new Error("Missing return statement in function"); } - /* ********************************** */ - /* BOOLEAN EXPRESSIONS (WHERE clause) */ - /* ********************************** */ - final public ClauseConstraints ConditionsList(ClauseConstraints clause) throws ParseException{ - ADQLConstraint constraint = null; - Token op = null; - boolean notOp = false; - try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - jj_consume_token(NOT); - notOp = true; - break; - default: - jj_la1[61] = jj_gen; - ; - } - constraint = Constraint(); - if (notOp) - constraint = queryFactory.createNot(constraint); - notOp = false; - if (clause instanceof ADQLConstraint) - clause.add(constraint); - else - clause.add(constraint); - label_10: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AND: - case OR: - ; - break; - default: - jj_la1[62] = jj_gen; - break label_10; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AND: - op = jj_consume_token(AND); - break; - case OR: - op = jj_consume_token(OR); - break; - default: - jj_la1[63] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - jj_consume_token(NOT); - notOp = true; - break; - default: - jj_la1[64] = jj_gen; - ; - } - constraint = Constraint(); - if (notOp) - constraint = queryFactory.createNot(constraint); - notOp = false; - if (clause instanceof ADQLConstraint) - clause.add(op.image, constraint); - else - clause.add(op.image, constraint); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - { - if (true) - return clause; - } - throw new Error("Missing return statement in function"); - } - - final public ADQLConstraint Constraint() throws ParseException{ - ADQLConstraint constraint = null; - if (jj_2_12(2147483647)){ - constraint = Predicate(); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - jj_consume_token(LEFT_PAR); - try{ - constraint = queryFactory.createGroupOfConstraints(); - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - ConditionsList((ConstraintsGroup)constraint); - jj_consume_token(RIGHT_PAR); - break; - default: - jj_la1[65] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - } - { - if (true) - return constraint; - } - throw new Error("Missing return statement in function"); - } - - final public ADQLConstraint Predicate() throws ParseException{ - ADQLQuery q = null; - ADQLColumn column = null; - ADQLOperand strExpr1 = null, strExpr2 = null; - ADQLOperand op; - Token notToken = null; - ADQLConstraint constraint = null; - try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case EXISTS: - jj_consume_token(EXISTS); - q = SubQueryExpression(); - { - if (true) - return queryFactory.createExists(q); - } - break; - default: - jj_la1[70] = jj_gen; - if (jj_2_14(2147483647)){ - column = Column(); - jj_consume_token(IS); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - notToken = jj_consume_token(NOT); + final public ADQLJoin JoinSpecification(FromContent leftTable) throws ParseException{ + trace_call("JoinSpecification"); + try{ + boolean natural = false; + JoinType type = JoinType.INNER; + ClauseConstraints condition = new ClauseConstraints("ON"); + ArrayList lstColumns = new ArrayList(); + IdentifierItem id; + FromContent rightTable; + ADQLJoin join; + Token lastPar; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NATURAL:{ + jj_consume_token(NATURAL); + natural = true; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case INNER: + case RIGHT: + case LEFT: + case FULL:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case INNER:{ + jj_consume_token(INNER); + break; + } + case RIGHT: + case LEFT: + case FULL:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT:{ + jj_consume_token(LEFT); + type = JoinType.OUTER_LEFT; + break; + } + case RIGHT:{ + jj_consume_token(RIGHT); + type = JoinType.OUTER_RIGHT; + break; + } + case FULL:{ + jj_consume_token(FULL); + type = JoinType.OUTER_FULL; + break; + } + default: + jj_la1[30] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case OUTER:{ + jj_consume_token(OUTER); + break; + } + default: + jj_la1[31] = jj_gen;; + } + break; + } + default: + jj_la1[32] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } break; + } default: - jj_la1[66] = jj_gen; - ; + jj_la1[33] = jj_gen;; } - jj_consume_token(NULL); + jj_consume_token(JOIN); + rightTable = SimpleTableRef(); + join = queryFactory.createJoin(type, leftTable, rightTable); + join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition())); { - if (true) - return queryFactory.createIsNull((notToken != null), column); + if ("" != null) + return join; } - }else if (jj_2_15(2147483647)){ - strExpr1 = StringExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - notToken = jj_consume_token(NOT); + break; + } + case INNER: + case RIGHT: + case LEFT: + case FULL: + case JOIN:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case INNER: + case RIGHT: + case LEFT: + case FULL:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case INNER:{ + jj_consume_token(INNER); + break; + } + case RIGHT: + case LEFT: + case FULL:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT:{ + jj_consume_token(LEFT); + type = JoinType.OUTER_LEFT; + break; + } + case RIGHT:{ + jj_consume_token(RIGHT); + type = JoinType.OUTER_RIGHT; + break; + } + case FULL:{ + jj_consume_token(FULL); + type = JoinType.OUTER_FULL; + break; + } + default: + jj_la1[34] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case OUTER:{ + jj_consume_token(OUTER); + break; + } + default: + jj_la1[35] = jj_gen;; + } + break; + } + default: + jj_la1[36] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } break; + } default: - jj_la1[67] = jj_gen; - ; - } - jj_consume_token(LIKE); - strExpr2 = StringExpression(); - { - if (true) - return queryFactory.createComparison(strExpr1, (notToken == null) ? ComparisonOperator.LIKE : ComparisonOperator.NOTLIKE, strExpr2); + jj_la1[37] = jj_gen;; } - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case PLUS: - case MINUS: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case BOX: - case CENTROID: - case CIRCLE: - case POINT: - case POLYGON: - case REGION: - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case COORDSYS: - case DISTANCE: - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - case STRING_LITERAL: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - op = ValueExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case EQUAL: - case NOT_EQUAL: - case LESS_THAN: - case LESS_EQUAL_THAN: - case GREATER_THAN: - case GREATER_EQUAL_THAN: - constraint = ComparisonEnd(op); - break; - default: - jj_la1[68] = jj_gen; - if (jj_2_13(2)){ - constraint = BetweenEnd(op); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - case IN: - constraint = InEnd(op); - break; - default: - jj_la1[69] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } + jj_consume_token(JOIN); + rightTable = SimpleTableRef(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ON:{ + jj_consume_token(ON); + ConditionsList(condition); + join = queryFactory.createJoin(type, leftTable, rightTable, condition); + join.setPosition(new TextPosition(leftTable.getPosition(), condition.getPosition())); + { + if ("" != null) + return join; + } + break; + } + case USING:{ + jj_consume_token(USING); + jj_consume_token(LEFT_PAR); + id = Identifier(); + lstColumns.add(queryFactory.createColumn(id)); + label_7: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; + break; } + default: + jj_la1[38] = jj_gen; + break label_7; + } + jj_consume_token(COMMA); + id = Identifier(); + lstColumns.add(queryFactory.createColumn(id)); + } + lastPar = jj_consume_token(RIGHT_PAR); + join = queryFactory.createJoin(type, leftTable, rightTable, lstColumns); + join.setPosition(new TextPosition(leftTable.getPosition().beginLine, leftTable.getPosition().beginColumn, lastPar.endLine, (lastPar.endColumn < 0) ? -1 : (lastPar.endColumn + 1))); + { + if ("" != null) + return join; } break; + } default: - jj_la1[71] = jj_gen; + jj_la1[39] = jj_gen; jj_consume_token(-1); throw new ParseException(); } + break; } + default: + jj_la1[40] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - { - if (true) - return constraint; + throw new Error("Missing return statement in function"); + }finally{ + trace_return("JoinSpecification"); } - throw new Error("Missing return statement in function"); } - final public Comparison ComparisonEnd(ADQLOperand leftOp) throws ParseException{ - Token comp; - ADQLOperand rightOp; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case EQUAL: - comp = jj_consume_token(EQUAL); - break; - case NOT_EQUAL: - comp = jj_consume_token(NOT_EQUAL); - break; - case LESS_THAN: - comp = jj_consume_token(LESS_THAN); - break; - case LESS_EQUAL_THAN: - comp = jj_consume_token(LESS_EQUAL_THAN); - break; - case GREATER_THAN: - comp = jj_consume_token(GREATER_THAN); - break; - case GREATER_EQUAL_THAN: - comp = jj_consume_token(GREATER_EQUAL_THAN); - break; - default: - jj_la1[72] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - rightOp = ValueExpression(); + /* ****** */ + /* STRING */ + /* ****** */ + final public StringConstant String() throws ParseException{ + trace_call("String"); try{ - { - if (true) - return queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp); + Token t, start = null; + String str = ""; + StringConstant cst; + label_8: while(true){ + t = jj_consume_token(STRING_LITERAL); + str += t.image.substring(1, t.image.length() - 1).replaceAll("''", "'"); + if (start == null) + start = t; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case STRING_LITERAL:{ + ; + break; + } + default: + jj_la1[41] = jj_gen; + break label_8; + } } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + try{ + cst = queryFactory.createStringConstant(str); + cst.setPosition(new TextPosition(start, t)); + { + if ("" != null) + return cst; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("String"); } - throw new Error("Missing return statement in function"); } - final public Between BetweenEnd(ADQLOperand leftOp) throws ParseException{ - Token notToken = null; - ADQLOperand min, max; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - notToken = jj_consume_token(NOT); - break; - default: - jj_la1[73] = jj_gen; - ; - } - jj_consume_token(BETWEEN); - min = ValueExpression(); - jj_consume_token(AND); - max = ValueExpression(); + /* ************* */ + /* NUMERIC TYPES */ + /* ************* */ + final public NumericConstant UnsignedNumeric() throws ParseException{ + trace_call("UnsignedNumeric"); try{ - { - if (true) - return queryFactory.createBetween((notToken != null), leftOp, min, max); + Token t; + NumericConstant cst; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case SCIENTIFIC_NUMBER:{ + t = jj_consume_token(SCIENTIFIC_NUMBER); + break; + } + case UNSIGNED_FLOAT:{ + t = jj_consume_token(UNSIGNED_FLOAT); + break; + } + case UNSIGNED_INTEGER:{ + t = jj_consume_token(UNSIGNED_INTEGER); + break; + } + default: + jj_la1[42] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + try{ + cst = queryFactory.createNumericConstant(t.image); + cst.setPosition(new TextPosition(t)); + { + if ("" != null) + return cst; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("UnsignedNumeric"); } - throw new Error("Missing return statement in function"); } - final public In InEnd(ADQLOperand leftOp) throws ParseException{ - Token not = null; - ADQLQuery q = null; - ADQLOperand item; - Vector items = new Vector(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case NOT: - not = jj_consume_token(NOT); - break; - default: - jj_la1[74] = jj_gen; - ; - } - jj_consume_token(IN); - if (jj_2_16(2)){ - q = SubQueryExpression(); - }else{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - jj_consume_token(LEFT_PAR); - item = ValueExpression(); - items.add(item); - label_11: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; - break; - default: - jj_la1[75] = jj_gen; - break label_11; - } - jj_consume_token(COMMA); - item = ValueExpression(); - items.add(item); - } - jj_consume_token(RIGHT_PAR); + final public NumericConstant UnsignedFloat() throws ParseException{ + trace_call("UnsignedFloat"); + try{ + Token t; + NumericConstant cst; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case UNSIGNED_INTEGER:{ + t = jj_consume_token(UNSIGNED_INTEGER); + break; + } + case UNSIGNED_FLOAT:{ + t = jj_consume_token(UNSIGNED_FLOAT); break; + } default: - jj_la1[76] = jj_gen; + jj_la1[43] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - } - try{ - if (q != null){ - if (true) - return queryFactory.createIn(leftOp, q, not != null); - }else{ - ADQLOperand[] list = new ADQLOperand[items.size()]; - int i = 0; - for(ADQLOperand op : items) - list[i++] = op; + try{ + cst = queryFactory.createNumericConstant(t.image); + cst.setPosition(new TextPosition(t)); + { + if ("" != null) + return cst; + } + }catch(Exception ex){ { if (true) - return queryFactory.createIn(leftOp, list, not != null); + throw generateParseException(ex); } } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("UnsignedFloat"); } - throw new Error("Missing return statement in function"); } - /* ************* */ - /* SQL FUNCTIONS */ - /* ************* */ - final public SQLFunction SqlFunction() throws ParseException{ - Token fct, all = null, distinct = null; - ADQLOperand op = null; - SQLFunction funct = null; + final public NumericConstant SignedInteger() throws ParseException{ + trace_call("SignedInteger"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COUNT: - jj_consume_token(COUNT); - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case QUANTIFIER: - distinct = jj_consume_token(QUANTIFIER); - break; - default: - jj_la1[77] = jj_gen; - ; - } - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ASTERISK: - all = jj_consume_token(ASTERISK); - break; - case LEFT_PAR: - case PLUS: - case MINUS: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case BOX: - case CENTROID: - case CIRCLE: - case POINT: - case POLYGON: - case REGION: - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case COORDSYS: - case DISTANCE: - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - case STRING_LITERAL: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - op = ValueExpression(); - break; - default: - jj_la1[78] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - jj_consume_token(RIGHT_PAR); - funct = queryFactory.createSQLFunction((all != null) ? SQLFunctionType.COUNT_ALL : SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); - break; - case AVG: - case MAX: - case MIN: - case SUM: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case AVG: - fct = jj_consume_token(AVG); - break; - case MAX: - fct = jj_consume_token(MAX); + Token sign = null, number; + NumericConstant cst; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case PLUS: + case MINUS:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case PLUS:{ + sign = jj_consume_token(PLUS); break; - case MIN: - fct = jj_consume_token(MIN); - break; - case SUM: - fct = jj_consume_token(SUM); + } + case MINUS:{ + sign = jj_consume_token(MINUS); break; + } default: - jj_la1[79] = jj_gen; + jj_la1[44] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case QUANTIFIER: - distinct = jj_consume_token(QUANTIFIER); - break; - default: - jj_la1[80] = jj_gen; - ; - } - op = ValueExpression(); - jj_consume_token(RIGHT_PAR); - funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); break; + } default: - jj_la1[81] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[45] = jj_gen;; } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + number = jj_consume_token(UNSIGNED_INTEGER); + try{ + if (sign == null){ + cst = queryFactory.createNumericConstant(number.image); + cst.setPosition(new TextPosition(number)); + }else{ + cst = queryFactory.createNumericConstant(sign.image + number.image); + cst.setPosition(new TextPosition(sign, number)); + } + { + if ("" != null) + return cst; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("SignedInteger"); } - { - if (true) - return funct; + } + + /* *********** */ + /* EXPRESSIONS */ + /* *********** */ + final public ADQLOperand NumericValueExpressionPrimary() throws ParseException{ + trace_call("NumericValueExpressionPrimary"); + try{ + ADQLColumn column; + ADQLOperand op; + Token left, right; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + // unsigned_value_specification + op = UnsignedNumeric(); + { + if ("" != null) + return op; + } + break; + } + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + column = Column(); + column.setExpectedType('N'); + { + if ("" != null) + return column; + } + break; + } + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT:{ + op = SqlFunction(); + { + if ("" != null) + return op; + } + break; + } + case LEFT_PAR:{ + left = jj_consume_token(LEFT_PAR); + op = NumericExpression(); + right = jj_consume_token(RIGHT_PAR); + WrappedOperand wop = queryFactory.createWrappedOperand(op); + wop.setPosition(new TextPosition(left, right)); + { + if ("" != null) + return wop; + } + break; + } + default: + jj_la1[46] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("NumericValueExpressionPrimary"); } - throw new Error("Missing return statement in function"); } - /* ************** */ - /* ADQL FUNCTIONS */ - /* ************** */ - final public ADQLOperand[] Coordinates() throws ParseException{ - ADQLOperand[] ops = new ADQLOperand[2]; - ops[0] = NumericExpression(); - jj_consume_token(COMMA); - ops[1] = NumericExpression(); - { - if (true) - return ops; + final public ADQLOperand StringValueExpressionPrimary() throws ParseException{ + trace_call("StringValueExpressionPrimary"); + try{ + StringConstant expr; + ADQLColumn column; + ADQLOperand op; + Token left, right; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case STRING_LITERAL:{ + // string + expr = String(); + { + if ("" != null) + return expr; + } + break; + } + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = UnsignedNumeric(); + { + if ("" != null) + return op; + } + break; + } + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT:{ + op = SqlFunction(); + { + if ("" != null) + return op; + } + break; + } + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + column = Column(); + column.setExpectedType('*'); + { + if ("" != null) + return column; + } + break; + } + case LEFT_PAR:{ + left = jj_consume_token(LEFT_PAR); + op = ValueExpression(); + right = jj_consume_token(RIGHT_PAR); + WrappedOperand wop = queryFactory.createWrappedOperand(op); + wop.setPosition(new TextPosition(left, right)); + { + if ("" != null) + return wop; + } + break; + } + default: + jj_la1[47] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("StringValueExpressionPrimary"); } - throw new Error("Missing return statement in function"); } - final public GeometryFunction GeometryFunction() throws ParseException{ - Token t = null; - GeometryValue gvf1, gvf2; - GeometryValue gvp1, gvp2; - GeometryFunction gf = null; - PointFunction p1 = null, p2 = null; - ADQLColumn col1 = null, col2 = null; + final public ADQLOperand ValueExpression() throws ParseException{ + trace_call("ValueExpression"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case CONTAINS: - case INTERSECTS: - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case CONTAINS: - t = jj_consume_token(CONTAINS); - break; - case INTERSECTS: - t = jj_consume_token(INTERSECTS); + ADQLOperand valueExpr = null; + Token left, right; + try{ + if (jj_2_4(2147483647)){ + valueExpr = NumericExpression(); + }else if (jj_2_5(2147483647)){ + valueExpr = StringExpression(); + }else if (jj_2_6(2147483647)){ + left = jj_consume_token(LEFT_PAR); + valueExpr = ValueExpression(); + right = jj_consume_token(RIGHT_PAR); + valueExpr = queryFactory.createWrappedOperand(valueExpr); + ((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right)); + }else if (jj_2_7(2147483647)){ + valueExpr = UserDefinedFunction(); + }else if (jj_2_8(2)){ + valueExpr = GeometryValueFunction(); + }else if (jj_2_9(2147483647)){ + valueExpr = Column(); + }else if (jj_2_10(2147483647)){ + valueExpr = StringFactor(); + }else if (jj_2_11(3)){ + valueExpr = Factor(); + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + valueExpr = Column(); break; + } default: - jj_la1[82] = jj_gen; + jj_la1[48] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - jj_consume_token(LEFT_PAR); - gvf1 = GeometryExpression(); - jj_consume_token(COMMA); - gvf2 = GeometryExpression(); - jj_consume_token(RIGHT_PAR); - if (t.image.equalsIgnoreCase("contains")) - gf = queryFactory.createContains(gvf1, gvf2); - else - gf = queryFactory.createIntersects(gvf1, gvf2); - break; - case AREA: - jj_consume_token(AREA); - jj_consume_token(LEFT_PAR); - gvf1 = GeometryExpression(); - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createArea(gvf1); - break; - case COORD1: - jj_consume_token(COORD1); - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case POINT: - p1 = Point(); - gf = queryFactory.createCoord1(p1); + } + { + if ("" != null) + return valueExpr; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("ValueExpression"); + } + } + + final public ADQLOperand NumericExpression() throws ParseException{ + trace_call("NumericExpression"); + try{ + Token sign = null; + ADQLOperand leftOp, rightOp = null; + leftOp = NumericTerm(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case PLUS: + case MINUS:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case PLUS:{ + sign = jj_consume_token(PLUS); break; - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - col1 = Column(); - col1.setExpectedType('G'); - gf = queryFactory.createCoord1(col1); + } + case MINUS:{ + sign = jj_consume_token(MINUS); break; + } default: - jj_la1[83] = jj_gen; + jj_la1[49] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - jj_consume_token(RIGHT_PAR); + rightOp = NumericExpression(); break; - case COORD2: - jj_consume_token(COORD2); - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case POINT: - p1 = Point(); - gf = queryFactory.createCoord2(p1); + } + default: + jj_la1[50] = jj_gen;; + } + if (sign == null){ + if ("" != null) + return leftOp; + }else{ + try{ + Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition())); + { + if ("" != null) + return operation; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("NumericExpression"); + } + } + + final public ADQLOperand NumericTerm() throws ParseException{ + trace_call("NumericTerm"); + try{ + Token sign = null; + ADQLOperand leftOp, rightOp = null; + leftOp = Factor(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ASTERISK: + case DIVIDE:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ASTERISK:{ + sign = jj_consume_token(ASTERISK); break; - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - col1 = Column(); - col1.setExpectedType('G'); - gf = queryFactory.createCoord2(col1); + } + case DIVIDE:{ + sign = jj_consume_token(DIVIDE); break; + } default: - jj_la1[84] = jj_gen; + jj_la1[51] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - jj_consume_token(RIGHT_PAR); + rightOp = NumericTerm(); break; - case DISTANCE: - jj_consume_token(DISTANCE); - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case POINT: - p1 = Point(); - break; - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - col1 = Column(); - break; - default: - jj_la1[85] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + } + default: + jj_la1[52] = jj_gen;; + } + if (sign == null){ + if ("" != null) + return leftOp; + }else{ + try{ + Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp); + operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition())); + { + if ("" != null) + return operation; } - if (p1 != null) - gvp1 = new GeometryValue(p1); - else{ - col1.setExpectedType('G'); - gvp1 = new GeometryValue(col1); + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); } - jj_consume_token(COMMA); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case POINT: - p2 = Point(); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("NumericTerm"); + } + } + + final public ADQLOperand Factor() throws ParseException{ + trace_call("Factor"); + try{ + boolean negative = false; + Token minusSign = null; + ADQLOperand op; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case PLUS: + case MINUS:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case PLUS:{ + jj_consume_token(PLUS); break; - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - col2 = Column(); + } + case MINUS:{ + minusSign = jj_consume_token(MINUS); + negative = true; break; + } default: - jj_la1[86] = jj_gen; + jj_la1[53] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - if (p2 != null) - gvp2 = new GeometryValue(p2); - else{ - col2.setExpectedType('G'); - gvp2 = new GeometryValue(col2); - } - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createDistance(gvp1, gvp2); break; + } default: - jj_la1[87] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[54] = jj_gen;; } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + if (jj_2_12(2)){ + op = NumericFunction(); + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = NumericValueExpressionPrimary(); + break; + } + default: + jj_la1[55] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + if (negative){ + try{ + TextPosition position = op.getPosition(); + op = queryFactory.createNegativeOperand(op); + NegativeOperand negativeOp = (NegativeOperand)op; + if (minusSign != null) + negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, position.endLine, position.endColumn)); + else + negativeOp.setPosition(position); + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } } - } - { - if (true) - return gf; - } - throw new Error("Missing return statement in function"); - } - final public ADQLOperand CoordinateSystem() throws ParseException{ - ADQLOperand coordSys = null; - coordSys = StringExpression(); - { - if (true) - return coordSys; + { + if ("" != null) + return op; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Factor"); } - throw new Error("Missing return statement in function"); } - final public GeometryFunction GeometryValueFunction() throws ParseException{ - ADQLOperand coordSys; - ADQLOperand width, height; - ADQLOperand[] coords, tmp; - Vector vCoords; - ADQLOperand op = null; - GeometryValue gvf = null; - GeometryFunction gf = null; + final public ADQLOperand StringExpression() throws ParseException{ + trace_call("StringExpression"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case BOX: - jj_consume_token(BOX); - jj_consume_token(LEFT_PAR); - coordSys = CoordinateSystem(); - jj_consume_token(COMMA); - coords = Coordinates(); - jj_consume_token(COMMA); - width = NumericExpression(); - jj_consume_token(COMMA); - height = NumericExpression(); - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height); - break; - case CENTROID: - jj_consume_token(CENTROID); - jj_consume_token(LEFT_PAR); - gvf = GeometryExpression(); - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createCentroid(gvf); - break; - case CIRCLE: - jj_consume_token(CIRCLE); - jj_consume_token(LEFT_PAR); - coordSys = CoordinateSystem(); - jj_consume_token(COMMA); - coords = Coordinates(); - jj_consume_token(COMMA); - width = NumericExpression(); - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width); + ADQLOperand leftOp; + ADQLOperand rightOp = null; + leftOp = StringFactor(); + label_9: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case CONCAT:{ + ; + break; + } + default: + jj_la1[56] = jj_gen; + break label_9; + } + jj_consume_token(CONCAT); + rightOp = StringFactor(); + if (!(leftOp instanceof Concatenation)){ + try{ + ADQLOperand temp = leftOp; + leftOp = queryFactory.createConcatenation(); + ((Concatenation)leftOp).add(temp); + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + } + ((Concatenation)leftOp).add(rightOp); + } + if (leftOp instanceof Concatenation){ + Concatenation concat = (Concatenation)leftOp; + concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size() - 1).getPosition())); + } + { + if ("" != null) + return leftOp; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("StringExpression"); + } + } + + final public ADQLOperand StringFactor() throws ParseException{ + trace_call("StringFactor"); + try{ + ADQLOperand op; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COORDSYS:{ + op = ExtractCoordSys(); break; - case POINT: - gf = Point(); + } + default: + jj_la1[57] = jj_gen; + if (jj_2_13(2)){ + op = UserDefinedFunction(); + ((UserDefinedFunction)op).setExpectedType('S'); + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case STRING_LITERAL: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = StringValueExpressionPrimary(); + break; + } + default: + jj_la1[58] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + { + if ("" != null) + return op; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("StringFactor"); + } + } + + final public GeometryValue GeometryExpression() throws ParseException{ + trace_call("GeometryExpression"); + try{ + ADQLColumn col = null; + GeometryFunction gf = null; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + col = Column(); break; + } + case BOX: + case CENTROID: + case CIRCLE: + case POINT: case POLYGON: - jj_consume_token(POLYGON); - jj_consume_token(LEFT_PAR); - coordSys = CoordinateSystem(); - vCoords = new Vector(); - jj_consume_token(COMMA); - tmp = Coordinates(); - vCoords.add(tmp[0]); - vCoords.add(tmp[1]); - jj_consume_token(COMMA); - tmp = Coordinates(); - vCoords.add(tmp[0]); - vCoords.add(tmp[1]); - jj_consume_token(COMMA); - tmp = Coordinates(); - vCoords.add(tmp[0]); - vCoords.add(tmp[1]); - label_12: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; + case REGION:{ + gf = GeometryValueFunction(); + break; + } + default: + jj_la1[59] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + if (col != null){ + col.setExpectedType('G'); + { + if ("" != null) + return new GeometryValue(col); + } + }else{ + if ("" != null) + return new GeometryValue(gf); + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("GeometryExpression"); + } + } + + /* ********************************** */ + /* BOOLEAN EXPRESSIONS (WHERE clause) */ + /* ********************************** */ + final public ClauseConstraints ConditionsList(ClauseConstraints clause) throws ParseException{ + trace_call("ConditionsList"); + try{ + ADQLConstraint constraint = null; + Token op = null; + boolean notOp = false; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT:{ + op = jj_consume_token(NOT); + notOp = true; + break; + } + default: + jj_la1[60] = jj_gen;; + } + constraint = Constraint(); + if (notOp){ + TextPosition oldPos = constraint.getPosition(); + constraint = queryFactory.createNot(constraint); + ((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn)); + } + notOp = false; + + if (clause instanceof ADQLConstraint) + clause.add(constraint); + else + clause.add(constraint); + label_10: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AND: + case OR:{ + ; + break; + } + default: + jj_la1[61] = jj_gen; + break label_10; + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AND:{ + op = jj_consume_token(AND); + break; + } + case OR:{ + op = jj_consume_token(OR); + break; + } + default: + jj_la1[62] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT:{ + jj_consume_token(NOT); + notOp = true; + break; + } + default: + jj_la1[63] = jj_gen;; + } + constraint = Constraint(); + if (notOp){ + TextPosition oldPos = constraint.getPosition(); + constraint = queryFactory.createNot(constraint); + ((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn)); + } + notOp = false; + + if (clause instanceof ADQLConstraint) + clause.add(op.image, constraint); + else + clause.add(op.image, constraint); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + if (!clause.isEmpty()){ + TextPosition start = clause.get(0).getPosition(); + TextPosition end = clause.get(clause.size() - 1).getPosition(); + clause.setPosition(new TextPosition(start, end)); + } + { + if ("" != null) + return clause; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("ConditionsList"); + } + } + + final public ADQLConstraint Constraint() throws ParseException{ + trace_call("Constraint"); + try{ + ADQLConstraint constraint = null; + Token start, end; + if (jj_2_14(2147483647)){ + constraint = Predicate(); + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR:{ + start = jj_consume_token(LEFT_PAR); + try{ + constraint = queryFactory.createGroupOfConstraints(); + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + ConditionsList((ConstraintsGroup)constraint); + end = jj_consume_token(RIGHT_PAR); + ((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end)); + break; + } + default: + jj_la1[64] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + { + if ("" != null) + return constraint; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Constraint"); + } + } + + final public ADQLConstraint Predicate() throws ParseException{ + trace_call("Predicate"); + try{ + ADQLQuery q = null; + ADQLColumn column = null; + ADQLOperand strExpr1 = null, strExpr2 = null; + ADQLOperand op; + Token start, notToken = null, end; + ADQLConstraint constraint = null; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case EXISTS:{ + start = jj_consume_token(EXISTS); + q = SubQueryExpression(); + Exists e = queryFactory.createExists(q); + e.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn)); + { + if ("" != null) + return e; + } + break; + } + default: + jj_la1[69] = jj_gen; + if (jj_2_16(2147483647)){ + column = Column(); + jj_consume_token(IS); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT:{ + notToken = jj_consume_token(NOT); + break; + } + default: + jj_la1[65] = jj_gen;; + } + end = jj_consume_token(NULL); + IsNull in = queryFactory.createIsNull((notToken != null), column); + in.setPosition(new TextPosition(column.getPosition().beginLine, column.getPosition().beginColumn, end.endLine, (end.endColumn < 0) ? -1 : (end.endColumn + 1))); + { + if ("" != null) + return in; + } + }else if (jj_2_17(2147483647)){ + strExpr1 = StringExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT:{ + notToken = jj_consume_token(NOT); + break; + } + default: + jj_la1[66] = jj_gen;; + } + jj_consume_token(LIKE); + strExpr2 = StringExpression(); + Comparison comp = queryFactory.createComparison(strExpr1, (notToken == null) ? ComparisonOperator.LIKE : ComparisonOperator.NOTLIKE, strExpr2); + comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition())); + { + if ("" != null) + return comp; + } + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR: + case PLUS: + case MINUS: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case BOX: + case CENTROID: + case CIRCLE: + case POINT: + case POLYGON: + case REGION: + case CONTAINS: + case INTERSECTS: + case AREA: + case COORD1: + case COORD2: + case COORDSYS: + case DISTANCE: + case ABS: + case CEILING: + case DEGREES: + case EXP: + case FLOOR: + case LOG: + case LOG10: + case MOD: + case PI: + case POWER: + case RADIANS: + case RAND: + case ROUND: + case SQRT: + case TRUNCATE: + case ACOS: + case ASIN: + case ATAN: + case ATAN2: + case COS: + case COT: + case SIN: + case TAN: + case STRING_LITERAL: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = ValueExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case EQUAL: + case NOT_EQUAL: + case LESS_THAN: + case LESS_EQUAL_THAN: + case GREATER_THAN: + case GREATER_EQUAL_THAN:{ + constraint = ComparisonEnd(op); + break; + } + default: + jj_la1[67] = jj_gen; + if (jj_2_15(2)){ + constraint = BetweenEnd(op); + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT: + case IN:{ + constraint = InEnd(op); + break; + } + default: + jj_la1[68] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + break; + } + default: + jj_la1[70] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + { + if ("" != null) + return constraint; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Predicate"); + } + } + + final public Comparison ComparisonEnd(ADQLOperand leftOp) throws ParseException{ + trace_call("ComparisonEnd"); + try{ + Token comp; + ADQLOperand rightOp; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case EQUAL:{ + comp = jj_consume_token(EQUAL); + break; + } + case NOT_EQUAL:{ + comp = jj_consume_token(NOT_EQUAL); + break; + } + case LESS_THAN:{ + comp = jj_consume_token(LESS_THAN); + break; + } + case LESS_EQUAL_THAN:{ + comp = jj_consume_token(LESS_EQUAL_THAN); + break; + } + case GREATER_THAN:{ + comp = jj_consume_token(GREATER_THAN); + break; + } + case GREATER_EQUAL_THAN:{ + comp = jj_consume_token(GREATER_EQUAL_THAN); + break; + } + default: + jj_la1[71] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + rightOp = ValueExpression(); + try{ + Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp); + comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition())); + { + if ("" != null) + return comparison; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("ComparisonEnd"); + } + } + + final public Between BetweenEnd(ADQLOperand leftOp) throws ParseException{ + trace_call("BetweenEnd"); + try{ + Token start, notToken = null; + ADQLOperand min, max; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT:{ + notToken = jj_consume_token(NOT); + break; + } + default: + jj_la1[72] = jj_gen;; + } + start = jj_consume_token(BETWEEN); + min = ValueExpression(); + jj_consume_token(AND); + max = ValueExpression(); + try{ + Between bet = queryFactory.createBetween((notToken != null), leftOp, min, max); + if (notToken != null) + start = notToken; + bet.setPosition(new TextPosition(start.beginLine, start.beginColumn, max.getPosition().endLine, max.getPosition().endColumn)); + { + if ("" != null) + return bet; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("BetweenEnd"); + } + } + + final public In InEnd(ADQLOperand leftOp) throws ParseException{ + trace_call("InEnd"); + try{ + Token not = null, start; + ADQLQuery q = null; + ADQLOperand item; + Vector items = new Vector(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case NOT:{ + not = jj_consume_token(NOT); + break; + } + default: + jj_la1[73] = jj_gen;; + } + start = jj_consume_token(IN); + if (jj_2_18(2)){ + q = SubQueryExpression(); + }else{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR:{ + jj_consume_token(LEFT_PAR); + item = ValueExpression(); + items.add(item); + label_11: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; + break; + } + default: + jj_la1[74] = jj_gen; + break label_11; + } + jj_consume_token(COMMA); + item = ValueExpression(); + items.add(item); + } + jj_consume_token(RIGHT_PAR); + break; + } + default: + jj_la1[75] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + try{ + In in; + start = (not != null) ? not : start; + if (q != null){ + in = queryFactory.createIn(leftOp, q, not != null); + in.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn)); + }else{ + ADQLOperand[] list = new ADQLOperand[items.size()]; + int i = 0; + for(ADQLOperand op : items) + list[i++] = op; + in = queryFactory.createIn(leftOp, list, not != null); + in.setPosition(new TextPosition(start.beginLine, start.beginColumn, list[list.length - 1].getPosition().endLine, list[list.length - 1].getPosition().endColumn)); + } + { + if ("" != null) + return in; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("InEnd"); + } + } + + /* ************* */ + /* SQL FUNCTIONS */ + /* ************* */ + final public SQLFunction SqlFunction() throws ParseException{ + trace_call("SqlFunction"); + try{ + Token fct, all = null, distinct = null, end; + ADQLOperand op = null; + SQLFunction funct = null; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COUNT:{ + fct = jj_consume_token(COUNT); + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case QUANTIFIER:{ + distinct = jj_consume_token(QUANTIFIER); + break; + } + default: + jj_la1[76] = jj_gen;; + } + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ASTERISK:{ + all = jj_consume_token(ASTERISK); + break; + } + case LEFT_PAR: + case PLUS: + case MINUS: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case BOX: + case CENTROID: + case CIRCLE: + case POINT: + case POLYGON: + case REGION: + case CONTAINS: + case INTERSECTS: + case AREA: + case COORD1: + case COORD2: + case COORDSYS: + case DISTANCE: + case ABS: + case CEILING: + case DEGREES: + case EXP: + case FLOOR: + case LOG: + case LOG10: + case MOD: + case PI: + case POWER: + case RADIANS: + case RAND: + case ROUND: + case SQRT: + case TRUNCATE: + case ACOS: + case ASIN: + case ATAN: + case ATAN2: + case COS: + case COT: + case SIN: + case TAN: + case STRING_LITERAL: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = ValueExpression(); + break; + } + default: + jj_la1[77] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + end = jj_consume_token(RIGHT_PAR); + funct = queryFactory.createSQLFunction((all != null) ? SQLFunctionType.COUNT_ALL : SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); + funct.setPosition(new TextPosition(fct, end)); + break; + } + case AVG: + case MAX: + case MIN: + case SUM:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case AVG:{ + fct = jj_consume_token(AVG); + break; + } + case MAX:{ + fct = jj_consume_token(MAX); + break; + } + case MIN:{ + fct = jj_consume_token(MIN); + break; + } + case SUM:{ + fct = jj_consume_token(SUM); + break; + } + default: + jj_la1[78] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case QUANTIFIER:{ + distinct = jj_consume_token(QUANTIFIER); + break; + } + default: + jj_la1[79] = jj_gen;; + } + op = ValueExpression(); + end = jj_consume_token(RIGHT_PAR); + funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); + funct.setPosition(new TextPosition(fct, end)); + break; + } + default: + jj_la1[80] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + { + if ("" != null) + return funct; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("SqlFunction"); + } + } + + /* ************** */ + /* ADQL FUNCTIONS */ + /* ************** */ + final public ADQLOperand[] Coordinates() throws ParseException{ + trace_call("Coordinates"); + try{ + ADQLOperand[] ops = new ADQLOperand[2]; + ops[0] = NumericExpression(); + jj_consume_token(COMMA); + ops[1] = NumericExpression(); + { + if ("" != null) + return ops; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Coordinates"); + } + } + + final public GeometryFunction GeometryFunction() throws ParseException{ + trace_call("GeometryFunction"); + try{ + Token fct = null, end; + GeometryValue gvf1, gvf2; + GeometryValue gvp1, gvp2; + GeometryFunction gf = null; + PointFunction p1 = null, p2 = null; + ADQLColumn col1 = null, col2 = null; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case CONTAINS: + case INTERSECTS:{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case CONTAINS:{ + fct = jj_consume_token(CONTAINS); + break; + } + case INTERSECTS:{ + fct = jj_consume_token(INTERSECTS); + break; + } + default: + jj_la1[81] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + jj_consume_token(LEFT_PAR); + gvf1 = GeometryExpression(); + jj_consume_token(COMMA); + gvf2 = GeometryExpression(); + end = jj_consume_token(RIGHT_PAR); + if (fct.image.equalsIgnoreCase("contains")) + gf = queryFactory.createContains(gvf1, gvf2); + else + gf = queryFactory.createIntersects(gvf1, gvf2); + break; + } + case AREA:{ + fct = jj_consume_token(AREA); + jj_consume_token(LEFT_PAR); + gvf1 = GeometryExpression(); + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createArea(gvf1); + break; + } + case COORD1:{ + fct = jj_consume_token(COORD1); + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case POINT:{ + p1 = Point(); + gf = queryFactory.createCoord1(p1); + break; + } + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + col1 = Column(); + col1.setExpectedType('G'); + gf = queryFactory.createCoord1(col1); + break; + } + default: + jj_la1[82] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + end = jj_consume_token(RIGHT_PAR); + break; + } + case COORD2:{ + fct = jj_consume_token(COORD2); + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case POINT:{ + p1 = Point(); + gf = queryFactory.createCoord2(p1); + break; + } + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + col1 = Column(); + col1.setExpectedType('G'); + gf = queryFactory.createCoord2(col1); + break; + } + default: + jj_la1[83] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + end = jj_consume_token(RIGHT_PAR); + break; + } + case DISTANCE:{ + fct = jj_consume_token(DISTANCE); + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case POINT:{ + p1 = Point(); + break; + } + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + col1 = Column(); + break; + } + default: + jj_la1[84] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + if (p1 != null) + gvp1 = new GeometryValue(p1); + else{ + col1.setExpectedType('G'); + gvp1 = new GeometryValue(col1); + } + jj_consume_token(COMMA); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case POINT:{ + p2 = Point(); + break; + } + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER:{ + col2 = Column(); break; + } default: - jj_la1[88] = jj_gen; - break label_12; + jj_la1[85] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); } + if (p2 != null) + gvp2 = new GeometryValue(p2); + else{ + col2.setExpectedType('G'); + gvp2 = new GeometryValue(col2); + } + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createDistance(gvp1, gvp2); + break; + } + default: + jj_la1[86] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + gf.setPosition(new TextPosition(fct, end)); + { + if ("" != null) + return gf; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("GeometryFunction"); + } + } + + final public ADQLOperand CoordinateSystem() throws ParseException{ + trace_call("CoordinateSystem"); + try{ + ADQLOperand coordSys = null; + coordSys = StringExpression(); + { + if ("" != null) + return coordSys; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("CoordinateSystem"); + } + } + + final public GeometryFunction GeometryValueFunction() throws ParseException{ + trace_call("GeometryValueFunction"); + try{ + Token fct = null, end = null; + ADQLOperand coordSys; + ADQLOperand width, height; + ADQLOperand[] coords, tmp; + Vector vCoords; + ADQLOperand op = null; + GeometryValue gvf = null; + GeometryFunction gf = null; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case BOX:{ + fct = jj_consume_token(BOX); + jj_consume_token(LEFT_PAR); + coordSys = CoordinateSystem(); + jj_consume_token(COMMA); + coords = Coordinates(); + jj_consume_token(COMMA); + width = NumericExpression(); + jj_consume_token(COMMA); + height = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height); + break; + } + case CENTROID:{ + fct = jj_consume_token(CENTROID); + jj_consume_token(LEFT_PAR); + gvf = GeometryExpression(); + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createCentroid(gvf); + break; + } + case CIRCLE:{ + fct = jj_consume_token(CIRCLE); + jj_consume_token(LEFT_PAR); + coordSys = CoordinateSystem(); + jj_consume_token(COMMA); + coords = Coordinates(); + jj_consume_token(COMMA); + width = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width); + break; + } + case POINT:{ + gf = Point(); + break; + } + case POLYGON:{ + fct = jj_consume_token(POLYGON); + jj_consume_token(LEFT_PAR); + coordSys = CoordinateSystem(); + vCoords = new Vector(); + jj_consume_token(COMMA); + tmp = Coordinates(); + vCoords.add(tmp[0]); + vCoords.add(tmp[1]); + jj_consume_token(COMMA); + tmp = Coordinates(); + vCoords.add(tmp[0]); + vCoords.add(tmp[1]); jj_consume_token(COMMA); tmp = Coordinates(); vCoords.add(tmp[0]); vCoords.add(tmp[1]); + label_12: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; + break; + } + default: + jj_la1[87] = jj_gen; + break label_12; + } + jj_consume_token(COMMA); + tmp = Coordinates(); + vCoords.add(tmp[0]); + vCoords.add(tmp[1]); + } + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createPolygon(coordSys, vCoords); + break; + } + case REGION:{ + fct = jj_consume_token(REGION); + jj_consume_token(LEFT_PAR); + op = StringExpression(); + end = jj_consume_token(RIGHT_PAR); + gf = queryFactory.createRegion(op); + break; } - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createPolygon(coordSys, vCoords); + default: + jj_la1[88] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + if (fct != null && end != null) // = !(gf instanceof Point) + gf.setPosition(new TextPosition(fct, end)); + { + if ("" != null) + return gf; + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("GeometryValueFunction"); + } + } + + final public PointFunction Point() throws ParseException{ + trace_call("Point"); + try{ + Token start, end; + ADQLOperand coordSys; + ADQLOperand[] coords; + start = jj_consume_token(POINT); + jj_consume_token(LEFT_PAR); + coordSys = CoordinateSystem(); + jj_consume_token(COMMA); + coords = Coordinates(); + end = jj_consume_token(RIGHT_PAR); + try{ + PointFunction pf = queryFactory.createPoint(coordSys, coords[0], coords[1]); + pf.setPosition(new TextPosition(start, end)); + { + if ("" != null) + return pf; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("Point"); + } + } + + final public GeometryFunction ExtractCoordSys() throws ParseException{ + trace_call("ExtractCoordSys"); + try{ + Token start, end; + GeometryValue gvf; + start = jj_consume_token(COORDSYS); + jj_consume_token(LEFT_PAR); + gvf = GeometryExpression(); + end = jj_consume_token(RIGHT_PAR); + try{ + GeometryFunction gf = queryFactory.createExtractCoordSys(gvf); + gf.setPosition(new TextPosition(start, end)); + { + if ("" != null) + return gf; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("ExtractCoordSys"); + } + } + + /* ***************** */ + /* NUMERIC FUNCTIONS */ + /* ***************** */ + final public ADQLFunction NumericFunction() throws ParseException{ + trace_call("NumericFunction"); + try{ + ADQLFunction fct; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ABS: + case CEILING: + case DEGREES: + case EXP: + case FLOOR: + case LOG: + case LOG10: + case MOD: + case PI: + case POWER: + case RADIANS: + case RAND: + case ROUND: + case SQRT: + case TRUNCATE:{ + fct = MathFunction(); break; - case REGION: - jj_consume_token(REGION); - jj_consume_token(LEFT_PAR); - op = StringExpression(); - jj_consume_token(RIGHT_PAR); - gf = queryFactory.createRegion(op); + } + case ACOS: + case ASIN: + case ATAN: + case ATAN2: + case COS: + case COT: + case SIN: + case TAN:{ + fct = TrigFunction(); + break; + } + case CONTAINS: + case INTERSECTS: + case AREA: + case COORD1: + case COORD2: + case DISTANCE:{ + fct = GeometryFunction(); + break; + } + case REGULAR_IDENTIFIER:{ + fct = UserDefinedFunction(); + ((UserDefinedFunction)fct).setExpectedType('N'); break; + } default: jj_la1[89] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - }catch(Exception ex){ { - if (true) - throw generateParseException(ex); - } - } - { - if (true) - return gf; - } - throw new Error("Missing return statement in function"); - } - - final public PointFunction Point() throws ParseException{ - ADQLOperand coordSys; - ADQLOperand[] coords; - jj_consume_token(POINT); - jj_consume_token(LEFT_PAR); - coordSys = CoordinateSystem(); - jj_consume_token(COMMA); - coords = Coordinates(); - jj_consume_token(RIGHT_PAR); - try{ - { - if (true) - return queryFactory.createPoint(coordSys, coords[0], coords[1]); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + if ("" != null) + return fct; } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("NumericFunction"); } - throw new Error("Missing return statement in function"); } - final public GeometryFunction ExtractCoordSys() throws ParseException{ - GeometryValue gvf; - jj_consume_token(COORDSYS); - jj_consume_token(LEFT_PAR); - gvf = GeometryExpression(); - jj_consume_token(RIGHT_PAR); + final public MathFunction MathFunction() throws ParseException{ + trace_call("MathFunction"); try{ - { - if (true) - return queryFactory.createExtractCoordSys(gvf); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + Token fct = null, end; + ADQLOperand param1 = null, param2 = null; + NumericConstant integerValue = null; + try{ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ABS:{ + fct = jj_consume_token(ABS); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case CEILING:{ + fct = jj_consume_token(CEILING); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case DEGREES:{ + fct = jj_consume_token(DEGREES); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case EXP:{ + fct = jj_consume_token(EXP); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case FLOOR:{ + fct = jj_consume_token(FLOOR); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case LOG:{ + fct = jj_consume_token(LOG); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case LOG10:{ + fct = jj_consume_token(LOG10); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case MOD:{ + fct = jj_consume_token(MOD); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + jj_consume_token(COMMA); + param2 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case PI:{ + fct = jj_consume_token(PI); + jj_consume_token(LEFT_PAR); + end = jj_consume_token(RIGHT_PAR); + break; + } + case POWER:{ + fct = jj_consume_token(POWER); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + jj_consume_token(COMMA); + param2 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case RADIANS:{ + fct = jj_consume_token(RADIANS); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case RAND:{ + fct = jj_consume_token(RAND); + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR: + case PLUS: + case MINUS: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case CONTAINS: + case INTERSECTS: + case AREA: + case COORD1: + case COORD2: + case DISTANCE: + case ABS: + case CEILING: + case DEGREES: + case EXP: + case FLOOR: + case LOG: + case LOG10: + case MOD: + case PI: + case POWER: + case RADIANS: + case RAND: + case ROUND: + case SQRT: + case TRUNCATE: + case ACOS: + case ASIN: + case ATAN: + case ATAN2: + case COS: + case COT: + case SIN: + case TAN: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + param1 = NumericExpression(); + break; + } + default: + jj_la1[90] = jj_gen;; + } + end = jj_consume_token(RIGHT_PAR); + break; + } + case ROUND:{ + fct = jj_consume_token(ROUND); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + jj_consume_token(COMMA); + param2 = SignedInteger(); + break; + } + default: + jj_la1[91] = jj_gen;; + } + end = jj_consume_token(RIGHT_PAR); + break; + } + case SQRT:{ + fct = jj_consume_token(SQRT); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); + break; + } + case TRUNCATE:{ + fct = jj_consume_token(TRUNCATE); + jj_consume_token(LEFT_PAR); + param1 = NumericExpression(); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + jj_consume_token(COMMA); + param2 = SignedInteger(); + break; + } + default: + jj_la1[92] = jj_gen;; + } + end = jj_consume_token(RIGHT_PAR); + break; + } + default: + jj_la1[93] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); + mf.setPosition(new TextPosition(fct, end)); + { + if ("" != null) + return mf; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("MathFunction"); } - throw new Error("Missing return statement in function"); - } - - /* ***************** */ - /* NUMERIC FUNCTIONS */ - /* ***************** */ - final public ADQLFunction NumericFunction() throws ParseException{ - ADQLFunction fct; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - fct = MathFunction(); - break; - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - fct = TrigFunction(); - break; - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case DISTANCE: - fct = GeometryFunction(); - break; - case REGULAR_IDENTIFIER: - fct = UserDefinedFunction(); - ((UserDefinedFunction)fct).setExpectedType('N'); - break; - default: - jj_la1[90] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - { - if (true) - return fct; - } - throw new Error("Missing return statement in function"); } - final public MathFunction MathFunction() throws ParseException{ - Token fct = null; - ADQLOperand param1 = null, param2 = null; - String integerValue = null; + final public MathFunction TrigFunction() throws ParseException{ + trace_call("TrigFunction"); try{ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ABS: - fct = jj_consume_token(ABS); + Token fct = null, end; + ADQLOperand param1 = null, param2 = null; + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case ACOS:{ + fct = jj_consume_token(ACOS); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; - case CEILING: - fct = jj_consume_token(CEILING); + } + case ASIN:{ + fct = jj_consume_token(ASIN); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; - case DEGREES: - fct = jj_consume_token(DEGREES); + } + case ATAN:{ + fct = jj_consume_token(ATAN); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; - case EXP: - fct = jj_consume_token(EXP); + } + case ATAN2:{ + fct = jj_consume_token(ATAN2); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + jj_consume_token(COMMA); + param2 = NumericExpression(); + end = jj_consume_token(RIGHT_PAR); break; - case FLOOR: - fct = jj_consume_token(FLOOR); + } + case COS:{ + fct = jj_consume_token(COS); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; - case LOG: - fct = jj_consume_token(LOG); + } + case COT:{ + fct = jj_consume_token(COT); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; - case LOG10: - fct = jj_consume_token(LOG10); + } + case SIN:{ + fct = jj_consume_token(SIN); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; - case MOD: - fct = jj_consume_token(MOD); + } + case TAN:{ + fct = jj_consume_token(TAN); jj_consume_token(LEFT_PAR); param1 = NumericExpression(); - jj_consume_token(COMMA); - param2 = NumericExpression(); - jj_consume_token(RIGHT_PAR); + end = jj_consume_token(RIGHT_PAR); break; + } + default: + jj_la1[94] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + try{ + MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); + mf.setPosition(new TextPosition(fct, end)); + { + if ("" != null) + return mf; + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); + } + } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("TrigFunction"); + } + } + + final public UserDefinedFunction UserDefinedFunction() throws ParseException{ + trace_call("UserDefinedFunction"); + try{ + Token fct, end; + Vector params = new Vector(); + ADQLOperand op; + fct = jj_consume_token(REGULAR_IDENTIFIER); + jj_consume_token(LEFT_PAR); + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case LEFT_PAR: + case PLUS: + case MINUS: + case AVG: + case MAX: + case MIN: + case SUM: + case COUNT: + case BOX: + case CENTROID: + case CIRCLE: + case POINT: + case POLYGON: + case REGION: + case CONTAINS: + case INTERSECTS: + case AREA: + case COORD1: + case COORD2: + case COORDSYS: + case DISTANCE: + case ABS: + case CEILING: + case DEGREES: + case EXP: + case FLOOR: + case LOG: + case LOG10: + case MOD: case PI: - fct = jj_consume_token(PI); - jj_consume_token(LEFT_PAR); - jj_consume_token(RIGHT_PAR); - break; case POWER: - fct = jj_consume_token(POWER); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(COMMA); - param2 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; case RADIANS: - fct = jj_consume_token(RADIANS); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; case RAND: - fct = jj_consume_token(RAND); - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case PLUS: - case MINUS: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case DISTANCE: - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - param1 = NumericExpression(); - break; - default: - jj_la1[91] = jj_gen; - ; - } - jj_consume_token(RIGHT_PAR); - break; case ROUND: - fct = jj_consume_token(ROUND); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - jj_consume_token(COMMA); - integerValue = SignedInteger(); - param2 = queryFactory.createNumericConstant(integerValue); - break; - default: - jj_la1[92] = jj_gen; - ; - } - jj_consume_token(RIGHT_PAR); - break; case SQRT: - fct = jj_consume_token(SQRT); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; case TRUNCATE: - fct = jj_consume_token(TRUNCATE); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - jj_consume_token(COMMA); - integerValue = SignedInteger(); - param2 = queryFactory.createNumericConstant(integerValue); - break; - default: - jj_la1[93] = jj_gen; - ; + case ACOS: + case ASIN: + case ATAN: + case ATAN2: + case COS: + case COT: + case SIN: + case TAN: + case STRING_LITERAL: + case DELIMITED_IDENTIFIER: + case REGULAR_IDENTIFIER: + case SCIENTIFIC_NUMBER: + case UNSIGNED_FLOAT: + case UNSIGNED_INTEGER:{ + op = ValueExpression(); + params.add(op); + label_13: while(true){ + switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk){ + case COMMA:{ + ; + break; + } + default: + jj_la1[95] = jj_gen; + break label_13; + } + jj_consume_token(COMMA); + op = ValueExpression(); + params.add(op); } - jj_consume_token(RIGHT_PAR); break; + } default: - jj_la1[94] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - if (param1 != null){ - if (true) - return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); - }else{ - if (true) - return null; - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); - } - } - throw new Error("Missing return statement in function"); - } - - final public MathFunction TrigFunction() throws ParseException{ - Token fct = null; - ADQLOperand param1 = null, param2 = null; - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case ACOS: - fct = jj_consume_token(ACOS); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case ASIN: - fct = jj_consume_token(ASIN); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case ATAN: - fct = jj_consume_token(ATAN); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case ATAN2: - fct = jj_consume_token(ATAN2); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(COMMA); - param2 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case COS: - fct = jj_consume_token(COS); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case COT: - fct = jj_consume_token(COT); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case SIN: - fct = jj_consume_token(SIN); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - case TAN: - fct = jj_consume_token(TAN); - jj_consume_token(LEFT_PAR); - param1 = NumericExpression(); - jj_consume_token(RIGHT_PAR); - break; - default: - jj_la1[95] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - try{ - if (param1 != null){ - if (true) - return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2); - }else{ - if (true) - return null; - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); + jj_la1[96] = jj_gen;; } - } - throw new Error("Missing return statement in function"); - } - - final public UserDefinedFunction UserDefinedFunction() throws ParseException{ - Token fct; - Vector params = new Vector(); - ADQLOperand op; - fct = jj_consume_token(REGULAR_IDENTIFIER); - jj_consume_token(LEFT_PAR); - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case LEFT_PAR: - case PLUS: - case MINUS: - case AVG: - case MAX: - case MIN: - case SUM: - case COUNT: - case BOX: - case CENTROID: - case CIRCLE: - case POINT: - case POLYGON: - case REGION: - case CONTAINS: - case INTERSECTS: - case AREA: - case COORD1: - case COORD2: - case COORDSYS: - case DISTANCE: - case ABS: - case CEILING: - case DEGREES: - case EXP: - case FLOOR: - case LOG: - case LOG10: - case MOD: - case PI: - case POWER: - case RADIANS: - case RAND: - case ROUND: - case SQRT: - case TRUNCATE: - case ACOS: - case ASIN: - case ATAN: - case ATAN2: - case COS: - case COT: - case SIN: - case TAN: - case STRING_LITERAL: - case DELIMITED_IDENTIFIER: - case REGULAR_IDENTIFIER: - case SCIENTIFIC_NUMBER: - case UNSIGNED_FLOAT: - case UNSIGNED_INTEGER: - op = ValueExpression(); - params.add(op); - label_13: while(true){ - switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){ - case COMMA: - ; - break; - default: - jj_la1[96] = jj_gen; - break label_13; - } - jj_consume_token(COMMA); - op = ValueExpression(); - params.add(op); + end = jj_consume_token(RIGHT_PAR); + //System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !"); + try{ + // Build the parameters list: + ADQLOperand[] parameters = new ADQLOperand[params.size()]; + for(int i = 0; i < params.size(); i++) + parameters[i] = params.get(i); + // Create the UDF function: + UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters); + udf.setPosition(new TextPosition(fct, end)); + { + if ("" != null) + return udf; + } + }catch(UnsupportedOperationException uoe){ + /* This catch clause is just for backward compatibility: + * if the createUserDefinedFunction(...) is overridden and + * the function can not be identified a such exception may be thrown). */ + { + if (true) + throw new ParseException(uoe.getMessage(), new TextPosition(fct, token)); + } + }catch(Exception ex){ + { + if (true) + throw generateParseException(ex); } - break; - default: - jj_la1[97] = jj_gen; - ; - } - jj_consume_token(RIGHT_PAR); - //System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !"); - try{ - // Build the parameters list: - ADQLOperand[] parameters = new ADQLOperand[params.size()]; - for(int i = 0; i < params.size(); i++) - parameters[i] = params.get(i); - - // Create the UDF function: - { - if (true) - return queryFactory.createUserDefinedFunction(fct.image, parameters); - } - }catch(UnsupportedOperationException uoe){ - /* This catch clause is just for backward compatibility: - * if the createUserDefinedFunction(...) is overridden and - * the function can not be identified a such exception may be thrown). */ - { - if (true) - throw new ParseException(uoe.getMessage(), new TextPosition(fct, token)); - } - }catch(Exception ex){ - { - if (true) - throw generateParseException(ex); } + throw new Error("Missing return statement in function"); + }finally{ + trace_return("UserDefinedFunction"); } - throw new Error("Missing return statement in function"); } private boolean jj_2_1(int xla){ @@ -3371,2159 +3954,1614 @@ } } - private boolean jj_3R_185(){ - if (jj_scan_token(NOT)) - return true; - return false; - } - - private boolean jj_3R_146(){ - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_46()) + private boolean jj_2_17(int xla){ + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try{ + return !jj_3_17(); + }catch(LookaheadSuccess ls){ return true; - return false; - } - - private boolean jj_3R_149(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_161()){ - jj_scanpos = xsp; - if (jj_3_1()){ - jj_scanpos = xsp; - if (jj_3R_162()) - return true; - } + }finally{ + jj_save(16, xla); } - return false; - } - - private boolean jj_3R_150(){ - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_149()) - return true; - return false; - } - - private boolean jj_3R_145(){ - if (jj_3R_109()) - return true; - return false; } - private boolean jj_3R_163(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_185()) - jj_scanpos = xsp; - if (jj_3R_186()) + private boolean jj_2_18(int xla){ + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try{ + return !jj_3_18(); + }catch(LookaheadSuccess ls){ return true; - while(true){ - xsp = jj_scanpos; - if (jj_3R_187()){ - jj_scanpos = xsp; - break; - } + }finally{ + jj_save(17, xla); } - return false; - } - - private boolean jj_3R_148(){ - if (jj_scan_token(TOP)) - return true; - if (jj_scan_token(UNSIGNED_INTEGER)) - return true; - return false; - } - - private boolean jj_3R_147(){ - if (jj_scan_token(QUANTIFIER)) - return true; - return false; } - private boolean jj_3R_48(){ - if (jj_scan_token(SELECT)) - return true; + private boolean jj_3R_128(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_147()) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3R_148()) + if (jj_scan_token(99)){ jj_scanpos = xsp; - if (jj_3R_149()) - return true; - while(true){ - xsp = jj_scanpos; - if (jj_3R_150()){ + if (jj_scan_token(100)){ jj_scanpos = xsp; - break; + if (jj_scan_token(101)) + return true; } } return false; } - private boolean jj_3R_144(){ - if (jj_3R_21()) - return true; - return false; - } - - private boolean jj_3R_16(){ - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_31()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3R_53(){ - if (jj_3R_74()) - return true; - return false; - } - - private boolean jj_3R_122(){ + private boolean jj_3R_129(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_144()){ + if (jj_3R_135()){ jj_scanpos = xsp; - if (jj_3R_145()) + if (jj_3R_136()) return true; } return false; } - private boolean jj_3R_55(){ - if (jj_3R_76()) - return true; - return false; - } - - private boolean jj_3_11(){ - if (jj_3R_24()) - return true; - return false; - } - - private boolean jj_3R_54(){ - if (jj_3R_75()) + private boolean jj_3R_113(){ + if (jj_scan_token(LEFT)) return true; return false; } - private boolean jj_3R_35(){ + private boolean jj_3R_73(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_54()){ + if (jj_3R_113()){ jj_scanpos = xsp; - if (jj_3_11()){ + if (jj_3R_114()){ jj_scanpos = xsp; - if (jj_3R_55()) + if (jj_3R_115()) return true; } } return false; } - private boolean jj_3R_133(){ - if (jj_3R_155()) - return true; - return false; - } - - private boolean jj_3R_132(){ - if (jj_3R_154()) - return true; - return false; - } - - private boolean jj_3R_131(){ - if (jj_3R_153()) - return true; - return false; - } - - private boolean jj_3R_130(){ - if (jj_3R_152()) - return true; - return false; - } - - private boolean jj_3R_123(){ - if (jj_3R_46()) - return true; + private boolean jj_3R_54(){ Token xsp; - while(true){ - xsp = jj_scanpos; - if (jj_3R_146()){ - jj_scanpos = xsp; - break; - } + xsp = jj_scanpos; + if (jj_scan_token(25)){ + jj_scanpos = xsp; + if (jj_3R_73()) + return true; } return false; } - private boolean jj_3R_47(){ - if (jj_scan_token(CONCAT)) - return true; - if (jj_3R_35()) - return true; - return false; - } - - private boolean jj_3R_174(){ - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_191()) - return true; - return false; - } - - private boolean jj_3R_173(){ - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_191()) + private boolean jj_3R_44(){ + if (jj_scan_token(STRING_LITERAL)) return true; return false; } - private boolean jj_3R_31(){ - if (jj_3R_48()) - return true; - if (jj_3R_129()) - return true; + private boolean jj_3R_23(){ Token xsp; - xsp = jj_scanpos; - if (jj_3R_130()) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3R_131()) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3R_132()) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3R_133()) - jj_scanpos = xsp; - return false; - } - - private boolean jj_3R_27(){ - if (jj_3R_35()) + if (jj_3R_44()) return true; - Token xsp; while(true){ xsp = jj_scanpos; - if (jj_3R_47()){ + if (jj_3R_44()){ jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3R_73(){ - if (jj_scan_token(MINUS)) - return true; + } return false; } - private boolean jj_3_10(){ - if (jj_3R_23()) + private boolean jj_3R_116(){ + if (jj_scan_token(LEFT)) return true; return false; } - private boolean jj_3R_52(){ + private boolean jj_3R_74(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(8)){ + if (jj_3R_116()){ jj_scanpos = xsp; - if (jj_3R_73()) - return true; + if (jj_3R_117()){ + jj_scanpos = xsp; + if (jj_3R_118()) + return true; + } } - return false; - } - - private boolean jj_3R_168(){ - Token xsp; xsp = jj_scanpos; - if (jj_scan_token(10)){ + if (jj_scan_token(26)) jj_scanpos = xsp; - if (jj_scan_token(11)) - return true; - } - if (jj_3R_135()) - return true; return false; } - private boolean jj_3R_112(){ - if (jj_scan_token(FULL)) + private boolean jj_3_18(){ + if (jj_3R_16()) return true; return false; } - private boolean jj_3R_34(){ + private boolean jj_3R_55(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_52()) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3_10()){ + if (jj_scan_token(25)){ jj_scanpos = xsp; - if (jj_3R_53()) + if (jj_3R_74()) return true; } return false; } - private boolean jj_3R_24(){ - if (jj_scan_token(REGULAR_IDENTIFIER)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; + private boolean jj_3R_35(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_123()) + if (jj_3R_55()) jj_scanpos = xsp; - if (jj_scan_token(RIGHT_PAR)) + if (jj_scan_token(JOIN)) + return true; + if (jj_3R_56()) return true; return false; } - private boolean jj_3R_156(){ + private boolean jj_3R_34(){ + if (jj_scan_token(NATURAL)) + return true; Token xsp; xsp = jj_scanpos; - if (jj_scan_token(8)){ + if (jj_3R_54()) jj_scanpos = xsp; - if (jj_scan_token(9)) - return true; - } - if (jj_3R_108()) + if (jj_scan_token(JOIN)) return true; return false; } - private boolean jj_3R_19(){ - if (jj_3R_34()) - return true; + private boolean jj_3R_28(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(8)){ + if (jj_scan_token(36)) jj_scanpos = xsp; - if (jj_scan_token(9)){ - jj_scanpos = xsp; - if (jj_scan_token(10)){ - jj_scanpos = xsp; - if (jj_scan_token(11)) - return true; - } - } - } - return false; - } - - private boolean jj_3R_172(){ - if (jj_3R_108()) + if (jj_scan_token(BETWEEN)) + return true; + if (jj_3R_51()) return true; return false; } - private boolean jj_3R_20(){ - if (jj_3R_35()) - return true; - if (jj_scan_token(CONCAT)) + private boolean jj_3_15(){ + if (jj_3R_28()) return true; return false; } - private boolean jj_3R_135(){ - if (jj_3R_34()) - return true; + private boolean jj_3R_17(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_168()) + if (jj_3R_34()){ jj_scanpos = xsp; + if (jj_3R_35()) + return true; + } return false; } - private boolean jj_3R_100(){ - if (jj_scan_token(TAN)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) + private boolean jj_3_17(){ + if (jj_3R_29()) return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3_9(){ - if (jj_3R_22()) + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(36)) + jj_scanpos = xsp; + if (jj_scan_token(LIKE)) return true; return false; } - private boolean jj_3R_99(){ - if (jj_scan_token(SIN)) - return true; + private boolean jj_3R_76(){ if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; return false; } - private boolean jj_3_8(){ - if (jj_3R_21()) + private boolean jj_3_3(){ + if (jj_3R_17()) return true; return false; } - private boolean jj_3R_98(){ - if (jj_scan_token(COT)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3_16(){ + if (jj_3R_22()) return true; - return false; - } - - private boolean jj_3R_115(){ - if (jj_scan_token(FULL)) + if (jj_scan_token(IS)) return true; return false; } - private boolean jj_3R_97(){ - if (jj_scan_token(COS)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3_2(){ + if (jj_3R_16()) return true; return false; } - private boolean jj_3_7(){ - if (jj_scan_token(REGULAR_IDENTIFIER)) - return true; - if (jj_scan_token(LEFT_PAR)) + private boolean jj_3R_75(){ + if (jj_3R_79()) return true; return false; } - private boolean jj_3R_96(){ - if (jj_scan_token(ATAN2)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; + private boolean jj_3R_134(){ if (jj_scan_token(COMMA)) return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3_6(){ - if (jj_scan_token(LEFT_PAR)) - return true; - return false; - } - - private boolean jj_3R_95(){ - if (jj_scan_token(ATAN)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_51()) return true; return false; } - private boolean jj_3_5(){ - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(63)){ - jj_scanpos = xsp; - if (jj_3R_20()) - return true; - } - return false; - } - - private boolean jj_3R_94(){ - if (jj_scan_token(ASIN)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3R_27(){ + if (jj_3R_51()) return true; return false; } - private boolean jj_3_4(){ + private boolean jj_3R_56(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_18()){ + if (jj_3R_75()){ jj_scanpos = xsp; - if (jj_3R_19()) - return true; + if (jj_3_2()){ + jj_scanpos = xsp; + if (jj_3R_76()) + return true; + } } return false; } - private boolean jj_3R_18(){ + private boolean jj_3_14(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(8)){ + if (jj_scan_token(42)){ jj_scanpos = xsp; - if (jj_scan_token(9)) + if (jj_3R_27()) return true; } return false; } - private boolean jj_3R_93(){ - if (jj_scan_token(ACOS)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) + private boolean jj_3R_60(){ + if (jj_scan_token(DOT)) return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_79()) return true; return false; } - private boolean jj_3R_58(){ + private boolean jj_3R_120(){ + if (jj_3R_51()) + return true; Token xsp; - xsp = jj_scanpos; - if (jj_3R_93()){ - jj_scanpos = xsp; - if (jj_3R_94()){ + while(true){ + xsp = jj_scanpos; + if (jj_3R_134()){ jj_scanpos = xsp; - if (jj_3R_95()){ - jj_scanpos = xsp; - if (jj_3R_96()){ - jj_scanpos = xsp; - if (jj_3R_97()){ - jj_scanpos = xsp; - if (jj_3R_98()){ - jj_scanpos = xsp; - if (jj_3R_99()){ - jj_scanpos = xsp; - if (jj_3R_100()) - return true; - } - } - } - } - } + break; } } return false; } - private boolean jj_3R_69(){ - if (jj_3R_34()) - return true; - return false; - } - - private boolean jj_3R_68(){ - if (jj_3R_35()) - return true; - return false; - } - - private boolean jj_3R_67(){ - if (jj_3R_21()) - return true; - return false; - } - - private boolean jj_3R_108(){ - if (jj_3R_135()) - return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_156()) - jj_scanpos = xsp; - return false; - } - - private boolean jj_3R_92(){ - if (jj_scan_token(TRUNCATE)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_174()) - jj_scanpos = xsp; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3R_66(){ - if (jj_3R_109()) + private boolean jj_3R_22(){ + if (jj_3R_43()) return true; return false; } - private boolean jj_3R_91(){ - if (jj_scan_token(SQRT)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) + private boolean jj_3R_150(){ + if (jj_scan_token(COMMA)) return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_153()) return true; return false; } - private boolean jj_3R_65(){ - if (jj_3R_24()) + private boolean jj_3R_149(){ + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_153()) return true; return false; } - private boolean jj_3R_90(){ - if (jj_scan_token(ROUND)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) + private boolean jj_3R_43(){ + if (jj_3R_14()) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_173()) + if (jj_3R_60()) jj_scanpos = xsp; - if (jj_scan_token(RIGHT_PAR)) - return true; return false; } - private boolean jj_3R_64(){ - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_46()) + private boolean jj_3R_127(){ + if (jj_scan_token(DOT)) return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_14()) return true; return false; } - private boolean jj_3R_89(){ - if (jj_scan_token(RAND)) + private boolean jj_3R_126(){ + if (jj_scan_token(DOT)) return true; - if (jj_scan_token(LEFT_PAR)) + if (jj_3R_14()) + return true; + return false; + } + + private boolean jj_3R_79(){ + if (jj_3R_14()) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_172()) + if (jj_3R_126()) + jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_127()) jj_scanpos = xsp; - if (jj_scan_token(RIGHT_PAR)) - return true; return false; } - private boolean jj_3R_63(){ - if (jj_3R_27()) + private boolean jj_3R_31(){ + if (jj_scan_token(DELIMITED_IDENTIFIER)) return true; return false; } - private boolean jj_3R_88(){ - if (jj_scan_token(RADIANS)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) + private boolean jj_3R_133(){ + if (jj_3R_21()) return true; - if (jj_scan_token(RIGHT_PAR)) + return false; + } + + private boolean jj_3R_30(){ + if (jj_scan_token(REGULAR_IDENTIFIER)) return true; return false; } - private boolean jj_3R_87(){ - if (jj_scan_token(POWER)) + private boolean jj_3R_26(){ + if (jj_scan_token(REGULAR_IDENTIFIER)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_108()) - return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_120()) + jj_scanpos = xsp; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_62(){ - if (jj_3R_108()) + private boolean jj_3R_141(){ + if (jj_3R_112()) return true; return false; } - private boolean jj_3R_86(){ - if (jj_scan_token(PI)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; + private boolean jj_3R_14(){ + Token xsp; + xsp = jj_scanpos; + if (jj_3R_30()){ + jj_scanpos = xsp; + if (jj_3R_31()) + return true; + } return false; } - private boolean jj_3R_111(){ - if (jj_scan_token(RIGHT)) + private boolean jj_3R_132(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_85(){ - if (jj_scan_token(MOD)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; + private boolean jj_3R_119(){ + Token xsp; + xsp = jj_scanpos; + if (jj_3R_132()){ + jj_scanpos = xsp; + if (jj_3R_133()) + return true; + } return false; } - private boolean jj_3R_84(){ - if (jj_scan_token(LOG10)) + private boolean jj_3R_106(){ + if (jj_scan_token(TAN)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_83(){ - if (jj_scan_token(LOG)) + private boolean jj_3R_105(){ + if (jj_scan_token(SIN)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_82(){ - if (jj_scan_token(FLOOR)) + private boolean jj_3R_104(){ + if (jj_scan_token(COT)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_81(){ - if (jj_scan_token(EXP)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3R_58(){ + if (jj_3R_78()) return true; return false; } - private boolean jj_3R_80(){ - if (jj_scan_token(DEGREES)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3_13(){ + if (jj_3R_26()) return true; return false; } - private boolean jj_3R_126(){ + private boolean jj_3R_103(){ + if (jj_scan_token(COS)) + return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_27()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_79(){ - if (jj_scan_token(CEILING)) + private boolean jj_3R_102(){ + if (jj_scan_token(ATAN2)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) + if (jj_3R_112()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_125(){ - if (jj_3R_21()) + private boolean jj_3R_57(){ + if (jj_3R_77()) return true; return false; } - private boolean jj_3R_78(){ - if (jj_scan_token(ABS)) + private boolean jj_3R_101(){ + if (jj_scan_token(ATAN)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_46(){ + private boolean jj_3R_36(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_62()){ + if (jj_3R_57()){ jj_scanpos = xsp; - if (jj_3R_63()){ + if (jj_3_13()){ jj_scanpos = xsp; - if (jj_3R_64()){ - jj_scanpos = xsp; - if (jj_3R_65()){ - jj_scanpos = xsp; - if (jj_3R_66()){ - jj_scanpos = xsp; - if (jj_3R_67()){ - jj_scanpos = xsp; - if (jj_3R_68()){ - jj_scanpos = xsp; - if (jj_3R_69()) - return true; - } - } - } - } - } + if (jj_3R_58()) + return true; } } return false; } - private boolean jj_3R_124(){ - if (jj_3R_22()) + private boolean jj_3R_100(){ + if (jj_scan_token(ASIN)) return true; - return false; - } - - private boolean jj_3R_57(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_78()){ - jj_scanpos = xsp; - if (jj_3R_79()){ - jj_scanpos = xsp; - if (jj_3R_80()){ - jj_scanpos = xsp; - if (jj_3R_81()){ - jj_scanpos = xsp; - if (jj_3R_82()){ - jj_scanpos = xsp; - if (jj_3R_83()){ - jj_scanpos = xsp; - if (jj_3R_84()){ - jj_scanpos = xsp; - if (jj_3R_85()){ - jj_scanpos = xsp; - if (jj_3R_86()){ - jj_scanpos = xsp; - if (jj_3R_87()){ - jj_scanpos = xsp; - if (jj_3R_88()){ - jj_scanpos = xsp; - if (jj_3R_89()){ - jj_scanpos = xsp; - if (jj_3R_90()){ - jj_scanpos = xsp; - if (jj_3R_91()){ - jj_scanpos = xsp; - if (jj_3R_92()) - return true; - } - } - } - } - } - } - } - } - } - } - } - } - } - } - return false; - } - - private boolean jj_3R_121(){ if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_108()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_120(){ - if (jj_3R_143()) - return true; - return false; - } - - private boolean jj_3R_41(){ - if (jj_3R_24()) - return true; - return false; - } - - private boolean jj_3R_76(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_124()){ - jj_scanpos = xsp; - if (jj_3R_125()){ - jj_scanpos = xsp; - if (jj_3R_126()) - return true; - } - } - return false; - } - - private boolean jj_3R_40(){ - if (jj_3R_59()) - return true; - return false; - } - - private boolean jj_3R_114(){ - if (jj_scan_token(RIGHT)) - return true; - return false; - } - - private boolean jj_3R_119(){ - if (jj_3R_21()) + private boolean jj_3R_99(){ + if (jj_scan_token(ACOS)) return true; - return false; - } - - private boolean jj_3R_39(){ - if (jj_3R_58()) + if (jj_scan_token(LEFT_PAR)) return true; - return false; - } - - private boolean jj_3R_118(){ - if (jj_3R_142()) + if (jj_3R_112()) return true; - return false; - } - - private boolean jj_3R_38(){ - if (jj_3R_57()) + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_23(){ + private boolean jj_3R_64(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_38()){ + if (jj_3R_99()){ jj_scanpos = xsp; - if (jj_3R_39()){ + if (jj_3R_100()){ jj_scanpos = xsp; - if (jj_3R_40()){ + if (jj_3R_101()){ jj_scanpos = xsp; - if (jj_3R_41()) - return true; + if (jj_3R_102()){ + jj_scanpos = xsp; + if (jj_3R_103()){ + jj_scanpos = xsp; + if (jj_3R_104()){ + jj_scanpos = xsp; + if (jj_3R_105()){ + jj_scanpos = xsp; + if (jj_3R_106()) + return true; + } + } + } + } } } } return false; } - private boolean jj_3R_201(){ - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_14()) + private boolean jj_3R_46(){ + if (jj_3R_62()) return true; return false; } - private boolean jj_3R_74(){ + private boolean jj_3R_98(){ + if (jj_scan_token(TRUNCATE)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_118()){ + if (jj_3R_150()) jj_scanpos = xsp; - if (jj_3R_119()){ - jj_scanpos = xsp; - if (jj_3R_120()){ - jj_scanpos = xsp; - if (jj_3R_121()) - return true; - } - } - } + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3R_110(){ - if (jj_scan_token(LEFT)) + private boolean jj_3R_97(){ + if (jj_scan_token(SQRT)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_70(){ + private boolean jj_3R_96(){ + if (jj_scan_token(ROUND)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_110()){ - jj_scanpos = xsp; - if (jj_3R_111()){ - jj_scanpos = xsp; - if (jj_3R_112()) - return true; - } - } - xsp = jj_scanpos; - if (jj_scan_token(25)) + if (jj_3R_149()) jj_scanpos = xsp; + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3R_75(){ - if (jj_scan_token(COORDSYS)) + private boolean jj_3R_95(){ + if (jj_scan_token(RAND)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_122()) - return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_141()) + jj_scanpos = xsp; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_178(){ - if (jj_3R_21()) + private boolean jj_3R_94(){ + if (jj_scan_token(RADIANS)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_171(){ + private boolean jj_3R_93(){ + if (jj_scan_token(POWER)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; if (jj_scan_token(COMMA)) return true; - if (jj_3R_170()) + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_176(){ - if (jj_3R_21()) + private boolean jj_3R_92(){ + if (jj_scan_token(PI)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_197(){ - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(8)){ - jj_scanpos = xsp; - if (jj_scan_token(9)) - return true; - } + private boolean jj_3R_91(){ + if (jj_scan_token(MOD)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3R_191(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_197()) - jj_scanpos = xsp; - if (jj_scan_token(UNSIGNED_INTEGER)) + private boolean jj_3R_90(){ + if (jj_scan_token(LOG10)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_49(){ - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(24)){ - jj_scanpos = xsp; - if (jj_3R_70()) - return true; - } + private boolean jj_3R_89(){ + if (jj_scan_token(LOG)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3R_141(){ - if (jj_scan_token(REGION)) + private boolean jj_3R_88(){ + if (jj_scan_token(FLOOR)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_27()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_158(){ - if (jj_scan_token(POINT)) + private boolean jj_3R_87(){ + if (jj_scan_token(EXP)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_169()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_170()) + if (jj_3R_112()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_142(){ - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(99)){ - jj_scanpos = xsp; - if (jj_scan_token(100)){ - jj_scanpos = xsp; - if (jj_scan_token(101)) - return true; - } - } + private boolean jj_3R_52(){ + if (jj_scan_token(CONCAT)) + return true; + if (jj_3R_36()) + return true; return false; } - private boolean jj_3R_200(){ - if (jj_scan_token(USING)) + private boolean jj_3R_86(){ + if (jj_scan_token(DEGREES)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_14()) + if (jj_3R_112()) return true; - Token xsp; - while(true){ - xsp = jj_scanpos; - if (jj_3R_201()){ - jj_scanpos = xsp; - break; - } - } if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_113(){ - if (jj_scan_token(LEFT)) - return true; - return false; - } - - private boolean jj_3R_140(){ - if (jj_scan_token(POLYGON)) + private boolean jj_3R_85(){ + if (jj_scan_token(CEILING)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_169()) + if (jj_3R_112()) return true; - if (jj_scan_token(COMMA)) + if (jj_scan_token(RIGHT_PAR)) return true; - if (jj_3R_170()) + return false; + } + + private boolean jj_3R_84(){ + if (jj_scan_token(ABS)) return true; - if (jj_scan_token(COMMA)) + if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_170()) + if (jj_3R_112()) return true; - if (jj_scan_token(COMMA)) + if (jj_scan_token(RIGHT_PAR)) return true; - if (jj_3R_170()) + return false; + } + + private boolean jj_3R_29(){ + if (jj_3R_36()) return true; Token xsp; while(true){ xsp = jj_scanpos; - if (jj_3R_171()){ + if (jj_3R_52()){ jj_scanpos = xsp; break; } } - if (jj_scan_token(RIGHT_PAR)) + return false; + } + + private boolean jj_3R_63(){ + Token xsp; + xsp = jj_scanpos; + if (jj_3R_84()){ + jj_scanpos = xsp; + if (jj_3R_85()){ + jj_scanpos = xsp; + if (jj_3R_86()){ + jj_scanpos = xsp; + if (jj_3R_87()){ + jj_scanpos = xsp; + if (jj_3R_88()){ + jj_scanpos = xsp; + if (jj_3R_89()){ + jj_scanpos = xsp; + if (jj_3R_90()){ + jj_scanpos = xsp; + if (jj_3R_91()){ + jj_scanpos = xsp; + if (jj_3R_92()){ + jj_scanpos = xsp; + if (jj_3R_93()){ + jj_scanpos = xsp; + if (jj_3R_94()){ + jj_scanpos = xsp; + if (jj_3R_95()){ + jj_scanpos = xsp; + if (jj_3R_96()){ + jj_scanpos = xsp; + if (jj_3R_97()){ + jj_scanpos = xsp; + if (jj_3R_98()) + return true; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_61(){ + if (jj_scan_token(MINUS)) + return true; + return false; + } + + private boolean jj_3R_50(){ + if (jj_3R_26()) + return true; + return false; + } + + private boolean jj_3R_49(){ + if (jj_3R_65()) + return true; + return false; + } + + private boolean jj_3R_48(){ + if (jj_3R_64()) + return true; + return false; + } + + private boolean jj_3R_47(){ + if (jj_3R_63()) return true; return false; } - private boolean jj_3R_71(){ + private boolean jj_3R_25(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_113()){ + if (jj_3R_47()){ jj_scanpos = xsp; - if (jj_3R_114()){ + if (jj_3R_48()){ jj_scanpos = xsp; - if (jj_3R_115()) - return true; + if (jj_3R_49()){ + jj_scanpos = xsp; + if (jj_3R_50()) + return true; + } } } - xsp = jj_scanpos; - if (jj_scan_token(25)) - jj_scanpos = xsp; return false; } - private boolean jj_3R_199(){ - if (jj_scan_token(ON)) - return true; - if (jj_3R_163()) + private boolean jj_3R_32(){ + if (jj_3R_14()) return true; - return false; - } - - private boolean jj_3R_139(){ - if (jj_3R_158()) + if (jj_scan_token(DOT)) return true; return false; } - private boolean jj_3R_37(){ - if (jj_scan_token(STRING_LITERAL)) + private boolean jj_3_12(){ + if (jj_3R_25()) return true; return false; } - private boolean jj_3R_22(){ + private boolean jj_3R_45(){ Token xsp; - if (jj_3R_37()) - return true; - while(true){ - xsp = jj_scanpos; - if (jj_3R_37()){ - jj_scanpos = xsp; - break; - } + xsp = jj_scanpos; + if (jj_scan_token(9)){ + jj_scanpos = xsp; + if (jj_3R_61()) + return true; } return false; } - private boolean jj_3R_138(){ - if (jj_scan_token(CIRCLE)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_169()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_170()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_108()) + private boolean jj_3R_15(){ + if (jj_3R_14()) return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_scan_token(DOT)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_32()) + jj_scanpos = xsp; return false; } - private boolean jj_3R_50(){ + private boolean jj_3R_137(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(24)){ + if (jj_scan_token(11)){ jj_scanpos = xsp; - if (jj_3R_71()) + if (jj_scan_token(12)) return true; } + if (jj_3R_130()) + return true; return false; } - private boolean jj_3R_33(){ + private boolean jj_3R_24(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_50()) + if (jj_3R_45()) jj_scanpos = xsp; - if (jj_scan_token(JOIN)) - return true; - if (jj_3R_51()) - return true; xsp = jj_scanpos; - if (jj_3R_199()){ + if (jj_3_12()){ jj_scanpos = xsp; - if (jj_3R_200()) + if (jj_3R_46()) return true; } return false; } - private boolean jj_3R_137(){ - if (jj_scan_token(CENTROID)) + private boolean jj_3R_77(){ + if (jj_scan_token(COORDSYS)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_122()) + if (jj_3R_119()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_32(){ - if (jj_scan_token(NATURAL)) - return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_49()) - jj_scanpos = xsp; - if (jj_scan_token(JOIN)) - return true; - if (jj_3R_51()) + private boolean jj_3R_145(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_136(){ - if (jj_scan_token(BOX)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_169()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_170()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_108()) + private boolean jj_3R_143(){ + if (jj_3R_22()) return true; + return false; + } + + private boolean jj_3R_140(){ if (jj_scan_token(COMMA)) return true; - if (jj_3R_108()) - return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_139()) return true; return false; } - private boolean jj_3R_192(){ + private boolean jj_3R_131(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(22)) + if (jj_scan_token(9)){ jj_scanpos = xsp; - if (jj_3R_14()) + if (jj_scan_token(10)) + return true; + } + if (jj_3R_112()) return true; return false; } - private boolean jj_3R_182(){ - if (jj_3R_21()) + private boolean jj_3R_59(){ + if (jj_scan_token(POINT)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_138()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_139()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_190(){ + private boolean jj_3R_130(){ + if (jj_3R_24()) + return true; Token xsp; xsp = jj_scanpos; - if (jj_scan_token(45)){ + if (jj_3R_137()) jj_scanpos = xsp; - if (jj_scan_token(46)) - return true; - } return false; } - private boolean jj_3R_183(){ - if (jj_3R_46()) + private boolean jj_3R_42(){ + if (jj_scan_token(REGION)) return true; - return false; - } - - private boolean jj_3R_180(){ - if (jj_3R_21()) + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_29()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_109(){ + private boolean jj_3R_19(){ + if (jj_3R_24()) + return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_136()){ + if (jj_scan_token(9)){ jj_scanpos = xsp; - if (jj_3R_137()){ + if (jj_scan_token(10)){ jj_scanpos = xsp; - if (jj_3R_138()){ + if (jj_scan_token(11)){ jj_scanpos = xsp; - if (jj_3R_139()){ - jj_scanpos = xsp; - if (jj_3R_140()){ - jj_scanpos = xsp; - if (jj_3R_141()) - return true; - } - } + if (jj_scan_token(12)) + return true; } } } return false; } - private boolean jj_3R_181(){ - if (jj_3R_158()) - return true; - return false; - } - - private boolean jj_3R_177(){ - if (jj_3R_158()) + private boolean jj_3_1(){ + if (jj_3R_14()) return true; - return false; - } - - private boolean jj_3R_175(){ - if (jj_3R_158()) + if (jj_scan_token(DOT)) return true; - return false; - } - - private boolean jj_3R_17(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_32()){ + if (jj_3R_15()) jj_scanpos = xsp; - if (jj_3R_33()) - return true; - } - return false; - } - - private boolean jj_3R_169(){ - if (jj_3R_27()) + if (jj_scan_token(ASTERISK)) return true; return false; } - private boolean jj_3R_198(){ - if (jj_3R_17()) + private boolean jj_3R_20(){ + if (jj_3R_36()) + return true; + if (jj_scan_token(CONCAT)) return true; return false; } - private boolean jj_3R_117(){ - if (jj_scan_token(LEFT_PAR)) + private boolean jj_3R_41(){ + if (jj_scan_token(POLYGON)) return true; - if (jj_3R_193()) + if (jj_scan_token(LEFT_PAR)) return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_138()) return true; - return false; - } - - private boolean jj_3R_193(){ - if (jj_3R_72()) + if (jj_scan_token(COMMA)) return true; - Token xsp; - if (jj_3R_198()) + if (jj_3R_139()) return true; - while(true){ - xsp = jj_scanpos; - if (jj_3R_198()){ - jj_scanpos = xsp; - break; - } - } - return false; - } - - private boolean jj_3R_179(){ - if (jj_3R_158()) + if (jj_scan_token(COMMA)) return true; - return false; - } - - private boolean jj_3_3(){ - if (jj_3R_17()) + if (jj_3R_139()) return true; - return false; - } - - private boolean jj_3R_116(){ - if (jj_3R_77()) + if (jj_scan_token(COMMA)) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_192()) - jj_scanpos = xsp; - return false; - } - - private boolean jj_3R_51(){ - if (jj_3R_72()) + if (jj_3R_139()) return true; Token xsp; while(true){ xsp = jj_scanpos; - if (jj_3_3()){ + if (jj_3R_140()){ jj_scanpos = xsp; break; } } + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3_2(){ - if (jj_3R_16()) - return true; - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(22)) - jj_scanpos = xsp; - if (jj_3R_14()) + private boolean jj_3R_72(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_105(){ - if (jj_scan_token(DISTANCE)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_179()){ - jj_scanpos = xsp; - if (jj_3R_180()) - return true; - } - if (jj_scan_token(COMMA)) - return true; - xsp = jj_scanpos; - if (jj_3R_181()){ - jj_scanpos = xsp; - if (jj_3R_182()) - return true; - } - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3R_40(){ + if (jj_3R_59()) return true; return false; } - private boolean jj_3R_104(){ - if (jj_scan_token(COORD2)) - return true; - if (jj_scan_token(LEFT_PAR)) - return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_177()){ - jj_scanpos = xsp; - if (jj_3R_178()) - return true; - } - if (jj_scan_token(RIGHT_PAR)) + private boolean jj_3_10(){ + if (jj_3R_23()) return true; return false; } - private boolean jj_3R_103(){ - if (jj_scan_token(COORD1)) - return true; - if (jj_scan_token(LEFT_PAR)) + private boolean jj_3R_112(){ + if (jj_3R_130()) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_175()){ - jj_scanpos = xsp; - if (jj_3R_176()) - return true; - } - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_131()) + jj_scanpos = xsp; + return false; + } + + private boolean jj_3_9(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_102(){ - if (jj_scan_token(AREA)) + private boolean jj_3_7(){ + if (jj_scan_token(REGULAR_IDENTIFIER)) return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_122()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; return false; } - private boolean jj_3R_72(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_116()){ - jj_scanpos = xsp; - if (jj_3_2()){ - jj_scanpos = xsp; - if (jj_3R_117()) - return true; - } - } + private boolean jj_3_6(){ + if (jj_scan_token(LEFT_PAR)) + return true; return false; } - private boolean jj_3R_101(){ - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(58)){ - jj_scanpos = xsp; - if (jj_scan_token(59)) - return true; - } + private boolean jj_3R_39(){ + if (jj_scan_token(CIRCLE)) + return true; if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_122()) + if (jj_3R_138()) return true; if (jj_scan_token(COMMA)) return true; - if (jj_3R_122()) - return true; - if (jj_scan_token(RIGHT_PAR)) + if (jj_3R_139()) return true; - return false; - } - - private boolean jj_3R_157(){ if (jj_scan_token(COMMA)) return true; - if (jj_3R_46()) + if (jj_3R_112()) return true; - return false; - } - - private boolean jj_3R_189(){ - if (jj_3R_36()) + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_166(){ + private boolean jj_3_5(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_189()){ + if (jj_scan_token(65)){ jj_scanpos = xsp; - if (jj_scan_token(101)) + if (jj_3R_20()) return true; } - xsp = jj_scanpos; - if (jj_3R_190()) - jj_scanpos = xsp; return false; } - private boolean jj_3R_59(){ + private boolean jj_3_4(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_101()){ + if (jj_3R_18()){ jj_scanpos = xsp; - if (jj_3R_102()){ - jj_scanpos = xsp; - if (jj_3R_103()){ - jj_scanpos = xsp; - if (jj_3R_104()){ - jj_scanpos = xsp; - if (jj_3R_105()) - return true; - } - } - } + if (jj_3R_19()) + return true; } return false; } - private boolean jj_3R_160(){ + private boolean jj_3R_18(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(47)){ + if (jj_scan_token(9)){ jj_scanpos = xsp; - if (jj_scan_token(48)){ - jj_scanpos = xsp; - if (jj_scan_token(49)){ - jj_scanpos = xsp; - if (jj_scan_token(50)) - return true; - } - } + if (jj_scan_token(10)) + return true; } + return false; + } + + private boolean jj_3R_38(){ + if (jj_scan_token(CENTROID)) + return true; if (jj_scan_token(LEFT_PAR)) return true; - xsp = jj_scanpos; - if (jj_scan_token(19)) - jj_scanpos = xsp; - if (jj_3R_46()) + if (jj_3R_119()) return true; if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_170(){ - if (jj_3R_108()) - return true; - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_108()) + private boolean jj_3_11(){ + if (jj_3R_24()) return true; return false; } - private boolean jj_3R_159(){ - if (jj_scan_token(COUNT)) - return true; - if (jj_scan_token(LEFT_PAR)) + private boolean jj_3R_71(){ + if (jj_3R_36()) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(19)) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_scan_token(10)){ - jj_scanpos = xsp; - if (jj_3R_183()) - return true; - } - if (jj_scan_token(RIGHT_PAR)) + return false; + } + + private boolean jj_3R_70(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_188(){ - if (jj_3R_36()) + private boolean jj_3_8(){ + if (jj_3R_21()) return true; return false; } - private boolean jj_3R_164(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_188()){ - jj_scanpos = xsp; - if (jj_scan_token(101)) - return true; - } + private boolean jj_3R_69(){ + if (jj_3R_26()) + return true; return false; } - private boolean jj_3R_56(){ - if (jj_scan_token(DOT)) + private boolean jj_3R_68(){ + if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_77()) + if (jj_3R_51()) + return true; + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_143(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_159()){ - jj_scanpos = xsp; - if (jj_3R_160()) - return true; - } + private boolean jj_3R_37(){ + if (jj_scan_token(BOX)) + return true; + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_138()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_139()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_112()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3R_21(){ - if (jj_3R_36()) + private boolean jj_3R_67(){ + if (jj_3R_29()) return true; return false; } - private boolean jj_3R_36(){ - if (jj_3R_14()) + private boolean jj_3R_66(){ + if (jj_3R_112()) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_56()) - jj_scanpos = xsp; return false; } - private boolean jj_3R_128(){ - if (jj_scan_token(DOT)) - return true; - if (jj_3R_14()) + private boolean jj_3R_152(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_127(){ - if (jj_scan_token(DOT)) - return true; - if (jj_3R_14()) + private boolean jj_3R_53(){ + if (jj_scan_token(SELECT)) return true; return false; } - private boolean jj_3R_134(){ + private boolean jj_3R_125(){ if (jj_scan_token(LEFT_PAR)) return true; - if (jj_3R_46()) + if (jj_3R_51()) return true; - Token xsp; - while(true){ - xsp = jj_scanpos; - if (jj_3R_157()){ - jj_scanpos = xsp; - break; - } - } if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3_16(){ - if (jj_3R_16()) + private boolean jj_3R_144(){ + if (jj_3R_59()) return true; return false; } - private boolean jj_3R_107(){ + private boolean jj_3R_21(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(35)) - jj_scanpos = xsp; - if (jj_scan_token(IN)) - return true; - xsp = jj_scanpos; - if (jj_3_16()){ + if (jj_3R_37()){ jj_scanpos = xsp; - if (jj_3R_134()) - return true; + if (jj_3R_38()){ + jj_scanpos = xsp; + if (jj_3R_39()){ + jj_scanpos = xsp; + if (jj_3R_40()){ + jj_scanpos = xsp; + if (jj_3R_41()){ + jj_scanpos = xsp; + if (jj_3R_42()) + return true; + } + } + } + } } return false; } - private boolean jj_3R_77(){ - if (jj_3R_14()) + private boolean jj_3R_148(){ + if (jj_3R_51()) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_127()) - jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3R_128()) - jj_scanpos = xsp; return false; } - private boolean jj_3R_29(){ - if (jj_scan_token(DELIMITED_IDENTIFIER)) + private boolean jj_3R_142(){ + if (jj_3R_59()) return true; return false; } - private boolean jj_3R_28(){ - if (jj_scan_token(REGULAR_IDENTIFIER)) + private boolean jj_3R_124(){ + if (jj_3R_22()) return true; return false; } - private boolean jj_3R_26(){ + private boolean jj_3R_51(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(35)) + if (jj_3R_66()){ jj_scanpos = xsp; - if (jj_scan_token(BETWEEN)) - return true; - if (jj_3R_46()) + if (jj_3R_67()){ + jj_scanpos = xsp; + if (jj_3R_68()){ + jj_scanpos = xsp; + if (jj_3R_69()){ + jj_scanpos = xsp; + if (jj_3_8()){ + jj_scanpos = xsp; + if (jj_3R_70()){ + jj_scanpos = xsp; + if (jj_3R_71()){ + jj_scanpos = xsp; + if (jj_3_11()){ + jj_scanpos = xsp; + if (jj_3R_72()) + return true; + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_147(){ + if (jj_3R_22()) return true; - if (jj_scan_token(AND)) + return false; + } + + private boolean jj_3R_123(){ + if (jj_3R_129()) return true; - if (jj_3R_46()) + return false; + } + + private boolean jj_3R_151(){ + if (jj_3R_59()) return true; return false; } - private boolean jj_3R_61(){ - if (jj_3R_107()) + private boolean jj_3R_16(){ + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_33()) return true; return false; } - private boolean jj_3R_14(){ - Token xsp; - xsp = jj_scanpos; - if (jj_3R_28()){ - jj_scanpos = xsp; - if (jj_3R_29()) - return true; - } + private boolean jj_3R_138(){ + if (jj_3R_29()) + return true; return false; } - private boolean jj_3_13(){ - if (jj_3R_26()) + private boolean jj_3R_122(){ + if (jj_3R_128()) return true; return false; } - private boolean jj_3_15(){ - if (jj_3R_27()) + private boolean jj_3R_121(){ + if (jj_3R_23()) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(35)) - jj_scanpos = xsp; - if (jj_scan_token(LIKE)) + return false; + } + + private boolean jj_3R_115(){ + if (jj_scan_token(FULL)) return true; return false; } - private boolean jj_3R_60(){ - if (jj_3R_106()) + private boolean jj_3R_146(){ + if (jj_3R_59()) return true; return false; } - private boolean jj_3R_167(){ - if (jj_scan_token(COMMA)) + private boolean jj_3R_83(){ + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_112()) return true; - if (jj_3R_166()) + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3_14(){ - if (jj_3R_21()) - return true; - if (jj_scan_token(IS)) + private boolean jj_3R_82(){ + if (jj_3R_129()) return true; return false; } - private boolean jj_3R_106(){ + private boolean jj_3R_78(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(12)){ + if (jj_3R_121()){ jj_scanpos = xsp; - if (jj_scan_token(13)){ + if (jj_3R_122()){ jj_scanpos = xsp; - if (jj_scan_token(14)){ + if (jj_3R_123()){ jj_scanpos = xsp; - if (jj_scan_token(15)){ + if (jj_3R_124()){ jj_scanpos = xsp; - if (jj_scan_token(16)){ - jj_scanpos = xsp; - if (jj_scan_token(17)) - return true; - } + if (jj_3R_125()) + return true; } } } } - if (jj_3R_46()) - return true; return false; } - private boolean jj_3R_155(){ - if (jj_scan_token(ORDER_BY)) - return true; - if (jj_3R_166()) + private boolean jj_3R_81(){ + if (jj_3R_22()) return true; - Token xsp; - while(true){ - xsp = jj_scanpos; - if (jj_3R_167()){ - jj_scanpos = xsp; - break; - } - } return false; } - private boolean jj_3R_154(){ - if (jj_scan_token(HAVING)) - return true; - if (jj_3R_163()) + private boolean jj_3R_80(){ + if (jj_3R_128()) return true; return false; } - private boolean jj_3R_45(){ - if (jj_3R_46()) + private boolean jj_3R_111(){ + if (jj_scan_token(DISTANCE)) + return true; + if (jj_scan_token(LEFT_PAR)) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_60()){ + if (jj_3R_146()){ jj_scanpos = xsp; - if (jj_3_13()){ - jj_scanpos = xsp; - if (jj_3R_61()) - return true; - } + if (jj_3R_147()) + return true; } - return false; - } - - private boolean jj_3R_44(){ - if (jj_3R_27()) + if (jj_scan_token(COMMA)) return true; - Token xsp; xsp = jj_scanpos; - if (jj_scan_token(35)) + if (jj_3R_151()){ jj_scanpos = xsp; - if (jj_scan_token(LIKE)) - return true; - if (jj_3R_27()) - return true; - return false; - } - - private boolean jj_3R_165(){ - if (jj_scan_token(COMMA)) - return true; - if (jj_3R_164()) + if (jj_3R_152()) + return true; + } + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_43(){ - if (jj_3R_21()) + private boolean jj_3R_110(){ + if (jj_scan_token(COORD2)) return true; - if (jj_scan_token(IS)) + if (jj_scan_token(LEFT_PAR)) return true; Token xsp; xsp = jj_scanpos; - if (jj_scan_token(35)) + if (jj_3R_144()){ jj_scanpos = xsp; - if (jj_scan_token(NULL)) - return true; - return false; - } - - private boolean jj_3R_184(){ - if (jj_scan_token(AS)) - return true; - if (jj_3R_14()) + if (jj_3R_145()) + return true; + } + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_153(){ - if (jj_scan_token(GROUP_BY)) + private boolean jj_3R_109(){ + if (jj_scan_token(COORD1)) return true; - if (jj_3R_164()) + if (jj_scan_token(LEFT_PAR)) return true; Token xsp; - while(true){ - xsp = jj_scanpos; - if (jj_3R_165()){ - jj_scanpos = xsp; - break; - } + xsp = jj_scanpos; + if (jj_3R_142()){ + jj_scanpos = xsp; + if (jj_3R_143()) + return true; } - return false; - } - - private boolean jj_3R_42(){ - if (jj_scan_token(EXISTS)) - return true; - if (jj_3R_16()) + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_151(){ - if (jj_scan_token(COMMA)) + private boolean jj_3R_108(){ + if (jj_scan_token(AREA)) return true; - if (jj_3R_51()) + if (jj_scan_token(LEFT_PAR)) return true; - return false; - } - - private boolean jj_3R_152(){ - if (jj_scan_token(WHERE)) + if (jj_3R_119()) return true; - if (jj_3R_163()) + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3R_30(){ - if (jj_3R_14()) - return true; - if (jj_scan_token(DOT)) + private boolean jj_3R_118(){ + if (jj_scan_token(FULL)) return true; return false; } - private boolean jj_3R_25(){ + private boolean jj_3R_62(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_42()){ + if (jj_3R_80()){ jj_scanpos = xsp; - if (jj_3R_43()){ + if (jj_3R_81()){ jj_scanpos = xsp; - if (jj_3R_44()){ + if (jj_3R_82()){ jj_scanpos = xsp; - if (jj_3R_45()) + if (jj_3R_83()) return true; } } @@ -5531,115 +5569,138 @@ return false; } - private boolean jj_3R_129(){ - if (jj_scan_token(FROM)) - return true; - if (jj_3R_51()) + private boolean jj_3R_33(){ + if (jj_3R_53()) return true; + return false; + } + + private boolean jj_3R_107(){ Token xsp; - while(true){ - xsp = jj_scanpos; - if (jj_3R_151()){ - jj_scanpos = xsp; - break; - } + xsp = jj_scanpos; + if (jj_scan_token(60)){ + jj_scanpos = xsp; + if (jj_scan_token(61)) + return true; } + if (jj_scan_token(LEFT_PAR)) + return true; + if (jj_3R_119()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_119()) + return true; + if (jj_scan_token(RIGHT_PAR)) + return true; return false; } - private boolean jj_3_12(){ - if (jj_3R_25()) + private boolean jj_3R_114(){ + if (jj_scan_token(RIGHT)) return true; return false; } - private boolean jj_3R_162(){ - if (jj_3R_46()) - return true; + private boolean jj_3R_154(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_184()) + if (jj_scan_token(9)){ jj_scanpos = xsp; + if (jj_scan_token(10)) + return true; + } return false; } - private boolean jj_3R_15(){ - if (jj_3R_14()) - return true; - if (jj_scan_token(DOT)) - return true; + private boolean jj_3R_153(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_30()) + if (jj_3R_154()) jj_scanpos = xsp; - return false; - } - - private boolean jj_3R_195(){ - if (jj_scan_token(LEFT_PAR)) - return true; - if (jj_3R_163()) - return true; - if (jj_scan_token(RIGHT_PAR)) - return true; - return false; - } - - private boolean jj_3R_194(){ - if (jj_3R_25()) + if (jj_scan_token(UNSIGNED_INTEGER)) return true; return false; } - private boolean jj_3R_186(){ + private boolean jj_3R_65(){ Token xsp; xsp = jj_scanpos; - if (jj_3R_194()){ + if (jj_3R_107()){ jj_scanpos = xsp; - if (jj_3R_195()) - return true; + if (jj_3R_108()){ + jj_scanpos = xsp; + if (jj_3R_109()){ + jj_scanpos = xsp; + if (jj_3R_110()){ + jj_scanpos = xsp; + if (jj_3R_111()) + return true; + } + } + } } return false; } - private boolean jj_3R_196(){ - if (jj_scan_token(NOT)) + private boolean jj_3R_139(){ + if (jj_3R_112()) + return true; + if (jj_scan_token(COMMA)) + return true; + if (jj_3R_112()) return true; return false; } - private boolean jj_3R_187(){ + private boolean jj_3R_136(){ Token xsp; xsp = jj_scanpos; - if (jj_scan_token(33)){ + if (jj_scan_token(49)){ jj_scanpos = xsp; - if (jj_scan_token(34)) - return true; + if (jj_scan_token(50)){ + jj_scanpos = xsp; + if (jj_scan_token(51)){ + jj_scanpos = xsp; + if (jj_scan_token(52)) + return true; + } + } } + if (jj_scan_token(LEFT_PAR)) + return true; xsp = jj_scanpos; - if (jj_3R_196()) + if (jj_scan_token(20)) jj_scanpos = xsp; - if (jj_3R_186()) + if (jj_3R_51()) return true; - return false; - } - - private boolean jj_3R_161(){ - if (jj_scan_token(ASTERISK)) + if (jj_scan_token(RIGHT_PAR)) return true; return false; } - private boolean jj_3_1(){ - if (jj_3R_14()) + private boolean jj_3R_135(){ + if (jj_scan_token(COUNT)) return true; - if (jj_scan_token(DOT)) + if (jj_scan_token(LEFT_PAR)) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_15()) + if (jj_scan_token(20)) jj_scanpos = xsp; - if (jj_scan_token(ASTERISK)) + xsp = jj_scanpos; + if (jj_scan_token(11)){ + jj_scanpos = xsp; + if (jj_3R_148()) + return true; + } + if (jj_scan_token(RIGHT_PAR)) + return true; + return false; + } + + private boolean jj_3R_117(){ + if (jj_scan_token(RIGHT)) return true; return false; } @@ -5655,7 +5716,7 @@ private Token jj_scanpos, jj_lastpos; private int jj_la; private int jj_gen; - final private int[] jj_la1 = new int[98]; + final private int[] jj_la1 = new int[97]; static private int[] jj_la1_0; static private int[] jj_la1_1; static private int[] jj_la1_2; @@ -5668,22 +5729,22 @@ } private static void jj_la1_init_0(){ - jj_la1_0 = new int[]{0x41,0x0,0x0,0x0,0x0,0x80000,0x100000,0x20,0x0,0x0,0x400000,0x400,0x304,0x20,0x20,0x20,0x0,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x400000,0x400000,0x400000,0x0,0x4,0x3d800000,0x1c000000,0x2000000,0x1d000000,0x1d000000,0x1c000000,0x2000000,0x1d000000,0x1d000000,0x20,0xc0000000,0x3d800000,0x0,0x0,0x0,0x300,0x300,0x4,0x4,0x0,0x304,0x300,0x300,0xc00,0xc00,0x300,0x300,0x4,0x80,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x3f000,0x0,0x0,0x304,0x3f000,0x0,0x0,0x20,0x4,0x80000,0x704,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x304,0x20,0x20,0x0,0x0,0x20,0x304,}; + jj_la1_0 = new int[]{0x81,0x0,0x0,0x0,0x0,0x100000,0x200000,0x40,0x0,0x0,0x800000,0x800000,0x800,0x608,0x40,0x40,0x40,0x0,0x20,0x20,0x20,0x0,0x0,0x0,0x800000,0x800000,0x800000,0x0,0x8,0x7b000000,0x38000000,0x4000000,0x3a000000,0x3a000000,0x38000000,0x4000000,0x3a000000,0x3a000000,0x40,0x80000000,0x7b000000,0x0,0x0,0x0,0x600,0x600,0x8,0x8,0x0,0x600,0x600,0x1800,0x1800,0x600,0x600,0x8,0x100,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x7e000,0x0,0x0,0x608,0x7e000,0x0,0x0,0x40,0x8,0x100000,0xe08,0x0,0x100000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x608,0x40,0x40,0x0,0x0,0x40,0x608,}; } private static void jj_la1_init_1(){ - jj_la1_1 = new int[]{0x0,0x1,0x400,0x800,0x1000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x6000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8000,0x0,0x3f00000,0x7c0f8000,0x0,0x0,0x0,0x0,0x0,0x0,0xf8000,0x0,0x80000000,0x0,0x3f00000,0x8,0x6,0x6,0x8,0x0,0x8,0x8,0x0,0x108,0x200,0xffff8000,0x0,0x8,0x8,0x0,0x0,0x0,0xffff8000,0x78000,0x0,0xf8000,0xc000000,0x800000,0x800000,0x800000,0x800000,0x7c000000,0x0,0x3f00000,0x7c000000,0x7c0f8000,0x0,0x0,0x0,0x0,0x0,0xffff8000,}; + jj_la1_1 = new int[]{0x0,0x2,0x1000,0x2000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffe0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000,0x18000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,0x3e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,0x0,0x0,0x3e0000,0xfc00000,0x10,0xc,0xc,0x10,0x0,0x10,0x10,0x0,0x210,0x400,0xfffe0000,0x0,0x10,0x10,0x0,0x0,0x0,0xfffe0000,0x1e0000,0x0,0x3e0000,0x30000000,0x2000000,0x2000000,0x2000000,0x2000000,0xf0000000,0x0,0xfc00000,0xf0000000,0xf03e0000,0x0,0x0,0x0,0x0,0x0,0xfffe0000,}; } private static void jj_la1_init_2(){ - jj_la1_2 = new int[]{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0xffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x20ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0xffffff,0xffffff,0x0,0x0,0xfffe,0xff0000,0x0,0x20ffffff,}; + jj_la1_2 = new int[]{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x23ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x23ffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x0,0x3fffffd,0x3fffffd,0x0,0x0,0x3fff8,0x3fc0000,0x0,0x23ffffff,}; } private static void jj_la1_init_3(){ - jj_la1_3 = new int[]{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x3b,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x23,0x23,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x30,0x0,0x0,0x3b,0x3,0x0,0x3b,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x0,0x0,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x2,0x3b,0x0,0x0,0x0,0x0,0x0,0x3b,}; + jj_la1_3 = new int[]{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x3,0x0,0x3b,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x23,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x30,0x0,0x0,0x3b,0x3b,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x3b,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x0,0x0,0x0,0x0,0x3b,0x0,0x0,0x0,0x0,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x2,0x3b,0x0,0x0,0x0,0x0,0x0,0x3b,}; } - final private JJCalls[] jj_2_rtns = new JJCalls[16]; + final private JJCalls[] jj_2_rtns = new JJCalls[18]; private boolean jj_rescan = false; private int jj_gc = 0; @@ -5703,7 +5764,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for(int i = 0; i < 98; i++) + for(int i = 0; i < 97; i++) jj_la1[i] = -1; for(int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); @@ -5725,7 +5786,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for(int i = 0; i < 98; i++) + for(int i = 0; i < 97; i++) jj_la1[i] = -1; for(int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); @@ -5738,7 +5799,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for(int i = 0; i < 98; i++) + for(int i = 0; i < 97; i++) jj_la1[i] = -1; for(int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); @@ -5751,7 +5812,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for(int i = 0; i < 98; i++) + for(int i = 0; i < 97; i++) jj_la1[i] = -1; for(int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); @@ -5763,7 +5824,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for(int i = 0; i < 98; i++) + for(int i = 0; i < 97; i++) jj_la1[i] = -1; for(int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); @@ -5775,7 +5836,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for(int i = 0; i < 98; i++) + for(int i = 0; i < 97; i++) jj_la1[i] = -1; for(int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); @@ -5801,6 +5862,7 @@ } } } + trace_token(token, ""); return token; } token = oldToken; @@ -5808,6 +5870,7 @@ throw generateParseException(); } + @SuppressWarnings("serial") static private final class LookaheadSuccess extends java.lang.Error {} final private LookaheadSuccess jj_ls = new LookaheadSuccess(); @@ -5848,6 +5911,7 @@ token = token.next = token_source.getNextToken(); jj_ntk = -1; jj_gen++; + trace_token(token, " (in getNextToken)"); return token; } @@ -5863,7 +5927,7 @@ return t; } - private int jj_ntk(){ + private int jj_ntk_f(){ if ((jj_nt = token.next) == null) return (jj_ntk = (token.next = token_source.getNextToken()).kind); else @@ -5911,7 +5975,7 @@ la1tokens[jj_kind] = true; jj_kind = -1; } - for(int i = 0; i < 98; i++){ + for(int i = 0; i < 97; i++){ if (jj_la1[i] == jj_gen){ for(int j = 0; j < 32; j++){ if ((jj_la1_0[i] & (1 << j)) != 0){ @@ -5946,15 +6010,68 @@ return new ParseException(token, exptokseq, tokenImage); } + private int trace_indent = 0; + private boolean trace_enabled = true; + /** Enable tracing. */ - final public void enable_tracing(){} + final public void enable_tracing(){ + trace_enabled = true; + } /** Disable tracing. */ - final public void disable_tracing(){} + final public void disable_tracing(){ + trace_enabled = false; + } + + private void trace_call(String s){ + if (trace_enabled){ + for(int i = 0; i < trace_indent; i++){ + System.out.print(" "); + } + System.out.println("Call: " + s); + } + trace_indent = trace_indent + 2; + } + + private void trace_return(String s){ + trace_indent = trace_indent - 2; + if (trace_enabled){ + for(int i = 0; i < trace_indent; i++){ + System.out.print(" "); + } + System.out.println("Return: " + s); + } + } + + private void trace_token(Token t, String where){ + if (trace_enabled){ + for(int i = 0; i < trace_indent; i++){ + System.out.print(" "); + } + System.out.print("Consumed token: <" + tokenImage[t.kind]); + if (t.kind != 0 && !tokenImage[t.kind].equals("\"" + t.image + "\"")){ + System.out.print(": \"" + t.image + "\""); + } + System.out.println(" at line " + t.beginLine + " column " + t.beginColumn + ">" + where); + } + } + + private void trace_scan(Token t1, int t2){ + if (trace_enabled){ + for(int i = 0; i < trace_indent; i++){ + System.out.print(" "); + } + System.out.print("Visited token: <" + tokenImage[t1.kind]); + if (t1.kind != 0 && !tokenImage[t1.kind].equals("\"" + t1.image + "\"")){ + System.out.print(": \"" + t1.image + "\""); + } + System.out.println(" at line " + t1.beginLine + " column " + t1.beginColumn + ">; Expected token: <" + tokenImage[t2] + ">"); + } + } private void jj_rescan_token(){ jj_rescan = true; - for(int i = 0; i < 16; i++){ + for(int i = 0; i < 18; i++){ try{ JJCalls p = jj_2_rtns[i]; do{ @@ -6010,6 +6127,12 @@ case 15: jj_3_16(); break; + case 16: + jj_3_17(); + break; + case 17: + jj_3_18(); + break; } } p = p.next; diff -Nru adql-1.3/src/adql/parser/ADQLParserTokenManager.java adql-1.4/src/adql/parser/ADQLParserTokenManager.java --- adql-1.3/src/adql/parser/ADQLParserTokenManager.java 2015-03-13 18:21:20.000000000 +0000 +++ adql-1.4/src/adql/parser/ADQLParserTokenManager.java 2018-01-12 13:50:22.000000000 +0000 @@ -1,3 +1,4 @@ +/* ADQLParserTokenManager.java */ /* Generated By:JavaCC: Do not edit this line. ADQLParserTokenManager.java */ package adql.parser; import java.util.Stack; @@ -20,24 +21,21 @@ import adql.translator.TranslationException; /** Token Manager. */ -public class ADQLParserTokenManager implements ADQLParserConstants -{ +@SuppressWarnings("unused")public class ADQLParserTokenManager implements ADQLParserConstants { /** Debug output. */ public java.io.PrintStream debugStream = System.out; /** Set debug output. */ public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } -private final int jjStopStringLiteralDfa_3(int pos, long active0, long active1) -{ +private final int jjStopStringLiteralDfa_2(int pos, long active0, long active1){ switch (pos) { default : return -1; } } -private final int jjStartNfa_3(int pos, long active0, long active1) -{ - return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0, active1), pos + 1); +private final int jjStartNfa_2(int pos, long active0, long active1){ + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0, active1), pos + 1); } private int jjStopAtPos(int pos, int kind) { @@ -45,28 +43,27 @@ jjmatchedPos = pos; return pos + 1; } -private int jjMoveStringLiteralDfa0_3() -{ +private int jjMoveStringLiteralDfa0_2(){ switch(curChar) { case 34: - return jjStartNfaWithStates_3(0, 96, 1); + return jjStartNfaWithStates_2(0, 96, 1); default : - return jjMoveNfa_3(0, 0); + return jjMoveNfa_2(0, 0); } } -private int jjStartNfaWithStates_3(int pos, int kind, int state) +private int jjStartNfaWithStates_2(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } - return jjMoveNfa_3(state, pos + 1); + return jjMoveNfa_2(state, pos + 1); } static final long[] jjbitVec0 = { 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL }; -private int jjMoveNfa_3(int startState, int curPos) +private int jjMoveNfa_2(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 3; @@ -148,197 +145,675 @@ catch(java.io.IOException e) { return curPos; } } } -private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) -{ +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1){ switch (pos) { case 0: - if ((active0 & 0xefff1ffdffb40000L) != 0L || (active1 & 0xf0fff4L) != 0L) + if ((active0 & 0x40000000L) != 0L) + { + jjmatchedKind = 97; + return 962; + } + if ((active0 & 0x600000000000000L) != 0L || (active1 & 0x1800L) != 0L) + { + jjmatchedKind = 97; + return 491; + } + if ((active0 & 0x20400000L) != 0L || (active1 & 0x80L) != 0L) + { + jjmatchedKind = 97; + return 295; + } + if ((active0 & 0x2000022002000000L) != 0L) + { + jjmatchedKind = 97; + return 332; + } + if ((active0 & 0x10000000080000L) != 0L || (active1 & 0x1010000L) != 0L) + { + jjmatchedKind = 97; + return 590; + } + if ((active0 & 0x4002800400800000L) != 0L || (active1 & 0x3c0008L) != 0L) + { + jjmatchedKind = 97; + return 910; + } + if ((active0 & 0x200000000L) != 0L) + { + jjmatchedKind = 97; + return 797; + } + if ((active0 & 0xc000000000000L) != 0L || (active1 & 0x400L) != 0L) + { + jjmatchedKind = 97; + return 424; + } + if ((active0 & 0x5001000000L) != 0L) + { + jjmatchedKind = 97; + return 439; + } + if ((active0 & 0x1000000000000L) != 0L || (active1 & 0x24L) != 0L) + { + jjmatchedKind = 97; + return 813; + } + if ((active0 & 0x40000000000L) != 0L || (active1 & 0x40L) != 0L) + { + jjmatchedKind = 97; + return 249; + } + if ((active0 & 0x10010000000L) != 0L || (active1 & 0x300L) != 0L) + { + jjmatchedKind = 97; + return 404; + } + if ((active0 & 0x20L) != 0L) + return 963; + if ((active0 & 0x100000000L) != 0L) + { + jjmatchedKind = 97; + return 752; + } + if ((active0 & 0x18000L) != 0L) + return 17; + if ((active0 & 0x800000008000000L) != 0L || (active1 & 0xe000L) != 0L) + { + jjmatchedKind = 97; + return 550; + } + if ((active0 & 0x400L) != 0L) + return 22; + if ((active0 & 0x200000000000L) != 0L) + { + jjmatchedKind = 97; + return 5; + } + if ((active0 & 0x91a0000000000000L) != 0L || (active1 & 0xc00013L) != 0L) + { + jjmatchedKind = 97; + return 52; + } + if ((active0 & 0x40088000000000L) != 0L) + { + jjmatchedKind = 97; + return 33; + } + if ((active0 & 0x100000000000L) != 0L) { jjmatchedKind = 97; - return 37; + return 315; } - if ((active0 & 0x1000a00200400000L) != 0L || (active1 & 0xf0002L) != 0L) + if ((active0 & 0x400884000000L) != 0L) { jjmatchedKind = 97; - return 16; + return 471; } - if ((active0 & 0x10L) != 0L) - return 38; - if ((active0 & 0x400000000000L) != 0L || (active1 & 0x9L) != 0L) + if ((active0 & 0x200000L) != 0L || (active1 & 0x2020000L) != 0L) { jjmatchedKind = 97; - return 13; + return 670; } - if ((active0 & 0xc000L) != 0L) - return 3; - if ((active0 & 0x200L) != 0L) - return 19; return -1; case 1: - if ((active0 & 0xf7ffceebbeb40000L) != 0L || (active1 & 0xfdfdfeL) != 0L) + if ((active0 & 0x2000020002000000L) != 0L) + return 345; + if ((active1 & 0x4L) != 0L) { if (jjmatchedPos != 1) { jjmatchedKind = 97; jjmatchedPos = 1; } - return 37; + return 877; } - if ((active0 & 0x800311441400000L) != 0L || (active1 & 0x20200L) != 0L) - return 37; - if ((active1 & 0x1L) != 0L) + if ((active0 & 0x800000000000000L) != 0L) { if (jjmatchedPos != 1) { jjmatchedKind = 97; jjmatchedPos = 1; } - return 12; + return 549; } - return -1; - case 2: - if ((active1 & 0x1L) != 0L) + if ((active1 & 0x2000000L) != 0L) { - if (jjmatchedPos != 2) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 2; + jjmatchedPos = 1; } - return 11; + return 669; } - if ((active0 & 0x17a00a00100000L) != 0L || (active1 & 0xf001d2L) != 0L) - return 37; - if ((active0 & 0xffe85ee1bfa40000L) != 0L || (active1 & 0xffc2cL) != 0L) + if ((active1 & 0x40000L) != 0L) { - if (jjmatchedPos != 2) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 2; + jjmatchedPos = 1; } - return 37; + return 913; } - return -1; - case 3: - if ((active0 & 0xefe81e4187840000L) != 0L || (active1 & 0xac2cL) != 0L) + if ((active0 & 0x4000000000000000L) != 0L) { - if (jjmatchedPos != 3) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 3; + jjmatchedPos = 1; + } + return 964; + } + if ((active0 & 0x10000000000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 656; + } + if ((active0 & 0x9020000000000000L) != 0L || (active1 & 0xc00003L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 113; + } + if ((active0 & 0x1000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 438; + } + if ((active1 & 0x20000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 717; + } + if ((active0 & 0x2000000000L) != 0L) + return 396; + if ((active0 & 0x40000000000L) != 0L || (active1 & 0x40L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 264; + } + if ((active0 & 0x100000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 770; + } + if ((active0 & 0x4000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 482; + } + if ((active0 & 0x600000000000000L) != 0L || (active1 & 0x1000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 501; + } + if ((active1 & 0x400L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 431; + } + if ((active0 & 0x8000000000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 427; + } + if ((active1 & 0x8L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 909; + } + if ((active1 & 0x300L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 416; + } + if ((active1 & 0x10000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; } - return 37; + return 637; } - if ((active0 & 0x100040a038200000L) != 0L || (active1 & 0xf5000L) != 0L) - return 37; if ((active1 & 0x80L) != 0L) { - if (jjmatchedPos != 3) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 3; + jjmatchedPos = 1; } - return 21; + return 303; } - if ((active1 & 0x1L) != 0L) + if ((active0 & 0x40000000000000L) != 0L) { - if (jjmatchedPos != 3) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 3; + jjmatchedPos = 1; } - return 10; + return 45; } - return -1; - case 4: - if ((active0 & 0xef601e4000840000L) != 0L || (active1 & 0x880dL) != 0L) + if ((active0 & 0x480800000000L) != 0L || (active1 & 0x800L) != 0L) + return 962; + if ((active0 & 0x200000000L) != 0L) { - jjmatchedKind = 97; - jjmatchedPos = 4; - return 37; + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 796; } - if ((active0 & 0x88000187000000L) != 0L || (active1 & 0x2420L) != 0L) - return 37; - if ((active1 & 0x80080L) != 0L) - return 21; - return -1; - case 5: - if ((active0 & 0x2400a0000040000L) != 0L) - return 37; - if ((active0 & 0x6000000000000000L) != 0L) - return 21; - if ((active0 & 0x8d20004000800000L) != 0L || (active1 & 0x880dL) != 0L) + if ((active0 & 0x4000000000000L) != 0L) { - jjmatchedKind = 97; - jjmatchedPos = 5; - return 37; + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 423; } - if ((active0 & 0x140000000000L) != 0L) + if ((active0 & 0x80000000L) != 0L) + return 472; + if ((active0 & 0x10000000L) != 0L) { - if (jjmatchedPos < 4) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 4; + jjmatchedPos = 1; } - return -1; + return 410; } - return -1; - case 6: - if ((active0 & 0x8c20000000000000L) != 0L || (active1 & 0x8001L) != 0L) + if ((active0 & 0x1000000000000L) != 0L || (active1 & 0x20L) != 0L) { - jjmatchedKind = 97; - jjmatchedPos = 6; - return 37; + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 821; + } + if ((active0 & 0x1000200000L) != 0L || (active1 & 0x300000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 2; + jjmatchedPos = 1; + } + return 962; } - if ((active0 & 0x100004000800000L) != 0L || (active1 & 0x80cL) != 0L) - return 37; - if ((active0 & 0x140000000000L) != 0L) + if ((active0 & 0x100000000000L) != 0L) { - if (jjmatchedPos < 4) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 4; + jjmatchedPos = 1; } - return -1; + return 324; } - return -1; - case 7: - if ((active0 & 0x800000000000000L) != 0L) + if ((active0 & 0x8000000000L) != 0L) { - jjmatchedKind = 97; - jjmatchedPos = 7; - return 37; + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 32; } - if ((active0 & 0x8420000000000000L) != 0L || (active1 & 0x8001L) != 0L) - return 37; - if ((active0 & 0x140000000000L) != 0L) + if ((active1 & 0x1000000L) != 0L) { - if (jjmatchedPos < 4) + if (jjmatchedPos != 1) { jjmatchedKind = 97; - jjmatchedPos = 4; + jjmatchedPos = 1; } - return -1; + return 620; } - return -1; - case 8: - if ((active0 & 0x800000000000000L) != 0L) + if ((active1 & 0x8000L) != 0L) { - jjmatchedKind = 97; - jjmatchedPos = 8; - return 37; + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 581; + } + if ((active0 & 0x800000800000L) != 0L || (active1 & 0x80000L) != 0L) + return 932; + if ((active0 & 0x182210068400000L) != 0L || (active1 & 0x6010L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 962; + } + if ((active0 & 0x400000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 965; + } + if ((active0 & 0x80000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 597; + } + if ((active0 & 0x4000000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 97; + jjmatchedPos = 1; + } + return 454; + } + return -1; + case 2: + if ((active1 & 0x80L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 302; + } + if ((active0 & 0x56801400200000L) != 0L || (active1 & 0x3c00340L) != 0L) + return 962; + if ((active0 & 0x8000000000000L) != 0L) + return 426; + if ((active1 & 0x20000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 964; + } + if ((active0 & 0x2000000000000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 2; + jjmatchedPos = 2; + } + return 373; + } + if ((active0 & 0x4000000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 453; + } + if ((active1 & 0x400L) != 0L) + return 430; + if ((active0 & 0x1000000000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 859; + } + if ((active0 & 0x4000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 481; + } + if ((active1 & 0x8L) != 0L) + return 908; + if ((active0 & 0x1000000000000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 137; + } + if ((active0 & 0x1000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 443; + } + if ((active1 & 0x4L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 884; + } + if ((active0 & 0x4000000000000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 2; + jjmatchedPos = 2; + } + return 962; + } + if ((active0 & 0x8fa075817a480000L) != 0L || (active1 & 0x3df033L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 962; + } + if ((active0 & 0x200000000L) != 0L) + { + if (jjmatchedPos != 2) + { + jjmatchedKind = 97; + jjmatchedPos = 2; + } + return 801; + } + return -1; + case 3: + if ((active0 & 0x2000000000000000L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 97; + jjmatchedPos = 3; + } + return 372; + } + if ((active1 & 0x4L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 97; + jjmatchedPos = 3; + } + return 900; + } + if ((active1 & 0x200L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 97; + jjmatchedPos = 3; + } + return 28; + } + if ((active0 & 0x4000000000L) != 0L) + return 452; + if ((active0 & 0x1000000000000000L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 97; + jjmatchedPos = 3; + } + return 168; + } + if ((active0 & 0x8fa074830f080000L) != 0L || (active1 & 0x2b0b3L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 97; + jjmatchedPos = 3; + } + return 962; + } + if ((active0 & 0x4000010070400000L) != 0L || (active1 & 0x3d4000L) != 0L) + return 962; + if ((active0 & 0x1000000000000L) != 0L) + return 858; + return -1; + case 4: + if ((active1 & 0x200200L) != 0L) + return 28; + if ((active0 & 0x9d80248001080000L) != 0L || (active1 & 0x22037L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 4; + return 962; + } + if ((active0 & 0x2000000000000000L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 4; + return 378; + } + if ((active0 & 0x22050030e000000L) != 0L || (active1 & 0x9080L) != 0L) + return 962; + return -1; + case 5: + if ((active0 & 0x1480008001000000L) != 0L || (active1 & 0x22036L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 5; + return 962; + } + if ((active0 & 0x8000000000000000L) != 0L || (active1 & 0x1L) != 0L) + return 28; + if ((active0 & 0x2000000000000000L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 5; + return 377; + } + if ((active0 & 0x900240000080000L) != 0L) + return 962; + return -1; + case 6: + if ((active0 & 0x2000000000000000L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 6; + return 376; + } + if ((active0 & 0x1080000000000000L) != 0L || (active1 & 0x20006L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 6; + return 962; + } + if ((active0 & 0x400008001000000L) != 0L || (active1 & 0x2030L) != 0L) + return 962; + return -1; + case 7: + if ((active0 & 0x2000000000000000L) != 0L) + { + jjmatchedKind = 97; + jjmatchedPos = 7; + return 966; + } + if ((active0 & 0x1080000000000000L) != 0L || (active1 & 0x20006L) != 0L) + return 962; + return -1; + case 8: + if ((active0 & 0x2000000000000000L) != 0L) + { + jjmatchedKind = 2; + jjmatchedPos = 8; + return 962; } return -1; default : return -1; } } -private final int jjStartNfa_0(int pos, long active0, long active1) -{ +private final int jjStartNfa_0(int pos, long active0, long active1){ return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); } -private int jjMoveStringLiteralDfa0_0() -{ +private int jjMoveStringLiteralDfa0_0(){ switch(curChar) { case 34: @@ -346,99 +821,98 @@ case 39: return jjStopAtPos(0, 91); case 40: - return jjStopAtPos(0, 2); - case 41: return jjStopAtPos(0, 3); + case 41: + return jjStopAtPos(0, 4); case 42: - return jjStopAtPos(0, 10); + return jjStopAtPos(0, 11); case 43: - return jjStopAtPos(0, 8); + return jjStopAtPos(0, 9); case 44: - return jjStopAtPos(0, 5); + return jjStopAtPos(0, 6); case 45: - return jjStartNfaWithStates_0(0, 9, 19); + return jjStartNfaWithStates_0(0, 10, 22); case 46: - return jjStartNfaWithStates_0(0, 4, 38); + return jjStartNfaWithStates_0(0, 5, 963); case 47: - return jjStopAtPos(0, 11); + return jjStopAtPos(0, 12); case 59: - return jjStopAtPos(0, 6); + return jjStopAtPos(0, 7); case 60: - jjmatchedKind = 14; - return jjMoveStringLiteralDfa1_0(0x8000L, 0x0L); + jjmatchedKind = 15; + return jjMoveStringLiteralDfa1_0(0x10000L, 0x0L); case 61: - return jjStopAtPos(0, 12); + return jjStopAtPos(0, 13); case 62: - jjmatchedKind = 16; - return jjMoveStringLiteralDfa1_0(0x20000L, 0x0L); + jjmatchedKind = 17; + return jjMoveStringLiteralDfa1_0(0x40000L, 0x0L); case 65: case 97: - return jjMoveStringLiteralDfa1_0(0x1000a00200400000L, 0xf0002L); + return jjMoveStringLiteralDfa1_0(0x4002800400800000L, 0x3c0008L); case 66: case 98: - return jjMoveStringLiteralDfa1_0(0x10004000000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x40088000000000L, 0x0L); case 67: case 99: - return jjMoveStringLiteralDfa1_0(0xe468000000000000L, 0x300004L); + return jjMoveStringLiteralDfa1_0(0x91a0000000000000L, 0xc00013L); case 68: case 100: - return jjMoveStringLiteralDfa1_0(0x400000000000L, 0x9L); + return jjMoveStringLiteralDfa1_0(0x1000000000000L, 0x24L); case 69: case 101: - return jjMoveStringLiteralDfa1_0(0x20000000000L, 0x10L); + return jjMoveStringLiteralDfa1_0(0x40000000000L, 0x40L); case 70: case 102: - return jjMoveStringLiteralDfa1_0(0x10200000L, 0x20L); + return jjMoveStringLiteralDfa1_0(0x20400000L, 0x80L); case 71: case 103: - return jjMoveStringLiteralDfa1_0(0x40000000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x100000000000L, 0x0L); case 72: case 104: - return jjMoveStringLiteralDfa1_0(0x80000000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x200000000000L, 0x0L); case 73: case 105: - return jjMoveStringLiteralDfa1_0(0x800011001000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x2000022002000000L, 0x0L); case 74: case 106: - return jjMoveStringLiteralDfa1_0(0x20000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x40000000L, 0x0L); case 76: case 108: - return jjMoveStringLiteralDfa1_0(0x8008000000L, 0xc0L); + return jjMoveStringLiteralDfa1_0(0x10010000000L, 0x300L); case 77: case 109: - return jjMoveStringLiteralDfa1_0(0x3000000000000L, 0x100L); + return jjMoveStringLiteralDfa1_0(0xc000000000000L, 0x400L); case 78: case 110: - return jjMoveStringLiteralDfa1_0(0x2800800000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x5001000000L, 0x0L); case 79: case 111: - return jjMoveStringLiteralDfa1_0(0x100442000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x400884000000L, 0x0L); case 80: case 112: - return jjMoveStringLiteralDfa1_0(0x180000000000000L, 0x600L); + return jjMoveStringLiteralDfa1_0(0x600000000000000L, 0x1800L); case 82: case 114: - return jjMoveStringLiteralDfa1_0(0x200000004000000L, 0x3800L); + return jjMoveStringLiteralDfa1_0(0x800000008000000L, 0xe000L); case 83: case 115: - return jjMoveStringLiteralDfa1_0(0x4000000040000L, 0x404000L); + return jjMoveStringLiteralDfa1_0(0x10000000080000L, 0x1010000L); case 84: case 116: - return jjMoveStringLiteralDfa1_0(0x100000L, 0x808000L); + return jjMoveStringLiteralDfa1_0(0x200000L, 0x2020000L); case 85: case 117: - return jjMoveStringLiteralDfa1_0(0x80000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x100000000L, 0x0L); case 87: case 119: - return jjMoveStringLiteralDfa1_0(0x100000000L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x200000000L, 0x0L); case 124: - return jjMoveStringLiteralDfa1_0(0x80L, 0x0L); + return jjMoveStringLiteralDfa1_0(0x100L, 0x0L); default : return jjMoveNfa_0(0, 0); } } -private int jjMoveStringLiteralDfa1_0(long active0, long active1) -{ +private int jjMoveStringLiteralDfa1_0(long active0, long active1){ try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_0(0, active0, active1); @@ -447,91 +921,95 @@ switch(curChar) { case 61: - if ((active0 & 0x8000L) != 0L) - return jjStopAtPos(1, 15); - else if ((active0 & 0x20000L) != 0L) - return jjStopAtPos(1, 17); + if ((active0 & 0x10000L) != 0L) + return jjStopAtPos(1, 16); + else if ((active0 & 0x40000L) != 0L) + return jjStopAtPos(1, 18); break; case 65: case 97: - return jjMoveStringLiteralDfa2_0(active0, 0x1080000800000L, active1, 0x801800L); + return jjMoveStringLiteralDfa2_0(active0, 0x4200001000000L, active1, 0x2006000L); case 66: case 98: - return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x2L); + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x8L); case 67: case 99: - return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10000L); + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x40000L); case 69: case 101: - return jjMoveStringLiteralDfa2_0(active0, 0x220404008040000L, active1, 0xcL); + return jjMoveStringLiteralDfa2_0(active0, 0x881008010080000L, active1, 0x30L); case 72: case 104: - return jjMoveStringLiteralDfa2_0(active0, 0x100000000L, active1, 0L); + return jjMoveStringLiteralDfa2_0(active0, 0x200000000L, active1, 0L); case 73: case 105: - if ((active1 & 0x200L) != 0L) - return jjStartNfaWithStates_0(1, 73, 37); - return jjMoveStringLiteralDfa2_0(active0, 0x42008004000000L, active1, 0x400001L); + if ((active1 & 0x800L) != 0L) + return jjStartNfaWithStates_0(1, 75, 962); + return jjMoveStringLiteralDfa2_0(active0, 0x108010008000000L, active1, 0x1000004L); case 76: case 108: - return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x20L); + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x80L); case 78: case 110: - if ((active0 & 0x40000000L) != 0L) - return jjStartNfaWithStates_0(1, 30, 37); - else if ((active0 & 0x10000000000L) != 0L) + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 472); + else if ((active0 & 0x20000000000L) != 0L) { - jjmatchedKind = 40; + jjmatchedKind = 41; jjmatchedPos = 1; } - return jjMoveStringLiteralDfa2_0(active0, 0x800000201000000L, active1, 0L); + return jjMoveStringLiteralDfa2_0(active0, 0x2000000402000000L, active1, 0L); case 79: case 111: - return jjMoveStringLiteralDfa2_0(active0, 0xe598000820100000L, active1, 0x3025c0L); + return jjMoveStringLiteralDfa2_0(active0, 0x9660001040200000L, active1, 0xc09703L); case 81: case 113: - return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x4000L); + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10000L); case 82: case 114: - if ((active0 & 0x400000000L) != 0L) + if ((active0 & 0x800000000L) != 0L) { - jjmatchedKind = 34; + jjmatchedKind = 35; jjmatchedPos = 1; } - return jjMoveStringLiteralDfa2_0(active0, 0x1000140000200000L, active1, 0x8000L); + return jjMoveStringLiteralDfa2_0(active0, 0x4000500000400000L, active1, 0x20000L); case 83: case 115: - if ((active0 & 0x400000L) != 0L) + if ((active0 & 0x800000L) != 0L) { - jjmatchedKind = 22; + jjmatchedKind = 23; jjmatchedPos = 1; } - else if ((active0 & 0x1000000000L) != 0L) - return jjStartNfaWithStates_0(1, 36, 37); - return jjMoveStringLiteralDfa2_0(active0, 0x200080000000L, active1, 0x20000L); + else if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(1, 37, 396); + return jjMoveStringLiteralDfa2_0(active0, 0x800100000000L, active1, 0x80000L); case 84: case 116: - return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0xc0000L); + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x300000L); case 85: case 117: - return jjMoveStringLiteralDfa2_0(active0, 0x4002012000000L, active1, 0L); + return jjMoveStringLiteralDfa2_0(active0, 0x10004024000000L, active1, 0L); case 86: case 118: - return jjMoveStringLiteralDfa2_0(active0, 0x800000000000L, active1, 0L); + return jjMoveStringLiteralDfa2_0(active0, 0x2000000000000L, active1, 0L); case 88: case 120: - return jjMoveStringLiteralDfa2_0(active0, 0x20000000000L, active1, 0x10L); + return jjMoveStringLiteralDfa2_0(active0, 0x40000000000L, active1, 0x40L); + case 89: + case 121: + if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(1, 43, 962); + break; case 124: - if ((active0 & 0x80L) != 0L) - return jjStopAtPos(1, 7); + if ((active0 & 0x100L) != 0L) + return jjStopAtPos(1, 8); break; default : break; } return jjStartNfa_0(0, active0, active1); } -private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(0, old0, old1); try { curChar = input_stream.readChar(); } @@ -543,108 +1021,107 @@ { case 65: case 97: - return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0xc0000L); + return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x300000L); case 67: case 99: - if ((active0 & 0x200000000000L) != 0L) - return jjStartNfaWithStates_0(2, 45, 37); + if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(2, 47, 962); break; case 68: case 100: - if ((active0 & 0x200000000L) != 0L) - return jjStartNfaWithStates_0(2, 33, 37); - else if ((active1 & 0x100L) != 0L) - return jjStartNfaWithStates_0(2, 72, 37); - return jjMoveStringLiteralDfa3_0(active0, 0x100000000000L, active1, 0x800L); + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(2, 34, 962); + else if ((active1 & 0x400L) != 0L) + return jjStartNfaWithStates_0(2, 74, 430); + return jjMoveStringLiteralDfa3_0(active0, 0x400000000000L, active1, 0x2000L); case 69: case 101: - return jjMoveStringLiteralDfa3_0(active0, 0x1000000100000000L, active1, 0L); + return jjMoveStringLiteralDfa3_0(active0, 0x4000000200000000L, active1, 0L); case 70: case 102: - return jjMoveStringLiteralDfa3_0(active0, 0x8000000L, active1, 0L); + return jjMoveStringLiteralDfa3_0(active0, 0x10000000L, active1, 0L); case 71: case 103: - if ((active0 & 0x800000000000L) != 0L) - return jjStartNfaWithStates_0(2, 47, 37); - else if ((active1 & 0x40L) != 0L) + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 49, 962); + else if ((active1 & 0x100L) != 0L) { - jjmatchedKind = 70; + jjmatchedKind = 72; jjmatchedPos = 2; } - return jjMoveStringLiteralDfa3_0(active0, 0x200000004000000L, active1, 0x88L); + return jjMoveStringLiteralDfa3_0(active0, 0x800000008000000L, active1, 0x220L); case 73: case 105: - return jjMoveStringLiteralDfa3_0(active0, 0x800200a0000000L, active1, 0x20004L); + return jjMoveStringLiteralDfa3_0(active0, 0x200040140000000L, active1, 0x80010L); case 75: case 107: - return jjMoveStringLiteralDfa3_0(active0, 0x8000000000L, active1, 0L); + return jjMoveStringLiteralDfa3_0(active0, 0x10000000000L, active1, 0L); case 76: case 108: - return jjMoveStringLiteralDfa3_0(active0, 0x100002010040000L, active1, 0L); + return jjMoveStringLiteralDfa3_0(active0, 0x400004020080000L, active1, 0L); case 77: case 109: - if ((active0 & 0x4000000000000L) != 0L) - return jjStartNfaWithStates_0(2, 50, 37); + if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 52, 962); break; case 78: case 110: - if ((active0 & 0x2000000000000L) != 0L) - return jjStartNfaWithStates_0(2, 49, 37); - else if ((active1 & 0x400000L) != 0L) - return jjStartNfaWithStates_0(2, 86, 37); - else if ((active1 & 0x800000L) != 0L) - return jjStartNfaWithStates_0(2, 87, 37); - return jjMoveStringLiteralDfa3_0(active0, 0x420000001000000L, active1, 0x1000L); + if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 51, 426); + else if ((active1 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(2, 88, 962); + else if ((active1 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(2, 89, 962); + return jjMoveStringLiteralDfa3_0(active0, 0x1080000002000000L, active1, 0x4000L); case 79: case 111: - return jjMoveStringLiteralDfa3_0(active0, 0xe000040000200000L, active1, 0x10020L); + return jjMoveStringLiteralDfa3_0(active0, 0x8000100000400000L, active1, 0x40083L); case 80: case 112: - if ((active0 & 0x100000L) != 0L) - return jjStartNfaWithStates_0(2, 20, 37); - else if ((active1 & 0x10L) != 0L) - return jjStartNfaWithStates_0(2, 68, 37); + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 962); + else if ((active1 & 0x40L) != 0L) + return jjStartNfaWithStates_0(2, 70, 962); break; case 82: case 114: - return jjMoveStringLiteralDfa3_0(active0, 0x40000000000000L, active1, 0x4000L); + return jjMoveStringLiteralDfa3_0(active0, 0x100000000000000L, active1, 0x10000L); case 83: case 115: - if ((active1 & 0x2L) != 0L) - return jjStartNfaWithStates_0(2, 65, 37); - else if ((active1 & 0x100000L) != 0L) - return jjStartNfaWithStates_0(2, 84, 37); - return jjMoveStringLiteralDfa3_0(active0, 0x400000000000L, active1, 0x1L); + if ((active1 & 0x8L) != 0L) + return jjStartNfaWithStates_0(2, 67, 908); + else if ((active1 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(2, 86, 962); + return jjMoveStringLiteralDfa3_0(active0, 0x1000000000000L, active1, 0x4L); case 84: case 116: - if ((active0 & 0x800000000L) != 0L) - return jjStartNfaWithStates_0(2, 35, 37); - else if ((active1 & 0x200000L) != 0L) - return jjStartNfaWithStates_0(2, 85, 37); - return jjMoveStringLiteralDfa3_0(active0, 0x800004002800000L, active1, 0L); + if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(2, 36, 962); + else if ((active1 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(2, 87, 962); + return jjMoveStringLiteralDfa3_0(active0, 0x2000008005000000L, active1, 0L); case 85: case 117: - return jjMoveStringLiteralDfa3_0(active0, 0x8000000000000L, active1, 0xa000L); + return jjMoveStringLiteralDfa3_0(active0, 0x20000000000000L, active1, 0x28000L); case 86: case 118: - return jjMoveStringLiteralDfa3_0(active0, 0x80000000000L, active1, 0L); + return jjMoveStringLiteralDfa3_0(active0, 0x200000000000L, active1, 0L); case 87: case 119: - return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400L); + return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x1000L); case 88: case 120: - if ((active0 & 0x1000000000000L) != 0L) - return jjStartNfaWithStates_0(2, 48, 37); - else if ((active0 & 0x10000000000000L) != 0L) - return jjStartNfaWithStates_0(2, 52, 37); + if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 50, 962); + else if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 54, 962); break; default : break; } return jjStartNfa_0(1, active0, active1); } -private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(1, old0, old1); try { curChar = input_stream.readChar(); } @@ -655,91 +1132,90 @@ switch(curChar) { case 49: - return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x80L); + return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x200L); case 65: case 97: - if ((active0 & 0x1000000000000000L) != 0L) - return jjStartNfaWithStates_0(3, 60, 37); + if ((active0 & 0x4000000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 62, 962); break; case 67: case 99: - if ((active0 & 0x400000000000L) != 0L) - return jjStartNfaWithStates_0(3, 46, 37); - return jjMoveStringLiteralDfa4_0(active0, 0x40000000000000L, active1, 0L); + if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 48, 858); + return jjMoveStringLiteralDfa4_0(active0, 0x100000000000000L, active1, 0L); case 68: case 100: - if ((active1 & 0x1000L) != 0L) - return jjStartNfaWithStates_0(3, 76, 37); + if ((active1 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(3, 78, 962); break; case 69: case 101: - if ((active0 & 0x8000000000L) != 0L) - return jjStartNfaWithStates_0(3, 39, 37); - return jjMoveStringLiteralDfa4_0(active0, 0x800100003040000L, active1, 0x400L); + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(3, 40, 962); + return jjMoveStringLiteralDfa4_0(active0, 0x2000400006080000L, active1, 0x1000L); case 72: case 104: - return jjMoveStringLiteralDfa4_0(active0, 0x4000000L, active1, 0L); + return jjMoveStringLiteralDfa4_0(active0, 0x8000000L, active1, 0L); case 73: case 105: - return jjMoveStringLiteralDfa4_0(active0, 0x200080000000000L, active1, 0x800L); + return jjMoveStringLiteralDfa4_0(active0, 0x800200000000000L, active1, 0x2000L); case 76: case 108: - if ((active0 & 0x10000000L) != 0L) - return jjStartNfaWithStates_0(3, 28, 37); - else if ((active0 & 0x2000000000L) != 0L) - return jjStartNfaWithStates_0(3, 37, 37); - return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x4L); + if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(3, 29, 962); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(3, 38, 452); + return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x10L); case 77: case 109: - if ((active0 & 0x200000L) != 0L) - return jjStartNfaWithStates_0(3, 21, 37); + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(3, 22, 962); break; case 78: case 110: - if ((active0 & 0x20000000L) != 0L) - return jjStartNfaWithStates_0(3, 29, 37); - else if ((active1 & 0x20000L) != 0L) - return jjStartNfaWithStates_0(3, 81, 37); - else if ((active1 & 0x40000L) != 0L) + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(3, 30, 962); + else if ((active1 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(3, 83, 962); + else if ((active1 & 0x100000L) != 0L) { - jjmatchedKind = 82; + jjmatchedKind = 84; jjmatchedPos = 3; } - return jjMoveStringLiteralDfa4_0(active0, 0x88000080000000L, active1, 0x8a000L); + return jjMoveStringLiteralDfa4_0(active0, 0x220000100000000L, active1, 0x228000L); case 79: case 111: - return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x20L); + return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x80L); case 82: case 114: - return jjMoveStringLiteralDfa4_0(active0, 0xe000000100000000L, active1, 0x8L); + return jjMoveStringLiteralDfa4_0(active0, 0x8000000200000000L, active1, 0x23L); case 83: case 115: - if ((active1 & 0x10000L) != 0L) - return jjStartNfaWithStates_0(3, 80, 37); - return jjMoveStringLiteralDfa4_0(active0, 0x20000000000L, active1, 0L); + if ((active1 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(3, 82, 962); + return jjMoveStringLiteralDfa4_0(active0, 0x40000000000L, active1, 0L); case 84: case 116: - if ((active0 & 0x8000000L) != 0L) - return jjStartNfaWithStates_0(3, 27, 37); - else if ((active1 & 0x4000L) != 0L) - return jjStartNfaWithStates_0(3, 78, 37); - return jjMoveStringLiteralDfa4_0(active0, 0x420000000000000L, active1, 0x1L); + if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(3, 28, 962); + else if ((active1 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(3, 80, 962); + return jjMoveStringLiteralDfa4_0(active0, 0x1080000000000000L, active1, 0x4L); case 85: case 117: - return jjMoveStringLiteralDfa4_0(active0, 0x40000800000L, active1, 0L); + return jjMoveStringLiteralDfa4_0(active0, 0x100001000000L, active1, 0L); case 87: case 119: - return jjMoveStringLiteralDfa4_0(active0, 0x4000000000L, active1, 0L); + return jjMoveStringLiteralDfa4_0(active0, 0x8000000000L, active1, 0L); case 89: case 121: - return jjMoveStringLiteralDfa4_0(active0, 0x100000000000000L, active1, 0L); + return jjMoveStringLiteralDfa4_0(active0, 0x400000000000000L, active1, 0L); default : break; } return jjStartNfa_0(2, active0, active1); } -private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(2, old0, old1); try { curChar = input_stream.readChar(); } @@ -750,76 +1226,79 @@ switch(curChar) { case 48: - if ((active1 & 0x80L) != 0L) - return jjStartNfaWithStates_0(4, 71, 21); + if ((active1 & 0x200L) != 0L) + return jjStartNfaWithStates_0(4, 73, 28); break; case 50: - if ((active1 & 0x80000L) != 0L) - return jjStartNfaWithStates_0(4, 83, 21); + if ((active1 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(4, 85, 28); break; case 65: case 97: - return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0x801L); + return jjMoveStringLiteralDfa5_0(active0, 0x1000000000000000L, active1, 0x2004L); case 67: case 99: - return jjMoveStringLiteralDfa5_0(active0, 0x40000L, active1, 0x8000L); + return jjMoveStringLiteralDfa5_0(active0, 0x80000L, active1, 0x20000L); case 68: case 100: - if ((active1 & 0x2000L) != 0L) - return jjStartNfaWithStates_0(4, 77, 37); - return jjMoveStringLiteralDfa5_0(active0, 0xe000000000000000L, active1, 0L); + if ((active1 & 0x8000L) != 0L) + return jjStartNfaWithStates_0(4, 79, 962); + return jjMoveStringLiteralDfa5_0(active0, 0x8000000000000000L, active1, 0x3L); case 69: case 101: - if ((active0 & 0x100000000L) != 0L) - return jjStartNfaWithStates_0(4, 32, 37); - return jjMoveStringLiteralDfa5_0(active0, 0x4000000000L, active1, 0x8L); + if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(4, 33, 962); + return jjMoveStringLiteralDfa5_0(active0, 0x8000000000L, active1, 0x20L); case 71: case 103: - if ((active0 & 0x80000000L) != 0L) - return jjStartNfaWithStates_0(4, 31, 37); - return jjMoveStringLiteralDfa5_0(active0, 0x100000000000000L, active1, 0L); + if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(4, 32, 962); + return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0L); case 73: case 105: - return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x4L); + return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x10L); case 76: case 108: - return jjMoveStringLiteralDfa5_0(active0, 0x40000000000000L, active1, 0L); + return jjMoveStringLiteralDfa5_0(active0, 0x100000000000000L, active1, 0L); case 78: case 110: - return jjMoveStringLiteralDfa5_0(active0, 0x80000000000L, active1, 0L); + return jjMoveStringLiteralDfa5_0(active0, 0x200000000000L, active1, 0L); case 79: case 111: - return jjMoveStringLiteralDfa5_0(active0, 0x200000000000000L, active1, 0L); + return jjMoveStringLiteralDfa5_0(active0, 0x800000000000000L, active1, 0L); case 80: case 112: - return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L); + if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(4, 44, 962); + break; case 82: case 114: - if ((active0 & 0x1000000L) != 0L) - return jjStartNfaWithStates_0(4, 24, 37); - else if ((active0 & 0x2000000L) != 0L) - return jjStartNfaWithStates_0(4, 25, 37); - else if ((active1 & 0x20L) != 0L) - return jjStartNfaWithStates_0(4, 69, 37); - else if ((active1 & 0x400L) != 0L) - return jjStartNfaWithStates_0(4, 74, 37); - return jjMoveStringLiteralDfa5_0(active0, 0x820100000800000L, active1, 0L); + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(4, 25, 962); + else if ((active0 & 0x4000000L) != 0L) + return jjStartNfaWithStates_0(4, 26, 962); + else if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(4, 46, 962); + else if ((active1 & 0x80L) != 0L) + return jjStartNfaWithStates_0(4, 71, 962); + else if ((active1 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(4, 76, 962); + return jjMoveStringLiteralDfa5_0(active0, 0x2080000001000000L, active1, 0L); case 84: case 116: - if ((active0 & 0x4000000L) != 0L) - return jjStartNfaWithStates_0(4, 26, 37); - else if ((active0 & 0x8000000000000L) != 0L) - return jjStartNfaWithStates_0(4, 51, 37); - else if ((active0 & 0x80000000000000L) != 0L) - return jjStartNfaWithStates_0(4, 55, 37); - return jjMoveStringLiteralDfa5_0(active0, 0x20000000000L, active1, 0L); + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(4, 27, 962); + else if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 53, 962); + else if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 57, 962); + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L); default : break; } return jjStartNfa_0(3, active0, active1); } -private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(3, old0, old1); try { curChar = input_stream.readChar(); } @@ -829,57 +1308,54 @@ } switch(curChar) { - case 32: - return jjMoveStringLiteralDfa6_0(active0, 0x140000000000L, active1, 0L); case 49: - if ((active0 & 0x2000000000000000L) != 0L) - return jjStartNfaWithStates_0(5, 61, 21); + if ((active0 & 0x8000000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 63, 28); break; case 50: - if ((active0 & 0x4000000000000000L) != 0L) - return jjStartNfaWithStates_0(5, 62, 21); + if ((active1 & 0x1L) != 0L) + return jjStartNfaWithStates_0(5, 64, 28); break; case 65: case 97: - return jjMoveStringLiteralDfa6_0(active0, 0x800000L, active1, 0x8000L); + return jjMoveStringLiteralDfa6_0(active0, 0x1000000L, active1, 0x20000L); case 69: case 101: - if ((active0 & 0x40000000000000L) != 0L) - return jjStartNfaWithStates_0(5, 54, 37); - return jjMoveStringLiteralDfa6_0(active0, 0x4000000000L, active1, 0x8L); + if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 56, 962); + return jjMoveStringLiteralDfa6_0(active0, 0x8000000000L, active1, 0x20L); case 71: case 103: - if ((active0 & 0x80000000000L) != 0L) - return jjStartNfaWithStates_0(5, 43, 37); + if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(5, 45, 962); break; case 73: case 105: - return jjMoveStringLiteralDfa6_0(active0, 0x400000000000000L, active1, 0L); + return jjMoveStringLiteralDfa6_0(active0, 0x1000000000000000L, active1, 0L); case 78: case 110: - if ((active0 & 0x200000000000000L) != 0L) - return jjStartNfaWithStates_0(5, 57, 37); - return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x805L); + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 59, 962); + return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x2014L); case 79: case 111: - return jjMoveStringLiteralDfa6_0(active0, 0x120000000000000L, active1, 0L); + return jjMoveStringLiteralDfa6_0(active0, 0x480000000000000L, active1, 0L); case 83: case 115: - if ((active0 & 0x20000000000L) != 0L) - return jjStartNfaWithStates_0(5, 41, 37); - return jjMoveStringLiteralDfa6_0(active0, 0x8800000000000000L, active1, 0L); + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(5, 42, 962); + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000000000L, active1, 0x2L); case 84: case 116: - if ((active0 & 0x40000L) != 0L) - return jjStartNfaWithStates_0(5, 18, 37); + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(5, 19, 962); break; default : break; } return jjStartNfa_0(4, active0, active1); } -private int jjMoveStringLiteralDfa6_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa6_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(4, old0, old1); try { curChar = input_stream.readChar(); } @@ -889,55 +1365,51 @@ } switch(curChar) { - case 66: - case 98: - return jjMoveStringLiteralDfa7_0(active0, 0x140000000000L, active1, 0L); case 67: case 99: - return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x1L); + return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x4L); case 69: case 101: - return jjMoveStringLiteralDfa7_0(active0, 0x800000000000000L, active1, 0L); + return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000000L, active1, 0L); case 71: case 103: - if ((active1 & 0x4L) != 0L) - return jjStartNfaWithStates_0(6, 66, 37); + if ((active1 & 0x10L) != 0L) + return jjStartNfaWithStates_0(6, 68, 962); break; case 73: case 105: - return jjMoveStringLiteralDfa7_0(active0, 0x20000000000000L, active1, 0L); + return jjMoveStringLiteralDfa7_0(active0, 0x80000000000000L, active1, 0L); case 76: case 108: - if ((active0 & 0x800000L) != 0L) - return jjStartNfaWithStates_0(6, 23, 37); + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(6, 24, 962); break; case 78: case 110: - if ((active0 & 0x4000000000L) != 0L) - return jjStartNfaWithStates_0(6, 38, 37); - else if ((active0 & 0x100000000000000L) != 0L) - return jjStartNfaWithStates_0(6, 56, 37); - return jjMoveStringLiteralDfa7_0(active0, 0x400000000000000L, active1, 0L); + if ((active0 & 0x8000000000L) != 0L) + return jjStartNfaWithStates_0(6, 39, 962); + else if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(6, 58, 962); + return jjMoveStringLiteralDfa7_0(active0, 0x1000000000000000L, active1, 0L); case 83: case 115: - if ((active1 & 0x8L) != 0L) - return jjStartNfaWithStates_0(6, 67, 37); - else if ((active1 & 0x800L) != 0L) - return jjStartNfaWithStates_0(6, 75, 37); + if ((active1 & 0x20L) != 0L) + return jjStartNfaWithStates_0(6, 69, 962); + else if ((active1 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(6, 77, 962); break; case 84: case 116: - return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x8000L); + return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x20000L); case 89: case 121: - return jjMoveStringLiteralDfa7_0(active0, 0x8000000000000000L, active1, 0L); + return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x2L); default : break; } return jjStartNfa_0(5, active0, active1); } -private int jjMoveStringLiteralDfa7_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa7_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(5, old0, old1); try { curChar = input_stream.readChar(); } @@ -949,40 +1421,32 @@ { case 67: case 99: - return jjMoveStringLiteralDfa8_0(active0, 0x800000000000000L, active1, 0L); + return jjMoveStringLiteralDfa8_0(active0, 0x2000000000000000L, active1, 0L); case 68: case 100: - if ((active0 & 0x20000000000000L) != 0L) - return jjStartNfaWithStates_0(7, 53, 37); + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 55, 962); break; case 69: case 101: - if ((active1 & 0x1L) != 0L) - return jjStartNfaWithStates_0(7, 64, 37); - else if ((active1 & 0x8000L) != 0L) - return jjStartNfaWithStates_0(7, 79, 37); + if ((active1 & 0x4L) != 0L) + return jjStartNfaWithStates_0(7, 66, 962); + else if ((active1 & 0x20000L) != 0L) + return jjStartNfaWithStates_0(7, 81, 962); break; case 83: case 115: - if ((active0 & 0x400000000000000L) != 0L) - return jjStartNfaWithStates_0(7, 58, 37); - else if ((active0 & 0x8000000000000000L) != 0L) - return jjStartNfaWithStates_0(7, 63, 37); - break; - case 89: - case 121: - if ((active0 & 0x40000000000L) != 0L) - return jjStopAtPos(7, 42); - else if ((active0 & 0x100000000000L) != 0L) - return jjStopAtPos(7, 44); + if ((active0 & 0x1000000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 60, 962); + else if ((active1 & 0x2L) != 0L) + return jjStartNfaWithStates_0(7, 65, 962); break; default : break; } return jjStartNfa_0(6, active0, active1); } -private int jjMoveStringLiteralDfa8_0(long old0, long active0, long old1, long active1) -{ +private int jjMoveStringLiteralDfa8_0(long old0, long active0, long old1, long active1){ if (((active0 &= old0) | (active1 &= old1)) == 0L) return jjStartNfa_0(6, old0, old1); try { curChar = input_stream.readChar(); } @@ -994,14 +1458,13 @@ { case 84: case 116: - return jjMoveStringLiteralDfa9_0(active0, 0x800000000000000L); + return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000000L); default : break; } return jjStartNfa_0(7, active0, 0L); } -private int jjMoveStringLiteralDfa9_0(long old0, long active0) -{ +private int jjMoveStringLiteralDfa9_0(long old0, long active0){ if (((active0 &= old0)) == 0L) return jjStartNfa_0(7, old0, 0L); try { curChar = input_stream.readChar(); } @@ -1013,8 +1476,8 @@ { case 83: case 115: - if ((active0 & 0x800000000000000L) != 0L) - return jjStartNfaWithStates_0(9, 59, 37); + if ((active0 & 0x2000000000000000L) != 0L) + return jjStartNfaWithStates_0(9, 61, 962); break; default : break; @@ -1032,7 +1495,7 @@ private int jjMoveNfa_0(int startState, int curPos) { int startsAt = 0; - jjnewStateCnt = 37; + jjnewStateCnt = 962; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; @@ -1047,349 +1510,5657 @@ { switch(jjstateSet[--i]) { - case 12: - case 21: + case 590: + case 28: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 97) kind = 97; - jjCheckNAdd(21); + { jjCheckNAdd(28); } break; - case 38: + case 620: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 656: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 373: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 376: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 963: if ((0x3ff000000000000L & l) != 0L) { if (kind > 100) kind = 100; - jjCheckNAdd(27); + { jjCheckNAdd(952); } } if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddTwoStates(23, 24); + { jjCheckNAddTwoStates(948, 949); } break; - case 37: + case 303: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 97) kind = 97; - jjCheckNAdd(21); - break; - case 0: - if ((0x3ff000000000000L & l) != 0L) - { - if (kind > 101) - kind = 101; - jjCheckNAddStates(0, 6); - } - else if ((0x100002600L & l) != 0L) - { - if (kind > 1) - kind = 1; - } - else if (curChar == 46) - jjCheckNAddTwoStates(23, 27); - else if (curChar == 45) - jjCheckNAdd(19); - else if (curChar == 33) - jjstateSet[jjnewStateCnt++] = 5; - else if (curChar == 60) - jjstateSet[jjnewStateCnt++] = 3; - if (curChar == 13) - jjstateSet[jjnewStateCnt++] = 1; + { jjCheckNAdd(28); } break; - case 11: + case 431: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 97) kind = 97; - jjCheckNAdd(21); + { jjCheckNAdd(28); } break; - case 16: + case 5: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 97) kind = 97; - jjCheckNAdd(21); + { jjCheckNAdd(28); } break; - case 13: + case 168: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 97) kind = 97; - jjCheckNAdd(21); + { jjCheckNAdd(28); } break; - case 10: + case 669: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 97) kind = 97; - jjCheckNAdd(21); + { jjCheckNAdd(28); } break; - case 1: - if (curChar == 10 && kind > 1) - kind = 1; + case 137: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 2: - if (curChar == 13) - jjstateSet[jjnewStateCnt++] = 1; + case 324: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 3: - if (curChar == 62) - kind = 13; + case 910: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 4: - if (curChar == 60) - jjstateSet[jjnewStateCnt++] = 3; + case 295: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 5: - if (curChar == 61) - kind = 13; + case 33: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 6: - if (curChar == 33) - jjstateSet[jjnewStateCnt++] = 5; + case 877: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 18: - if (curChar == 45) - jjCheckNAdd(19); + case 423: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 19: - if (curChar != 45) + case 908: + if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 88) - kind = 88; - jjCheckNAdd(19); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 22: - if (curChar == 46) - jjCheckNAddTwoStates(23, 27); + case 932: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 23: - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddTwoStates(23, 24); + case 249: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 25: - if ((0x280000000000L & l) != 0L) - jjCheckNAdd(26); + case 821: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 26: + case 491: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 99) - kind = 99; - jjCheckNAdd(26); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 27: + case 637: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 100) - kind = 100; - jjCheckNAdd(27); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 28: + case 964: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 101) - kind = 101; - jjCheckNAddStates(0, 6); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 29: - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddTwoStates(29, 24); + case 813: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 30: - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddTwoStates(30, 31); + case 501: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 31: - if (curChar == 46) - jjCheckNAddTwoStates(32, 24); + case 481: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 32: - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddTwoStates(32, 24); + case 452: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 33: - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddTwoStates(33, 34); + case 410: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 34: - if (curChar != 46) + case 372: + if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 100) - kind = 100; - jjCheckNAdd(35); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 35: + case 752: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 100) - kind = 100; - jjCheckNAdd(35); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 36: + case 966: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 101) - kind = 101; - jjCheckNAdd(36); + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - default : break; - } - } while(i != startsAt); - } - else if (curChar < 128) - { - long l = 1L << (curChar & 077); - do - { - switch(jjstateSet[--i]) - { - case 12: - if ((0x7fffffe87fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAdd(21); - } - if ((0x7fffffe07fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); - } - if ((0x8000000080000L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 11; + case 859: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } break; - case 37: - if ((0x7fffffe87fffffeL & l) != 0L) + case 315: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 32: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 52: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 426: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 0: + if ((0x3ff000000000000L & l) != 0L) { - if (kind > 97) - kind = 97; - jjCheckNAdd(21); + if (kind > 101) + kind = 101; + { jjCheckNAddStates(0, 6); } } - if ((0x7fffffe07fffffeL & l) != 0L) + else if ((0x100002600L & l) != 0L) { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); + if (kind > 1) + kind = 1; } + else if (curChar == 46) + { jjCheckNAddTwoStates(948, 952); } + else if (curChar == 45) + jjstateSet[jjnewStateCnt++] = 22; + else if (curChar == 33) + jjstateSet[jjnewStateCnt++] = 19; + else if (curChar == 60) + jjstateSet[jjnewStateCnt++] = 17; + if (curChar == 13) + jjstateSet[jjnewStateCnt++] = 1; break; - case 0: - if ((0x7fffffe07fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); - } - if ((0x200000002L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 16; - else if ((0x1000000010L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 13; + case 332: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 377: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 404: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 45: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 717: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 345: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 909: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 378: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 302: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 454: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 416: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 670: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 797: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 482: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 453: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 439: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 396: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 550: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 597: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 471: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 770: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 549: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 430: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 962: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 438: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 801: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 581: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 858: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 472: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 913: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 796: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 427: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 443: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 424: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 900: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 264: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 965: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 113: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 884: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 1: + if (curChar == 10 && kind > 1) + kind = 1; + break; + case 2: + if (curChar == 13) + jjstateSet[jjnewStateCnt++] = 1; + break; + case 17: + if (curChar == 62 && kind > 14) + kind = 14; + break; + case 18: + if (curChar == 60) + jjstateSet[jjnewStateCnt++] = 17; + break; + case 19: + if (curChar == 61 && kind > 14) + kind = 14; + break; + case 20: + if (curChar == 33) + jjstateSet[jjnewStateCnt++] = 19; + break; + case 21: + if (curChar == 45) + jjstateSet[jjnewStateCnt++] = 22; + break; + case 22: + if (curChar != 45) + break; + if (kind > 90) + kind = 90; + { jjCheckNAddStates(7, 9); } + break; + case 23: + if ((0xffffffffffffdbffL & l) == 0L) + break; + if (kind > 90) + kind = 90; + { jjCheckNAddStates(7, 9); } + break; + case 24: + if ((0x2400L & l) != 0L && kind > 90) + kind = 90; + break; + case 25: + if (curChar == 10 && kind > 90) + kind = 90; + break; + case 26: + if (curChar == 13) + jjstateSet[jjnewStateCnt++] = 25; + break; + case 255: + if (curChar == 45) + jjstateSet[jjnewStateCnt++] = 254; + break; + case 947: + if (curChar == 46) + { jjCheckNAddTwoStates(948, 952); } + break; + case 948: + if ((0x3ff000000000000L & l) != 0L) + { jjCheckNAddTwoStates(948, 949); } + break; + case 950: + if ((0x280000000000L & l) != 0L) + { jjCheckNAdd(951); } + break; + case 951: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 99) + kind = 99; + { jjCheckNAdd(951); } + break; + case 952: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 100) + kind = 100; + { jjCheckNAdd(952); } + break; + case 953: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 101) + kind = 101; + { jjCheckNAddStates(0, 6); } + break; + case 954: + if ((0x3ff000000000000L & l) != 0L) + { jjCheckNAddTwoStates(954, 949); } + break; + case 955: + if ((0x3ff000000000000L & l) != 0L) + { jjCheckNAddTwoStates(955, 956); } + break; + case 956: + if (curChar == 46) + { jjCheckNAddTwoStates(957, 949); } + break; + case 957: + if ((0x3ff000000000000L & l) != 0L) + { jjCheckNAddTwoStates(957, 949); } + break; + case 958: + if ((0x3ff000000000000L & l) != 0L) + { jjCheckNAddTwoStates(958, 959); } + break; + case 959: + if (curChar != 46) + break; + if (kind > 100) + kind = 100; + { jjCheckNAdd(960); } + break; + case 960: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 100) + kind = 100; + { jjCheckNAdd(960); } + break; + case 961: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 101) + kind = 101; + { jjCheckNAdd(961); } + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 590: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x200000002000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 665; + else if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 656; + else if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 649; + else if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 631; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 628; + else if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 626; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 620; + else if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(34); } + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 593; + if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 643; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 617; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 589; + if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 637; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 607; + if ((0x2000000020000L & l) != 0L) + { jjCheckNAdd(280); } + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 602; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 597; + break; + case 620: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x400000004000000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 656: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 655; + break; + case 373: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 385; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 379; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 372; + break; + case 376: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 303: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 302; + break; + case 431: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 433; + else if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 430; + break; + case 5: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 4; + break; + case 168: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 167; + break; + case 669: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 668; + break; + case 137: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 173; + else if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 168; + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 162; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 144; + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 152; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 136; + break; + case 324: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 323; + break; + case 910: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 945; + else if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 943; + else if ((0x10000000100000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 932; + else if ((0x4000000040000L & l) != 0L) + { jjCheckNAdd(13); } + else if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(7); } + else if ((0x1000000010L & l) != 0L) + { jjCheckNAdd(53); } + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 913; + else if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 909; + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 923; + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 920; + break; + case 295: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 312; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 303; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 300; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 297; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 294; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 309; + if ((0x800000008000L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 33: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 45; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 43; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 32; + if ((0x20000000200L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 877: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 901; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 876; + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 884; + break; + case 423: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 422; + break; + case 908: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 907; + break; + case 932: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 931; + break; + case 249: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 290; + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 260; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 256; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 248; + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 285; + else if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(53); } + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 278; + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 273; + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 271; + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 264; + break; + case 821: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 867; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 853; + else if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 849; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 830; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 820; + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 859; + else if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 843; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 825; + if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 835; + break; + case 491: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 546; + else if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 542; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 501; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 495; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 535; + else if ((0x200000002L & l) != 0L) + { jjCheckNAdd(53); } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 527; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 524; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 519; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 513; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 508; + break; + case 637: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 648; + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 642; + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 636; + if ((0x100000001000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 964: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x2000000020L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 813: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 902; + else if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 895; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 893; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 868; + else if ((0x200000002L & l) != 0L) + { jjCheckNAdd(7); } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 889; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 885; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 860; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 812; + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 877; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 854; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 850; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 844; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 836; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 831; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 826; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 821; + break; + case 501: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 500; + break; + case 481: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 480; + break; + case 452: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200L & l) != 0L) + { jjCheckNAdd(451); } + break; + case 410: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 412; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 409; + break; + case 372: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 384; + else if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 371; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 378; + break; + case 752: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 772; + else if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 767; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 760; + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 770; + else if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 764; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 755; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 751; + break; + case 966: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 859: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 866; + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 858; + break; + case 315: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 324; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 321; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 318; + else if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(34); } + if ((0x800000008000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 32: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 31; + break; + case 52: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 245; + else if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 190; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 186; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 107; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 104; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 68; + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 241; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 175; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 100; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 62; + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 231; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 170; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 86; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 60; + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 215; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 164; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 77; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 58; + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 205; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 154; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 70; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 51; + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 195; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 146; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 138; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 133; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 129; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 125; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 118; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 113; + break; + case 426: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 425; + break; + case 0: + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x200000002L & l) != 0L) + { jjCheckNAddStates(10, 20); } + else if ((0x1000000010L & l) != 0L) + { jjAddStates(21, 37); } + else if ((0x80000000800000L & l) != 0L) + { jjAddStates(38, 42); } + else if ((0x40000000400000L & l) != 0L) + { jjAddStates(43, 47); } + else if ((0x20000000200000L & l) != 0L) + { jjAddStates(48, 54); } + else if ((0x10000000100000L & l) != 0L) + { jjCheckNAddStates(55, 68); } + else if ((0x8000000080000L & l) != 0L) + { jjAddStates(69, 85); } + else if ((0x4000000040000L & l) != 0L) + { jjAddStates(86, 93); } + else if ((0x1000000010000L & l) != 0L) + { jjAddStates(94, 104); } + else if ((0x800000008000L & l) != 0L) + { jjCheckNAddStates(105, 111); } + else if ((0x400000004000L & l) != 0L) + { jjCheckNAddStates(112, 118); } + else if ((0x200000002000L & l) != 0L) + { jjAddStates(119, 122); } + else if ((0x100000001000L & l) != 0L) + { jjAddStates(123, 128); } + else if ((0x20000000200L & l) != 0L) + { jjAddStates(129, 141); } + else if ((0x8000000080L & l) != 0L) + { jjCheckNAddStates(142, 146); } + else if ((0x4000000040L & l) != 0L) + { jjAddStates(147, 153); } + else if ((0x2000000020L & l) != 0L) + { jjAddStates(154, 163); } + else if ((0x800000008L & l) != 0L) + { jjAddStates(164, 193); } + else if ((0x400000004L & l) != 0L) + { jjAddStates(194, 197); } + else if ((0x400000004000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 15; + else if ((0x200000002000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 11; + else if ((0x80000000800L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 8; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 5; + break; + case 332: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 396; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 389; + else if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 338; + else if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 331; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 387; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 381; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 374; + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(34); } + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 368; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 364; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 355; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 352; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 345; + break; + case 377: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 376; + break; + case 404: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 419; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 413; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 405; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 416; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 410; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 403; + break; + case 45: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(36); } + break; + case 717: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200000L & l) != 0L) + { jjCheckNAdd(13); } + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 744; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 741; + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 732; + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 725; + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 716; + break; + case 345: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(320); } + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 367; + else if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 354; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 351; + else if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 344; + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 386; + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 363; + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 380; + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 373; + if ((0x10000000100000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 909: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 908; + break; + case 378: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 383; + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 377; + break; + case 302: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x200000002L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 454: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 458; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 453; + break; + case 416: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x80000000800000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 418; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 415; + break; + case 670: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 747; + else if ((0x800000008000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 711; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 678; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 676; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 669; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 745; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 698; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 742; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 687; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 733; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 680; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 726; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 717; + break; + case 797: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 809; + else if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 806; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 804; + else if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 802; + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 796; + break; + case 482: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 481; + break; + case 453: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 452; + break; + case 439: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 459; + else if ((0x800000008000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 449; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 447; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 444; + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 454; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 438; + break; + case 396: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 395; + break; + case 550: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 583; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 575; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 581; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 571; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 565; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 559; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 551; + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 549; + break; + case 597: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 616; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 601; + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 606; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 596; + break; + case 471: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 488; + else if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 482; + else if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 478; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 472; + else if ((0x4000000040L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 470; + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 474; + break; + case 770: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(3); } + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 769; + break; + case 549: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 574; + else if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 570; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 564; + else if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 558; + else if ((0x200000002L & l) != 0L) + { jjCheckNAdd(280); } + if ((0x200000002L & l) != 0L) + { jjCheckNAdd(53); } + break; + case 430: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 429; + break; + case 962: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + break; + case 438: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 443; + else if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 437; + break; + case 801: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 800; + if ((0x400000004000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 581: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x80000000800000L & l) != 0L) + { jjCheckNAdd(156); } + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 580; + break; + case 858: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 865; + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 857; + break; + case 472: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x100000001000L & l) != 0L) + { jjCheckNAdd(7); } + break; + case 913: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 912; + break; + case 796: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 801; + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 427: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 426; + break; + case 443: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 442; + break; + case 424: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 434; + else if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 427; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 423; + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 431; + break; + case 900: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 899; + break; + case 264: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 289; + else if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 277; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 270; + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 284; + else if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(251); } + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 263; + break; + case 965: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x200000002000000L & l) != 0L) + { + if (kind > 2) + kind = 2; + } + break; + case 113: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 185; + else if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 174; + else if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 132; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 128; + else if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 112; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 169; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 124; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 163; + else if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 117; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 153; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 145; + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 137; + break; + case 884: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + } + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 900; + else if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 883; + break; + case 3: + if ((0x4000000040000L & l) != 0L && kind > 2) + kind = 2; + break; + case 4: + case 689: + if ((0x20000000200000L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 6: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 5; + break; + case 7: + if ((0x200000002000000L & l) != 0L && kind > 2) + kind = 2; + break; + case 8: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(7); } + break; + case 9: + if ((0x80000000800L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 8; + break; + case 10: + case 70: + case 446: + case 782: + if ((0x200000002L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 11: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 10; + break; + case 12: + if ((0x200000002000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 13: + if ((0x2000000020L & l) != 0L && kind > 2) + kind = 2; + break; + case 14: + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 15: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 14; + break; + case 16: + if ((0x400000004000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 15; + break; + case 23: + if (kind > 90) + kind = 90; + { jjAddStates(7, 9); } + break; + case 27: + if ((0x7fffffe07fffffeL & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAddTwoStates(27, 28); } + break; + case 28: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 97) + kind = 97; + { jjCheckNAdd(28); } + break; + case 29: + if ((0x400000004L & l) != 0L) + { jjAddStates(194, 197); } + break; + case 30: + if ((0x400000004000L & l) != 0L && kind > 2) + kind = 2; + break; + case 31: + case 887: + if ((0x20000000200L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 34: + if ((0x10000000100000L & l) != 0L && kind > 2) + kind = 2; + break; + case 35: + case 131: + if ((0x20000000200L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 36: + if ((0x10000000100L & l) != 0L && kind > 2) + kind = 2; + break; + case 37: + case 79: + case 88: + case 433: + case 462: + case 804: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(36); } + break; + case 38: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 37; + break; + case 39: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 38; + break; + case 40: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 39; + break; + case 41: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 40; + break; + case 42: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 41; + break; + case 43: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 42; + break; + case 44: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 43; + break; + case 46: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 45; + break; + case 47: + if ((0x800000008L & l) != 0L) + { jjAddStates(164, 193); } + break; + case 48: + case 634: + if ((0x1000000010L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 49: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 48; + break; + case 50: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 49; + break; + case 51: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 50; + break; + case 53: + if ((0x1000000010L & l) != 0L && kind > 2) + kind = 2; + break; + case 54: + case 846: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(53); } + break; + case 55: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 54; + break; + case 56: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 55; + break; + case 57: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 56; + break; + case 58: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 57; + break; + case 59: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 58; + break; + case 60: + case 106: + case 248: + case 293: + if ((0x8000000080000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 61: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 60; + break; + case 62: + case 299: + case 405: + if ((0x8000000080000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 63: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 62; + break; + case 64: + if ((0x8000000080L & l) != 0L && kind > 2) + kind = 2; + break; + case 65: + if ((0x800000008000L & l) != 0L) + { jjCheckNAdd(64); } + break; + case 66: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 65; + break; + case 67: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 66; + break; + case 68: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 67; + break; + case 69: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 68; + break; + case 71: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 70; + break; + case 72: + case 233: + case 371: + case 418: + case 609: + case 658: + case 766: + case 798: + case 922: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 73: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 72; + break; + case 74: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 73; + break; + case 75: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 74; + break; + case 76: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 75; + break; + case 77: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 76; + break; + case 78: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 77; + break; + case 80: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 79; + break; + case 81: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 80; + break; + case 82: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 81; + break; + case 83: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 82; + break; + case 84: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 83; + break; + case 85: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 84; + break; + case 86: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 85; + break; + case 87: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 86; + break; + case 89: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 88; + break; + case 90: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 89; + break; + case 91: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 90; + break; + case 92: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 91; + break; + case 93: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 92; + break; + case 94: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 93; + break; + case 95: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 94; + break; + case 96: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 95; + break; + case 97: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 96; + break; + case 98: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 97; + break; + case 99: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 98; + break; + case 100: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 99; + break; + case 101: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 100; + break; + case 102: + if ((0x80000000800L & l) != 0L && kind > 2) + kind = 2; + break; + case 103: + case 577: + if ((0x800000008L & l) != 0L) + { jjCheckNAdd(102); } + break; + case 104: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 103; + break; + case 105: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 104; + break; + case 107: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 106; + break; + case 108: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 107; + break; + case 109: + case 630: + if ((0x800000008L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 110: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 109; + break; + case 111: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 110; + break; + case 112: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 111; + break; + case 114: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 113; + break; + case 115: + case 188: + case 197: + case 275: + case 333: + case 425: + case 645: + case 700: + case 728: + case 762: + case 808: + case 812: + case 815: + case 852: + case 905: + case 916: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 116: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 115; + break; + case 117: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 116; + break; + case 118: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 117; + break; + case 119: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 118; + break; + case 120: + case 140: + case 266: + case 391: + case 476: + case 497: + case 503: + case 599: + case 604: + case 719: + case 735: + case 750: + case 911: + case 927: + case 934: + if ((0x800000008000L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 121: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 120; + break; + case 122: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 121; + break; + case 123: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 122; + break; + case 124: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 123; + break; + case 125: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 124; + break; + case 126: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 125; + break; + case 127: + if ((0x200000002000L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 128: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 127; + break; + case 129: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 128; + break; + case 130: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 129; + break; + case 132: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 131; + break; + case 133: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 132; + break; + case 134: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 133; + break; + case 135: + case 287: + case 567: + case 879: + if ((0x800000008L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 136: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 135; + break; + case 138: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 137; + break; + case 139: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 138; + break; + case 141: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 140; + break; + case 142: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 141; + break; + case 143: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 142; + break; + case 144: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 143; + break; + case 145: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 144; + break; + case 146: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 145; + break; + case 147: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 146; + break; + case 148: + case 192: + case 323: + case 622: + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 149: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 148; + break; + case 150: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 149; + break; + case 151: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 150; + break; + case 152: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 151; + break; + case 153: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 152; + break; + case 154: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 153; + break; + case 155: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 154; + break; + case 156: + if ((0x8000000080000L & l) != 0L && kind > 2) + kind = 2; + break; + case 157: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(156); } + break; + case 158: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 157; + break; + case 159: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 158; + break; + case 160: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 159; + break; + case 161: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 160; + break; + case 162: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 161; + break; + case 163: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 162; + break; + case 164: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 163; + break; + case 165: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 164; + break; + case 166: + case 753: + case 775: + if ((0x20000000200000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 167: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 166; + break; + case 169: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 168; + break; + case 170: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 169; + break; + case 171: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 170; + break; + case 172: + case 366: + if ((0x4000000040000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 173: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 172; + break; + case 174: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 173; + break; + case 175: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 174; + break; + case 176: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 175; + break; + case 177: + case 407: + case 651: + case 713: + case 787: + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(64); } + break; + case 178: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 177; + break; + case 179: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 178; + break; + case 180: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 179; + break; + case 181: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 180; + break; + case 182: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 181; + break; + case 183: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 182; + break; + case 184: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 183; + break; + case 185: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 184; + break; + case 186: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 185; + break; + case 187: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 186; + break; + case 189: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 188; + break; + case 190: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 189; + break; + case 191: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 190; + break; + case 193: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 192; + break; + case 194: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 193; + break; + case 195: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 194; + break; + case 196: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 195; + break; + case 198: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 197; + break; + case 199: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 198; + break; + case 200: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 199; + break; + case 201: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 200; + break; + case 202: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 201; + break; + case 203: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 202; + break; + case 204: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 203; + break; + case 205: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 204; + break; + case 206: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 205; + break; + case 207: + case 628: + case 680: + if ((0x200000002000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 208: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 207; + break; + case 209: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 208; + break; + case 210: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 209; + break; + case 211: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 210; + break; + case 212: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 211; + break; + case 213: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 212; + break; + case 214: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 213; + break; + case 215: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 214; + break; + case 216: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 215; + break; + case 217: + if ((0x1000000010000L & l) != 0L && kind > 2) + kind = 2; + break; + case 218: + case 682: + if ((0x200000002000L & l) != 0L) + { jjCheckNAdd(217); } + break; + case 219: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 218; + break; + case 220: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 219; + break; + case 221: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 220; + break; + case 222: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 221; + break; + case 223: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 222; + break; + case 224: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 223; + break; + case 225: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 224; + break; + case 226: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 225; + break; + case 227: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 226; + break; + case 228: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 227; + break; + case 229: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 228; + break; + case 230: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 229; + break; + case 231: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 230; + break; + case 232: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 231; + break; + case 234: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 233; + break; + case 235: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 234; + break; + case 236: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 235; + break; + case 237: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 236; + break; + case 238: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 237; + break; + case 239: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 238; + break; + case 240: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 239; + break; + case 241: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 240; + break; + case 242: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 241; + break; + case 243: + case 340: + case 526: + case 639: + case 862: + if ((0x800000008000L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 244: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 243; + break; + case 245: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 244; + break; + case 246: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 245; + break; + case 247: + if ((0x2000000020L & l) != 0L) + { jjAddStates(154, 163); } + break; + case 250: + case 311: + case 595: + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(53); } + break; + case 251: + if ((0x800000008L & l) != 0L && kind > 2) + kind = 2; + break; + case 252: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(251); } + break; + case 253: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 252; + break; + case 254: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 253; + break; + case 256: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 255; + break; + case 257: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 256; + break; + case 258: + if ((0x1000000010000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 259: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 258; + break; + case 260: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 259; + break; + case 261: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 260; + break; + case 262: + if ((0x1000000010000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 263: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 262; + break; + case 265: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 264; + break; + case 267: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 266; + break; + case 268: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 267; + break; + case 269: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 268; + break; + case 270: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 269; + break; + case 271: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 270; + break; + case 272: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 271; + break; + case 273: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(251); } + break; + case 274: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 273; + break; + case 276: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 275; + break; + case 277: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 276; + break; + case 278: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 277; + break; + case 279: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 278; + break; + case 280: + if ((0x100000001000L & l) != 0L && kind > 2) + kind = 2; + break; + case 281: + case 316: + case 383: + case 415: + case 440: + case 492: + case 823: + if ((0x200000002L & l) != 0L) + { jjCheckNAdd(280); } + break; + case 282: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 281; + break; + case 283: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 282; + break; + case 284: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 283; + break; + case 285: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 284; + break; + case 286: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 285; + break; + case 288: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 287; + break; + case 289: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 288; + break; + case 290: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 289; + break; + case 291: + if ((0x100000001000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 290; + break; + case 292: + if ((0x4000000040L & l) != 0L) + { jjAddStates(147, 153); } + break; + case 294: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 293; + break; + case 296: + case 422: + if ((0x800000008L & l) != 0L) + { jjCheckNAdd(36); } + break; + case 297: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 296; + break; + case 298: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 297; + break; + case 300: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 299; + break; + case 301: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 300; + break; + case 304: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 303; + break; + case 305: + if ((0x800000008000L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 306: + if ((0x8000000080L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 307: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 306; + break; + case 308: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 307; + break; + case 309: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 308; + break; + case 310: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 309; + break; + case 312: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 311; + break; + case 313: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 312; + break; + case 314: + if ((0x8000000080L & l) != 0L) + { jjCheckNAddStates(142, 146); } + break; + case 317: + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 316; + break; + case 318: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 317; + break; + case 319: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 318; + break; + case 320: + if ((0x800000008000L & l) != 0L && kind > 2) + kind = 2; + break; + case 321: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(320); } + break; + case 322: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 321; + break; + case 325: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 324; + break; + case 326: + if ((0x20000000200L & l) != 0L) + { jjAddStates(129, 141); } + break; + case 327: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(7); } + break; + case 328: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 327; + break; + case 329: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 328; + break; + case 330: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 329; + break; + case 331: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 330; + break; + case 334: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 333; + break; + case 335: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 334; + break; + case 336: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 335; + break; + case 337: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 336; + break; + case 338: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 337; + break; + case 339: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 338; + break; + case 341: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 340; + break; + case 342: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 341; + break; + case 343: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 342; + break; + case 344: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 343; + break; + case 346: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 345; + break; + case 347: + if ((0x100000001000L & l) != 0L) + { jjCheckNAdd(7); } + break; + case 348: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 347; + break; + case 349: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 348; + break; + case 350: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 349; + break; + case 351: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 350; + break; + case 352: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 351; + break; + case 353: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 352; + break; + case 354: + case 480: + if ((0x20000000200000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 355: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 354; + break; + case 356: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 355; + break; + case 357: + case 515: + case 561: + if ((0x40000000400000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 358: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 357; + break; + case 359: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 358; + break; + case 360: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 359; + break; + case 361: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 360; + break; + case 362: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 361; + break; + case 363: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 362; + break; + case 364: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 363; + break; + case 365: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 364; + break; + case 367: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 366; + break; + case 368: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 367; + break; + case 369: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 368; + break; + case 370: + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 374: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 373; + break; + case 375: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 374; + break; + case 379: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 378; + break; + case 380: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 379; + break; + case 381: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 380; + break; + case 382: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 381; + break; + case 384: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 383; + break; + case 385: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 384; + break; + case 386: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 385; + break; + case 387: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 386; + break; + case 388: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 387; + break; + case 389: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAdd(320); } + break; + case 390: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 389; + break; + case 392: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 391; + break; + case 393: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 392; + break; + case 394: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 393; + break; + case 395: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 394; + break; + case 397: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 396; + break; + case 398: + if ((0x100000001000L & l) != 0L) + { jjAddStates(123, 128); } + break; + case 399: + case 769: + if ((0x8000000080L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 400: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 399; + break; + case 401: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 400; + break; + case 402: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 401; + break; + case 403: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 402; + break; + case 406: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 405; + break; + case 408: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 407; + break; + case 409: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 408; + break; + case 411: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 410; + break; + case 412: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(280); } + break; + case 413: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 412; + break; + case 414: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 413; + break; + case 417: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 416; + break; + case 419: + if ((0x80000000800000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 418; + break; + case 420: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 419; + break; + case 421: + if ((0x200000002000L & l) != 0L) + { jjAddStates(119, 122); } + break; + case 428: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 427; + break; + case 429: + case 668: + case 838: + case 891: + if ((0x100000001000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 432: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 431; + break; + case 434: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 433; + break; + case 435: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 434; + break; + case 436: + if ((0x400000004000L & l) != 0L) + { jjCheckNAddStates(112, 118); } + break; + case 437: + case 529: + case 553: + case 778: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(156); } + break; + case 441: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 440; + break; + case 442: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 441; + break; + case 444: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 443; + break; + case 445: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 444; + break; + case 447: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 446; + break; + case 448: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 447; + break; + case 449: + if ((0x100000001000000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 450: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 449; + break; + case 451: + if ((0x4000000040L & l) != 0L && kind > 2) + kind = 2; + break; + case 455: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 454; + break; + case 456: + case 544: + if ((0x20000000200L & l) != 0L) + { jjCheckNAdd(251); } + break; + case 457: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 456; + break; + case 458: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 457; + break; + case 459: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 458; + break; + case 460: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 459; + break; + case 461: + if ((0x800000008000L & l) != 0L) + { jjCheckNAddStates(105, 111); } + break; + case 463: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 462; + break; + case 464: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 463; + break; + case 465: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 464; + break; + case 466: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 465; + break; + case 467: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 466; + break; + case 468: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 467; + break; + case 469: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 468; + break; + case 470: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 469; + break; + case 473: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 472; + break; + case 474: + case 678: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 475: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 474; + break; + case 477: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 476; + break; + case 478: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 477; + break; + case 479: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 478; + break; + case 483: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 482; + break; + case 484: + if ((0x1000000010000L & l) != 0L) + { jjCheckNAdd(156); } + break; + case 485: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 484; + break; + case 486: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 485; + break; + case 487: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 486; + break; + case 488: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 487; + break; + case 489: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 488; + break; + case 490: + if ((0x1000000010000L & l) != 0L) + { jjAddStates(94, 104); } + break; + case 493: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 492; + break; + case 494: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 493; + break; + case 495: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 494; + break; + case 496: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 495; + break; + case 498: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 497; + break; + case 499: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 498; + break; + case 500: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 499; + break; + case 502: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 501; + break; + case 504: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 503; + break; + case 505: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 504; + break; + case 506: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 505; + break; + case 507: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 506; + break; + case 508: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 507; + break; + case 509: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 508; + break; + case 510: + case 537: + case 828: + if ((0x4000000040000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 511: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 510; + break; + case 512: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 511; + break; + case 513: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 512; + break; + case 514: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 513; + break; + case 516: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 515; + break; + case 517: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 516; + break; + case 518: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 517; + break; + case 519: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 518; + break; + case 520: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 519; + break; + case 521: + case 671: + if ((0x4000000040000L & l) != 0L) + { jjCheckNAdd(7); } + break; + case 522: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 521; + break; + case 523: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 522; + break; + case 524: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 523; + break; + case 525: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 524; + break; + case 527: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 526; + break; + case 528: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 527; + break; + case 530: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 529; + break; + case 531: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 530; + break; + case 532: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 531; + break; + case 533: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 532; + break; + case 534: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 533; + break; + case 535: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 534; + break; + case 536: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 535; + break; + case 538: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 537; + break; + case 539: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 538; + break; + case 540: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 539; + break; + case 541: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 540; + break; + case 542: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 541; + break; + case 543: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 542; + break; + case 545: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 544; + break; + case 546: + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 545; + break; + case 547: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 546; + break; + case 548: + if ((0x4000000040000L & l) != 0L) + { jjAddStates(86, 93); } + break; + case 551: + if ((0x200000002L & l) != 0L) + { jjCheckNAdd(280); } + break; + case 552: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 551; + break; + case 554: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 553; + break; + case 555: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 554; + break; + case 556: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 555; + break; + case 557: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 556; + break; + case 558: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 557; + break; + case 559: + if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 558; + break; + case 560: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 559; + break; + case 562: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 561; + break; + case 563: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 562; + break; + case 564: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 563; + break; + case 565: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 564; + break; + case 566: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 565; + break; + case 568: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 567; + break; + case 569: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 568; + break; + case 570: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 569; + break; + case 571: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 570; + break; + case 572: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 571; + break; + case 573: + if ((0x80000000800L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 574: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 573; + break; + case 575: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 574; + break; + case 576: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 575; + break; + case 578: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 577; + break; + case 579: + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 578; + break; + case 580: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 579; + break; + case 582: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 581; + break; + case 583: + if ((0x80000000800000L & l) != 0L) + { jjCheckNAdd(156); } + break; + case 584: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 583; + break; + case 585: + if ((0x8000000080000L & l) != 0L) + { jjAddStates(69, 85); } + break; + case 586: + if ((0x200000002L & l) != 0L && kind > 2) + kind = 2; + break; + case 587: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 586; + break; + case 588: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 587; + break; + case 589: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 588; + break; + case 591: + if ((0x100000001000L & l) != 0L) + { jjCheckNAdd(280); } + break; + case 592: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 591; + break; + case 593: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 592; + break; + case 594: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 593; + break; + case 596: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 595; + break; + case 598: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 597; + break; + case 600: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 599; + break; + case 601: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 600; + break; + case 602: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 601; + break; + case 603: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 602; + break; + case 605: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 604; + break; + case 606: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 605; + break; + case 607: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 606; + break; + case 608: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 607; + break; + case 610: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 609; + break; + case 611: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 610; + break; + case 612: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 611; + break; + case 613: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 612; + break; + case 614: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 613; + break; + case 615: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 614; + break; + case 616: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 615; + break; + case 617: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 616; + break; + case 618: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 617; + break; + case 619: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 621: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 620; + break; + case 623: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 622; + break; + case 624: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 623; + break; + case 625: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 624; + break; + case 626: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 625; + break; + case 627: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 626; + break; + case 629: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 628; + break; + case 631: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 630; + break; + case 632: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 631; + break; + case 633: + if ((0x2000000020000L & l) != 0L) + { jjCheckNAdd(280); } + break; + case 635: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 634; + break; + case 636: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 635; + break; + case 638: + if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 637; + break; + case 640: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 639; + break; + case 641: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 640; + break; + case 642: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 641; + break; + case 643: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 642; + break; + case 644: + if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 643; + break; + case 646: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 645; + break; + case 647: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 646; + break; + case 648: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 647; + break; + case 649: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 648; + break; + case 650: + if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 649; + break; + case 652: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 651; + break; + case 653: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 652; + break; + case 654: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 653; + break; + case 655: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 654; + break; + case 657: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 656; + break; + case 659: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 658; + break; + case 660: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 659; + break; + case 661: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 660; + break; + case 662: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 661; + break; + case 663: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 662; + break; + case 664: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 663; + break; + case 665: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 664; + break; + case 666: + if ((0x200000002000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 665; + break; + case 667: + if ((0x10000000100000L & l) != 0L) + { jjCheckNAddStates(55, 68); } + break; + case 672: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 671; + break; + case 673: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 672; + break; + case 674: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 673; + break; + case 675: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 674; + break; + case 676: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 675; + break; + case 677: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 676; + break; + case 679: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 678; + break; + case 681: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 680; + break; + case 683: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 682; + break; + case 684: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 683; + break; + case 685: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 684; + break; + case 686: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 685; + break; + case 687: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 686; + break; + case 688: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 687; + break; + case 690: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 689; + break; + case 691: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 690; + break; + case 692: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 691; + break; + case 693: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 692; + break; + case 694: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 693; + break; + case 695: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 694; + break; + case 696: + if ((0x400000004000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 695; + break; + case 697: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 696; + break; + case 698: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 697; + break; + case 699: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 698; + break; + case 701: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 700; + break; + case 702: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 701; + break; + case 703: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 702; + break; + case 704: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 703; + break; + case 705: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 704; + break; + case 706: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 705; + break; + case 707: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 706; + break; + case 708: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 707; + break; + case 709: + if ((0x400000004000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 708; + break; + case 710: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 709; + break; + case 711: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 710; + break; + case 712: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 711; + break; + case 714: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 713; + break; + case 715: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 714; + break; + case 716: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 715; + break; + case 718: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 717; + break; + case 720: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 719; + break; + case 721: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 720; + break; + case 722: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 721; + break; + case 723: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 722; + break; + case 724: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 723; + break; + case 725: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 724; + break; + case 726: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 725; + break; + case 727: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 726; + break; + case 729: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 728; + break; + case 730: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 729; + break; + case 731: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 730; + break; + case 732: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 731; + break; + case 733: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 732; + break; + case 734: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 733; + break; + case 736: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 735; + break; + case 737: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 736; + break; + case 738: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 737; + break; + case 739: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 738; + break; + case 740: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 739; + break; + case 741: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 740; + break; + case 742: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 741; + break; + case 743: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 742; + break; + case 744: + if ((0x200000002000L & l) != 0L && kind > 2) + kind = 2; + break; + case 745: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 744; + break; + case 746: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 745; + break; + case 747: + if ((0x20000000200000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 748: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 747; + break; + case 749: + if ((0x20000000200000L & l) != 0L) + { jjAddStates(48, 54); } + break; + case 751: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 750; + break; + case 754: + if ((0x2000000020000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 753; + break; + case 755: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 754; + break; + case 756: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 755; + break; + case 757: + if ((0x80000000800000L & l) != 0L) + { jjCheckNAdd(30); } + break; + case 758: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 757; + break; + case 759: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 758; + break; + case 760: + if ((0x80000000800L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 759; + break; + case 761: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 760; + break; + case 763: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 762; + break; + case 764: + if ((0x1000000010L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 763; + break; + case 765: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 764; + break; + case 767: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 766; + break; + case 768: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 767; + break; + case 771: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 770; + break; + case 772: + if ((0x2000000020L & l) != 0L) + { jjCheckNAdd(3); } + break; + case 773: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 772; + break; + case 774: + if ((0x40000000400000L & l) != 0L) + { jjAddStates(43, 47); } + break; + case 776: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 775; + break; + case 777: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 776; + break; + case 779: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 778; + break; + case 780: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 779; + break; + case 781: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 780; + break; + case 783: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 782; + break; + case 784: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 783; + break; + case 785: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 784; + break; + case 786: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 785; + break; + case 788: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 787; + break; + case 789: + if ((0x200000002000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 788; + break; + case 790: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 789; + break; + case 791: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 790; + break; + case 792: + if ((0x80000000800000L & l) != 0L && kind > 2) + kind = 2; + break; + case 793: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 792; + break; + case 794: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 793; + break; + case 795: + if ((0x80000000800000L & l) != 0L) + { jjAddStates(38, 42); } + break; + case 799: + if ((0x40000000400000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 798; + break; + case 800: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 799; + break; + case 802: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 801; + break; + case 803: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 802; + break; + case 805: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 804; + break; + case 806: + if ((0x4000000040000L & l) != 0L) + { jjCheckNAdd(102); } + break; + case 807: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 806; + break; + case 809: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 808; + break; + case 810: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 809; + break; + case 811: + if ((0x1000000010L & l) != 0L) + { jjAddStates(21, 37); } + break; + case 814: + if ((0x200000002L & l) != 0L) + { jjCheckNAdd(7); } + break; + case 816: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 815; + break; + case 817: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 816; + break; + case 818: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 817; + break; + case 819: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 818; + break; + case 820: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 819; + break; + case 822: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 821; + break; + case 824: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 823; + break; + case 825: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 824; + break; + case 826: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 825; + break; + case 827: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 826; + break; + case 829: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 828; + break; + case 830: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 829; + break; + case 831: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 830; + break; + case 832: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 831; + break; + case 833: + if ((0x100000001000L & l) != 0L) + { jjCheckNAdd(34); } + break; + case 834: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 833; + break; + case 835: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 834; + break; + case 836: + if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 835; + break; + case 837: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 836; + break; + case 839: + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 838; + break; + case 840: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 839; + break; + case 841: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 840; + break; + case 842: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 841; + break; + case 843: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 842; + break; + case 844: + if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 843; + break; + case 845: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 844; + break; + case 847: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 846; + break; + case 848: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 847; + break; + case 849: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 848; + break; + case 850: + if ((0x4000000040L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 849; + break; + case 851: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 850; + break; + case 853: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 852; + break; + case 854: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 853; + break; + case 855: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 854; + break; + case 856: + if ((0x400000004L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 857: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 856; + break; + case 860: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 859; + break; + case 861: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 860; + break; + case 863: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 862; + break; + case 864: + if ((0x1000000010000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 863; + break; + case 865: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 864; + break; + case 866: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 865; + break; + case 867: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 866; + break; + case 868: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 867; + break; + case 869: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 868; + break; + case 870: + if ((0x800000008L & l) != 0L) + { jjCheckNAdd(156); } + break; + case 871: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 870; + break; + case 872: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 871; + break; + case 873: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 872; + break; + case 874: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 873; + break; + case 875: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 874; + break; + case 876: + if ((0x8000000080L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 875; + break; + case 878: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 877; + break; + case 880: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 879; + break; + case 881: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 880; + break; + case 882: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 881; + break; + case 883: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 882; + break; + case 885: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 884; + break; + case 886: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 885; + break; + case 888: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 887; + break; + case 889: + if ((0x200000002000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 888; + break; + case 890: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 889; + break; + case 892: + if ((0x400000004L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 891; + break; + case 893: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 892; + break; + case 894: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 893; + break; + case 895: + if ((0x800000008000L & l) != 0L) + { jjCheckNAdd(217); } + break; + case 896: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 895; + break; + case 897: + if ((0x10000000100000L & l) != 0L && kind > 20) + kind = 20; + break; + case 898: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 897; + break; + case 899: + if ((0x400000004000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 898; + break; + case 901: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 900; + break; + case 902: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 901; + break; + case 903: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 902; + break; + case 904: + if ((0x200000002L & l) != 0L) + { jjCheckNAddStates(10, 20); } + break; + case 906: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 905; + break; + case 907: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 906; + break; + case 912: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 911; + break; + case 914: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 913; + break; + case 915: + if ((0x1000000010L & l) != 0L) + { jjCheckNAdd(53); } + break; + case 917: + if ((0x200000002L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 916; + break; + case 918: + if ((0x800000008L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 917; + break; + case 919: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 918; + break; + case 920: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 919; + break; + case 921: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 920; break; - case 11: - if ((0x7fffffe87fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAdd(21); - } - if ((0x7fffffe07fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); - } + case 923: if ((0x10000000100000L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 10; + jjstateSet[jjnewStateCnt++] = 922; break; - case 16: - if ((0x7fffffe87fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAdd(21); - } - if ((0x7fffffe07fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); - } + case 924: if ((0x100000001000L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 15; + jjstateSet[jjnewStateCnt++] = 923; break; - case 13: - if ((0x7fffffe87fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAdd(21); - } - if ((0x7fffffe07fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); - } - if ((0x20000000200L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 12; + case 925: + if ((0x400000004000L & l) != 0L) + { jjCheckNAdd(7); } break; - case 10: - if ((0x7fffffe87fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAdd(21); - } - if ((0x7fffffe07fffffeL & l) != 0L) - { - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); - } + case 926: + if ((0x4000000040000L & l) != 0L) + { jjCheckNAdd(13); } + break; + case 928: if ((0x20000000200L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 9; + jjstateSet[jjnewStateCnt++] = 927; break; - case 7: - if ((0x10000000100000L & l) != 0L && kind > 19) - kind = 19; + case 929: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 928; break; - case 8: - if ((0x800000008L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 7; + case 930: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 929; break; - case 9: - if ((0x400000004000L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 8; + case 931: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 930; break; - case 14: - if ((0x1000000010L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 13; + case 933: + if ((0x8000000080000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 932; break; - case 15: - if ((0x100000001000L & l) != 0L && kind > 19) - kind = 19; + case 935: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 934; break; - case 17: + case 936: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 935; + break; + case 937: if ((0x200000002L & l) != 0L) - jjstateSet[jjnewStateCnt++] = 16; + jjstateSet[jjnewStateCnt++] = 936; break; - case 20: - if ((0x7fffffe07fffffeL & l) == 0L) - break; - if (kind > 97) - kind = 97; - jjCheckNAddTwoStates(20, 21); + case 938: + if ((0x400000004000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 937; break; - case 21: - if ((0x7fffffe87fffffeL & l) == 0L) - break; - if (kind > 97) - kind = 97; - jjCheckNAdd(21); + case 939: + if ((0x20000000200L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 938; break; - case 24: + case 940: + if ((0x4000000040000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 939; + break; + case 941: + if ((0x800000008000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 940; + break; + case 942: + if ((0x10000000100L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 941; + break; + case 943: + if ((0x10000000100000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 942; + break; + case 944: + if ((0x20000000200000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 943; + break; + case 945: + if ((0x100000001000L & l) != 0L && kind > 20) + kind = 20; + break; + case 946: + if ((0x100000001000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 945; + break; + case 949: if ((0x2000000020L & l) != 0L) - jjAddStates(7, 8); + { jjAddStates(198, 199); } break; default : break; } @@ -1403,6 +7174,13 @@ { switch(jjstateSet[--i]) { + case 23: + if ((jjbitVec0[i2] & l2) == 0L) + break; + if (kind > 90) + kind = 90; + { jjAddStates(7, 9); } + break; default : break; } } while(i != startsAt); @@ -1414,43 +7192,40 @@ kind = 0x7fffffff; } ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 37 - (jjnewStateCnt = startsAt))) + if ((i = jjnewStateCnt) == (startsAt = 962 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } -private final int jjStopStringLiteralDfa_2(int pos, long active0, long active1) -{ +private final int jjStopStringLiteralDfa_1(int pos, long active0, long active1){ switch (pos) { default : return -1; } } -private final int jjStartNfa_2(int pos, long active0, long active1) -{ - return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0, active1), pos + 1); +private final int jjStartNfa_1(int pos, long active0, long active1){ + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0, active1), pos + 1); } -private int jjMoveStringLiteralDfa0_2() -{ +private int jjMoveStringLiteralDfa0_1(){ switch(curChar) { case 39: - return jjStartNfaWithStates_2(0, 93, 1); + return jjStartNfaWithStates_1(0, 93, 1); default : - return jjMoveNfa_2(0, 0); + return jjMoveNfa_1(0, 0); } } -private int jjStartNfaWithStates_2(int pos, int kind, int state) +private int jjStartNfaWithStates_1(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } - return jjMoveNfa_2(state, pos + 1); + return jjMoveNfa_1(state, pos + 1); } -private int jjMoveNfa_2(int startState, int curPos) +private int jjMoveNfa_1(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 3; @@ -1532,174 +7307,32 @@ catch(java.io.IOException e) { return curPos; } } } -private int jjMoveStringLiteralDfa0_1() -{ - return jjMoveNfa_1(0, 0); -} -private int jjMoveNfa_1(int startState, int curPos) -{ - int startsAt = 0; - jjnewStateCnt = 3; - int i = 1; - jjstateSet[0] = startState; - int kind = 0x7fffffff; - for (;;) - { - if (++jjround == 0x7fffffff) - ReInitRounds(); - if (curChar < 64) - { - long l = 1L << curChar; - do - { - switch(jjstateSet[--i]) - { - case 0: - if ((0x2400L & l) != 0L) - { - if (kind > 89) - kind = 89; - } - if (curChar == 13) - jjstateSet[jjnewStateCnt++] = 1; - break; - case 1: - if (curChar == 10 && kind > 89) - kind = 89; - break; - case 2: - if (curChar == 13) - jjstateSet[jjnewStateCnt++] = 1; - break; - default : break; - } - } while(i != startsAt); - } - else if (curChar < 128) - { - long l = 1L << (curChar & 077); - do - { - switch(jjstateSet[--i]) - { - default : break; - } - } while(i != startsAt); - } - else - { - int i2 = (curChar & 0xff) >> 6; - long l2 = 1L << (curChar & 077); - do - { - switch(jjstateSet[--i]) - { - default : break; - } - } while(i != startsAt); - } - if (kind != 0x7fffffff) - { - jjmatchedKind = kind; - jjmatchedPos = curPos; - kind = 0x7fffffff; - } - ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt))) - return curPos; - try { curChar = input_stream.readChar(); } - catch(java.io.IOException e) { return curPos; } - } -} static final int[] jjnextStates = { - 29, 30, 31, 24, 33, 34, 36, 25, 26, + 954, 955, 956, 949, 958, 959, 961, 23, 24, 26, 910, 914, 915, 921, 924, 925, + 926, 933, 34, 944, 946, 813, 814, 822, 827, 832, 837, 845, 851, 855, 861, 869, + 878, 886, 890, 894, 896, 903, 797, 803, 805, 807, 810, 777, 781, 786, 791, 794, + 752, 756, 761, 765, 768, 771, 773, 670, 677, 679, 681, 688, 699, 712, 320, 718, + 727, 734, 743, 746, 748, 590, 594, 598, 603, 608, 618, 619, 621, 627, 629, 632, + 633, 638, 644, 650, 657, 666, 550, 552, 560, 566, 572, 576, 582, 584, 491, 496, + 502, 509, 514, 520, 525, 528, 536, 543, 547, 471, 451, 473, 475, 479, 483, 489, + 439, 445, 448, 450, 320, 455, 460, 424, 428, 432, 435, 404, 406, 411, 414, 417, + 420, 332, 339, 346, 353, 356, 365, 369, 370, 375, 382, 388, 390, 397, 315, 319, + 320, 322, 325, 295, 298, 301, 304, 305, 310, 313, 249, 250, 257, 261, 265, 272, + 274, 279, 286, 291, 52, 59, 61, 63, 69, 71, 78, 87, 101, 105, 108, 114, + 119, 126, 130, 134, 139, 147, 155, 165, 171, 176, 187, 191, 196, 206, 216, 232, + 242, 246, 33, 35, 44, 46, 950, 951, }; /** Token literal values. */ public static final String[] jjstrLiteralImages = { -"", null, "\50", "\51", "\56", "\54", "\73", "\174\174", "\53", "\55", "\52", -"\57", "\75", null, "\74", "\74\75", "\76", "\76\75", null, null, null, null, null, +"", null, null, "\50", "\51", "\56", "\54", "\73", "\174\174", "\53", "\55", +"\52", "\57", "\75", null, "\74", "\74\75", "\76", "\76\75", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }; - -/** Lexer state names. */ -public static final String[] lexStateNames = { - "DEFAULT", - "WithinComment", - "WithinString", - "WithinDelimitedId", -}; - -/** Lex State array. */ -public static final int[] jjnewLexState = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, -1, 2, -1, 0, 3, -1, 0, -1, -1, -1, - -1, -1, -1, -}; -static final long[] jjtoToken = { - 0xfffffffffffffffdL, 0x3b20ffffffL, -}; -static final long[] jjtoSkip = { - 0x2L, 0x2000000L, -}; -static final long[] jjtoMore = { - 0x0L, 0xdd000000L, -}; -protected SimpleCharStream input_stream; -private final int[] jjrounds = new int[37]; -private final int[] jjstateSet = new int[74]; -protected char curChar; -/** Constructor. */ -public ADQLParserTokenManager(SimpleCharStream stream){ - if (SimpleCharStream.staticFlag) - throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); - input_stream = stream; -} - -/** Constructor. */ -public ADQLParserTokenManager(SimpleCharStream stream, int lexState){ - this(stream); - SwitchTo(lexState); -} - -/** Reinitialise parser. */ -public void ReInit(SimpleCharStream stream) -{ - jjmatchedPos = jjnewStateCnt = 0; - curLexState = defaultLexState; - input_stream = stream; - ReInitRounds(); -} -private void ReInitRounds() -{ - int i; - jjround = 0x80000001; - for (i = 37; i-- > 0;) - jjrounds[i] = 0x80000000; -} - -/** Reinitialise parser. */ -public void ReInit(SimpleCharStream stream, int lexState) -{ - ReInit(stream); - SwitchTo(lexState); -} - -/** Switch to specified lex state. */ -public void SwitchTo(int lexState) -{ - if (lexState >= 4 || lexState < 0) - throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); - else - curLexState = lexState; -} - protected Token jjFillToken() { final Token t; @@ -1747,6 +7380,7 @@ catch(java.io.IOException e) { jjmatchedKind = 0; + jjmatchedPos = -1; matchedToken = jjFillToken(); return matchedToken; } @@ -1764,21 +7398,12 @@ jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_1(); - if (jjmatchedPos == 0 && jjmatchedKind > 90) - { - jjmatchedKind = 90; - } break; case 2: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_2(); break; - case 3: - jjmatchedKind = 0x7fffffff; - jjmatchedPos = 0; - curPos = jjMoveStringLiteralDfa0_3(); - break; } if (jjmatchedKind != 0x7fffffff) { @@ -1858,4 +7483,83 @@ } while (start++ != end); } + /** Constructor. */ + public ADQLParserTokenManager(SimpleCharStream stream){ + + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + + input_stream = stream; + } + + /** Constructor. */ + public ADQLParserTokenManager (SimpleCharStream stream, int lexState){ + ReInit(stream); + SwitchTo(lexState); + } + + /** Reinitialise parser. */ + public void ReInit(SimpleCharStream stream) + { + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); + } + + private void ReInitRounds() + { + int i; + jjround = 0x80000001; + for (i = 962; i-- > 0;) + jjrounds[i] = 0x80000000; + } + + /** Reinitialise parser. */ + public void ReInit(SimpleCharStream stream, int lexState) + { + ReInit(stream); + SwitchTo(lexState); + } + + /** Switch to specified lex state. */ + public void SwitchTo(int lexState) + { + if (lexState >= 3 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; + } + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", + "WithinString", + "WithinDelimitedId", +}; + +/** Lex State array. */ +public static final int[] jjnewLexState = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 0, 2, -1, 0, -1, -1, -1, + -1, -1, -1, +}; +static final long[] jjtoToken = { + 0xfffffffffffffffdL, 0x3b23ffffffL, +}; +static final long[] jjtoSkip = { + 0x2L, 0x4000000L, +}; +static final long[] jjtoMore = { + 0x0L, 0xd8000000L, +}; + protected SimpleCharStream input_stream; + + private final int[] jjrounds = new int[962]; + private final int[] jjstateSet = new int[2 * 962]; + + + protected char curChar; } diff -Nru adql-1.3/src/adql/parser/ADQLQueryFactory.java adql-1.4/src/adql/parser/ADQLQueryFactory.java --- adql-1.3/src/adql/parser/ADQLQueryFactory.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/parser/ADQLQueryFactory.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -83,7 +83,7 @@ *

      To customize the object representation you merely have to extends the appropriate functions of this class.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (04/2017) * * @see ADQLParser */ @@ -123,9 +123,6 @@ caseSensitivity = IdentifierField.ALIAS.setCaseSensitive(caseSensitivity, alias.caseSensitivity); t.setCaseSensitive(caseSensitivity); - // Set the position in the query: - t.setPosition(idItems.getPosition()); - return t; } @@ -285,7 +282,7 @@ *

      IMPORTANT: * The tests done to check whether a user defined function is allowed/managed in this implementation, is done later by the parser. * Only declared UDF will pass the test of the parser. For that, you should give it a list of allowed UDFs (each UDF will be then - * represented by a {@link FunctionDef} object). + * represented by a {@link FunctionDef} object). *

      * * @param name Name of the user defined function to create. @@ -387,6 +384,18 @@ return new IntersectsFunction(left, right); } + /** + * Replace {@link #createOrder(int, boolean, TextPosition)}. + * @since 1.4 + */ + public ADQLOrder createOrder(final int ind, final boolean desc) throws Exception{ + return new ADQLOrder(ind, desc); + } + + /** + * @deprecated since 1.4 ; Replaced by {@link #createOrder(int, boolean)} + */ + @Deprecated public ADQLOrder createOrder(final int ind, final boolean desc, final TextPosition position) throws Exception{ ADQLOrder order = new ADQLOrder(ind, desc); if (order != null) @@ -394,15 +403,33 @@ return order; } + public ADQLOrder createOrder(final IdentifierItem colName, final boolean desc) throws Exception{ + ADQLOrder order = new ADQLOrder(colName.identifier, desc); + if (order != null) + order.setCaseSensitive(colName.caseSensitivity); + return order; + } + + /** + * @deprecated since 1.4 ; Former version's mistake: an ORDER BY item is either a regular/delimited column name or an integer, not a qualified column name ; Replaced by {@link #createOrder(adql.parser.IdentifierItems.IdentifierItem, boolean)} ; This function is no longer used by ADQLParser. + */ + @Deprecated public ADQLOrder createOrder(final IdentifierItems idItems, final boolean desc) throws Exception{ ADQLOrder order = new ADQLOrder(idItems.join("."), desc); - if (order != null){ - order.setPosition(idItems.getPosition()); + if (order != null) order.setCaseSensitive(idItems.getColumnCaseSensitivity()); - } return order; } + public ColumnReference createColRef(final IdentifierItem idItem) throws Exception{ + ColumnReference colRef = new ColumnReference(idItem.identifier); + if (colRef != null){ + colRef.setPosition(idItem.position); + colRef.setCaseSensitive(idItem.caseSensitivity); + } + return colRef; + } + public ColumnReference createColRef(final IdentifierItems idItems) throws Exception{ ColumnReference colRef = new ColumnReference(idItems.join(".")); if (colRef != null){ diff -Nru adql-1.3/src/adql/parser/IdentifierItems.java adql-1.4/src/adql/parser/IdentifierItems.java --- adql-1.3/src/adql/parser/IdentifierItems.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/parser/IdentifierItems.java 2017-11-10 16:35:00.000000000 +0000 @@ -2,55 +2,59 @@ /* * This file is part of ADQLLibrary. - * + * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . - * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institut (ARI) */ import adql.query.IdentifierField; import adql.query.TextPosition; /** - *

      Important: This class is designed to be filled ONLY by {@link ADQLParser} !

      - * + * Important: This class is designed to be filled ONLY by + * {@link ADQLParser}! + * *

      This class is an array of maximum 4 {@link IdentifierItem}.

      *

      * The goal is to represent complex ADQL identifiers (column, table, ...) * which may be composed of more than only one identifier. *

      *

      - * For instance, a table can be referenced either by only its name or by the name of its schema and its name. - * So, in this last case there are 2 identifiers. + * For instance, a table can be referenced either by only its name or by the + * name of its schema and its name. So, in this last case there are 2 + * identifiers. *

      *

      - * It is possible to get one by one each identifier item (by using the getters), - * or the concatenation of all (thanks to {@link #join(String)}). + * It is possible to get one by one each identifier item (by using the + * getters), or the concatenation of all (thanks to {@link #join(String)}). *

      - * - * @author Grégory Mantelet (CDS) - * @version 01/2012 - * - * see IdentifierItem + * + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (11/2017) + * + * @see IdentifierItem */ public class IdentifierItems { /** - * Represent any ADQL identifier (column name, table name or table/column alias). - * - * @author Grégory Mantelet (CDS) - * @version 01/2012 + * Represent any ADQL identifier (column name, table name or table/column + * alias). + * + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (11/2017) */ public static class IdentifierItem { public String identifier = null; @@ -58,7 +62,7 @@ public TextPosition position = null; public IdentifierItem(final Token token, final boolean caseSensitive){ - identifier = token.image; + identifier = token.image.replaceAll("\"\"", "\""); caseSensitivity = caseSensitive; position = new TextPosition(token); } @@ -81,7 +85,7 @@ /** * Builds an IdentifierItems by specifying it is a table or a column identifier. - * + * * @param tableIdentifier true if this IdentifierItems is a table identifier, false otherwise. */ public IdentifierItems(final boolean tableIdentifier){ @@ -90,9 +94,9 @@ /** *

      Apppends a simple identifier, that's to say an additional field (catalog, schema, table, column).

      - * + * *

      Note: This function has no effect if there are already 4 identifiers.

      - * + * * @param item Additional item (may be null). */ public void append(final IdentifierItem item){ @@ -103,7 +107,7 @@ /** * Gets the number of fields/identifiers stored in this {@link IdentifierItems}. - * + * * @return The number of identifiers. */ public int size(){ @@ -112,9 +116,9 @@ /** * Gets the whole ind-th identifier/field. - * + * * @param ind Index of the identifier/field to get. - * + * * @return The wanted identifier/field. */ public IdentifierItem get(final int ind){ @@ -123,9 +127,9 @@ /** * Gets the value of the ind-th identifier/field. - * + * * @param ind Index of the identifier/field to get. - * + * * @return The value of the wanted identifier/field. */ public String getIdentifier(final int ind){ @@ -212,9 +216,9 @@ /** * Joins all identifiers with the given delimiter. - * + * * @param delim The string which must separate the identifiers (if null, the delimiter will be an empty string). - * + * * @return The joint complex identifier. */ public String join(String delim){ diff -Nru adql-1.3/src/adql/parser/ParseException.java adql-1.4/src/adql/parser/ParseException.java --- adql-1.3/src/adql/parser/ParseException.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/parser/ParseException.java 2017-11-03 17:18:00.000000000 +0000 @@ -1,7 +1,24 @@ -/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 6.0 */ /* JavaCCOptions:KEEP_LINE_COL=null * - * Modified by Grégory Mantelet (CDS), on February 2012 + * Modified by Grégory Mantelet (CDS), on March 2017 + * Modifications: + * - addition of a getPosition() function in order to get the exact location + * of the error in the original ADQL query + * - generate the error message at creation instead of doing that at each + * call of getMessage() + * - use of StringBuffer to build the error message + * - small other alterations of the generated error message + * + * Modified by Grégory Mantelet (ARI), on Sept. 2017 + * Modifications: + * - addition of a HINT in the error message when an ADQL or SQL reserved + * word is at the origin of the error (see initialise(...)) + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by ParseException.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). */ package adql.parser; @@ -16,7 +33,6 @@ * You can modify this class to customize your error reporting * mechanisms so long as you retain the public fields. */ -@SuppressWarnings("all") public class ParseException extends Exception { /** @@ -89,6 +105,38 @@ /** Line in the ADQL query where the exception occurs. */ protected TextPosition position = null; + /** Regular expression listing all ADQL reserved words. + * + *

      Note 1: + * This list is built NOT from the list given in the ADQL-2.0 standard, + * but from the collation of all words potentially used in an ADQL query + * (including standard function names). + *

      + * + *

      Note 2: + * This regular expression is only used to display an appropriate hint + * to the user in the error message if a such word is at the origin of + * the error. (see {@link #initialise(Token, int[][], String[])} for more + * details). + *

      */ + private final static String ADQL_RESERVED_WORDS_REGEX = "(ABS|ACOS|AREA|ASIN|ATAN|ATAN2|BOX|CEILING|CENTROID|CIRCLE|CONTAINS|COORD1|COORD2|COORDSYS|COS|DEGREES|DISTANCE|EXP|FLOOR|INTERSECTS|LOG|LOG10|MOD|PI|POINT|POLYGON|POWER|RADIANS|REGION|RAND|ROUND|SIN|SQRT|TOP|TAN|TRUNCATE|SELECT|TOP|DISTINCT|ALL|AS|COUNT|AVG|MAX|MIN|SUM|FROM|JOIN|CROSS|INNER|OUTER|LEFT|RIGHT|FULL|NATURAL|USING|ON|WHERE|IS|NOT|AND|OR|EXISTS|IN|LIKE|NULL|BETWEEN|ORDER|ASC|DESC|GROUP|BY|HAVING)"; + + /** Regular expression listing all SQL reserved words. + * + *

      Note 1: + * This list is built from the list given in the ADQL-2.0 standard, + * after removal of all words potentially used in an ADQL query + * (see {@link #ADQL_RESERVED_WORDS_REGEX}). + *

      + * + *

      Note 2: + * This regular expression is only used to display an appropriate hint + * to the user in the error message if a such word is at the origin of + * the error. (see {@link #initialise(Token, int[][], String[])} for more + * details). + *

      */ + private final static String SQL_RESERVED_WORDS_REGEX = "(ABSOLUTE|ACTION|ADD|ALLOCATE|ALTER|ANY|ARE|ASSERTION|AT|AUTHORIZATION|BEGIN|BIT|BIT_LENGTH|BOTH|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR|CHARACTER|CHAR_LENGTH|CHARACTER_LENGTH|CHECK|CLOSE|COALESCE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|CREATE|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATE|DAY|DEALLOCATE|DECIMAL|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DOMAIN|DOUBLE|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXTERNAL|EXTRACT|FALSE|FETCH|FIRST|FLOAT|FOR|FOREIGN|FOUND|GET|GLOBAL|GO|GOTO|GRANT|HOUR|IDENTITY|IMMEDIATE|INDICATOR|INITIALLY|INPUT|INSENSITIVE|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|ISOLATION|KEY|LANGUAGE|LAST|LEADING|LEVEL|LOCAL|LOWER|MATCH|MINUTE|MODULE|MONTH|NAMES|NATIONAL|NCHAR|NEXT|NO|NULLIF|NUMERIC|OCTET_LENGTH|OF|ONLY|OPEN|OPTION|OUTPUT|OVERLAPS|PAD|PARTIAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|ROLLBACK|ROWS|SCHEMA|SCROLL|SECOND|SECTION|SESSION|SESSION_USER|SET|SIZE|SMALLINT|SOME|SPACE|SQL|SQLCODE|SQLERROR|SQLSTATE|SUBSTRING|SYSTEM_USER|TABLE|TEMPORARY|THEN|TIME|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIM|TRUE|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|VALUE|VALUES|VARCHAR|VARYING|VIEW|WHEN|WHENEVER|WITH|WORK|WRITE|YEAR|ZONE)"; + /** * Gets the position in the ADQL query of the token which generates this exception. * @@ -124,17 +172,18 @@ StringBuffer msg = new StringBuffer(); msg.append(" Encountered \""); Token tok = currentToken.next; + StringBuffer tokenName = new StringBuffer(); for(int i = 0; i < maxSize; i++){ if (i != 0) - msg.append(' '); + tokenName.append(' '); if (tok.kind == 0){ - msg.append(tokenImage[0]); + tokenName.append(tokenImage[0]); break; } - msg.append(add_escapes(tok.image)); + tokenName.append(add_escapes(tok.image)); tok = tok.next; } - msg.append("\"."); + msg.append(tokenName.toString()).append("\"."); // Append the expected tokens list: if (expectedTokenSequences.length == 1){ @@ -144,27 +193,34 @@ } msg.append(expected); + // Append a hint about reserved words if it is one: + String word = tokenName.toString().trim(); + if (word.toUpperCase().matches(ADQL_RESERVED_WORDS_REGEX)) + msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)"); + else if (word.toUpperCase().matches(SQL_RESERVED_WORDS_REGEX)) + msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)"); + return msg.toString(); /*String eol = System.getProperty("line.separator", "\n"); StringBuffer expected = new StringBuffer(); int maxSize = 0; - for (int i = 0; i < expectedTokenSequences.length; i++) { - if (maxSize < expectedTokenSequences[i].length) { + for(int i = 0; i < expectedTokenSequences.length; i++){ + if (maxSize < expectedTokenSequences[i].length){ maxSize = expectedTokenSequences[i].length; } - for (int j = 0; j < expectedTokenSequences[i].length; j++) { + for(int j = 0; j < expectedTokenSequences[i].length; j++){ expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); } - if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0){ expected.append("..."); } expected.append(eol).append(" "); } String retval = "Encountered \""; Token tok = currentToken.next; - for (int i = 0; i < maxSize; i++) { + for(int i = 0; i < maxSize; i++){ if (i != 0) retval += " "; - if (tok.kind == 0) { + if (tok.kind == 0){ retval += tokenImage[0]; break; } @@ -176,9 +232,9 @@ } retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; retval += "." + eol; - if (expectedTokenSequences.length == 1) { + if (expectedTokenSequences.length == 1){ retval += "Was expecting:" + eol + " "; - } else { + }else{ retval += "Was expecting one of:" + eol + " "; } retval += expected.toString(); diff -Nru adql-1.3/src/adql/parser/ParseException.java.backup adql-1.4/src/adql/parser/ParseException.java.backup --- adql-1.3/src/adql/parser/ParseException.java.backup 2014-04-03 17:52:24.000000000 +0000 +++ adql-1.4/src/adql/parser/ParseException.java.backup 2017-11-03 17:18:00.000000000 +0000 @@ -1,5 +1,25 @@ -/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ -/* JavaCCOptions:KEEP_LINE_COL=null */ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 6.0 */ +/* JavaCCOptions:KEEP_LINE_COL=null + * + * Modified by Grégory Mantelet (CDS), on March 2017 + * Modifications: + * - addition of a getPosition() function in order to get the exact location + * of the error in the original ADQL query + * - generate the error message at creation instead of doing that at each + * call of getMessage() + * - use of StringBuffer to build the error message + * - small other alterations of the generated error message + * + * Modified by Grégory Mantelet (ARI), on Sept. 2017 + * Modifications: + * - addition of a HINT in the error message when an ADQL or SQL reserved + * word is at the origin of the error (see initialise(...)) + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by ParseException.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). + */ package adql.parser; import adql.query.TextPosition; @@ -13,7 +33,6 @@ * You can modify this class to customize your error reporting * mechanisms so long as you retain the public fields. */ -@SuppressWarnings("all") public class ParseException extends Exception { /** @@ -29,11 +48,7 @@ * a new object of this type with the fields "currentToken", * "expectedTokenSequences", and "tokenImage" set. */ - public ParseException(Token currentTokenVal, - int[][] expectedTokenSequencesVal, - String[] tokenImageVal - ) - { + public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal){ super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); currentToken = currentTokenVal; expectedTokenSequences = expectedTokenSequencesVal; @@ -52,12 +67,12 @@ * these constructors. */ - public ParseException() { + public ParseException(){ super(); } /** Constructor with message. */ - public ParseException(String message) { + public ParseException(String message){ super(message); } @@ -66,7 +81,6 @@ position = errorPosition; } - /** * This is the last token that has been consumed successfully. If * this object has been created due to a parse error, the token @@ -91,6 +105,38 @@ /** Line in the ADQL query where the exception occurs. */ protected TextPosition position = null; + /** Regular expression listing all ADQL reserved words. + * + *

      Note 1: + * This list is built NOT from the list given in the ADQL-2.0 standard, + * but from the collation of all words potentially used in an ADQL query + * (including standard function names). + *

      + * + *

      Note 2: + * This regular expression is only used to display an appropriate hint + * to the user in the error message if a such word is at the origin of + * the error. (see {@link #initialise(Token, int[][], String[])} for more + * details). + *

      */ + private final static String ADQL_RESERVED_WORDS_REGEX = "(ABS|ACOS|AREA|ASIN|ATAN|ATAN2|BOX|CEILING|CENTROID|CIRCLE|CONTAINS|COORD1|COORD2|COORDSYS|COS|DEGREES|DISTANCE|EXP|FLOOR|INTERSECTS|LOG|LOG10|MOD|PI|POINT|POLYGON|POWER|RADIANS|REGION|RAND|ROUND|SIN|SQRT|TOP|TAN|TRUNCATE|SELECT|TOP|DISTINCT|ALL|AS|COUNT|AVG|MAX|MIN|SUM|FROM|JOIN|CROSS|INNER|OUTER|LEFT|RIGHT|FULL|NATURAL|USING|ON|WHERE|IS|NOT|AND|OR|EXISTS|IN|LIKE|NULL|BETWEEN|ORDER|ASC|DESC|GROUP|BY|HAVING)"; + + /** Regular expression listing all SQL reserved words. + * + *

      Note 1: + * This list is built from the list given in the ADQL-2.0 standard, + * after removal of all words potentially used in an ADQL query + * (see {@link #ADQL_RESERVED_WORDS_REGEX}). + *

      + * + *

      Note 2: + * This regular expression is only used to display an appropriate hint + * to the user in the error message if a such word is at the origin of + * the error. (see {@link #initialise(Token, int[][], String[])} for more + * details). + *

      */ + private final static String SQL_RESERVED_WORDS_REGEX = "(ABSOLUTE|ACTION|ADD|ALLOCATE|ALTER|ANY|ARE|ASSERTION|AT|AUTHORIZATION|BEGIN|BIT|BIT_LENGTH|BOTH|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR|CHARACTER|CHAR_LENGTH|CHARACTER_LENGTH|CHECK|CLOSE|COALESCE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|CREATE|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATE|DAY|DEALLOCATE|DECIMAL|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DOMAIN|DOUBLE|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXTERNAL|EXTRACT|FALSE|FETCH|FIRST|FLOAT|FOR|FOREIGN|FOUND|GET|GLOBAL|GO|GOTO|GRANT|HOUR|IDENTITY|IMMEDIATE|INDICATOR|INITIALLY|INPUT|INSENSITIVE|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|ISOLATION|KEY|LANGUAGE|LAST|LEADING|LEVEL|LOCAL|LOWER|MATCH|MINUTE|MODULE|MONTH|NAMES|NATIONAL|NCHAR|NEXT|NO|NULLIF|NUMERIC|OCTET_LENGTH|OF|ONLY|OPEN|OPTION|OUTPUT|OVERLAPS|PAD|PARTIAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|ROLLBACK|ROWS|SCHEMA|SCROLL|SECOND|SECTION|SESSION|SESSION_USER|SET|SIZE|SMALLINT|SOME|SPACE|SQL|SQLCODE|SQLERROR|SQLSTATE|SUBSTRING|SYSTEM_USER|TABLE|TEMPORARY|THEN|TIME|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIM|TRUE|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|VALUE|VALUES|VARCHAR|VARYING|VIEW|WHEN|WHENEVER|WITH|WORK|WRITE|YEAR|ZONE)"; + /** * Gets the position in the ADQL query of the token which generates this exception. * @@ -107,16 +153,16 @@ * from the parser) the correct error message * gets displayed. */ - private static String initialise(Token currentToken, int[][] expectedTokenSequences, String[] tokenImage) { + private static String initialise(Token currentToken, int[][] expectedTokenSequences, String[] tokenImage){ int maxSize = 0; // Build the list of expected tokens: StringBuffer expected = new StringBuffer(); - for (int i = 0; i < expectedTokenSequences.length; i++) { - if (maxSize < expectedTokenSequences[i].length) { + for(int i = 0; i < expectedTokenSequences.length; i++){ + if (maxSize < expectedTokenSequences[i].length){ maxSize = expectedTokenSequences[i].length; } - for (int j = 0; j < expectedTokenSequences[i].length; j++) { + for(int j = 0; j < expectedTokenSequences[i].length; j++){ expected.append(tokenImage[expectedTokenSequences[i][j]]); } expected.append(" "); @@ -126,46 +172,55 @@ StringBuffer msg = new StringBuffer(); msg.append(" Encountered \""); Token tok = currentToken.next; - for (int i = 0; i < maxSize; i++) { - if (i != 0) msg.append(' '); - if (tok.kind == 0) { - msg.append(tokenImage[0]); + StringBuffer tokenName = new StringBuffer(); + for(int i = 0; i < maxSize; i++){ + if (i != 0) + tokenName.append(' '); + if (tok.kind == 0){ + tokenName.append(tokenImage[0]); break; } - msg.append(add_escapes(tok.image)); + tokenName.append(add_escapes(tok.image)); tok = tok.next; } - msg.append("\"."); + msg.append(tokenName.toString()).append("\"."); // Append the expected tokens list: - if (expectedTokenSequences.length == 1) { + if (expectedTokenSequences.length == 1){ msg.append(" Was expecting: "); - } else { + }else{ msg.append(" Was expecting one of: "); } msg.append(expected); + // Append a hint about reserved words if it is one: + String word = tokenName.toString().trim(); + if (word.toUpperCase().matches(ADQL_RESERVED_WORDS_REGEX)) + msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)"); + else if (word.toUpperCase().matches(SQL_RESERVED_WORDS_REGEX)) + msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)"); + return msg.toString(); /*String eol = System.getProperty("line.separator", "\n"); StringBuffer expected = new StringBuffer(); int maxSize = 0; - for (int i = 0; i < expectedTokenSequences.length; i++) { - if (maxSize < expectedTokenSequences[i].length) { + for(int i = 0; i < expectedTokenSequences.length; i++){ + if (maxSize < expectedTokenSequences[i].length){ maxSize = expectedTokenSequences[i].length; } - for (int j = 0; j < expectedTokenSequences[i].length; j++) { + for(int j = 0; j < expectedTokenSequences[i].length; j++){ expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); } - if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0){ expected.append("..."); } expected.append(eol).append(" "); } String retval = "Encountered \""; Token tok = currentToken.next; - for (int i = 0; i < maxSize; i++) { + for(int i = 0; i < maxSize; i++){ if (i != 0) retval += " "; - if (tok.kind == 0) { + if (tok.kind == 0){ retval += tokenImage[0]; break; } @@ -177,9 +232,9 @@ } retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; retval += "." + eol; - if (expectedTokenSequences.length == 1) { + if (expectedTokenSequences.length == 1){ retval += "Was expecting:" + eol + " "; - } else { + }else{ retval += "Was expecting one of:" + eol + " "; } retval += expected.toString(); @@ -196,46 +251,45 @@ * when these raw version cannot be used as part of an ASCII * string literal. */ - static String add_escapes(String str) { + static String add_escapes(String str){ StringBuffer retval = new StringBuffer(); char ch; - for (int i = 0; i < str.length(); i++) { - switch (str.charAt(i)) - { - case 0 : - continue; - case '\b': - retval.append("\\b"); - continue; - case '\t': - retval.append("\\t"); - continue; - case '\n': - retval.append("\\n"); - continue; - case '\f': - retval.append("\\f"); - continue; - case '\r': - retval.append("\\r"); - continue; - case '\"': - retval.append("\\\""); - continue; - case '\'': - retval.append("\\\'"); - continue; - case '\\': - retval.append("\\\\"); - continue; - default: - if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { - String s = "0000" + Integer.toString(ch, 16); - retval.append("\\u" + s.substring(s.length() - 4, s.length())); - } else { - retval.append(ch); - } - continue; + for(int i = 0; i < str.length(); i++){ + switch(str.charAt(i)){ + case 0: + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e){ + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + }else{ + retval.append(ch); + } + continue; } } return retval.toString(); diff -Nru adql-1.3/src/adql/parser/SimpleCharStream.java adql-1.4/src/adql/parser/SimpleCharStream.java --- adql-1.3/src/adql/parser/SimpleCharStream.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/parser/SimpleCharStream.java 2017-11-03 17:18:00.000000000 +0000 @@ -1,4 +1,4 @@ -/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 6.0 */ /* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ package adql.parser; @@ -7,7 +7,6 @@ * contain only ASCII characters (without unicode processing). */ -@SuppressWarnings("all") public class SimpleCharStream { /** Whether parser is static. */ public static final boolean staticFlag = false; @@ -31,12 +30,13 @@ protected int maxNextCharInd = 0; protected int inBuf = 0; protected int tabSize = 8; + protected boolean trackLineColumn = true; - protected void setTabSize(int i){ + public void setTabSize(int i){ tabSize = i; } - protected int getTabSize(int i){ + public int getTabSize(){ return tabSize; } @@ -183,6 +183,7 @@ * @deprecated * @see #getEndColumn */ + public int getColumn(){ return bufcolumn[bufpos]; } @@ -192,6 +193,7 @@ * @deprecated * @see #getEndLine */ + public int getLine(){ return bufline[bufpos]; } @@ -402,5 +404,12 @@ column = bufcolumn[j]; } + boolean getTrackLineColumn(){ + return trackLineColumn; + } + + void setTrackLineColumn(boolean tlc){ + trackLineColumn = tlc; + } } -/* JavaCC - OriginalChecksum=42af0fefd9dd6e805cbddca0a6f8ad37 (do not edit this line) */ +/* JavaCC - OriginalChecksum=25c201ae6a86f1f10a8af29118337505 (do not edit this line) */ diff -Nru adql-1.3/src/adql/parser/SimpleCharStream.java.backup adql-1.4/src/adql/parser/SimpleCharStream.java.backup --- adql-1.3/src/adql/parser/SimpleCharStream.java.backup 2014-04-03 17:52:24.000000000 +0000 +++ adql-1.4/src/adql/parser/SimpleCharStream.java.backup 2017-11-03 17:18:00.000000000 +0000 @@ -1,4 +1,4 @@ -/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 6.0 */ /* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ package adql.parser; @@ -7,466 +7,409 @@ * contain only ASCII characters (without unicode processing). */ -@SuppressWarnings("all") -public class SimpleCharStream -{ -/** Whether parser is static. */ - public static final boolean staticFlag = false; - int bufsize; - int available; - int tokenBegin; -/** Position in buffer. */ - public int bufpos = -1; - protected int bufline[]; - protected int bufcolumn[]; - - protected int column = 0; - protected int line = 1; - - protected boolean prevCharIsCR = false; - protected boolean prevCharIsLF = false; - - protected java.io.Reader inputStream; - - protected char[] buffer; - protected int maxNextCharInd = 0; - protected int inBuf = 0; - protected int tabSize = 8; - - protected void setTabSize(int i) { tabSize = i; } - protected int getTabSize(int i) { return tabSize; } - - - protected void ExpandBuff(boolean wrapAround) - { - char[] newbuffer = new char[bufsize + 2048]; - int newbufline[] = new int[bufsize + 2048]; - int newbufcolumn[] = new int[bufsize + 2048]; - - try - { - if (wrapAround) - { - System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); - System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); - buffer = newbuffer; - - System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); - System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); - bufline = newbufline; - - System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); - System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); - bufcolumn = newbufcolumn; - - maxNextCharInd = (bufpos += (bufsize - tokenBegin)); - } - else - { - System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); - buffer = newbuffer; - - System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); - bufline = newbufline; - - System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); - bufcolumn = newbufcolumn; - - maxNextCharInd = (bufpos -= tokenBegin); - } - } - catch (Throwable t) - { - throw new Error(t.getMessage()); - } - - - bufsize += 2048; - available = bufsize; - tokenBegin = 0; - } - - protected void FillBuff() throws java.io.IOException - { - if (maxNextCharInd == available) - { - if (available == bufsize) - { - if (tokenBegin > 2048) - { - bufpos = maxNextCharInd = 0; - available = tokenBegin; - } - else if (tokenBegin < 0) - bufpos = maxNextCharInd = 0; - else - ExpandBuff(false); - } - else if (available > tokenBegin) - available = bufsize; - else if ((tokenBegin - available) < 2048) - ExpandBuff(true); - else - available = tokenBegin; - } - - int i; - try { - if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) - { - inputStream.close(); - throw new java.io.IOException(); - } - else - maxNextCharInd += i; - return; - } - catch(java.io.IOException e) { - --bufpos; - backup(0); - if (tokenBegin == -1) - tokenBegin = bufpos; - throw e; - } - } - -/** Start. */ - public char BeginToken() throws java.io.IOException - { - tokenBegin = -1; - char c = readChar(); - tokenBegin = bufpos; - - return c; - } - - protected void UpdateLineColumn(char c) - { - column++; - - if (prevCharIsLF) - { - prevCharIsLF = false; - line += (column = 1); - } - else if (prevCharIsCR) - { - prevCharIsCR = false; - if (c == '\n') - { - prevCharIsLF = true; - } - else - line += (column = 1); - } - - switch (c) - { - case '\r' : - prevCharIsCR = true; - break; - case '\n' : - prevCharIsLF = true; - break; - case '\t' : - column--; - column += (tabSize - (column % tabSize)); - break; - default : - break; - } - - bufline[bufpos] = line; - bufcolumn[bufpos] = column; - } - -/** Read a character. */ - public char readChar() throws java.io.IOException - { - if (inBuf > 0) - { - --inBuf; - - if (++bufpos == bufsize) - bufpos = 0; - - return buffer[bufpos]; - } - - if (++bufpos >= maxNextCharInd) - FillBuff(); - - char c = buffer[bufpos]; - - UpdateLineColumn(c); - return c; - } - - @Deprecated - /** - * @deprecated - * @see #getEndColumn - */ - - public int getColumn() { - return bufcolumn[bufpos]; - } - - @Deprecated - /** - * @deprecated - * @see #getEndLine - */ - - public int getLine() { - return bufline[bufpos]; - } - - /** Get token end column number. */ - public int getEndColumn() { - return bufcolumn[bufpos]; - } - - /** Get token end line number. */ - public int getEndLine() { - return bufline[bufpos]; - } - - /** Get token beginning column number. */ - public int getBeginColumn() { - return bufcolumn[tokenBegin]; - } - - /** Get token beginning line number. */ - public int getBeginLine() { - return bufline[tokenBegin]; - } - -/** Backup a number of characters. */ - public void backup(int amount) { - - inBuf += amount; - if ((bufpos -= amount) < 0) - bufpos += bufsize; - } - - /** Constructor. */ - public SimpleCharStream(java.io.Reader dstream, int startline, - int startcolumn, int buffersize) - { - inputStream = dstream; - line = startline; - column = startcolumn - 1; - - available = bufsize = buffersize; - buffer = new char[buffersize]; - bufline = new int[buffersize]; - bufcolumn = new int[buffersize]; - } - - /** Constructor. */ - public SimpleCharStream(java.io.Reader dstream, int startline, - int startcolumn) - { - this(dstream, startline, startcolumn, 4096); - } - - /** Constructor. */ - public SimpleCharStream(java.io.Reader dstream) - { - this(dstream, 1, 1, 4096); - } - - /** Reinitialise. */ - public void ReInit(java.io.Reader dstream, int startline, - int startcolumn, int buffersize) - { - inputStream = dstream; - line = startline; - column = startcolumn - 1; - - if (buffer == null || buffersize != buffer.length) - { - available = bufsize = buffersize; - buffer = new char[buffersize]; - bufline = new int[buffersize]; - bufcolumn = new int[buffersize]; - } - prevCharIsLF = prevCharIsCR = false; - tokenBegin = inBuf = maxNextCharInd = 0; - bufpos = -1; - } - - /** Reinitialise. */ - public void ReInit(java.io.Reader dstream, int startline, - int startcolumn) - { - ReInit(dstream, startline, startcolumn, 4096); - } - - /** Reinitialise. */ - public void ReInit(java.io.Reader dstream) - { - ReInit(dstream, 1, 1, 4096); - } - /** Constructor. */ - public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, - int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException - { - this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); - } - - /** Constructor. */ - public SimpleCharStream(java.io.InputStream dstream, int startline, - int startcolumn, int buffersize) - { - this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); - } - - /** Constructor. */ - public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, - int startcolumn) throws java.io.UnsupportedEncodingException - { - this(dstream, encoding, startline, startcolumn, 4096); - } - - /** Constructor. */ - public SimpleCharStream(java.io.InputStream dstream, int startline, - int startcolumn) - { - this(dstream, startline, startcolumn, 4096); - } - - /** Constructor. */ - public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException - { - this(dstream, encoding, 1, 1, 4096); - } - - /** Constructor. */ - public SimpleCharStream(java.io.InputStream dstream) - { - this(dstream, 1, 1, 4096); - } - - /** Reinitialise. */ - public void ReInit(java.io.InputStream dstream, String encoding, int startline, - int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException - { - ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); - } - - /** Reinitialise. */ - public void ReInit(java.io.InputStream dstream, int startline, - int startcolumn, int buffersize) - { - ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); - } - - /** Reinitialise. */ - public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException - { - ReInit(dstream, encoding, 1, 1, 4096); - } - - /** Reinitialise. */ - public void ReInit(java.io.InputStream dstream) - { - ReInit(dstream, 1, 1, 4096); - } - /** Reinitialise. */ - public void ReInit(java.io.InputStream dstream, String encoding, int startline, - int startcolumn) throws java.io.UnsupportedEncodingException - { - ReInit(dstream, encoding, startline, startcolumn, 4096); - } - /** Reinitialise. */ - public void ReInit(java.io.InputStream dstream, int startline, - int startcolumn) - { - ReInit(dstream, startline, startcolumn, 4096); - } - /** Get token literal value. */ - public String GetImage() - { - if (bufpos >= tokenBegin) - return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); - else - return new String(buffer, tokenBegin, bufsize - tokenBegin) + - new String(buffer, 0, bufpos + 1); - } - - /** Get the suffix. */ - public char[] GetSuffix(int len) - { - char[] ret = new char[len]; - - if ((bufpos + 1) >= len) - System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); - else - { - System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, - len - bufpos - 1); - System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); - } - - return ret; - } - - /** Reset buffer when finished. */ - public void Done() - { - buffer = null; - bufline = null; - bufcolumn = null; - } - - /** - * Method to adjust line and column numbers for the start of a token. - */ - public void adjustBeginLineColumn(int newLine, int newCol) - { - int start = tokenBegin; - int len; - - if (bufpos >= tokenBegin) - { - len = bufpos - tokenBegin + inBuf + 1; - } - else - { - len = bufsize - tokenBegin + bufpos + 1 + inBuf; - } - - int i = 0, j = 0, k = 0; - int nextColDiff = 0, columnDiff = 0; - - while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) - { - bufline[j] = newLine; - nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; - bufcolumn[j] = newCol + columnDiff; - columnDiff = nextColDiff; - i++; - } - - if (i < len) - { - bufline[j] = newLine++; - bufcolumn[j] = newCol + columnDiff; - - while (i++ < len) - { - if (bufline[j = start % bufsize] != bufline[++start % bufsize]) - bufline[j] = newLine++; - else - bufline[j] = newLine; - } - } - - line = bufline[j]; - column = bufcolumn[j]; - } - +public class SimpleCharStream { + /** Whether parser is static. */ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; + /** Position in buffer. */ + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + protected boolean trackLineColumn = true; + + public void setTabSize(int i){ + tabSize = i; + } + + public int getTabSize(){ + return tabSize; + } + + protected void ExpandBuff(boolean wrapAround){ + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try{ + if (wrapAround){ + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + }else{ + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + }catch(Throwable t){ + throw new Error(t.getMessage()); + } + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException{ + if (maxNextCharInd == available){ + if (available == bufsize){ + if (tokenBegin > 2048){ + bufpos = maxNextCharInd = 0; + available = tokenBegin; + }else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + }else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try{ + if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1){ + inputStream.close(); + throw new java.io.IOException(); + }else + maxNextCharInd += i; + return; + }catch(java.io.IOException e){ + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + + /** Start. */ + public char BeginToken() throws java.io.IOException{ + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c){ + column++; + + if (prevCharIsLF){ + prevCharIsLF = false; + line += (column = 1); + }else if (prevCharIsCR){ + prevCharIsCR = false; + if (c == '\n'){ + prevCharIsLF = true; + }else + line += (column = 1); + } + + switch(c){ + case '\r': + prevCharIsCR = true; + break; + case '\n': + prevCharIsLF = true; + break; + case '\t': + column--; + column += (tabSize - (column % tabSize)); + break; + default: + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + + /** Read a character. */ + public char readChar() throws java.io.IOException{ + if (inBuf > 0){ + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn(){ + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine(){ + return bufline[bufpos]; + } + + /** Get token end column number. */ + public int getEndColumn(){ + return bufcolumn[bufpos]; + } + + /** Get token end line number. */ + public int getEndLine(){ + return bufline[bufpos]; + } + + /** Get token beginning column number. */ + public int getBeginColumn(){ + return bufcolumn[tokenBegin]; + } + + /** Get token beginning line number. */ + public int getBeginLine(){ + return bufline[tokenBegin]; + } + + /** Backup a number of characters. */ + public void backup(int amount){ + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, int startcolumn, int buffersize){ + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, int startcolumn){ + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream){ + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, int startcolumn, int buffersize){ + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length){ + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, int startcolumn){ + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream){ + ReInit(dstream, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException{ + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, int startcolumn, int buffersize){ + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, int startcolumn) throws java.io.UnsupportedEncodingException{ + this(dstream, encoding, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, int startcolumn){ + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException{ + this(dstream, encoding, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream){ + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException{ + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, int startcolumn, int buffersize){ + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException{ + ReInit(dstream, encoding, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream){ + ReInit(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, int startcolumn) throws java.io.UnsupportedEncodingException{ + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, int startcolumn){ + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Get token literal value. */ + public String GetImage(){ + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + new String(buffer, 0, bufpos + 1); + } + + /** Get the suffix. */ + public char[] GetSuffix(int len){ + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else{ + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Reset buffer when finished. */ + public void Done(){ + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol){ + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin){ + len = bufpos - tokenBegin + inBuf + 1; + }else{ + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while(i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]){ + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len){ + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while(i++ < len){ + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + + boolean getTrackLineColumn(){ + return trackLineColumn; + } + + void setTrackLineColumn(boolean tlc){ + trackLineColumn = tlc; + } } -/* JavaCC - OriginalChecksum=42af0fefd9dd6e805cbddca0a6f8ad37 (do not edit this line) */ +/* JavaCC - OriginalChecksum=25c201ae6a86f1f10a8af29118337505 (do not edit this line) */ diff -Nru adql-1.3/src/adql/parser/SQLServer_ADQLQueryFactory.java adql-1.4/src/adql/parser/SQLServer_ADQLQueryFactory.java --- adql-1.3/src/adql/parser/SQLServer_ADQLQueryFactory.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/parser/SQLServer_ADQLQueryFactory.java 2017-11-03 17:18:00.000000000 +0000 @@ -0,0 +1,75 @@ +package adql.parser; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ADQLLibrary. If not, see . + * + * Copyright 2016 - Astronomisches Rechen Institut (ARI) + */ + +import adql.query.from.ADQLJoin; +import adql.query.from.CrossJoin; +import adql.query.from.FromContent; +import adql.query.from.InnerJoin; +import adql.query.from.OuterJoin; +import adql.query.from.SQLServer_InnerJoin; +import adql.query.from.SQLServer_OuterJoin; +import adql.query.from.OuterJoin.OuterType; +import adql.translator.SQLServerTranslator; + +/** + *

      Special extension of {@link ADQLQueryFactory} for MS SQL Server.

      + * + *

      Important: + * This class is generally used when an ADQL translator for MS SQL Server is needed. + * See {@link SQLServerTranslator} for more details. + *

      + * + *

      + * The only difference with {@link ADQLQueryFactory} is the creation of an + * {@link ADQLJoin}. Instead of creating {@link InnerJoin} and {@link OuterJoin}, + * {@link SQLServer_InnerJoin} and {@link SQLServer_OuterJoin} are respectively created. + * The only difference between these last classes and the first ones is in the processing + * of NATURAL JOINs and JOINs using the keyword USING. + *

      + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (03/2016) + * @since 1.4 + * + * @see SQLServer_InnerJoin + * @see SQLServer_OuterJoin + * @see SQLServerTranslator + */ +public class SQLServer_ADQLQueryFactory extends ADQLQueryFactory { + + public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable) throws Exception{ + switch(type){ + case CROSS: + return new CrossJoin(leftTable, rightTable); + case INNER: + return new SQLServer_InnerJoin(leftTable, rightTable); + case OUTER_LEFT: + return new SQLServer_OuterJoin(leftTable, rightTable, OuterType.LEFT); + case OUTER_RIGHT: + return new SQLServer_OuterJoin(leftTable, rightTable, OuterType.RIGHT); + case OUTER_FULL: + return new SQLServer_OuterJoin(leftTable, rightTable, OuterType.FULL); + default: + throw new Exception("Unknown join type: " + type); + } + } + +} \ No newline at end of file diff -Nru adql-1.3/src/adql/parser/Token.java adql-1.4/src/adql/parser/Token.java --- adql-1.3/src/adql/parser/Token.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/parser/Token.java 2017-11-03 17:18:00.000000000 +0000 @@ -1,12 +1,20 @@ -/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ -/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 6.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true + * + * Modified by Grégory Mantelet (CDS), on March 2017 + * Modification: addition of position (line and column) in the original text. + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by + * Token.java.backup (but maybe after a diff + * in case of significant modifications have been done + * by a new version of JavaCC). + */ package adql.parser; /** * Describes the input token stream. */ -@SuppressWarnings("all") public class Token implements java.io.Serializable { /** @@ -96,6 +104,7 @@ /** * Returns the image. */ + @Override public String toString(){ return image; } @@ -124,4 +133,4 @@ } } -/* JavaCC - OriginalChecksum=d231e694113b489b136cc4eb57fc02f6 (do not edit this line) */ +/* JavaCC - OriginalChecksum=4c61cfbec4532a0e2168ba896283031a (do not edit this line) */ diff -Nru adql-1.3/src/adql/parser/Token.java.backup adql-1.4/src/adql/parser/Token.java.backup --- adql-1.3/src/adql/parser/Token.java.backup 2014-04-03 17:52:24.000000000 +0000 +++ adql-1.4/src/adql/parser/Token.java.backup 2017-11-03 17:18:00.000000000 +0000 @@ -1,132 +1,136 @@ -/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ -/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 6.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true + * + * Modified by Grégory Mantelet (CDS), on March 2017 + * Modification: addition of position (line and column) in the original text. + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by + * Token.java.backup (but maybe after a diff + * in case of significant modifications have been done + * by a new version of JavaCC). + */ package adql.parser; /** * Describes the input token stream. */ -@SuppressWarnings("all") public class Token implements java.io.Serializable { - /** - * The version identifier for this Serializable class. - * Increment only if the serialized form of the - * class changes. - */ - private static final long serialVersionUID = 1L; - - /** - * An integer that describes the kind of this token. This numbering - * system is determined by JavaCCParser, and a table of these numbers is - * stored in the file ...Constants.java. - */ - public int kind; - - /** The line number of the first character of this Token. */ - public int beginLine; - /** The column number of the first character of this Token. */ - public int beginColumn; - /** The line number of the last character of this Token. */ - public int endLine; - /** The column number of the last character of this Token. */ - public int endColumn; - - /** - * The string image of the token. - */ - public String image; - - /** - * A reference to the next regular (non-special) token from the input - * stream. If this is the last token from the input stream, or if the - * token manager has not read tokens beyond this one, this field is - * set to null. This is true only if this token is also a regular - * token. Otherwise, see below for a description of the contents of - * this field. - */ - public Token next; - - /** - * This field is used to access special tokens that occur prior to this - * token, but after the immediately preceding regular (non-special) token. - * If there are no such special tokens, this field is set to null. - * When there are more than one such special token, this field refers - * to the last of these special tokens, which in turn refers to the next - * previous special token through its specialToken field, and so on - * until the first special token (whose specialToken field is null). - * The next fields of special tokens refer to other special tokens that - * immediately follow it (without an intervening regular token). If there - * is no such token, this field is null. - */ - public Token specialToken; - - /** - * An optional attribute value of the Token. - * Tokens which are not used as syntactic sugar will often contain - * meaningful values that will be used later on by the compiler or - * interpreter. This attribute value is often different from the image. - * Any subclass of Token that actually wants to return a non-null value can - * override this method as appropriate. - */ - public Object getValue() { - return null; - } - - /** - * No-argument constructor - */ - public Token() {} - - /** - * Constructs a new token for the specified Image. - */ - public Token(int kind) - { - this(kind, null); - } - - /** - * Constructs a new token for the specified Image and Kind. - */ - public Token(int kind, String image) - { - this.kind = kind; - this.image = image; - } - - /** - * Returns the image. - */ - public String toString() - { - return image; - } - - /** - * Returns a new Token object, by default. However, if you want, you - * can create and return subclass objects based on the value of ofKind. - * Simply add the cases to the switch for all those special cases. - * For example, if you have a subclass of Token called IDToken that - * you want to create if ofKind is ID, simply add something like : - * - * case MyParserConstants.ID : return new IDToken(ofKind, image); - * - * to the following switch statement. Then you can cast matchedToken - * variable to the appropriate type and use sit in your lexical actions. - */ - public static Token newToken(int ofKind, String image) - { - switch(ofKind) - { - default : return new Token(ofKind, image); - } - } - - public static Token newToken(int ofKind) - { - return newToken(ofKind, null); - } + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public Object getValue(){ + return null; + } + + /** + * No-argument constructor + */ + public Token(){} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind){ + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image){ + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + @Override + public String toString(){ + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image){ + switch(ofKind){ + default: + return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind){ + return newToken(ofKind, null); + } } -/* JavaCC - OriginalChecksum=d231e694113b489b136cc4eb57fc02f6 (do not edit this line) */ +/* JavaCC - OriginalChecksum=4c61cfbec4532a0e2168ba896283031a (do not edit this line) */ diff -Nru adql-1.3/src/adql/parser/TokenMgrError.java adql-1.4/src/adql/parser/TokenMgrError.java --- adql-1.3/src/adql/parser/TokenMgrError.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/parser/TokenMgrError.java 2017-11-03 17:18:00.000000000 +0000 @@ -1,10 +1,21 @@ -/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ -/* JavaCCOptions: */ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 6.0 */ +/* JavaCCOptions: + * + * Modified by Grégory Mantelet (CDS), on Sept. 2017 + * Modifications: + * - addition of position (line and column) in the original text + * - adapt the error message so that being more explicit for humans + * and display the incorrect character as a character instead of an + * integer value + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by TokenMgrError.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). + */ package adql.parser; /** Token Manager Error. */ - -@SuppressWarnings("all") public class TokenMgrError extends Error { /** @@ -111,7 +122,7 @@ * Note: You can customize the lexical error message by modifying this method. */ protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar){ - return ("Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered: " + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + "after : \"" + addEscapes(errorAfter) + "\""); + return ("Incorrect character encountered at l." + errorLine + ", c." + errorColumn + ": " + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " ('" + curChar + "'), ") + "after : \"" + addEscapes(errorAfter) + "\""); } /** @@ -166,4 +177,4 @@ this.errorColumn = errorColumn; } } -/* JavaCC - OriginalChecksum=be62b718c6ea188d507367a8560343a1 (do not edit this line) */ +/* JavaCC - OriginalChecksum=f63fc7c10226c13ff5a304e2fb1ae182 (do not edit this line) */ diff -Nru adql-1.3/src/adql/parser/TokenMgrError.java.backup adql-1.4/src/adql/parser/TokenMgrError.java.backup --- adql-1.3/src/adql/parser/TokenMgrError.java.backup 2014-04-03 17:52:24.000000000 +0000 +++ adql-1.4/src/adql/parser/TokenMgrError.java.backup 2017-11-03 17:18:00.000000000 +0000 @@ -1,18 +1,20 @@ -/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ -/* JavaCCOptions: */ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 6.0 */ +/* JavaCCOptions: + * + * Modified by Grégory Mantelet (CDS), on Sept. 2017 + * Modifications: + * - addition of position (line and column) in the original text + * - display the incorrect character as a character instead of an integer + * + * /!\ DO NOT RE-GENERATE THIS FILE /!\ + * In case of re-generation, replace it by TokenMgrError.java.backup (but maybe + * after a diff in case of significant modifications have been done by a new + * version of JavaCC). + */ package adql.parser; /** Token Manager Error. */ -/** - * TODO Javadoc of TokenMgrError ! - * - * @author Grégory Mantelet (CDS) - * @version 08/2011 - * - */ -@SuppressWarnings("all") -public class TokenMgrError extends Error -{ +public class TokenMgrError extends Error { /** * The version identifier for this Serializable class. @@ -61,46 +63,45 @@ * Replaces unprintable characters by their escaped (or unicode escaped) * equivalents in the given string */ - protected static final String addEscapes(String str) { + protected static final String addEscapes(String str){ StringBuffer retval = new StringBuffer(); char ch; - for (int i = 0; i < str.length(); i++) { - switch (str.charAt(i)) - { - case 0 : - continue; - case '\b': - retval.append("\\b"); - continue; - case '\t': - retval.append("\\t"); - continue; - case '\n': - retval.append("\\n"); - continue; - case '\f': - retval.append("\\f"); - continue; - case '\r': - retval.append("\\r"); - continue; - case '\"': - retval.append("\\\""); - continue; - case '\'': - retval.append("\\\'"); - continue; - case '\\': - retval.append("\\\\"); - continue; - default: - if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { - String s = "0000" + Integer.toString(ch, 16); - retval.append("\\u" + s.substring(s.length() - 4, s.length())); - } else { - retval.append(ch); - } - continue; + for(int i = 0; i < str.length(); i++){ + switch(str.charAt(i)){ + case 0: + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e){ + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + }else{ + retval.append(ch); + } + continue; } } return retval.toString(); @@ -118,12 +119,8 @@ * curchar : the offending character * Note: You can customize the lexical error message by modifying this method. */ - protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { - return("Lexical error at line " + - errorLine + ", column " + - errorColumn + ". Encountered: " + - (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + - "after : \"" + addEscapes(errorAfter) + "\""); + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar){ + return ("Incorrect character encountered at l." + errorLine + ", c." + errorColumn + ": " + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " ('" + curChar + "'), ") + "after : \"" + addEscapes(errorAfter) + "\""); } /** @@ -135,7 +132,8 @@ * * from this method for such cases in the release version of your parser. */ - public String getMessage() { + @Override + public String getMessage(){ return super.getMessage(); } @@ -162,20 +160,19 @@ */ /** No arg constructor. */ - public TokenMgrError() { - } + public TokenMgrError(){} /** Constructor with message and reason. */ - public TokenMgrError(String message, int reason) { + public TokenMgrError(String message, int reason){ super(message); errorCode = reason; } /** Full Constructor. */ - public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason){ this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); this.errorLine = errorLine; this.errorColumn = errorColumn; } } -/* JavaCC - OriginalChecksum=be62b718c6ea188d507367a8560343a1 (do not edit this line) */ +/* JavaCC - OriginalChecksum=f63fc7c10226c13ff5a304e2fb1ae182 (do not edit this line) */ diff -Nru adql-1.3/src/adql/query/ADQLList.java adql-1.4/src/adql/query/ADQLList.java --- adql-1.3/src/adql/query/ADQLList.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/ADQLList.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -29,7 +29,7 @@ *

      Since it is a list, it is possible to add, remove, modify and iterate on a such object.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 2.2 (10/2014) + * @version 1.4 (06/2015) * * @see ClauseADQL * @see ClauseConstraints @@ -44,6 +44,10 @@ /** List of ADQL items. */ private final Vector list = new Vector(); + /** Position inside an ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds an ADQLList with only its name. This name will always prefix the list. * @@ -71,6 +75,7 @@ this(toCopy.getName()); for(T obj : toCopy) add((T)obj.getCopy()); + position = (toCopy.position != null) ? new TextPosition(toCopy.position) : null; } /** @@ -83,8 +88,13 @@ public boolean add(T item) throws NullPointerException{ if (item == null) throw new NullPointerException("It is impossible to add NULL items to an ADQL clause !"); - else - return list.add(item); + else{ + if (list.add(item)){ + position = null; + return true; + }else + return false; + } } /** @@ -96,9 +106,10 @@ * @throws ArrayIndexOutOfBoundsException If the index is out of range (index < 0 || index > size()). */ public void add(int index, T item) throws NullPointerException, ArrayIndexOutOfBoundsException{ - if (item != null) + if (item != null){ list.add(index, item); - else + position = null; + }else throw new NullPointerException("It is impossible to add NULL items to an ADQL clause !"); } @@ -112,9 +123,11 @@ * @throws ArrayIndexOutOfBoundsException If the index is out of range (index < 0 || index > size()). */ public T set(int index, T item) throws NullPointerException, ArrayIndexOutOfBoundsException{ - if (item != null) - return list.set(index, item); - else + if (item != null){ + T removed = list.set(index, item); + position = null; + return removed; + }else throw new NullPointerException("It is impossible to replace an ADQL item by a NULL item into an ADQL clause !"); } @@ -137,7 +150,10 @@ * @throws ArrayIndexOutOfBoundsException If the index is out of range (index < 0 || index > size()). */ public T remove(int index) throws ArrayIndexOutOfBoundsException{ - return list.remove(index); + T removed = list.remove(index); + if (removed != null) + position = null; + return removed; } /** @@ -145,6 +161,7 @@ */ public void clear(){ list.clear(); + position = null; } /** @@ -171,6 +188,21 @@ } @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Sets the position at which this {@link ADQLList} has been found in the original ADQL query string. + * + * @param position Position of this {@link ADQLList}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public String toADQL(){ StringBuffer adql = new StringBuffer((getName() == null) ? "" : (getName() + " ")); diff -Nru adql-1.3/src/adql/query/ADQLObject.java adql-1.4/src/adql/query/ADQLObject.java --- adql-1.3/src/adql/query/ADQLObject.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/ADQLObject.java 2017-11-03 17:18:00.000000000 +0000 @@ -18,7 +18,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ /** @@ -26,12 +27,13 @@ *
        *
      • to have a name in ADQL *
      • to be written in ADQL
      • - *
      • to offer a way to search any ADQL item (included itself).
      • + *
      • to offer a way to search any ADQL item (included itself)
      • + *
      • to get its position in the original ADQL query.
      • *
      *

      * - * @author Grégory Mantelet (CDS) - * @version 01/2012 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public interface ADQLObject { @@ -43,6 +45,17 @@ public String getName(); /** + *

      Gets the position of this object/token in the ADQL query.

      + *

      By default, no position should be set.

      + * + * @return Position of this ADQL item in the ADQL query, + * or NULL if not written originally in the query (for example, if added afterwards. + * + * @since 1.4 + */ + public TextPosition getPosition(); + + /** * Gets the ADQL expression of this object. * * @return The corresponding ADQL expression. diff -Nru adql-1.3/src/adql/query/ADQLQuery.java adql-1.4/src/adql/query/ADQLQuery.java --- adql-1.3/src/adql/query/ADQLQuery.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/ADQLQuery.java 2017-11-30 16:16:32.000000000 +0000 @@ -2,21 +2,21 @@ /* * This file is part of ADQLLibrary. - * + * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . - * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -25,20 +25,29 @@ import java.util.NoSuchElementException; import adql.db.DBColumn; +import adql.db.DBType; +import adql.db.DBType.DBDatatype; import adql.db.DefaultDBColumn; import adql.parser.ADQLParser; import adql.parser.ParseException; import adql.query.from.FromContent; import adql.query.operand.ADQLColumn; import adql.query.operand.ADQLOperand; +import adql.query.operand.function.DefaultUDF; +import adql.query.operand.function.geometry.BoxFunction; +import adql.query.operand.function.geometry.CentroidFunction; +import adql.query.operand.function.geometry.CircleFunction; +import adql.query.operand.function.geometry.PointFunction; +import adql.query.operand.function.geometry.PolygonFunction; +import adql.query.operand.function.geometry.RegionFunction; import adql.search.ISearchHandler; /** *

      Object representation of an ADQL query or sub-query.

      *

      The resulting object of the {@link ADQLParser} is an object of this class.

      - * + * * @author Grégory Mantelet (CDS;ARI) - * @version 1.2 (09/2014) + * @version 1.4 (11/2017) */ public class ADQLQuery implements ADQLObject { @@ -52,7 +61,7 @@ private ClauseConstraints where; /** The ADQL clause GROUP BY. */ - private ClauseADQL groupBy; + private ClauseADQL groupBy; /** The ADQL clause HAVING. */ private ClauseConstraints having; @@ -60,6 +69,10 @@ /** The ADQL clause ORDER BY. */ private ClauseADQL orderBy; + /** Position of this Query (or sub-query) inside the whole given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds an empty ADQL query. */ @@ -67,14 +80,14 @@ select = new ClauseSelect(); from = null; where = new ClauseConstraints("WHERE"); - groupBy = new ClauseADQL("GROUP BY"); + groupBy = new ClauseADQL("GROUP BY"); having = new ClauseConstraints("HAVING"); orderBy = new ClauseADQL("ORDER BY"); } /** * Builds an ADQL query by copying the given one. - * + * * @param toCopy The ADQL query to copy. * @throws Exception If there is an error during the copy. */ @@ -83,9 +96,10 @@ select = (ClauseSelect)toCopy.select.getCopy(); from = (FromContent)toCopy.from.getCopy(); where = (ClauseConstraints)toCopy.where.getCopy(); - groupBy = (ClauseADQL)toCopy.groupBy.getCopy(); + groupBy = (ClauseADQL)toCopy.groupBy.getCopy(); having = (ClauseConstraints)toCopy.having.getCopy(); orderBy = (ClauseADQL)toCopy.orderBy.getCopy(); + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -101,11 +115,12 @@ groupBy.clear(); having.clear(); orderBy.clear(); + position = null; } /** * Gets the SELECT clause of this query. - * + * * @return Its SELECT clause. */ public final ClauseSelect getSelect(){ @@ -113,10 +128,12 @@ } /** - * Replaces its SELECT clause by the given one. - * + *

      Replaces its SELECT clause by the given one.

      + * + *

      note: the position of the query is erased.

      + * * @param newSelect The new SELECT clause. - * + * * @throws NullPointerException If the given SELECT clause is null. */ public void setSelect(ClauseSelect newSelect) throws NullPointerException{ @@ -124,11 +141,12 @@ throw new NullPointerException("Impossible to replace the SELECT clause of a query by NULL !"); else select = newSelect; + position = null; } /** * Gets the FROM clause of this query. - * + * * @return Its FROM clause. */ public final FromContent getFrom(){ @@ -136,10 +154,12 @@ } /** - * Replaces its FROM clause by the given one. - * + *

      Replaces its FROM clause by the given one.

      + * + *

      note: the position of the query is erased.

      + * * @param newFrom The new FROM clause. - * + * * @throws NullPointerException If the given FROM clause is null. */ public void setFrom(FromContent newFrom) throws NullPointerException{ @@ -147,11 +167,12 @@ throw new NullPointerException("Impossible to replace the FROM clause of a query by NULL !"); else from = newFrom; + position = null; } /** * Gets the WHERE clause of this query. - * + * * @return Its WHERE clause. */ public final ClauseConstraints getWhere(){ @@ -159,10 +180,12 @@ } /** - * Replaces its WHERE clause by the given one. - * + *

      Replaces its WHERE clause by the given one.

      + * + *

      note: the position of the query is erased.

      + * * @param newWhere The new WHERE clause. - * + * * @throws NullPointerException If the given WHERE clause is null. */ public void setWhere(ClauseConstraints newWhere) throws NullPointerException{ @@ -170,33 +193,37 @@ where.clear(); else where = newWhere; + position = null; } /** * Gets the GROUP BY clause of this query. - * + * * @return Its GROUP BY clause. */ - public final ClauseADQL getGroupBy(){ + public final ClauseADQL getGroupBy(){ return groupBy; } /** - * Replaces its GROUP BY clause by the given one. - * + *

      Replaces its GROUP BY clause by the given one.

      + * + *

      note: the position of the query is erased.

      + * * @param newGroupBy The new GROUP BY clause. * @throws NullPointerException If the given GROUP BY clause is null. */ - public void setGroupBy(ClauseADQL newGroupBy) throws NullPointerException{ + public void setGroupBy(ClauseADQL newGroupBy) throws NullPointerException{ if (newGroupBy == null) groupBy.clear(); else groupBy = newGroupBy; + position = null; } /** * Gets the HAVING clause of this query. - * + * * @return Its HAVING clause. */ public final ClauseConstraints getHaving(){ @@ -204,8 +231,10 @@ } /** - * Replaces its HAVING clause by the given one. - * + *

      Replaces its HAVING clause by the given one.

      + * + *

      note: the position of the query is erased.

      + * * @param newHaving The new HAVING clause. * @throws NullPointerException If the given HAVING clause is null. */ @@ -214,11 +243,12 @@ having.clear(); else having = newHaving; + position = null; } /** * Gets the ORDER BY clause of this query. - * + * * @return Its ORDER BY clause. */ public final ClauseADQL getOrderBy(){ @@ -226,8 +256,10 @@ } /** - * Replaces its ORDER BY clause by the given one. - * + *

      Replaces its ORDER BY clause by the given one.

      + * + *

      note: the position of the query is erased.

      + * * @param newOrderBy The new ORDER BY clause. * @throws NullPointerException If the given ORDER BY clause is null. */ @@ -236,6 +268,22 @@ orderBy.clear(); else orderBy = newOrderBy; + position = null; + } + + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link ADQLQuery} (or sub-query) inside the whole given ADQL query string. + * + * @param position New position of this {@link ADQLQuery}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; } @Override @@ -250,9 +298,9 @@ /** *

      Gets the list of columns (database metadata) selected by this query.

      - * + * *

      Note: The list is generated on the fly !

      - * + * * @return Selected columns metadata. */ public DBColumn[] getResultingColumns(){ @@ -272,19 +320,59 @@ // Here, this error should not occur any more, since it must have been caught by the DBChecker! } }else{ + // Create the DBColumn: DBColumn col = null; + // ...whose the name will be set with the SELECT item's alias: if (item.hasAlias()){ + // put the alias in lower case if not written between "": + /* Note: This aims to avoid unexpected behavior at execution + * time in the DBMS (i.e. the case sensitivity is + * forced for every references to this column alias). */ + String alias = item.getAlias(); + if (!item.isCaseSensitive()) + alias = alias.toLowerCase(); + + // create the DBColumn: if (operand instanceof ADQLColumn && ((ADQLColumn)operand).getDBLink() != null){ col = ((ADQLColumn)operand).getDBLink(); - col = col.copy(col.getDBName(), item.getAlias(), col.getTable()); + col = col.copy(col.getDBName(), alias, col.getTable()); }else - col = new DefaultDBColumn(item.getAlias(), null); - }else{ + col = new DefaultDBColumn(alias, null); + } + // ...or whose the name will be the name of the SELECT item: + else{ if (operand instanceof ADQLColumn && ((ADQLColumn)operand).getDBLink() != null) col = ((ADQLColumn)operand).getDBLink(); - if (col == null) + else col = new DefaultDBColumn(item.getName(), null); } + + /* For columns created by default (from functions and operations generally), + * set the adequate type if known: */ + // CASE: Well-defined UDF + if (operand instanceof DefaultUDF && ((DefaultUDF)operand).getDefinition() != null){ + DBType type = ((DefaultUDF)operand).getDefinition().returnType; + ((DefaultDBColumn)col).setDatatype(type); + } + // CASE: Point type: + else if (operand instanceof PointFunction || operand instanceof CentroidFunction) + ((DefaultDBColumn)col).setDatatype(new DBType(DBDatatype.POINT)); + // CASE: Region type: + else if (operand instanceof RegionFunction || operand instanceof CircleFunction || operand instanceof BoxFunction || operand instanceof PolygonFunction) + ((DefaultDBColumn)col).setDatatype(new DBType(DBDatatype.REGION)); + // CASE: String and numeric types + else if (col instanceof DefaultDBColumn && col.getDatatype() == null && operand.isNumeric() != operand.isString()){ + // CASE: String types + if (operand.isString()) + ((DefaultDBColumn)col).setDatatype(new DBType(DBDatatype.VARCHAR)); + // CASE: Numeric types: + /* Note: a little special case here since a numeric could be a real, double, integer, or anything + * else and that we don't know precisely here. So we set the special UNKNOWN NUMERIC type. */ + else + ((DefaultDBColumn)col).setDatatype(new DBType(DBDatatype.UNKNOWN_NUMERIC)); + } + + // Add the new column to the list: columns.add(col); } } @@ -295,9 +383,9 @@ /** * Lets searching ADQL objects into this ADQL query thanks to the given search handler. - * + * * @param sHandler A search handler. - * + * * @return An iterator on all ADQL objects found. */ public Iterator search(ISearchHandler sHandler){ @@ -375,7 +463,7 @@ break; case 3: if (replacer instanceof ClauseADQL) - groupBy = (ClauseADQL)replacer; + groupBy = (ClauseADQL)replacer; else throw new UnsupportedOperationException("Impossible to replace a ClauseADQL (" + groupBy.toADQL() + ") by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); break; @@ -392,6 +480,7 @@ throw new UnsupportedOperationException("Impossible to replace a ClauseADQL (" + orderBy.toADQL() + ") by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); break; } + position = null; } } @@ -402,8 +491,10 @@ if (index == 0 || index == 1) throw new UnsupportedOperationException("Impossible to remove a " + ((index == 0) ? "SELECT" : "FROM") + " clause from a query !"); - else + else{ currentClause.clear(); + position = null; + } } }; } @@ -428,4 +519,4 @@ return adql.toString(); } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/ClauseSelect.java adql-1.4/src/adql/query/ClauseSelect.java --- adql-1.3/src/adql/query/ClauseSelect.java 2015-03-13 18:21:20.000000000 +0000 +++ adql-1.4/src/adql/query/ClauseSelect.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,10 +16,12 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institut (ARI) */ import java.util.ArrayList; +import java.util.List; import adql.query.operand.ADQLOperand; @@ -30,8 +32,8 @@ *
      • The user can specify the maximum number of rows the query must return.
      • *
      • He can also ask that all the returned rows are unique according to the first returned column.

      * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (09/2017) */ public class ClauseSelect extends ClauseADQL { @@ -218,7 +220,7 @@ * @see #searchByAlias(String, boolean) */ public ADQLOperand searchByAlias(String alias){ - ArrayList founds = searchByAlias(alias, true); + List founds = searchByAlias(alias, true); if (founds.isEmpty()) return null; else @@ -231,7 +233,7 @@ * @param alias Alias of the operand to retrieve. * @return All the corresponding select items. */ - public ArrayList searchByAlias(String alias, boolean caseSensitive){ + public List searchByAlias(String alias, boolean caseSensitive){ if (alias == null) return new ArrayList(0); diff -Nru adql-1.3/src/adql/query/ColumnReference.java adql-1.4/src/adql/query/ColumnReference.java --- adql-1.3/src/adql/query/ColumnReference.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/ColumnReference.java 2017-11-03 17:18:00.000000000 +0000 @@ -24,7 +24,7 @@ import adql.query.operand.ADQLColumn; /** - * Represents a reference to a selected column either by an index or by a name/alias. + * Represents a reference to a selected column either by an index or by a non-qualified column name/alias. * * @author Grégory Mantelet (CDS) * @version 01/2012 @@ -94,6 +94,7 @@ * * @return The position of this {@link ColumnReference}. */ + @Override public final TextPosition getPosition(){ return position; } @@ -235,18 +236,22 @@ this.adqlTable = adqlTable; } + @Override public ADQLObject getCopy() throws Exception{ return new ColumnReference(this); } + @Override public String getName(){ return isIndex() ? (columnIndex + "") : columnName; } + @Override public final ADQLIterator adqlIterator(){ return new NullADQLIterator(); } + @Override public String toADQL(){ return isIndex() ? ("" + columnIndex) : (isCaseSensitive() ? ("\"" + columnName + "\"") : columnName); } diff -Nru adql-1.3/src/adql/query/constraint/Between.java adql-1.4/src/adql/query/constraint/Between.java --- adql-1.3/src/adql/query/constraint/Between.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/constraint/Between.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,14 +16,15 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; import adql.query.ADQLIterator; import adql.query.ADQLObject; - +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** @@ -32,8 +33,8 @@ *

      This predicate returns true if the value of the left operand is * between the value of the two other operands, else it returns false.

      * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public class Between implements ADQLConstraint { @@ -49,6 +50,10 @@ /** Indicates which predicate must be used: BETWEEN (false) or NOT BETWEEN (true). */ private boolean notBetween = false; + /** Position of this {@link Between} in the given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds a BETWEEN constraints. * @@ -87,6 +92,7 @@ setLeftOperand((ADQLOperand)toCopy.leftOperand.getCopy()); setMinOperand((ADQLOperand)toCopy.minOperand.getCopy()); setMaxOperand((ADQLOperand)toCopy.maxOperand.getCopy()); + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -106,6 +112,7 @@ */ public void setLeftOperand(ADQLOperand leftOperand) throws NullPointerException{ this.leftOperand = leftOperand; + position = null; } /** @@ -125,6 +132,7 @@ */ public void setMinOperand(ADQLOperand minOperand) throws NullPointerException{ this.minOperand = minOperand; + position = null; } /** @@ -144,6 +152,7 @@ */ public void setMaxOperand(ADQLOperand maxOperand) throws NullPointerException{ this.maxOperand = maxOperand; + position = null; } /** @@ -162,21 +171,41 @@ */ public void setNotBetween(boolean notBetween){ this.notBetween = notBetween; + position = null; + } + + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link Between} in the given ADQL query string. + * + * @param position New position of this {@link Between}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; } + @Override public ADQLObject getCopy() throws Exception{ return new Between(this); } + @Override public String getName(){ return (isNotBetween() ? "NOT " : "") + "BETWEEN"; } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private int index = -1; + @Override public ADQLObject next(){ switch(++index){ case 0: @@ -190,10 +219,12 @@ } } + @Override public boolean hasNext(){ return index + 1 < 3; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (index <= -1) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); @@ -212,10 +243,12 @@ maxOperand = (ADQLOperand)replacer; break; } + position = null; }else throw new UnsupportedOperationException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); } + @Override public void remove(){ if (index <= -1) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -225,6 +258,7 @@ }; } + @Override public String toADQL(){ return leftOperand.toADQL() + " " + getName() + " " + minOperand.toADQL() + " AND " + maxOperand.toADQL(); } diff -Nru adql-1.3/src/adql/query/constraint/Comparison.java adql-1.4/src/adql/query/constraint/Comparison.java --- adql-1.3/src/adql/query/constraint/Comparison.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/constraint/Comparison.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,20 +16,22 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** * Represents a comparison (numeric or not) between two operands. * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) * * @see ComparisonOperator */ @@ -44,6 +46,10 @@ /** The right part of the comparison. */ private ADQLOperand rightOperand; + /** Position of this {@link Comparison} in the given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Creates a comparison between two operands. * @@ -73,6 +79,7 @@ leftOperand = (ADQLOperand)toCopy.leftOperand.getCopy(); compOperator = toCopy.compOperator; rightOperand = (ADQLOperand)toCopy.rightOperand.getCopy(); + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -100,6 +107,7 @@ throw new UnsupportedOperationException("Impossible to update the left operand of the comparison (" + toADQL() + ") with \"" + newLeftOperand.toADQL() + "\" because the comparison operator " + compOperator.toADQL() + " is not applicable on numeric operands !"); leftOperand = newLeftOperand; + position = null; } /** @@ -125,6 +133,7 @@ throw new UnsupportedOperationException("Impossible to update the comparison operator" + ((compOperator != null) ? (" (" + compOperator.toADQL() + ")") : "") + " by " + newOperation.toADQL() + " because the two operands (\"" + leftOperand.toADQL() + "\" & \"" + rightOperand.toADQL() + "\") are not all Strings !"); compOperator = newOperation; + position = null; } /** @@ -152,21 +161,41 @@ throw new UnsupportedOperationException("Impossible to update the right operand of the comparison (" + toADQL() + ") with \"" + newRightOperand.toADQL() + "\" because the comparison operator " + compOperator.toADQL() + " is not applicable on numeric operands !"); rightOperand = newRightOperand; + position = null; + } + + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link Comparison} in the given ADQL query string. + * + * @param position New position of this {@link Comparison}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; } + @Override public ADQLObject getCopy() throws Exception{ return new Comparison(this); } + @Override public String getName(){ return compOperator.toADQL(); } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private int index = -1; + @Override public ADQLObject next(){ index++; if (index == 0) @@ -177,10 +206,12 @@ throw new NoSuchElementException(); } + @Override public boolean hasNext(){ return index + 1 < 2; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (index <= -1) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); @@ -188,14 +219,18 @@ if (replacer == null) remove(); else if (replacer instanceof ADQLOperand){ - if (index == 0) + if (index == 0){ leftOperand = (ADQLOperand)replacer; - else if (index == 1) + position = null; + }else if (index == 1){ rightOperand = (ADQLOperand)replacer; + position = null; + } }else throw new UnsupportedOperationException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " in a comparison !"); } + @Override public void remove(){ if (index <= -1) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -205,6 +240,7 @@ }; } + @Override public String toADQL(){ return ((leftOperand == null) ? "NULL" : leftOperand.toADQL()) + " " + ((compOperator == null) ? "NULL" : compOperator.toADQL()) + " " + ((rightOperand == null) ? "NULL" : rightOperand.toADQL()); } diff -Nru adql-1.3/src/adql/query/constraint/Exists.java adql-1.4/src/adql/query/constraint/Exists.java --- adql-1.3/src/adql/query/constraint/Exists.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/constraint/Exists.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; @@ -24,20 +25,25 @@ import adql.query.ADQLIterator; import adql.query.ADQLObject; import adql.query.ADQLQuery; +import adql.query.TextPosition; /** *

      Represents the predicate EXISTS of SQL and ADQL.

      * *

      This function returns true if the sub-query given in parameter returns at least one result, else it returns false.

      * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public class Exists implements ADQLConstraint { /** The sub-query. */ private ADQLQuery subQuery; + /** Position of this {@link Exists} in the given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds an Exists constraint instance. * @@ -55,6 +61,7 @@ */ public Exists(Exists toCopy) throws Exception{ subQuery = (ADQLQuery)toCopy.subQuery.getCopy(); + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -75,23 +82,44 @@ public void setSubQuery(ADQLQuery query) throws NullPointerException{ if (query == null) throw new NullPointerException("Impossible to build an EXISTS constraint with a sub-query NULL !"); - else + else{ subQuery = query; + position = null; + } + } + + @Override + public final TextPosition getPosition(){ + return position; } + /** + * Set the position of this {@link Exists} in the given ADQL query string. + * + * @param position New position of this {@link Exists}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public ADQLObject getCopy() throws Exception{ return new Exists(this); } + @Override public String getName(){ return "EXISTS"; } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private boolean subQueryGot = (subQuery == null); + @Override public ADQLObject next(){ if (subQueryGot) throw new NoSuchElementException(); @@ -99,22 +127,26 @@ return subQuery; } + @Override public boolean hasNext(){ return !subQueryGot; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (!subQueryGot) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); if (replacer == null) remove(); - else if (replacer instanceof ADQLQuery) + else if (replacer instanceof ADQLQuery){ subQuery = (ADQLQuery)replacer; - else + position = null; + }else throw new UnsupportedOperationException("Impossible to replace an ADQLQuery by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); } + @Override public void remove(){ if (!subQueryGot) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -124,6 +156,7 @@ }; } + @Override public String toADQL(){ return getName() + "(" + subQuery.toADQL() + ")"; } diff -Nru adql-1.3/src/adql/query/constraint/In.java adql-1.4/src/adql/query/constraint/In.java --- adql-1.3/src/adql/query/constraint/In.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/constraint/In.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; @@ -26,7 +27,7 @@ import adql.query.ADQLObject; import adql.query.ADQLQuery; import adql.query.ClauseADQL; - +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** @@ -35,8 +36,8 @@ *

      This predicate returns true if the value of the given operand is * either in the given values list or in the results of the given sub-query, else it returns false.

      * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public class In implements ADQLConstraint { @@ -52,6 +53,10 @@ /** IN or NOT IN ? */ private boolean notIn = false; + /** Position of this {@link In} in the given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds an IN constraint with a sub-query. * @@ -141,6 +146,7 @@ else setValuesList((ADQLList)toCopy.list.getCopy()); notIn = toCopy.notIn; + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -161,8 +167,10 @@ public void setOperand(ADQLOperand newLeftOp) throws NullPointerException{ if (newLeftOp == null) throw new NullPointerException("Impossible to set a left operand NULL in an IN constraint !"); - else + else{ leftOp = newLeftOp; + position = null; + } } /** @@ -195,6 +203,7 @@ else{ list = null; subQuery = newSubQuery; + position = null; } } @@ -221,6 +230,7 @@ list = new ClauseADQL(); for(int i = 0; i < valuesList.length; i++) list.add(valuesList[i]); + position = null; } } @@ -236,6 +246,7 @@ else{ subQuery = null; list = valuesList; + position = null; } } @@ -255,21 +266,41 @@ */ public void setNotIn(boolean notIn){ this.notIn = notIn; + position = null; + } + + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link In} in the given ADQL query string. + * + * @param position New position of this {@link In}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; } + @Override public ADQLObject getCopy() throws Exception{ return new In(this); } + @Override public String getName(){ return notIn ? "NOT IN" : "IN"; } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private int index = -1; + @Override public ADQLObject next(){ index++; if (index == 0) @@ -280,10 +311,12 @@ throw new NoSuchElementException(); } + @Override public boolean hasNext(){ return index + 1 < 2; } + @Override @SuppressWarnings("unchecked") public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (index <= -1) @@ -293,20 +326,24 @@ remove(); if (index == 0){ - if (replacer instanceof ADQLOperand) + if (replacer instanceof ADQLOperand){ leftOp = (ADQLOperand)replacer; - else + position = null; + }else throw new UnsupportedOperationException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); }else if (index == 1){ - if (hasSubQuery() && replacer instanceof ADQLQuery) + if (hasSubQuery() && replacer instanceof ADQLQuery){ subQuery = (ADQLQuery)replacer; - else if (!hasSubQuery() && replacer instanceof ADQLList) + position = null; + }else if (!hasSubQuery() && replacer instanceof ADQLList){ list = (ADQLList)replacer; - else + position = null; + }else throw new UnsupportedOperationException("Impossible to replace an " + (hasSubQuery() ? "ADQLQuery" : "ADQLList") + " by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); } } + @Override public void remove(){ if (index <= -1) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -319,6 +356,7 @@ }; } + @Override public String toADQL(){ return leftOp.toADQL() + " " + getName() + " (" + (hasSubQuery() ? subQuery.toADQL() : list.toADQL()) + ")"; } diff -Nru adql-1.3/src/adql/query/constraint/IsNull.java adql-1.4/src/adql/query/constraint/IsNull.java --- adql-1.3/src/adql/query/constraint/IsNull.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/constraint/IsNull.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,20 +16,22 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; import adql.query.operand.ADQLColumn; /** * Represents a comparison between a column to the NULL value. * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public class IsNull implements ADQLConstraint { @@ -39,6 +41,10 @@ /** Indicates whether the predicate IS NOT NULL must be used rather than IS NULL. */ private boolean isNotNull = false; + /** Position of this {@link IsNull} in the given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds a comparison between the given column and NULL. * @@ -70,6 +76,7 @@ public IsNull(IsNull toCopy) throws Exception{ column = (ADQLColumn)toCopy.column.getCopy(); isNotNull = toCopy.isNotNull; + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -90,8 +97,10 @@ public final void setColumn(ADQLColumn column) throws NullPointerException{ if (column == null) throw new NullPointerException("Impossible to compare nothing to NULL: no column has been given to build a IsNull constraint !"); - else + else{ this.column = column; + position = null; + } } /** @@ -110,21 +119,41 @@ */ public final void setNotNull(boolean notNull){ isNotNull = notNull; + position = null; + } + + @Override + public final TextPosition getPosition(){ + return position; } + /** + * Set the position of this {@link IsNull} in the given ADQL query string. + * + * @param position New position of this {@link IsNull}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public ADQLObject getCopy() throws Exception{ return new IsNull(this); } + @Override public String getName(){ return "IS" + (isNotNull ? " NOT " : " ") + "NULL"; } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private boolean columnGot = (column == null); + @Override public ADQLObject next(){ if (columnGot) throw new NoSuchElementException(); @@ -132,22 +161,26 @@ return column; } + @Override public boolean hasNext(){ return !columnGot; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (!columnGot) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); if (replacer == null) remove(); - else if (replacer instanceof ADQLColumn) + else if (replacer instanceof ADQLColumn){ column = (ADQLColumn)replacer; - else + position = null; + }else throw new UnsupportedOperationException("Impossible to replace a column (" + column.toADQL() + ") by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") in a IsNull constraint (" + toADQL() + ") !"); } + @Override public void remove(){ if (!columnGot) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -157,6 +190,7 @@ }; } + @Override public String toADQL(){ return column.toADQL() + " " + getName(); } diff -Nru adql-1.3/src/adql/query/constraint/NotConstraint.java adql-1.4/src/adql/query/constraint/NotConstraint.java --- adql-1.3/src/adql/query/constraint/NotConstraint.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/constraint/NotConstraint.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,24 +16,30 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; /** * Lets apply the logical operator NOT on any constraint. * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public class NotConstraint implements ADQLConstraint { private ADQLConstraint constraint; + /** Position of this {@link NotConstraint} in the ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds a NotConstraint just with the constraint on which the logical operator NOT must be applied. * @@ -56,19 +62,38 @@ return constraint; } + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link NotConstraint} in the given ADQL query string. + * + * @param position New position of this {@link NotConstraint}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public ADQLObject getCopy() throws Exception{ return new NotConstraint((ADQLConstraint)constraint.getCopy()); } + @Override public String getName(){ return "NOT " + constraint.getName(); } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private boolean constraintGot = (constraint == null); + @Override public ADQLObject next(){ if (constraintGot) throw new NoSuchElementException(); @@ -76,22 +101,26 @@ return constraint; } + @Override public boolean hasNext(){ return !constraintGot; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (!constraintGot) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); if (replacer == null) remove(); - else if (replacer instanceof ADQLConstraint) + else if (replacer instanceof ADQLConstraint){ constraint = (ADQLConstraint)replacer; - else + position = null; + }else throw new UnsupportedOperationException("Impossible to replace an ADQLConstraint by a " + replacer.getClass().getName() + " !"); } + @Override public void remove(){ if (!constraintGot) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -101,6 +130,7 @@ }; } + @Override public String toADQL(){ return "NOT " + constraint.toADQL(); } diff -Nru adql-1.3/src/adql/query/from/ADQLJoin.java adql-1.4/src/adql/query/from/ADQLJoin.java --- adql-1.3/src/adql/query/from/ADQLJoin.java 2015-05-04 09:26:10.000000000 +0000 +++ adql-1.4/src/adql/query/from/ADQLJoin.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -35,13 +36,14 @@ import adql.query.ADQLObject; import adql.query.ClauseConstraints; import adql.query.IdentifierField; +import adql.query.TextPosition; import adql.query.operand.ADQLColumn; /** * Defines a join between two "tables". * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (05/2015) + * @version 1.4 (09/2017) */ public abstract class ADQLJoin implements ADQLObject, FromContent { @@ -60,6 +62,10 @@ /** List of columns on which the join must be done. */ protected ArrayList lstColumns = null; + /** Position of this {@link ADQLJoin} in the given ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /* ************ */ /* CONSTRUCTORS */ /* ************ */ @@ -92,6 +98,7 @@ for(ADQLColumn col : toCopy.lstColumns) lstColumns.add((ADQLColumn)col.getCopy()); } + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /* ***************** */ @@ -117,6 +124,7 @@ condition = null; lstColumns = null; } + position = null; } /** @@ -135,6 +143,7 @@ */ public void setLeftTable(FromContent table){ leftTable = table; + position = null; } /** @@ -153,6 +162,7 @@ */ public void setRightTable(FromContent table){ rightTable = table; + position = null; } /** @@ -175,6 +185,17 @@ natural = false; lstColumns = null; } + position = null; + } + + @Override + public final TextPosition getPosition(){ + return position; + } + + @Override + public final void setPosition(final TextPosition position){ + this.position = position; } /** @@ -228,6 +249,7 @@ natural = false; condition = null; + position = null; } } @@ -299,6 +321,7 @@ else throw new UnsupportedOperationException("Impossible to replace an ADQLColumn by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); } + position = null; } @@ -315,6 +338,7 @@ else if (itCol != null){ itCol.remove(); index--; + position = null; } } }; @@ -341,64 +365,69 @@ @Override public SearchColumnList getDBColumns() throws UnresolvedJoinException{ - SearchColumnList list = new SearchColumnList(); - SearchColumnList leftList = leftTable.getDBColumns(); - SearchColumnList rightList = rightTable.getDBColumns(); - - /* 1. Figure out duplicated columns */ - HashMap mapDuplicated = new HashMap(); - // CASE: NATURAL - if (natural){ - // Find duplicated items between the two lists and add one common column in mapDuplicated for each - DBColumn rightCol; - for(DBColumn leftCol : leftList){ - // search for at most one column with the same name in the RIGHT list - // and throw an exception is there are several matches: - rightCol = findAtMostOneColumn(leftCol.getADQLName(), (byte)0, rightList, false); - // if there is one... - if (rightCol != null){ - // ...check there is only one column with this name in the LEFT list, - // and throw an exception if it is not the case: - findExactlyOneColumn(leftCol.getADQLName(), (byte)0, leftList, true); - // ...create a common column: - mapDuplicated.put(leftCol.getADQLName().toLowerCase(), new DBCommonColumn(leftCol, rightCol)); + try{ + SearchColumnList list = new SearchColumnList(); + SearchColumnList leftList = leftTable.getDBColumns(); + SearchColumnList rightList = rightTable.getDBColumns(); + + /* 1. Figure out duplicated columns */ + HashMap mapDuplicated = new HashMap(); + // CASE: NATURAL + if (natural){ + // Find duplicated items between the two lists and add one common column in mapDuplicated for each + DBColumn rightCol; + for(DBColumn leftCol : leftList){ + // search for at most one column with the same name in the RIGHT list + // and throw an exception is there are several matches: + rightCol = findAtMostOneColumn(leftCol.getADQLName(), (byte)0, rightList, false); + // if there is one... + if (rightCol != null){ + // ...check there is only one column with this name in the LEFT list, + // and throw an exception if it is not the case: + findExactlyOneColumn(leftCol.getADQLName(), (byte)0, leftList, true); + // ...create a common column: + mapDuplicated.put(leftCol.getADQLName().toLowerCase(), new DBCommonColumn(leftCol, rightCol)); + } } - } - } - // CASE: USING - else if (lstColumns != null && !lstColumns.isEmpty()){ - // For each columns of usingList, check there is in each list exactly one matching column, and then, add it in mapDuplicated - DBColumn leftCol, rightCol; - for(ADQLColumn usingCol : lstColumns){ - // search for exactly one column with the same name in the LEFT list - // and throw an exception if there is none, or if there are several matches: - leftCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), leftList, true); - // idem in the RIGHT list: - rightCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), rightList, false); - // create a common column: - mapDuplicated.put((usingCol.isCaseSensitive(IdentifierField.COLUMN) ? ("\"" + usingCol.getColumnName() + "\"") : usingCol.getColumnName().toLowerCase()), new DBCommonColumn(leftCol, rightCol)); } + // CASE: USING + else if (lstColumns != null && !lstColumns.isEmpty()){ + // For each columns of usingList, check there is in each list exactly one matching column, and then, add it in mapDuplicated + DBColumn leftCol, rightCol; + for(ADQLColumn usingCol : lstColumns){ + // search for exactly one column with the same name in the LEFT list + // and throw an exception if there is none, or if there are several matches: + leftCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), leftList, true); + // idem in the RIGHT list: + rightCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), rightList, false); + // create a common column: + mapDuplicated.put((usingCol.isCaseSensitive(IdentifierField.COLUMN) ? ("\"" + usingCol.getColumnName() + "\"") : usingCol.getColumnName().toLowerCase()), new DBCommonColumn(leftCol, rightCol)); + } - } - // CASE: NO DUPLICATION TO FIGURE OUT - else{ - // Return the union of both lists: - list.addAll(leftList); - list.addAll(rightList); - return list; - } + } + // CASE: NO DUPLICATION TO FIGURE OUT + else{ + // Return the union of both lists: + list.addAll(leftList); + list.addAll(rightList); + return list; + } - /* 2. Add all columns of the left list except the ones identified as duplications */ - addAllExcept(leftList, list, mapDuplicated); + /* 2. Add all columns of the left list except the ones identified as duplications */ + addAllExcept(leftList, list, mapDuplicated); - /* 3. Add all columns of the right list except the ones identified as duplications */ - addAllExcept(rightList, list, mapDuplicated); + /* 3. Add all columns of the right list except the ones identified as duplications */ + addAllExcept(rightList, list, mapDuplicated); - /* 4. Add all common columns of mapDuplicated */ - list.addAll(mapDuplicated.values()); + /* 4. Add all common columns of mapDuplicated */ + list.addAll(0, mapDuplicated.values()); - return list; + return list; + }catch(UnresolvedJoinException uje){ + uje.setPosition(position); + throw uje; + } } public final static void addAllExcept(final SearchColumnList itemsToAdd, final SearchColumnList target, final Map exception){ @@ -417,7 +446,7 @@ } public final static DBColumn findAtMostOneColumn(final String columnName, final byte caseSensitive, final SearchColumnList list, final boolean leftList) throws UnresolvedJoinException{ - ArrayList result = list.search(null, null, null, columnName, caseSensitive); + List result = list.search(null, null, null, columnName, caseSensitive); if (result.isEmpty()) return null; else if (result.size() > 1) @@ -437,15 +466,15 @@ } @Override - public ArrayList getTables(){ - ArrayList tables = leftTable.getTables(); + public List getTables(){ + List tables = leftTable.getTables(); tables.addAll(rightTable.getTables()); return tables; } @Override - public ArrayList getTablesByAlias(final String alias, final boolean caseSensitive){ - ArrayList tables = leftTable.getTablesByAlias(alias, caseSensitive); + public List getTablesByAlias(final String alias, final boolean caseSensitive){ + List tables = leftTable.getTablesByAlias(alias, caseSensitive); tables.addAll(rightTable.getTablesByAlias(alias, caseSensitive)); return tables; } @@ -463,4 +492,4 @@ @Override public abstract ADQLObject getCopy() throws Exception; -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/from/ADQLTable.java adql-1.4/src/adql/query/from/ADQLTable.java --- adql-1.3/src/adql/query/from/ADQLTable.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/from/ADQLTable.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,10 +16,12 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institut (ARI) */ import java.util.ArrayList; +import java.util.List; import java.util.NoSuchElementException; import adql.db.DBChecker; @@ -37,8 +39,8 @@ * It represents any item of the clause FROM: a table name or a sub-query.
      * A table reference may have an alias (MUST if it is a sub-query). * - * @author Grégory Mantelet (CDS) - * @version 01/2012 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (09/2017) */ public class ADQLTable implements ADQLObject, FromContent { @@ -83,7 +85,7 @@ * @param table Name of the table. */ public ADQLTable(String schema, String table){ - this(table); + setTableName(table); setSchemaName(schema); } @@ -164,6 +166,7 @@ * * @return The position of this {@link ADQLTable}. */ + @Override public final TextPosition getPosition(){ return position; } @@ -173,6 +176,7 @@ * * @param pos Position of this {@link ADQLTable}. */ + @Override public final void setPosition(final TextPosition pos){ position = pos; } @@ -464,18 +468,15 @@ } /** - *

      Sets the {@link DBTable} corresponding to this {@link ADQLTable}.

      - *

      - * Note: This function will do nothing if this {@link ADQLTable} is a sub query. - *

      + * Sets the {@link DBTable} corresponding to this {@link ADQLTable}. * * @param dbLink Its corresponding {@link DBTable}. */ public final void setDBLink(DBTable dbLink){ - if (!isSubQuery()) - this.dbLink = dbLink; + this.dbLink = dbLink; } + @Override public SearchColumnList getDBColumns(){ SearchColumnList list = new SearchColumnList(); if (isSubQuery() && dbLink == null) @@ -487,13 +488,15 @@ return list; } - public ArrayList getTables(){ + @Override + public List getTables(){ ArrayList tables = new ArrayList(); tables.add(this); return tables; } - public ArrayList getTablesByAlias(final String alias, final boolean caseSensitive){ + @Override + public List getTablesByAlias(final String alias, final boolean caseSensitive){ ArrayList tables = new ArrayList(); if (hasAlias()){ @@ -514,19 +517,23 @@ return tables; } + @Override public ADQLObject getCopy() throws Exception{ return new ADQLTable(this); } + @Override public String getName(){ return hasAlias() ? alias : (isSubQuery() ? "{subquery}" : getTableName()); } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private boolean subQueryGot = !isSubQuery(); + @Override public ADQLObject next(){ if (!subQueryGot){ subQueryGot = true; @@ -535,10 +542,12 @@ throw new NoSuchElementException(); } + @Override public boolean hasNext(){ return !subQueryGot; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (!subQueryGot) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); @@ -552,6 +561,7 @@ throw new UnsupportedOperationException("Impossible to replace a sub-query (" + subQuery.toADQL() + ") by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); } + @Override public void remove(){ if (!subQueryGot) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -561,6 +571,7 @@ }; } + @Override public String toADQL(){ return (isSubQuery() ? ("(" + subQuery.toADQL() + ")") : getFullTableName()) + ((alias == null) ? "" : (" AS " + (isCaseSensitive(IdentifierField.ALIAS) ? ("\"" + alias + "\"") : alias))); } diff -Nru adql-1.3/src/adql/query/from/FromContent.java adql-1.4/src/adql/query/from/FromContent.java --- adql-1.3/src/adql/query/from/FromContent.java 2015-05-04 09:26:04.000000000 +0000 +++ adql-1.4/src/adql/query/from/FromContent.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,23 +16,24 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ -import java.util.ArrayList; +import java.util.List; import adql.db.DBColumn; import adql.db.SearchColumnList; import adql.db.exception.UnresolvedJoinException; import adql.query.ADQLObject; +import adql.query.TextPosition; /** * Represents the content of the whole or a part of the clause FROM. * It could be either a table ({@link ADQLTable}) or a join ({@link ADQLJoin}). * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (05/2015) + * @version 1.4 (09/2017) */ public interface FromContent extends ADQLObject { @@ -51,7 +52,7 @@ * * @return The list of all {@link ADQLTable}s found. */ - public ArrayList getTables(); + public List getTables(); /** *

      Gets all the table whose the alias is equals to the given one.

      @@ -65,6 +66,14 @@ * * @return The list of all tables found. */ - public ArrayList getTablesByAlias(final String alias, final boolean caseSensitive); + public List getTablesByAlias(final String alias, final boolean caseSensitive); + + /** + * Set the position of this {@link FromContent} in the given ADQL query string. + * + * @param position New position of this {@link FromContent}. + * @since 1.4 + */ + public void setPosition(final TextPosition position); } diff -Nru adql-1.3/src/adql/query/from/SQLServer_InnerJoin.java adql-1.4/src/adql/query/from/SQLServer_InnerJoin.java --- adql-1.3/src/adql/query/from/SQLServer_InnerJoin.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/query/from/SQLServer_InnerJoin.java 2017-11-03 17:18:00.000000000 +0000 @@ -0,0 +1,206 @@ +package adql.query.from; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ADQLLibrary. If not, see . + * + * Copyright 2016 - Astronomisches Rechen Institut (ARI) + */ + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import adql.db.DBColumn; +import adql.db.DBCommonColumn; +import adql.db.SearchColumnList; +import adql.db.exception.UnresolvedJoinException; +import adql.parser.SQLServer_ADQLQueryFactory; +import adql.query.ClauseConstraints; +import adql.query.IdentifierField; +import adql.query.operand.ADQLColumn; + +/** + *

      Special implementation of {@link InnerJoin} for MS SQL Server.

      + * + *

      Important: + * Instances of this class are created only by {@link SQLServer_ADQLQueryFactory}. + *

      + * + *

      + * This implementation just changes the behavior the {@link #getDBColumns()}. + * In MS SQL Server, there is no keyword NATURAL and USING. That's why the {@link DBColumn}s + * returned by {@link DBColumn} can not contain any {@link DBCommonColumn}. Instead, + * the {@link DBColumn} of the first joined table (i.e. the left one) is returned. + *

      + * + *

      + * Since this special behavior is also valid for {@link OuterJoin}, a special implementation + * of this class has been also created: {@link SQLServer_OuterJoin}. Both must have exactly the + * same behavior when {@link #getDBColumns()} is called. That's why the static function + * {@link #getDBColumns(ADQLJoin)} has been created. It is called by {@link SQLServer_InnerJoin} + * and {@link SQLServer_OuterJoin}. + *

      + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (03/2016) + * @since 1.4 + * + * @see SQLServer_ADQLQueryFactory + */ +public class SQLServer_InnerJoin extends InnerJoin { + + /** + * Builds a NATURAL INNER JOIN between the two given "tables". + * + * @param left Left "table". + * @param right Right "table". + * + * @see InnerJoin#InnerJoin(FromContent, FromContent) + */ + public SQLServer_InnerJoin(FromContent left, FromContent right){ + super(left, right); + } + + /** + * Builds an INNER JOIN between the two given "tables" with the given condition. + * + * @param left Left "table". + * @param right Right "table". + * @param condition Join condition. + * + * @see InnerJoin#InnerJoin(FromContent, FromContent, ClauseConstraints) + */ + public SQLServer_InnerJoin(FromContent left, FromContent right, ClauseConstraints condition){ + super(left, right, condition); + } + + /** + * Builds an INNER JOIN between the two given "tables" with the given condition. + * + * @param left Left "table". + * @param right Right "table". + * @param lstColumns List of columns to join. + * + * @see InnerJoin#InnerJoin(FromContent, FromContent, Collection) + */ + public SQLServer_InnerJoin(FromContent left, FromContent right, Collection lstColumns){ + super(left, right, lstColumns); + } + + /** + * Builds a copy of the given INNER join. + * + * @param toCopy The INNER join to copy. + * + * @throws Exception If there is an error during the copy. + * + * @see InnerJoin#InnerJoin(InnerJoin) + */ + public SQLServer_InnerJoin(InnerJoin toCopy) throws Exception{ + super(toCopy); + } + + @Override + public SearchColumnList getDBColumns() throws UnresolvedJoinException{ + return getDBColumns(this); + } + + /** + *

      Gets the list of all columns (~ database metadata) available in this FROM part. + * Columns implied in a NATURAL join or in a USING list, are not returned as a {@link DBCommonColumn} ; + * actually, just the corresponding {@link DBColumn} of the left table is returned.

      + * + * @return All the available {@link DBColumn}s. + * @throws UnresolvedJoinException If a join is not possible. + */ + public static SearchColumnList getDBColumns(final ADQLJoin join) throws UnresolvedJoinException{ + try{ + SearchColumnList list = new SearchColumnList(); + SearchColumnList leftList = join.getLeftTable().getDBColumns(); + SearchColumnList rightList = join.getRightTable().getDBColumns(); + + /* 1. Figure out duplicated columns */ + HashMap mapDuplicated = new HashMap(); + // CASE: NATURAL + if (join.isNatural()){ + // Find duplicated items between the two lists and add one common column in mapDuplicated for each + DBColumn rightCol; + for(DBColumn leftCol : leftList){ + // search for at most one column with the same name in the RIGHT list + // and throw an exception is there are several matches: + rightCol = findAtMostOneColumn(leftCol.getADQLName(), (byte)0, rightList, false); + // if there is one... + if (rightCol != null){ + // ...check there is only one column with this name in the LEFT list, + // and throw an exception if it is not the case: + findExactlyOneColumn(leftCol.getADQLName(), (byte)0, leftList, true); + // ...add the left column: + mapDuplicated.put(leftCol.getADQLName().toLowerCase(), leftCol); + } + } + + } + // CASE: USING + else if (join.hasJoinedColumns()){ + // For each columns of usingList, check there is in each list exactly one matching column, and then, add it in mapDuplicated + DBColumn leftCol; + ADQLColumn usingCol; + Iterator itCols = join.getJoinedColumns(); + while(itCols.hasNext()){ + usingCol = itCols.next(); + // search for exactly one column with the same name in the LEFT list + // and throw an exception if there is none, or if there are several matches: + leftCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), leftList, true); + // idem in the RIGHT list: + findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), rightList, false); + // add the left column: + mapDuplicated.put((usingCol.isCaseSensitive(IdentifierField.COLUMN) ? ("\"" + usingCol.getColumnName() + "\"") : usingCol.getColumnName().toLowerCase()), leftCol); + } + + } + // CASE: NO DUPLICATION TO FIGURE OUT + else{ + // Return the union of both lists: + list.addAll(leftList); + list.addAll(rightList); + return list; + } + + /* 2. Add all columns of the left list except the ones identified as duplications */ + addAllExcept2(leftList, list, mapDuplicated); + + /* 3. Add all columns of the right list except the ones identified as duplications */ + addAllExcept2(rightList, list, mapDuplicated); + + /* 4. Add all common columns of mapDuplicated */ + list.addAll(0, mapDuplicated.values()); + + return list; + }catch(UnresolvedJoinException uje){ + uje.setPosition(join.getPosition()); + throw uje; + } + } + + public final static void addAllExcept2(final SearchColumnList itemsToAdd, final SearchColumnList target, final Map exception){ + for(DBColumn col : itemsToAdd){ + if (!exception.containsKey(col.getADQLName().toLowerCase()) && !exception.containsKey("\"" + col.getADQLName() + "\"")) + target.add(col); + } + } + +} diff -Nru adql-1.3/src/adql/query/from/SQLServer_OuterJoin.java adql-1.4/src/adql/query/from/SQLServer_OuterJoin.java --- adql-1.3/src/adql/query/from/SQLServer_OuterJoin.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/query/from/SQLServer_OuterJoin.java 2017-11-03 17:18:00.000000000 +0000 @@ -0,0 +1,121 @@ +package adql.query.from; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ADQLLibrary. If not, see . + * + * Copyright 2016 - Astronomisches Rechen Institut (ARI) + */ + +import java.util.Collection; + +import adql.db.DBColumn; +import adql.db.DBCommonColumn; +import adql.db.SearchColumnList; +import adql.db.exception.UnresolvedJoinException; +import adql.parser.SQLServer_ADQLQueryFactory; +import adql.query.ClauseConstraints; +import adql.query.operand.ADQLColumn; + +/** + *

      Special implementation of {@link OuterJoin} for MS SQL Server.

      + * + *

      Important: + * Instances of this class are created only by {@link SQLServer_ADQLQueryFactory}. + *

      + * + *

      + * This implementation just changes the behavior the {@link #getDBColumns()}. + * In MS SQL Server, there is no keyword NATURAL and USING. That's why the {@link DBColumn}s + * returned by {@link DBColumn} can not contain any {@link DBCommonColumn}. Instead, + * the {@link DBColumn} of the first joined table (i.e. the left one) is returned. + *

      + * + *

      + * Since this special behavior is also valid for {@link InnerJoin}, a special implementation + * of this class has been also created: {@link SQLServer_InnerJoin}. Both must have exactly the + * same behavior when {@link #getDBColumns()} is called. That's why the static function + * {@link SQLServer_InnerJoin#getDBColumns(ADQLJoin)} has been created. + *

      + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (03/2016) + * @since 1.4 + * + * @see SQLServer_ADQLQueryFactory + * @see SQLServer_InnerJoin + */ +public class SQLServer_OuterJoin extends OuterJoin { + + /** + * Builds a NATURAL OUTER join between the two given "tables". + * + * @param left Left "table". + * @param right Right "table". + * @param type OUTER join type (left, right or full). + * + * @see OuterJoin#OuterJoin(FromContent, FromContent, OuterType) + */ + public SQLServer_OuterJoin(FromContent left, FromContent right, OuterType type){ + super(left, right, type); + } + + /** + * Builds an OUTER join between the two given "tables" with the given condition. + * + * @param left Left "table". + * @param right Right "table". + * @param type Outer join type (left, right or full). + * @param condition Join condition. + * + * @see OuterJoin#OuterJoin(FromContent, FromContent, OuterType, ClauseConstraints) + */ + public SQLServer_OuterJoin(FromContent left, FromContent right, OuterType type, ClauseConstraints condition){ + super(left, right, type, condition); + } + + /** + * Builds an OUTER join between the two given "tables" with a list of columns to join. + * + * @param left Left "table". + * @param right Right "table". + * @param type Outer join type. + * @param lstColumns List of columns to join. + * + * @see OuterJoin#OuterJoin(FromContent, FromContent, OuterType, Collection) + */ + public SQLServer_OuterJoin(FromContent left, FromContent right, OuterType type, Collection lstColumns){ + super(left, right, type, lstColumns); + } + + /** + * Builds a copy of the given OUTER join. + * + * @param toCopy The OUTER join to copy. + * + * @throws Exception If there is an error during the copy. + * + * @see OuterJoin#OuterJoin(OuterJoin) + */ + public SQLServer_OuterJoin(OuterJoin toCopy) throws Exception{ + super(toCopy); + } + + @Override + public SearchColumnList getDBColumns() throws UnresolvedJoinException{ + return SQLServer_InnerJoin.getDBColumns(this); + } + +} diff -Nru adql-1.3/src/adql/query/operand/ADQLColumn.java adql-1.4/src/adql/query/operand/ADQLColumn.java --- adql-1.3/src/adql/query/operand/ADQLColumn.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/ADQLColumn.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -32,7 +32,7 @@ * Represents the complete (literal) reference to a column ({schema(s)}.{table}.{column}). * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (03/2016) */ public class ADQLColumn implements ADQLOperand, UnknownType { @@ -167,11 +167,7 @@ /* ***************** */ /* GETTERS & SETTERS */ /* ***************** */ - /** - * Gets the position in the original ADQL query string. - * - * @return The position of this {@link ADQLTable}. - */ + @Override public final TextPosition getPosition(){ return position; } @@ -473,17 +469,17 @@ @Override public boolean isNumeric(){ - return (dbLink == null || dbLink.getDatatype() == null || dbLink.getDatatype().isNumeric()); + return (dbLink == null || dbLink.getDatatype() == null || dbLink.getDatatype().isNumeric() || dbLink.getDatatype().isUnknown()); } @Override public boolean isString(){ - return (dbLink == null || dbLink.getDatatype() == null || dbLink.getDatatype().isString()); + return (dbLink == null || dbLink.getDatatype() == null || dbLink.getDatatype().isString() || (dbLink.getDatatype().isUnknown() && !dbLink.getDatatype().isNumeric())); } @Override public boolean isGeometry(){ - return (dbLink == null || dbLink.getDatatype() == null || dbLink.getDatatype().isGeometry()); + return (dbLink == null || dbLink.getDatatype() == null || dbLink.getDatatype().isGeometry() || (dbLink.getDatatype().isUnknown() && !dbLink.getDatatype().isNumeric())); } @Override diff -Nru adql-1.3/src/adql/query/operand/Concatenation.java adql-1.4/src/adql/query/operand/Concatenation.java --- adql-1.3/src/adql/query/operand/Concatenation.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/Concatenation.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -27,7 +27,7 @@ * Represents a concatenation in ADQL (ex: "_s_ra" || ':' || "_s_dec"). * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (09/2017) */ public final class Concatenation extends ADQLList implements ADQLOperand { @@ -36,7 +36,7 @@ * To add operands, use the "add" functions. */ public Concatenation(){ - super((String)null); + super("CONCAT_STR"); } /** @@ -81,4 +81,17 @@ return false; } + @Override + public String toADQL(){ + StringBuffer adql = new StringBuffer(); + + for(int i = 0; i < size(); i++){ + if (i > 0) + adql.append(" " + getSeparator(i) + " "); + adql.append(get(i).toADQL()); + } + + return adql.toString(); + } + } \ No newline at end of file diff -Nru adql-1.3/src/adql/query/operand/function/ADQLFunction.java adql-1.4/src/adql/query/operand/function/ADQLFunction.java --- adql-1.3/src/adql/query/operand/function/ADQLFunction.java 2014-10-13 13:25:10.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/ADQLFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.Iterator; @@ -24,17 +25,36 @@ import adql.query.ADQLIterator; import adql.query.ADQLObject; - +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** * Represents any kind of function. * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public abstract class ADQLFunction implements ADQLOperand { + /** Position of this {@link ADQLFunction} in the ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link ADQLFunction} in the ADQL query string. + * + * @param position New position of this {@link ADQLFunction} + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + /** * Gets the number of parameters this function has. * @@ -82,11 +102,13 @@ return new ParameterIterator(this); } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private int index = -1; + @Override public ADQLObject next(){ try{ return getParameter(++index); @@ -95,10 +117,12 @@ } } + @Override public boolean hasNext(){ return index + 1 < getNbParameters(); } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (index <= -1) throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); @@ -116,6 +140,7 @@ throw new UnsupportedOperationException("Impossible to replace the " + index + "-th parameter of \"" + toADQL() + "\" by an object whose the class (" + replacer.getClass().getName() + ") is not ADQLOperand !"); } + @Override public void remove(){ if (index <= -1) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -125,6 +150,7 @@ }; } + @Override public String toADQL(){ String adql = getName() + "("; @@ -152,15 +178,18 @@ function = fct; } + @Override public boolean hasNext(){ return (index + 1) < function.getNbParameters(); } + @Override public ADQLOperand next(){ index++; return function.getParameter(index); } + @Override public void remove() throws UnsupportedOperationException{ try{ function.setParameter(index, null); diff -Nru adql-1.3/src/adql/query/operand/function/DefaultUDF.java adql-1.4/src/adql/query/operand/function/DefaultUDF.java --- adql-1.3/src/adql/query/operand/function/DefaultUDF.java 2015-02-11 19:13:28.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/DefaultUDF.java 2017-11-03 17:18:00.000000000 +0000 @@ -24,6 +24,7 @@ import adql.query.ADQLList; import adql.query.ADQLObject; import adql.query.ClauseADQL; +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; import adql.translator.ADQLTranslator; import adql.translator.TranslationException; @@ -32,7 +33,7 @@ * It represents any function which is not managed by ADQL. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (02/2015) + * @version 1.4 (06/2015) */ public final class DefaultUDF extends UserDefinedFunction { @@ -69,6 +70,7 @@ public DefaultUDF(final DefaultUDF toCopy) throws Exception{ functionName = toCopy.functionName; parameters = (ADQLList)(toCopy.parameters.getCopy()); + setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));; } /** @@ -156,7 +158,9 @@ */ @Override public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception{ - return parameters.set(index, replacer); + ADQLOperand oldParam = parameters.set(index, replacer); + setPosition(null); + return oldParam; } @Override diff -Nru adql-1.3/src/adql/query/operand/function/geometry/AreaFunction.java adql-1.4/src/adql/query/operand/function/geometry/AreaFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/AreaFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/AreaFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -34,7 +34,7 @@ *

      Inappropriate geometries for this construct (e.g. POINT) SHOULD either return zero or throw an error message. This choice must be done in an extended class of {@link AreaFunction}.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class AreaFunction extends GeometryFunction { @@ -85,6 +85,7 @@ */ public final void setParameter(GeometryValue parameter){ this.parameter = parameter; + setPosition(null); } @Override @@ -145,9 +146,10 @@ parameter.setGeometry((GeometryFunction)replacer); else throw new Exception("Impossible to replace a GeometryValue/Column/GeometryFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); + setPosition(null); return replaced; }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/BoxFunction.java adql-1.4/src/adql/query/operand/function/geometry/BoxFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/BoxFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/BoxFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -39,7 +39,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class BoxFunction extends GeometryFunction { @@ -133,6 +133,7 @@ */ public final void setCoord1(ADQLOperand coord1){ this.coord1 = coord1; + setPosition(null); } /** @@ -151,6 +152,7 @@ */ public final void setCoord2(ADQLOperand coord2){ this.coord2 = coord2; + setPosition(null); } /** @@ -169,6 +171,7 @@ */ public final void setWidth(ADQLOperand width){ this.width = width; + setPosition(null); } /** @@ -187,6 +190,7 @@ */ public final void setHeight(ADQLOperand height){ this.height = height; + setPosition(null); } @Override @@ -249,6 +253,7 @@ default: throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); } + setPosition(null); return replaced; } diff -Nru adql-1.3/src/adql/query/operand/function/geometry/CentroidFunction.java adql-1.4/src/adql/query/operand/function/geometry/CentroidFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/CentroidFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/CentroidFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -36,7 +36,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (02/2017) */ public class CentroidFunction extends GeometryFunction { @@ -80,7 +80,7 @@ @Override public boolean isNumeric(){ - return true; + return false; } @Override @@ -90,7 +90,7 @@ @Override public boolean isGeometry(){ - return false; + return true; } @Override @@ -126,9 +126,10 @@ parameter.setGeometry((GeometryFunction)replacer); else throw new Exception("Impossible to replace a GeometryValue/Column/GeometryFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); + setPosition(null); return replaced; }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/CircleFunction.java adql-1.4/src/adql/query/operand/function/geometry/CircleFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/CircleFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/CircleFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -36,7 +36,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class CircleFunction extends GeometryFunction { @@ -124,6 +124,7 @@ */ public final void setCoord1(ADQLOperand coord1){ this.coord1 = coord1; + setPosition(null); } /** @@ -142,6 +143,7 @@ */ public final void setCoord2(ADQLOperand coord2){ this.coord2 = coord2; + setPosition(null); } /** @@ -160,6 +162,7 @@ */ public final void setRadius(ADQLOperand radius){ this.radius = radius; + setPosition(null); } @Override @@ -214,6 +217,7 @@ default: throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); } + setPosition(null); return replaced; } diff -Nru adql-1.3/src/adql/query/operand/function/geometry/ContainsFunction.java adql-1.4/src/adql/query/operand/function/geometry/ContainsFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/ContainsFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/ContainsFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -42,7 +42,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class ContainsFunction extends GeometryFunction { @@ -117,8 +117,10 @@ * @param leftParam The leftParam to set. */ public final void setLeftParam(GeometryValue leftParam){ - if (leftParam != null) + if (leftParam != null){ this.leftParam = leftParam; + setPosition(null); + } } /** @@ -132,8 +134,10 @@ * @param rightParam The rightParam to set. */ public final void setRightParam(GeometryValue rightParam){ - if (rightParam != null) + if (rightParam != null){ this.rightParam = rightParam; + setPosition(null); + } } @Override @@ -183,7 +187,8 @@ rightParam.setGeometry((GeometryFunction)replacer); }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); + setPosition(null); return replaced; } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/DistanceFunction.java adql-1.4/src/adql/query/operand/function/geometry/DistanceFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/DistanceFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/DistanceFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -35,7 +35,7 @@ * coordinate system with GEOCENTER reference position.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class DistanceFunction extends GeometryFunction { @@ -120,6 +120,7 @@ */ public final void setP1(GeometryValue p1){ this.p1 = p1; + setPosition(null); } /** @@ -138,6 +139,7 @@ */ public final void setP2(GeometryValue p2){ this.p2 = p2; + setPosition(null); } @Override @@ -198,7 +200,9 @@ toUpdate.setGeometry((PointFunction)replacer); } + setPosition(null); + return replaced; } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/ExtractCoord.java adql-1.4/src/adql/query/operand/function/geometry/ExtractCoord.java --- adql-1.3/src/adql/query/operand/function/geometry/ExtractCoord.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/ExtractCoord.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -36,7 +36,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class ExtractCoord extends GeometryFunction { @@ -136,9 +136,10 @@ point.setGeometry((PointFunction)replacer); else throw new Exception("Impossible to replace GeometryValue/Column/PointFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); + setPosition(null); return replaced; }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/ExtractCoordSys.java adql-1.4/src/adql/query/operand/function/geometry/ExtractCoordSys.java --- adql-1.3/src/adql/query/operand/function/geometry/ExtractCoordSys.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/ExtractCoordSys.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -36,7 +36,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class ExtractCoordSys extends GeometryFunction { @@ -123,9 +123,10 @@ geomExpr.setGeometry((GeometryFunction)replacer); else throw new Exception("Impossible to replace GeometryValue/Column/GeometryFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); + setPosition(null); return replaced; }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function " + getName() + " !"); } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/GeometryFunction.java adql-1.4/src/adql/query/operand/function/geometry/GeometryFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/GeometryFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/GeometryFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,13 +16,14 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import adql.parser.ParseException; import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; import adql.query.operand.ADQLColumn; import adql.query.operand.ADQLOperand; import adql.query.operand.StringConstant; @@ -32,7 +33,7 @@ *

      It represents any geometric function of ADQL.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public abstract class GeometryFunction extends ADQLFunction { @@ -66,6 +67,7 @@ */ protected GeometryFunction(GeometryFunction toCopy) throws Exception{ coordSys = (ADQLOperand)(toCopy.coordSys.getCopy()); + setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition())); } /** @@ -90,8 +92,10 @@ this.coordSys = new StringConstant(""); else if (!coordSys.isString()) throw new ParseException("A coordinate system must be a string literal: \"" + coordSys.toADQL() + "\" is not a string operand!"); - else + else{ this.coordSys = coordSys; + setPosition(null); + } } /** @@ -99,34 +103,43 @@ * which, in general, is either a GeometryFunction or a Column. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public static final class GeometryValue< F extends GeometryFunction > implements ADQLOperand { private ADQLColumn column; private F geomFunct; + /** Position of this {@link GeometryValue} in the ADQL query string. + * @since 1.4 */ + private TextPosition position = null; public GeometryValue(ADQLColumn col) throws NullPointerException{ if (col == null) throw new NullPointerException("Impossible to build a GeometryValue without a column or a geometry function !"); setColumn(col); + if (col.getPosition() != null) + position = col.getPosition(); } public GeometryValue(F geometry) throws NullPointerException{ if (geometry == null) throw new NullPointerException("Impossible to build a GeometryValue without a column or a geometry function !"); setGeometry(geometry); + if (geometry.getPosition() != null) + position = geometry.getPosition(); } @SuppressWarnings("unchecked") public GeometryValue(GeometryValue toCopy) throws Exception{ column = (toCopy.column == null) ? null : ((ADQLColumn)(toCopy.column.getCopy())); geomFunct = (toCopy.geomFunct == null) ? null : ((F)(toCopy.geomFunct.getCopy())); + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } public void setColumn(ADQLColumn col){ if (col != null){ geomFunct = null; column = col; + position = (column.getPosition() != null) ? column.getPosition() : null; } } @@ -134,6 +147,7 @@ if (geometry != null){ column = null; geomFunct = geometry; + position = (geomFunct.getPosition() != null) ? geomFunct.getPosition() : null; } } @@ -156,6 +170,11 @@ } @Override + public TextPosition getPosition(){ + return position; + } + + @Override public boolean isGeometry(){ return getValue().isGeometry(); } @@ -180,4 +199,4 @@ return getValue().toADQL(); } } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/IntersectsFunction.java adql-1.4/src/adql/query/operand/function/geometry/IntersectsFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/IntersectsFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/IntersectsFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -43,7 +43,7 @@ *

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class IntersectsFunction extends GeometryFunction { @@ -118,8 +118,10 @@ * @param leftParam The leftParam to set. */ public final void setLeftParam(GeometryValue leftParam){ - if (leftParam != null) + if (leftParam != null){ this.leftParam = leftParam; + setPosition(null); + } } /** @@ -133,8 +135,10 @@ * @param rightParam The rightParam to set. */ public final void setRightParam(GeometryValue rightParam){ - if (rightParam != null) + if (rightParam != null){ this.rightParam = rightParam; + setPosition(null); + } } @Override @@ -184,7 +188,8 @@ rightParam.setGeometry((GeometryFunction)replacer); }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); + setPosition(null); return replaced; } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/function/geometry/PointFunction.java adql-1.4/src/adql/query/operand/function/geometry/PointFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/PointFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/PointFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -35,7 +35,7 @@ * to the ICRS coordinate system with GEOCENTER reference position.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class PointFunction extends GeometryFunction { @@ -98,8 +98,10 @@ throw new NullPointerException("The first coordinate of a POINT function must be different from NULL !"); else if (!coord1.isNumeric()) throw new Exception("Coordinates of a POINT function must be numeric !"); - else + else{ this.coord1 = coord1; + setPosition(null); + } } /** @@ -123,8 +125,10 @@ throw new NullPointerException("The second coordinate of a POINT function must be different from NULL !"); else if (!coord2.isNumeric()) throw new Exception("Coordinates of a POINT function must be numeric !"); - else + else{ this.coord2 = coord2; + setPosition(null); + } } @Override @@ -199,6 +203,8 @@ throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !"); } + setPosition(null); + return replaced; } diff -Nru adql-1.3/src/adql/query/operand/function/geometry/PolygonFunction.java adql-1.4/src/adql/query/operand/function/geometry/PolygonFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/PolygonFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/PolygonFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -42,7 +42,7 @@ * according to the STC coordinate system with GEOCENTER reference position.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class PolygonFunction extends GeometryFunction { @@ -168,6 +168,9 @@ coordinates.set(index - 1, replacer); }else throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" (" + toADQL() + ") !"); + + setPosition(null); + return replaced; } diff -Nru adql-1.3/src/adql/query/operand/function/geometry/RegionFunction.java adql-1.4/src/adql/query/operand/function/geometry/RegionFunction.java --- adql-1.3/src/adql/query/operand/function/geometry/RegionFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/geometry/RegionFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -38,7 +38,7 @@ * Inappropriate geometries for this construct SHOULD throw an error message, to be defined by the service making use of ADQL.

      * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public class RegionFunction extends GeometryFunction { @@ -122,6 +122,7 @@ else if (replacer instanceof ADQLOperand){ ADQLOperand replaced = parameter; parameter = replacer; + setPosition(null); return replaced; }else throw new Exception("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !"); diff -Nru adql-1.3/src/adql/query/operand/function/MathFunction.java adql-1.4/src/adql/query/operand/function/MathFunction.java --- adql-1.3/src/adql/query/operand/function/MathFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/MathFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,18 +16,19 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import adql.query.ADQLObject; +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** * It represents any basic mathematical function. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) * * @see MathFunctionType */ @@ -116,6 +117,7 @@ type = toCopy.type; param1 = (ADQLOperand)toCopy.param1.getCopy(); param2 = (ADQLOperand)toCopy.param2.getCopy(); + setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition())); } /** @@ -198,10 +200,12 @@ case 0: replaced = param1; param1 = replacer; + setPosition(null); break; case 1: replaced = param2; param2 = replacer; + setPosition(null); break; } return replaced; diff -Nru adql-1.3/src/adql/query/operand/function/SQLFunction.java adql-1.4/src/adql/query/operand/function/SQLFunction.java --- adql-1.3/src/adql/query/operand/function/SQLFunction.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/function/SQLFunction.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,18 +16,19 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), - * Astronomisches Rechen Institut (ARI) + * Copyright 2011-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import adql.query.ADQLObject; +import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** * It represents any SQL function (COUNT, MAX, MIN, AVG, SUM, etc...). * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) * * @see SQLFunctionType */ @@ -87,6 +88,7 @@ type = toCopy.type; param = (ADQLOperand)toCopy.param.getCopy(); distinct = toCopy.distinct; + setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));; } /** @@ -105,6 +107,7 @@ */ public void setDistinct(boolean distinctValues){ distinct = distinctValues; + setPosition(null); } /** @@ -172,6 +175,7 @@ ADQLOperand replaced = param; param = replacer; + setPosition(null); return replaced; } @@ -184,4 +188,4 @@ return getName() + "(" + (distinct ? "DISTINCT " : "") + param.toADQL() + ")"; } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/NegativeOperand.java adql-1.4/src/adql/query/operand/NegativeOperand.java --- adql-1.3/src/adql/query/operand/NegativeOperand.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/NegativeOperand.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -24,16 +24,21 @@ import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; /** * Lets putting a minus sign in front of any numeric operand. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (09/2017) */ public final class NegativeOperand implements ADQLOperand { + /** The negativated operand. */ private ADQLOperand operand; + /** Position of this operand. + * @since 1.4 */ + private TextPosition position = null; /** *

      Builds an operand which will negativate the given operand.

      @@ -80,6 +85,21 @@ return false; } + @Override + public final TextPosition getPosition(){ + return this.position; + } + + /** + * Sets the position at which this {@link NegativeOperand} has been found in the original ADQL query string. + * + * @param position Position of this {@link NegativeOperand}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + /** Always returns false. * @see adql.query.operand.ADQLOperand#isGeometry() */ @@ -96,7 +116,7 @@ @Override public String getName(){ - return "-" + operand.getName(); + return "NEG_" + operand.getName(); } @Override diff -Nru adql-1.3/src/adql/query/operand/NumericConstant.java adql-1.4/src/adql/query/operand/NumericConstant.java --- adql-1.3/src/adql/query/operand/NumericConstant.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/NumericConstant.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,23 +16,28 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import adql.query.ADQLIterator; import adql.query.ADQLObject; import adql.query.NullADQLIterator; +import adql.query.TextPosition; /** * A numeric (integer, double, ...) constant. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (09/2017) */ -public final class NumericConstant implements ADQLOperand { +public class NumericConstant implements ADQLOperand { - private String value; + protected String value; + + /** Position of this operand. + * @since 1.4 */ + protected TextPosition position = null; /** * The numeric value is saved as a string so that the exact user format can be saved. @@ -89,11 +94,11 @@ this.value = toCopy.value; } - public final String getValue(){ + public String getValue(){ return value; } - public final double getNumericValue(){ + public double getNumericValue(){ try{ return Double.parseDouble(value); }catch(NumberFormatException nfe){ @@ -106,7 +111,7 @@ * * @param value The numeric value. */ - public final void setValue(long value){ + public void setValue(long value){ this.value = "" + value; } @@ -115,7 +120,7 @@ * * @param value The numeric value. */ - public final void setValue(double value){ + public void setValue(double value){ this.value = "" + value; } @@ -127,7 +132,7 @@ * * @see NumericConstant#setValue(String, boolean) */ - public final void setValue(String value) throws NumberFormatException{ + public void setValue(String value) throws NumberFormatException{ setValue(value, true); } @@ -140,7 +145,7 @@ * @param checkNumeric true to check whether the given value is numeric, false otherwise. * @throws NumberFormatException If the given value can not be converted in a Double. */ - public final void setValue(String value, boolean checkNumeric) throws NumberFormatException{ + public void setValue(String value, boolean checkNumeric) throws NumberFormatException{ if (checkNumeric) Double.parseDouble(value); @@ -163,6 +168,21 @@ return false; } + @Override + public final TextPosition getPosition(){ + return this.position; + } + + /** + * Sets the position at which this {@link NumericConstant} has been found in the original ADQL query string. + * + * @param position Position of this {@link NumericConstant}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + /** Always returns false. * @see adql.query.operand.ADQLOperand#isGeometry() */ diff -Nru adql-1.3/src/adql/query/operand/Operation.java adql-1.4/src/adql/query/operand/Operation.java --- adql-1.3/src/adql/query/operand/Operation.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/Operation.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -24,12 +24,13 @@ import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; /** * It represents a simple numeric operation (sum, difference, multiplication and division). * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (09/2017) * * @see OperationType */ @@ -47,6 +48,10 @@ /** Part of the operation at the right of the operator. */ private ADQLOperand rightOperand; + /** Position of the operation in the ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds an operation. * @@ -69,6 +74,8 @@ operation = op; setRightOperand(rightOp); + + position = null; } /** @@ -82,6 +89,7 @@ leftOperand = (ADQLOperand)toCopy.leftOperand.getCopy(); operation = toCopy.operation; rightOperand = (ADQLOperand)toCopy.rightOperand.getCopy(); + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -108,6 +116,8 @@ throw new UnsupportedOperationException("Impossible to update an Operation because the left operand is not numeric (" + newLeftOperand.toADQL() + ") !"); leftOperand = newLeftOperand; + + position = null; } /** @@ -156,6 +166,8 @@ throw new UnsupportedOperationException("Impossible to update an Operation because the right operand is not numeric (" + newRightOperand.toADQL() + ") !"); rightOperand = newRightOperand; + + position = null; } /** Always returns true. @@ -174,6 +186,21 @@ return false; } + @Override + public final TextPosition getPosition(){ + return this.position; + } + + /** + * Sets the position at which this {@link WrappedOperand} has been found in the original ADQL query string. + * + * @param position Position of this {@link WrappedOperand}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + /** Always returns false. * @see adql.query.operand.ADQLOperand#isGeometry() */ @@ -189,7 +216,7 @@ @Override public String getName(){ - return operation.toString(); + return operation.name(); } @Override @@ -230,6 +257,7 @@ leftOperand = (ADQLOperand)replacer; else if (index == 1) rightOperand = (ADQLOperand)replacer; + position = null; }else throw new UnsupportedOperationException("Impossible to replace the operand \"" + operand.toADQL() + "\" by \"" + replacer.toADQL() + "\" in the operation \"" + toADQL() + "\" because the replacer is not an ADQLOperand or is not numeric !"); } @@ -250,4 +278,4 @@ return leftOperand.toADQL() + operation.toADQL() + rightOperand.toADQL(); } -} \ No newline at end of file +} diff -Nru adql-1.3/src/adql/query/operand/StringConstant.java adql-1.4/src/adql/query/operand/StringConstant.java --- adql-1.3/src/adql/query/operand/StringConstant.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/StringConstant.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,24 +16,29 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import adql.query.ADQLIterator; import adql.query.ADQLObject; import adql.query.NullADQLIterator; +import adql.query.TextPosition; /** * A string constant. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (06/2015) */ public final class StringConstant implements ADQLOperand { private String value; + /** Position of this operand. + * @since 1.4 */ + private TextPosition position = null; + public StringConstant(String value){ this.value = value; } @@ -61,6 +66,21 @@ } @Override + public final TextPosition getPosition(){ + return this.position; + } + + /** + * Sets the position at which this {@link StringConstant} has been found in the original ADQL query string. + * + * @param position Position of this {@link StringConstant}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public final boolean isGeometry(){ return false; } diff -Nru adql-1.3/src/adql/query/operand/WrappedOperand.java adql-1.4/src/adql/query/operand/WrappedOperand.java --- adql-1.3/src/adql/query/operand/WrappedOperand.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/operand/WrappedOperand.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -24,17 +24,21 @@ import adql.query.ADQLIterator; import adql.query.ADQLObject; +import adql.query.TextPosition; /** * Lets wrapping an operand by parenthesis. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (10/2014) + * @version 1.4 (09/2017) */ public class WrappedOperand implements ADQLOperand { /** The wrapped operand. */ private ADQLOperand operand; + /** Position of this operand. + * @since 1.4 */ + private TextPosition position = null; /** * Wraps the given operand. @@ -69,6 +73,21 @@ } @Override + public final TextPosition getPosition(){ + return this.position; + } + + /** + * Sets the position at which this {@link WrappedOperand} has been found in the original ADQL query string. + * + * @param position Position of this {@link WrappedOperand}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public final boolean isGeometry(){ return operand.isGeometry(); } @@ -80,7 +99,7 @@ @Override public String getName(){ - return "(" + operand.getName() + ")"; + return operand.getName(); } @Override @@ -109,9 +128,10 @@ if (replacer == null) remove(); - else if (replacer instanceof ADQLOperand) + else if (replacer instanceof ADQLOperand){ operand = (ADQLOperand)replacer; - else + position = null; + }else throw new UnsupportedOperationException("Impossible to replace an ADQLOperand (\"" + operand + "\") by a " + replacer.getClass().getName() + " (\"" + replacer.toADQL() + "\") !"); } diff -Nru adql-1.3/src/adql/query/SelectAllColumns.java adql-1.4/src/adql/query/SelectAllColumns.java --- adql-1.3/src/adql/query/SelectAllColumns.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/query/SelectAllColumns.java 2017-11-03 17:18:00.000000000 +0000 @@ -20,7 +20,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -29,7 +29,7 @@ * It means: 'select all columns'. * * @author Grégory Mantelet (CDS;ARI) - * @version 1.2 (09/2014) + * @version 1.4 (06/2015) */ public final class SelectAllColumns extends SelectItem { @@ -88,6 +88,7 @@ if (query != null){ this.query = query; adqlTable = null; + setPosition(null); } } @@ -110,6 +111,7 @@ if (table != null){ adqlTable = table; query = null; + setPosition(null); } } @@ -150,8 +152,10 @@ throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); else if (!(replacer instanceof ADQLTable)) throw new IllegalStateException("Impossible to replace an ADQLTable by a " + replacer.getClass().getName() + " !"); - else + else{ adqlTable = (ADQLTable)replacer; + setPosition(null); + } } @Override diff -Nru adql-1.3/src/adql/query/SelectItem.java adql-1.4/src/adql/query/SelectItem.java --- adql-1.3/src/adql/query/SelectItem.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/SelectItem.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,20 +16,22 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import java.util.NoSuchElementException; import adql.query.operand.ADQLOperand; +import adql.query.operand.Concatenation; /** *

      Represents an item of a SELECT clause.

      * *

      It merely encapsulates an operand and allows to associate to it an alias (according to the following syntax: "SELECT operand AS alias").

      * - * @author Grégory Mantelet (CDS) - * @version 01/2012 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (03/2016) * * @see ClauseSelect */ @@ -44,6 +46,10 @@ /** Indicates whether the alias is case sensitive (if yes, the alias is written between double-quotes). */ private boolean caseSensitive = false; + /** Position of this Select item in the ADQL query string. + * @since 1.4 */ + private TextPosition position = null; + /** * Builds a SELECT item just with an operand. * @@ -77,6 +83,7 @@ operand = null; alias = toCopy.getAlias(); caseSensitive = toCopy.caseSensitive; + position = (toCopy.position == null) ? null : new TextPosition(toCopy.position); } /** @@ -112,6 +119,8 @@ * @param newAlias The new alias of the operand. */ public final void setAlias(String newAlias){ + if (alias == null && newAlias != null || alias != null && newAlias == null || alias != null && !alias.equals(newAlias)) + position = null; alias = newAlias; caseSensitive = false; @@ -120,6 +129,7 @@ a.trimToSize(); if (a.length() == 0){ alias = null; + position = null; return; }else if (a.length() > 1 && a.charAt(0) == '\"' && a.charAt(a.length() - 1) == '\"'){ a.deleteCharAt(0); @@ -127,6 +137,7 @@ a.trimToSize(); if (a.length() == 0){ alias = null; + position = null; return; } caseSensitive = true; @@ -153,19 +164,43 @@ caseSensitive = sensitive; } + @Override + public final TextPosition getPosition(){ + return position; + } + + /** + * Set the position of this {@link SelectItem} in the given ADQL query string. + * + * @param position New position of this {@link SelectItem}. + * @since 1.4 + */ + public final void setPosition(final TextPosition position){ + this.position = position; + } + + @Override public ADQLObject getCopy() throws Exception{ return new SelectItem(this); } + @Override public String getName(){ - return hasAlias() ? alias : operand.getName(); + if (hasAlias()) + return alias; + else if (operand instanceof Concatenation) + return "concat"; + else + return operand.getName(); } + @Override public ADQLIterator adqlIterator(){ return new ADQLIterator(){ private boolean operandGot = (operand == null); + @Override public ADQLObject next() throws NoSuchElementException{ if (operandGot) throw new NoSuchElementException(); @@ -173,10 +208,12 @@ return operand; } + @Override public boolean hasNext(){ return !operandGot; } + @Override public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{ if (replacer == null) remove(); @@ -184,10 +221,13 @@ throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !"); else if (!(replacer instanceof ADQLOperand)) throw new IllegalStateException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " !"); - else + else{ operand = (ADQLOperand)replacer; + position = null; + } } + @Override public void remove(){ if (!operandGot) throw new IllegalStateException("remove() impossible: next() has not yet been called !"); @@ -197,6 +237,7 @@ }; } + @Override public String toADQL(){ StringBuffer adql = new StringBuffer(operand.toADQL()); if (hasAlias()){ diff -Nru adql-1.3/src/adql/query/TextPosition.java adql-1.4/src/adql/query/TextPosition.java --- adql-1.3/src/adql/query/TextPosition.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/query/TextPosition.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,7 +16,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institute (ARI) */ import adql.parser.Token; @@ -25,8 +26,8 @@ * Indicates a simple position or a token/string position in a text. * It is particularly used to localize columns and tables in the original ADQL query. * - * @author Grégory Mantelet (CDS) - * @version 01/2012 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2015) */ public class TextPosition { @@ -71,7 +72,7 @@ } /** - * Builds a position whose the end line and column are unknown => a simple position. + * Builds a position defining the region delimited by the given token. * * @param token The position will be the one of this token. */ @@ -89,6 +90,27 @@ this(beginToken.beginLine, beginToken.beginColumn, endToken.endLine, (endToken.endColumn < 0) ? -1 : (endToken.endColumn + 1)); } + /** + * Builds a copy of the given position. + * + * @param positionToCopy Position to copy. + * @since 1.4 + */ + public TextPosition(final TextPosition positionToCopy){ + this(positionToCopy.beginLine, positionToCopy.beginColumn, positionToCopy.endLine, positionToCopy.endColumn); + } + + /** + * Builds a position whose the start is the start position of the first parameter and the end is the end position of the second parameter. + * + * @param startPos Start position (only beginLine and beginColumn will be used). + * @param endPos End position (only endLine and endColumn will be used). + * @since 1.4 + */ + public TextPosition(final TextPosition startPos, final TextPosition endPos){ + this(startPos.beginLine, startPos.beginColumn, endPos.endLine, endPos.endColumn); + } + @Override public String toString(){ if (beginLine == -1 && beginColumn == -1) diff -Nru adql-1.3/src/adql/search/SimpleReplaceHandler.java adql-1.4/src/adql/search/SimpleReplaceHandler.java --- adql-1.3/src/adql/search/SimpleReplaceHandler.java 2014-10-10 17:14:46.000000000 +0000 +++ adql-1.4/src/adql/search/SimpleReplaceHandler.java 2017-11-03 17:18:00.000000000 +0000 @@ -1,5 +1,7 @@ package adql.search; +import java.util.Stack; + /* * This file is part of ADQLLibrary. * @@ -16,7 +18,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2012,2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Astronomisches Rechen Institut (ARI) */ import adql.query.ADQLIterator; @@ -31,16 +34,13 @@ *
    • Matching objects are collected before their replacement.
    • *
    * - * @author Grégory Mantelet (CDS) - * @version 06/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 1.4 (06/2016) * * @see RemoveHandler */ public abstract class SimpleReplaceHandler extends SimpleSearchHandler implements IReplaceHandler { - /** Indicates whether {@link #searchAndReplace(ADQLObject)} (=true) has been called or just {@link #search(ADQLObject)} (=false). */ - protected boolean replaceActive = false; - /** Count matching objects which have been replaced successfully. */ protected int nbReplacement = 0; @@ -74,6 +74,7 @@ super(recursive, onlyFirstMatch); } + @Override public int getNbReplacement(){ return nbReplacement; } @@ -84,11 +85,25 @@ nbReplacement = 0; } - @Override - protected void addMatch(ADQLObject matchObj, ADQLIterator it){ + /** + *

    Adds the given ADQL object as one result of the research, and then replace its reference + * inside its parent.

    + * + *

    Thus, the matched item added in the list is no longer available in its former parent.

    + * + *

    Warning: the second parameter (it) may be null if the given match is the root search object itself.

    + * + * @param matchObj An ADQL object which has matched to the research criteria. + * @param it The iterator from which the matched ADQL object has been extracted. + * + * @return The match item after replacement if any replacement has occurred, + * or null if the item has been removed, + * or the object given in parameter if there was no replacement. + */ + protected ADQLObject addMatchAndReplace(ADQLObject matchObj, ADQLIterator it){ super.addMatch(matchObj, it); - if (replaceActive && it != null){ + if (it != null){ try{ ADQLObject replacer = getReplacer(matchObj); if (replacer == null) @@ -96,18 +111,60 @@ else it.replace(replacer); nbReplacement++; + return replacer; }catch(IllegalStateException ise){ }catch(UnsupportedOperationException uoe){ } } + + return matchObj; } + @Override public void searchAndReplace(final ADQLObject startObj){ - replaceActive = true; - search(startObj); - replaceActive = false; + reset(); + + if (startObj == null) + return; + + // Test the root search object: + if (match(startObj)) + addMatch(startObj, null); + + Stack stackIt = new Stack(); + Stack stackObj = new Stack(); + ADQLObject obj = null; + ADQLIterator it = startObj.adqlIterator(); + + while(!isFinished()){ + + // Fetch the next ADQL object to test: + do{ + if (it != null && it.hasNext()){ + // Get the next object: + obj = it.next(); + // ...but continue the research inside it as long as it is possible: + if (obj != null && goInto(obj)){ + stackIt.push(it); + stackObj.push(obj); + it = obj.adqlIterator(); + obj = null; + } + }else if (!stackIt.isEmpty()){ + it = stackIt.pop(); + obj = stackObj.pop(); + }else + return; + }while(obj == null); + + // Add the current object if it is matching: + if (match(obj)) + addMatchAndReplace(obj, it); + + obj = null; + } } /** diff -Nru adql-1.3/src/adql/translator/JDBCTranslator.java adql-1.4/src/adql/translator/JDBCTranslator.java --- adql-1.3/src/adql/translator/JDBCTranslator.java 2015-05-04 09:25:20.000000000 +0000 +++ adql-1.4/src/adql/translator/JDBCTranslator.java 2018-01-12 14:15:02.000000000 +0000 @@ -2,30 +2,28 @@ /* * This file is part of ADQLLibrary. - * + * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . - * - * Copyright 2015 - Astronomisches Rechen Institut (ARI) + * + * Copyright 2017-2018 - Astronomisches Rechen Institut (ARI) */ -import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; -import tap.data.DataReadException; import adql.db.DBColumn; import adql.db.DBTable; +import adql.db.DBTableAlias; import adql.db.DBType; import adql.db.STCS.Region; import adql.db.exception.UnresolvedJoinException; @@ -80,55 +78,47 @@ import adql.query.operand.function.geometry.RegionFunction; /** - *

    Implementation of {@link ADQLTranslator} which translates ADQL queries in SQL queries.

    - * + * Implementation of {@link ADQLTranslator} which translates ADQL queries in + * SQL queries. + * *

    - * It is already able to translate all SQL standard features, but lets abstract the translation of all - * geometrical functions. So, this translator must be extended as {@link PostgreSQLTranslator} and - * {@link PgSphereTranslator} are doing. + * It is already able to translate all SQL standard features, but lets abstract + * the translation of all geometrical functions. So, this translator must be + * extended as {@link PostgreSQLTranslator}, {@link PgSphereTranslator}, + * {@link MySQLTranslator} and {@link SQLServerTranslator} are doing. *

    - * + * *

    Note: - * Its default implementation of the SQL syntax has been inspired by the PostgreSQL one. - * However, it should work also with SQLite and MySQL, but some translations might be needed - * (as it is has been done for PostgreSQL about the mathematical functions). + * Its default implementation of the SQL syntax has been inspired by the + * PostgreSQL one. However, it should work also with other DBMS, although some + * translations might be needed (as it is has been done for PostgreSQL about + * the mathematical functions). *

    - * - *

    PostgreSQLTranslator and PgSphereTranslator

    - * - *

    - * {@link PgSphereTranslator} extends {@link PostgreSQLTranslator} and is able to translate geometrical - * functions according to the syntax given by PgSphere. But it can also convert geometrical types - * (from and toward the database), translate PgSphere regions into STC expression and vice-versa. - *

    - * - *

    - * {@link PostgreSQLTranslator} overwrites the translation of mathematical functions whose some have - * a different name or signature. Besides, it is also implementing the translation of the geometrical - * functions. However, it does not really translate them. It is just returning the ADQL expression - * (by calling {@link #getDefaultADQLFunction(ADQLFunction)}). - * And so, of course, the execution of a SQL query containing geometrical functions and translated - * using this translator will not work. It is just a default implementation in case there is no interest - * of these geometrical functions. - *

    - * + * *

    SQL with or without case sensitivity?

    - * + * *

    - * In ADQL and in SQL, it is possible to tell the parser to respect the exact case or not of an identifier (schema, table or column name) - * by surrounding it with double quotes. However ADQL identifiers and SQL ones may be different. In that way, the case sensitivity specified - * in ADQL on the different identifiers can not be kept in SQL. That's why this translator lets specify a general rule on which types of - * SQL identifier must be double quoted. This can be done by implementing the abstract function {@link #isCaseSensitive(IdentifierField)}. - * The functions translating column and table names will call this function in order to surround the identifiers by double quotes or not. - * So, be careful if you want to override the functions translating columns and tables! + * In ADQL and in SQL, it is possible to tell the parser to respect the exact + * case or not of an identifier (schema, table or column name) by surrounding + * it with double quotes. However ADQL identifiers and SQL ones may be + * different. In that way, the case sensitivity specified in ADQL on the + * different identifiers can not be kept in SQL. That's why this translator + * lets specify a general rule on which types of SQL identifier must be double + * quoted. This can be done by implementing the abstract function + * {@link #isCaseSensitive(IdentifierField)}. The functions translating column + * and table names will call this function in order to surround the identifiers + * by double quotes or not. So, be careful if you want to override the + * functions translating columns and tables! *

    - * + * *

    Translation of "SELECT TOP"

    - * + * *

    - * The default behavior of this translator is to translate the ADQL "TOP" into the SQL "LIMIT" at the end of the query. - * This is ok for some DBMS, but not all. So, if your DBMS does not know the "LIMIT" keyword, you should override the function - * translating the whole query: {@link #translate(ADQLQuery)}. Here is its current implementation: + * The default behavior of this translator is to translate the ADQL "TOP" into + * the SQL "LIMIT" at the end of the query. This is ok for some DBMS, but not + * all. So, if your DBMS does not know the "LIMIT" keyword, you should override + * the function translating the whole query: {@link #translate(ADQLQuery)}. + * Here is its current implementation: *

    *
      * 	StringBuffer sql = new StringBuffer(translate(query.getSelect()));
    @@ -145,33 +135,39 @@
      *		sql.append("\nLimit ").append(query.getSelect().getLimit());
      *	return sql.toString();
      * 
    - * + * *

    Translation of ADQL functions

    - * + * *

    - * All ADQL functions are by default not translated. Consequently, the SQL translation is - * actually the ADQL expression. Generally the ADQL expression is generic enough. However some mathematical functions may need - * to be translated differently. For instance {@link PostgreSQLTranslator} is translating differently: LOG, LOG10, RAND and TRUNC. + * All ADQL functions are by default not translated. Consequently, the SQL + * translation is actually the ADQL expression. Generally the ADQL expression + * is generic enough. However some mathematical functions may need to be + * translated differently. For instance {@link PostgreSQLTranslator} is + * translating differently: LOG, LOG10, RAND and TRUNC. *

    - * + * *

    Note: - * Geometrical regions and types have not been managed here. They stay abstract because it is obviously impossible to have a generic - * translation and conversion ; it totally depends from the database system. + * Geometrical regions and types have not been managed here. They stay abstract + * because it is obviously impossible to have a generic translation and + * conversion ; it totally depends from the database system. *

    - * + * *

    Translation of "FROM" with JOINs

    - * + * *

    - * The FROM clause is translated into SQL as written in ADQL. There is no differences except the identifiers that are replaced. - * The tables' aliases and their case sensitivity are kept like in ADQL. + * The FROM clause is translated into SQL as written in ADQL. There is no + * differences except the identifiers that are replaced. The tables' aliases + * and their case sensitivity are kept like in ADQL. *

    - * + * * @author Grégory Mantelet (ARI) - * @version 1.3 (05/2015) - * @since 1.3 - * + * @version 1.4 (01/2018) + * @since 1.4 + * * @see PostgreSQLTranslator * @see PgSphereTranslator + * @see MySQLTranslator + * @see SQLServerTranslator */ public abstract class JDBCTranslator implements ADQLTranslator { @@ -179,30 +175,30 @@ *

    Tell whether the specified identifier MUST be translated so that being interpreted case sensitively or not. * By default, an identifier that must be translated with case sensitivity will be surrounded by double quotes. * But, if this function returns FALSE, the SQL name will be written just as given in the metadata, without double quotes.

    - * + * *

    WARNING: * An {@link IdentifierField} object can be a SCHEMA, TABLE, COLUMN and ALIAS. However, in this translator, * aliases are translated like in ADQL (so, with the same case sensitivity specification as in ADQL). * So, this function will never be used to know the case sensitivity to apply to an alias. It is then * useless to write a special behavior for the ALIAS value. *

    - * + * * @param field The identifier whose the case sensitive to apply is asked. - * + * * @return true if the specified identifier must be translated case sensitivity, false otherwise (included if ALIAS or NULL). */ public abstract boolean isCaseSensitive(final IdentifierField field); /** *

    Get the qualified DB name of the schema containing the given table.

    - * + * *

    Note: * This function will, by default, add double quotes if the schema name must be case sensitive in the SQL query. * This information is provided by {@link #isCaseSensitive(IdentifierField)}. *

    - * + * * @param table A table of the schema whose the qualified DB name is asked. - * + * * @return The qualified (with DB catalog name prefix if any, and with double quotes if needed) DB schema name, * or an empty string if there is no schema or no DB name. */ @@ -222,17 +218,17 @@ /** *

    Get the qualified DB name of the given table.

    - * + * *

    Note: * This function will, by default, add double quotes if the table name must be case sensitive in the SQL query. * This information is provided by {@link #isCaseSensitive(IdentifierField)}. *

    - * + * * @param table The table whose the qualified DB name is asked. - * + * * @return The qualified (with DB catalog and schema prefix if any, and with double quotes if needed) DB table name, * or an empty string if the given table is NULL or if there is no DB name. - * + * * @see #getTableName(DBTable, boolean) */ public String getQualifiedTableName(final DBTable table){ @@ -242,18 +238,18 @@ /** *

    Get the DB name of the given table. * The second parameter lets specify whether the table name must be prefixed by the qualified schema name or not.

    - * + * *

    Note: * This function will, by default, add double quotes if the table name must be case sensitive in the SQL query. * This information is provided by {@link #isCaseSensitive(IdentifierField)}. *

    - * + * * @param table The table whose the DB name is asked. - * @param withSchema true if the qualified schema name must prefix the table name, false otherwise. - * + * @param withSchema true if the qualified schema name must prefix the table name, false otherwise. + * * @return The DB table name (prefixed by the qualified schema name if asked, and with double quotes if needed), * or an empty string if the given table is NULL or if there is no DB name. - * + * * @since 2.0 */ public String getTableName(final DBTable table, final boolean withSchema){ @@ -273,19 +269,19 @@ /** *

    Get the DB name of the given column

    - * + * *

    Note: * This function will, by default, add double quotes if the column name must be case sensitive in the SQL query. * This information is provided by {@link #isCaseSensitive(IdentifierField)}. *

    - * + * *

    Caution: * The given column may be NULL and in this case an empty string will be returned. * But if the given column is not NULL, its DB name MUST NOT BE NULL! *

    - * + * * @param column The column whose the DB name is asked. - * + * * @return The DB column name (with double quotes if needed), * or an empty string if the given column is NULL. */ @@ -294,13 +290,26 @@ } /** - * Appends the given identifier in the given StringBuffer. - * + *

    Appends the given identifier in the given StringBuffer.

    + * + *

    + * This function just call {@link #appendIdentifier(StringBuffer, String, boolean)} + * with the same 2 first parameters. The third one is the result of: + * {@link #isCaseSensitive(IdentifierField) isCaseSensitive(field)}. + *

    + * + *

    Note: + * In order to keep a consistent output of the appendIdentifier(...) functions, + * this function can not be overwritten ; it is just a shortcut function. + *

    + * * @param str The string buffer. * @param id The identifier to append. * @param field The type of identifier (column, table, schema, catalog or alias ?). - * + * * @return The string buffer + identifier. + * + * @see #appendIdentifier(StringBuffer, String, boolean) */ public final StringBuffer appendIdentifier(final StringBuffer str, final String id, final IdentifierField field){ return appendIdentifier(str, id, isCaseSensitive(field)); @@ -308,15 +317,15 @@ /** * Appends the given identifier to the given StringBuffer. - * + * * @param str The string buffer. * @param id The identifier to append. * @param caseSensitive true to format the identifier so that preserving the case sensitivity, false otherwise. - * + * * @return The string buffer + identifier. */ - public static final StringBuffer appendIdentifier(final StringBuffer str, final String id, final boolean caseSensitive){ - if (caseSensitive) + public StringBuffer appendIdentifier(final StringBuffer str, final String id, final boolean caseSensitive){ + if (caseSensitive && !id.matches("\"[^\"]*\"")) return str.append('"').append(id).append('"'); else return str.append(id); @@ -378,21 +387,49 @@ return translate((ClauseSelect)list); else if (list instanceof ClauseConstraints) return translate((ClauseConstraints)list); + else if (list instanceof Concatenation) + return getDefaultADQLList(list, false); else return getDefaultADQLList(list); } /** * Gets the default SQL output for a list of ADQL objects. - * + * + *

    Implementation note: + * This function just calls {@link #getDefaultADQLList(ADQLList, boolean)} + * with the given list in first parameter and true in second + * one. In other words, this function always prefixes the list items by + * the list name. + *

    + * * @param list List to format into SQL. - * + * * @return The corresponding SQL. - * + * + * @throws TranslationException If there is an error during the translation. + * + * @see #getDefaultADQLList(ADQLList, boolean) + */ + protected final String getDefaultADQLList(ADQLList list) throws TranslationException{ + return getDefaultADQLList(list, true); + } + + /** + * Gets the default SQL output for a list of ADQL objects. + * + * @param list List to format into SQL. + * @param withNamePrefix Prefix the list by its name or not. + * (e.g. 'false' for a Concatenation) + * + * @return The corresponding SQL. + * * @throws TranslationException If there is an error during the translation. + * + * @since 1.4 */ - protected String getDefaultADQLList(ADQLList list) throws TranslationException{ - String sql = (list.getName() == null) ? "" : (list.getName() + " "); + protected String getDefaultADQLList(ADQLList list, final boolean withNamePrefix) throws TranslationException{ + String sql = (list.getName() == null || !withNamePrefix) ? "" : (list.getName() + " "); for(int i = 0; i < list.size(); i++) sql += ((i == 0) ? "" : (" " + list.getSeparator(i) + " ")) + translate(list.get(i)); @@ -432,7 +469,10 @@ StringBuffer translation = new StringBuffer(translate(item.getOperand())); if (item.hasAlias()){ translation.append(" AS "); - appendIdentifier(translation, item.getAlias(), item.isCaseSensitive()); + if (item.isCaseSensitive()) + appendIdentifier(translation, item.getAlias(), true); + else + appendIdentifier(translation, item.getAlias().toLowerCase(), true); }else{ translation.append(" AS "); appendIdentifier(translation, item.getName(), true); @@ -443,30 +483,17 @@ @Override public String translate(SelectAllColumns item) throws TranslationException{ - HashMap mapAlias = new HashMap(); - // Fetch the full list of columns to display: Iterable dbCols = null; if (item.getAdqlTable() != null && item.getAdqlTable().getDBLink() != null){ ADQLTable table = item.getAdqlTable(); dbCols = table.getDBLink(); - if (table.hasAlias()){ - String key = getQualifiedTableName(table.getDBLink()); - mapAlias.put(key, table.isCaseSensitive(IdentifierField.ALIAS) ? ("\"" + table.getAlias() + "\"") : table.getAlias()); - } }else if (item.getQuery() != null){ try{ dbCols = item.getQuery().getFrom().getDBColumns(); }catch(UnresolvedJoinException pe){ throw new TranslationException("Due to a join problem, the ADQL to SQL translation can not be completed!", pe); } - ArrayList tables = item.getQuery().getFrom().getTables(); - for(ADQLTable table : tables){ - if (table.hasAlias()){ - String key = getQualifiedTableName(table.getDBLink()); - mapAlias.put(key, table.isCaseSensitive(IdentifierField.ALIAS) ? ("\"" + table.getAlias() + "\"") : table.getAlias()); - } - } } // Write the DB name of all these columns: @@ -476,11 +503,10 @@ if (cols.length() > 0) cols.append(','); if (col.getTable() != null){ - String fullDbName = getQualifiedTableName(col.getTable()); - if (mapAlias.containsKey(fullDbName)) - appendIdentifier(cols, mapAlias.get(fullDbName), false).append('.'); + if (col.getTable() instanceof DBTableAlias) + cols.append(getTableName(col.getTable(), false)).append('.'); else - cols.append(fullDbName).append('.'); + cols.append(getQualifiedTableName(col.getTable())).append('.'); } appendIdentifier(cols, col.getDBName(), IdentifierField.COLUMN); cols.append(" AS \"").append(col.getADQLName()).append('\"'); @@ -501,11 +527,11 @@ /** * Gets the default SQL output for a column reference. - * + * * @param ref The column reference to format into SQL. - * + * * @return The corresponding SQL. - * + * * @throws TranslationException If there is an error during the translation. */ protected String getDefaultColumnReference(ColumnReference ref) throws TranslationException{ @@ -561,8 +587,16 @@ // CASE: TABLE REFERENCE: else{ // Use the corresponding DB table, if known: - if (table.getDBLink() != null) - sql.append(getQualifiedTableName(table.getDBLink())); + if (table.getDBLink() != null){ + /* Note: if the table is aliased, the aliased table is wrapped + * inside a DBTableAlias. So, to get the real table name + * we should get first the original table thanks to + * DBTableAlias.getOriginTable(). */ + if (table.getDBLink() instanceof DBTableAlias) + sql.append(getQualifiedTableName(((DBTableAlias)table.getDBLink()).getOriginTable())); + else + sql.append(getQualifiedTableName(table.getDBLink())); + } // Otherwise, use the whole table name given in the ADQL query: else sql.append(table.getFullTableName()); @@ -571,7 +605,19 @@ // Add the table alias, if any: if (table.hasAlias()){ sql.append(" AS "); - appendIdentifier(sql, table.getAlias(), table.isCaseSensitive(IdentifierField.ALIAS)); + /* In case where metadata are known, the alias must always be + * written case sensitively in order to ensure a translation + * stability (i.e. all references clearly point toward this alias + * whatever is their character case). */ + if (table.getDBLink() != null){ + if (table.isCaseSensitive(IdentifierField.ALIAS)) + appendIdentifier(sql, table.getAlias(), true); + else + appendIdentifier(sql, table.getAlias().toLowerCase(), true); + } + /* Otherwise, just write what is written in ADQL: */ + else + appendIdentifier(sql, table.getAlias(), table.isCaseSensitive(IdentifierField.ALIAS)); } return sql.toString(); @@ -639,13 +685,16 @@ if (column.getDBLink() != null){ DBColumn dbCol = column.getDBLink(); StringBuffer colName = new StringBuffer(); - // Use the table alias if any: - if (column.getAdqlTable() != null && column.getAdqlTable().hasAlias()) - appendIdentifier(colName, column.getAdqlTable().getAlias(), column.getAdqlTable().isCaseSensitive(IdentifierField.ALIAS)).append('.'); // Use the DBTable if any: - else if (dbCol.getTable() != null && dbCol.getTable().getDBName() != null) - colName.append(getQualifiedTableName(dbCol.getTable())).append('.'); + if (dbCol.getTable() != null && dbCol.getTable().getDBName() != null){ + /* Note: if the table is aliased, ensure no schema is prefixing + * this alias thanks to getTableName(..., false). */ + if (dbCol.getTable() instanceof DBTableAlias) + colName.append(getTableName(dbCol.getTable(), false)).append('.'); + else + colName.append(getQualifiedTableName(dbCol.getTable())).append('.'); + } // Otherwise, use the prefix of the column given in the ADQL query: else if (column.getTableName() != null) @@ -677,7 +726,7 @@ @Override public String translate(StringConstant strConst) throws TranslationException{ - return "'" + strConst.getValue() + "'"; + return "'" + strConst.getValue().replaceAll("'", "''") + "'"; } @Override @@ -760,11 +809,11 @@ /** * Gets the default SQL output for the given ADQL function. - * + * * @param fct The ADQL function to format into SQL. - * + * * @return The corresponding SQL. - * + * * @throws TranslationException If there is an error during the translation. */ protected final String getDefaultADQLFunction(ADQLFunction fct) throws TranslationException{ @@ -834,52 +883,52 @@ /** * Convert any type provided by a JDBC driver into a type understandable by the ADQL/TAP library. - * + * * @param dbmsType Type returned by a JDBC driver. Note: this value is returned by ResultSetMetadata.getColumnType(int) and correspond to a type of java.sql.Types * @param rawDbmsTypeName Full name of the type returned by a JDBC driver. Note: this name is returned by ResultSetMetadata.getColumnTypeName(int) ; this name may contain parameters * @param dbmsTypeName Name of type, without the eventual parameters. Note: this name is extracted from rawDbmsTypeName. * @param typeParams The eventual type parameters (e.g. char string length). Note: these parameters are extracted from rawDbmsTypeName. - * + * * @return The corresponding ADQL/TAP type or NULL if the specified type is unknown. */ public abstract DBType convertTypeFromDB(final int dbmsType, final String rawDbmsTypeName, final String dbmsTypeName, final String[] typeParams); /** *

    Convert any type provided by the ADQL/TAP library into a type understandable by a JDBC driver.

    - * + * *

    Note: * The returned DBMS type may contain some parameters between brackets. *

    - * + * * @param type The ADQL/TAP library's type to convert. - * + * * @return The corresponding DBMS type or NULL if the specified type is unknown. */ public abstract String convertTypeToDB(final DBType type); /** *

    Parse the given JDBC column value as a geometry object and convert it into a {@link Region}.

    - * + * *

    Note: * Generally the returned object will be used to get its STC-S expression. *

    - * + * *

    Note: * If the given column value is NULL, NULL will be returned. *

    - * + * *

    Important note: * This function is called ONLY for value of columns flagged as geometries by * {@link #convertTypeFromDB(int, String, String, String[])}. So the value should always * be of the expected type and format. However, if it turns out that the type is wrong * and that the conversion is finally impossible, this function SHOULD throw a - * {@link DataReadException}. + * {@link ParseException}. *

    - * + * * @param jdbcColValue A JDBC column value (returned by ResultSet.getObject(int)). - * + * * @return The corresponding {@link Region} if the given value is a geometry. - * + * * @throws ParseException If the given object is not a geometrical object * or can not be transformed into a {@link Region} object. */ @@ -887,20 +936,20 @@ /** *

    Convert the given STC region into a DB column value.

    - * + * *

    Note: * This function is used only by the UPLOAD feature, to import geometries provided as STC-S expression in * a VOTable document inside a DB column. *

    - * + * *

    Note: * If the given region is NULL, NULL will be returned. *

    - * + * * @param region The region to store in the DB. - * + * * @return The corresponding DB column object. - * + * * @throws ParseException If the given STC Region can not be converted into a DB object. */ public abstract Object translateGeometryToDB(final Region region) throws ParseException; diff -Nru adql-1.3/src/adql/translator/MySQLTranslator.java adql-1.4/src/adql/translator/MySQLTranslator.java --- adql-1.3/src/adql/translator/MySQLTranslator.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/translator/MySQLTranslator.java 2018-01-11 10:01:40.000000000 +0000 @@ -0,0 +1,304 @@ +package adql.translator; + +import adql.db.DBType; +import adql.db.DBType.DBDatatype; +import adql.db.STCS.Region; +import adql.parser.ParseException; +import adql.query.IdentifierField; +import adql.query.operand.function.geometry.AreaFunction; +import adql.query.operand.function.geometry.BoxFunction; +import adql.query.operand.function.geometry.CentroidFunction; +import adql.query.operand.function.geometry.CircleFunction; +import adql.query.operand.function.geometry.ContainsFunction; +import adql.query.operand.function.geometry.DistanceFunction; +import adql.query.operand.function.geometry.ExtractCoord; +import adql.query.operand.function.geometry.ExtractCoordSys; +import adql.query.operand.function.geometry.IntersectsFunction; +import adql.query.operand.function.geometry.PointFunction; +import adql.query.operand.function.geometry.PolygonFunction; +import adql.query.operand.function.geometry.RegionFunction; + +/* + * This file is part of ADQLLibrary. + * + * ADQLLibrary is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ADQLLibrary is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ADQLLibrary. If not, see . + * + * Copyright 2017 - Astronomisches Rechen Institut (ARI) + */ + +/** + *

    Translates all ADQL objects into an SQL interrogation query designed for MySQL.

    + * + *

    Important: + * The geometrical functions are translated exactly as in ADQL. + * You will probably need to extend this translator to correctly manage the geometrical functions. + *

    + * + * @author Grégory Mantelet (ARI) + * @version 2.1 (08/2017) + * @since 2.1 + */ +public class MySQLTranslator extends JDBCTranslator { + + /** MySQL requires a length for variable-length types such as CHAR, VARCHAR, + * BINARY and VARBINARY. This static attributes is the default value set + * by this translator if no length is specified. */ + public static int DEFAULT_VARIABLE_LENGTH = 200; + + /** Indicate the case sensitivity to apply to each SQL identifier + * (only SCHEMA, TABLE and COLUMN). + *

    Note: + * In this implementation, this field is set by the constructor and never + * modified elsewhere. It would be better to never modify it after the + * construction in order to keep a certain consistency. + *

    + */ + protected byte caseSensitivity = 0x00; + + /** + * Build a MySQLTranslator which always translates in SQL all identifiers + * (schema, table and column) in a case sensitive manner ; in other words, + * schema, table and column names will be surrounded by back-quotes in the + * SQL translation. + */ + public MySQLTranslator(){ + caseSensitivity = 0x0F; + } + + /** + * Build a MySQLTranslator which always translates in SQL all identifiers + * (schema, table and column) in the specified case sensitivity ; in other + * words, schema, table and column names will all be surrounded or not by + * back-quotes in the SQL translation. + * + * @param allCaseSensitive true to translate all identifiers in a + * case sensitive manner + * (surrounded by back-quotes), + * false for case insensitivity. + */ + public MySQLTranslator(final boolean allCaseSensitive){ + caseSensitivity = allCaseSensitive ? (byte)0x0F : (byte)0x00; + } + + /** + * Build a MySQLTranslator which will always translate in SQL identifiers + * with the defined case sensitivity. + * + * @param catalog true to translate catalog names with back-quotes + * (case sensitive in the DBMS), false otherwise. + * @param schema true to translate schema names with back-quotes + * (case sensitive in the DBMS), false otherwise. + * @param table true to translate table names with back-quotes + * (case sensitive in the DBMS), false otherwise. + * @param column true to translate column names with back-quotes + * (case sensitive in the DBMS), false otherwise. + */ + public MySQLTranslator(final boolean catalog, final boolean schema, final boolean table, final boolean column){ + caseSensitivity = IdentifierField.CATALOG.setCaseSensitive(caseSensitivity, catalog); + caseSensitivity = IdentifierField.SCHEMA.setCaseSensitive(caseSensitivity, schema); + caseSensitivity = IdentifierField.TABLE.setCaseSensitive(caseSensitivity, table); + caseSensitivity = IdentifierField.COLUMN.setCaseSensitive(caseSensitivity, column); + } + + @Override + public boolean isCaseSensitive(final IdentifierField field){ + return field == null ? false : field.isCaseSensitive(caseSensitivity); + } + + @Override + public StringBuffer appendIdentifier(final StringBuffer str, final String id, final boolean caseSensitive){ + /* Note: In MySQL the identifier quoting character is a back-quote. */ + if (caseSensitive && !id.matches("\"[^\"]*\"")) + return str.append('`').append(id).append('`'); + else + return str.append(id); + } + + /* ********************************************************************** */ + /* * * */ + /* * TYPE MANAGEMENT * */ + /* * * */ + /* ********************************************************************** */ + + @Override + public DBType convertTypeFromDB(final int dbmsType, final String rawDbmsTypeName, String dbmsTypeName, final String[] params){ + // If no type is provided return VARCHAR: + if (dbmsTypeName == null || dbmsTypeName.trim().length() == 0) + return null; + + // Put the dbmsTypeName in lower case for the following comparisons: + dbmsTypeName = dbmsTypeName.toLowerCase(); + + // Extract the length parameter (always the first one): + int lengthParam = DBType.NO_LENGTH; + if (params != null && params.length > 0){ + try{ + lengthParam = Integer.parseInt(params[0]); + }catch(NumberFormatException nfe){} + } + + // SMALLINT + if (dbmsTypeName.equals("smallint") || dbmsTypeName.equals("tinyint") || dbmsTypeName.equals("bool") || dbmsTypeName.equals("boolean")) + return new DBType(DBDatatype.SMALLINT); + // INTEGER + else if (dbmsTypeName.equals("integer") || dbmsTypeName.equals("int") || dbmsTypeName.equals("mediumint")) + return new DBType(DBDatatype.INTEGER); + // BIGINT + else if (dbmsTypeName.equals("bigint")) + return new DBType(DBDatatype.BIGINT); + // REAL + else if (dbmsTypeName.equals("float") || dbmsTypeName.equals("real")) + return new DBType(DBDatatype.REAL); + // DOUBLE + else if (dbmsTypeName.equals("double") || dbmsTypeName.equals("double precision") || dbmsTypeName.equals("dec") || dbmsTypeName.equals("decimal") || dbmsTypeName.equals("numeric") || dbmsTypeName.equals("fixed")) + return new DBType(DBDatatype.DOUBLE); + // BINARY + else if (dbmsTypeName.equals("bit") || dbmsTypeName.equals("binary") || dbmsTypeName.equals("char byte")) + return new DBType(DBDatatype.BINARY, lengthParam); + // VARBINARY + else if (dbmsTypeName.equals("varbinary")) + return new DBType(DBDatatype.VARBINARY, lengthParam); + // CHAR + else if (dbmsTypeName.equals("char") || dbmsTypeName.equals("character") || dbmsTypeName.equals("nchar") || dbmsTypeName.equals("national char")) + return new DBType(DBDatatype.CHAR, lengthParam); + // VARCHAR + else if (dbmsTypeName.equals("varchar") || dbmsTypeName.equals("character varying") || dbmsTypeName.equals("nvarchar") || dbmsTypeName.equals("national varchar")) + return new DBType(DBDatatype.VARCHAR, lengthParam); + // BLOB + else if (dbmsTypeName.equals("blob") || dbmsTypeName.equals("tinyblob") || dbmsTypeName.equals("mediumblob") || dbmsTypeName.equals("longblob")) + return new DBType(DBDatatype.BLOB); + // CLOB + else if (dbmsTypeName.equals("text") || dbmsTypeName.equals("tinytext") || dbmsTypeName.equals("mediumtext") || dbmsTypeName.equals("longtext")) + return new DBType(DBDatatype.CLOB); + // TIMESTAMP + else if (dbmsTypeName.equals("timestamp") || dbmsTypeName.equals("date") || dbmsTypeName.equals("datetime") || dbmsTypeName.equals("time") || dbmsTypeName.equals("year")) + return new DBType(DBDatatype.TIMESTAMP); + // Default: + else + return null; + } + + @Override + public String convertTypeToDB(final DBType type){ + if (type == null) + return "VARCHAR(" + DEFAULT_VARIABLE_LENGTH + ")"; + + switch(type.type){ + + case SMALLINT: + case INTEGER: + case REAL: + case BIGINT: + case TIMESTAMP: + return type.type.toString(); + + case DOUBLE: + return "DOUBLE PRECISION"; + + case CHAR: + case VARCHAR: + case BINARY: + case VARBINARY: + return type.type.toString() + "(" + (type.length > 0 ? type.length : DEFAULT_VARIABLE_LENGTH) + ")"; + + case BLOB: + return "BLOB"; + + case CLOB: + return "TEXT"; + + case POINT: + case REGION: + default: + return "VARCHAR(" + DEFAULT_VARIABLE_LENGTH + ")"; + } + } + + @Override + public Region translateGeometryFromDB(final Object jdbcColValue) throws ParseException{ + throw new ParseException("Unsupported geometrical value! The value \"" + jdbcColValue + "\" can not be parsed as a region."); + } + + @Override + public Object translateGeometryToDB(final Region region) throws ParseException{ + throw new ParseException("Geometries can not be uploaded in the database in this implementation!"); + } + + /* ********************************************************************** */ + /* * * */ + /* * SPATIAL FUNCTIONS TRANSLATION * */ + /* * * */ + /* ********************************************************************** */ + + @Override + public String translate(ExtractCoord extractCoord) throws TranslationException{ + return getDefaultADQLFunction(extractCoord); + } + + @Override + public String translate(ExtractCoordSys extractCoordSys) throws TranslationException{ + return getDefaultADQLFunction(extractCoordSys); + } + + @Override + public String translate(AreaFunction areaFunction) throws TranslationException{ + return getDefaultADQLFunction(areaFunction); + } + + @Override + public String translate(CentroidFunction centroidFunction) throws TranslationException{ + return getDefaultADQLFunction(centroidFunction); + } + + @Override + public String translate(DistanceFunction fct) throws TranslationException{ + return getDefaultADQLFunction(fct); + } + + @Override + public String translate(ContainsFunction fct) throws TranslationException{ + return getDefaultADQLFunction(fct); + } + + @Override + public String translate(IntersectsFunction fct) throws TranslationException{ + return getDefaultADQLFunction(fct); + } + + @Override + public String translate(BoxFunction box) throws TranslationException{ + return getDefaultADQLFunction(box); + } + + @Override + public String translate(CircleFunction circle) throws TranslationException{ + return getDefaultADQLFunction(circle); + } + + @Override + public String translate(PointFunction point) throws TranslationException{ + return getDefaultADQLFunction(point); + } + + @Override + public String translate(PolygonFunction polygon) throws TranslationException{ + return getDefaultADQLFunction(polygon); + } + + @Override + public String translate(RegionFunction region) throws TranslationException{ + return getDefaultADQLFunction(region); + } + +} diff -Nru adql-1.3/src/adql/translator/PgSphereTranslator.java adql-1.4/src/adql/translator/PgSphereTranslator.java --- adql-1.3/src/adql/translator/PgSphereTranslator.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/translator/PgSphereTranslator.java 2018-01-12 14:12:54.000000000 +0000 @@ -2,21 +2,21 @@ /* * This file is part of ADQLLibrary. - * + * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . - * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -34,6 +34,7 @@ import adql.query.constraint.ComparisonOperator; import adql.query.operand.function.geometry.AreaFunction; import adql.query.operand.function.geometry.BoxFunction; +import adql.query.operand.function.geometry.CentroidFunction; import adql.query.operand.function.geometry.CircleFunction; import adql.query.operand.function.geometry.ContainsFunction; import adql.query.operand.function.geometry.DistanceFunction; @@ -43,12 +44,15 @@ import adql.query.operand.function.geometry.PolygonFunction; /** - *

    Translates all ADQL objects into the SQL adaptation of Postgres+PgSphere. - * Actually only the geometrical functions are translated in this class. - * The other functions are managed by {@link PostgreSQLTranslator}.

    - * + * Translates all ADQL objects into the SQL adaptation of Postgres+PgSphere. + * + *

    + * Actually only the geometrical functions and types are translated in this + * class. The other functions are managed by {@link PostgreSQLTranslator}. + *

    + * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (11/2014) + * @version 1.4 (07/2017) */ public class PgSphereTranslator extends PostgreSQLTranslator { @@ -61,7 +65,7 @@ /** * Builds a PgSphereTranslator which always translates in SQL all identifiers (schema, table and column) in a case sensitive manner ; * in other words, schema, table and column names will be surrounded by double quotes in the SQL translation. - * + * * @see PostgreSQLTranslator#PostgreSQLTranslator() */ public PgSphereTranslator(){ @@ -71,9 +75,9 @@ /** * Builds a PgSphereTranslator which always translates in SQL all identifiers (schema, table and column) in the specified case sensitivity ; * in other words, schema, table and column names will all be surrounded or not by double quotes in the SQL translation. - * - * @param allCaseSensitive true to translate all identifiers in a case sensitive manner (surrounded by double quotes), false for case insensitivity. - * + * + * @param allCaseSensitive true to translate all identifiers in a case sensitive manner (surrounded by double quotes), false for case insensitivity. + * * @see PostgreSQLTranslator#PostgreSQLTranslator(boolean) */ public PgSphereTranslator(boolean allCaseSensitive){ @@ -82,12 +86,12 @@ /** * Builds a PgSphereTranslator which will always translate in SQL identifiers with the defined case sensitivity. - * + * * @param catalog true to translate catalog names with double quotes (case sensitive in the DBMS), false otherwise. * @param schema true to translate schema names with double quotes (case sensitive in the DBMS), false otherwise. * @param table true to translate table names with double quotes (case sensitive in the DBMS), false otherwise. * @param column true to translate column names with double quotes (case sensitive in the DBMS), false otherwise. - * + * * @see PostgreSQLTranslator#PostgreSQLTranslator(boolean, boolean, boolean, boolean) */ public PgSphereTranslator(boolean catalog, boolean schema, boolean table, boolean column){ @@ -175,6 +179,13 @@ } @Override + public String translate(CentroidFunction centroidFunction) throws TranslationException{ + StringBuffer str = new StringBuffer("center("); + str.append(translate(centroidFunction.getParameter(0))).append(")"); + return str.toString(); + } + + @Override public String translate(ContainsFunction fct) throws TranslationException{ StringBuffer str = new StringBuffer("("); str.append(translate(fct.getLeftParam())).append(" @ ").append(translate(fct.getRightParam())).append(")"); @@ -202,7 +213,7 @@ public DBType convertTypeFromDB(final int dbmsType, final String rawDbmsTypeName, String dbmsTypeName, final String[] params){ // If no type is provided return VARCHAR: if (dbmsTypeName == null || dbmsTypeName.trim().length() == 0) - return new DBType(DBDatatype.VARCHAR, DBType.NO_LENGTH); + return null; // Put the dbmsTypeName in lower case for the following comparisons: dbmsTypeName = dbmsTypeName.toLowerCase(); @@ -245,7 +256,7 @@ String objType = pgo.getType().toLowerCase(); String geomStr = pgo.getValue(); - /* Only spoint, scircle, sbox and spoly are supported ; + /* Only spoint, scircle, sbox and spoly are supported ; * these geometries are parsed and transformed in Region instances:*/ if (objType.equals("spoint")) return (new PgSphereGeometryParser()).parsePoint(geomStr); @@ -322,16 +333,16 @@ /** *

    Convert the specified circle into a polygon. * The generated polygon is formatted using the PgSphere syntax.

    - * + * *

    Note: * The center coordinates and the radius are expected in degrees. *

    - * + * * @param center Center of the circle ([0]=ra and [1]=dec). * @param radius Radius of the circle. - * + * * @return The PgSphere serialization of the corresponding polygon. - * + * * @since 1.3 */ protected String circleToPolygon(final double[] center, final double radius){ @@ -350,13 +361,13 @@ /** *

    Let parse a geometry serialized with the PgSphere syntax.

    - * + * *

    * There is one function parseXxx(String) for each supported geometry. * These functions always return a {@link Region} object, * which is the object representation of an STC region. *

    - * + * *

    Only the following geometries are supported:

    *
      *
    • spoint => Position
    • @@ -364,12 +375,12 @@ *
    • sbox => Box
    • *
    • spoly => Polygon
    • *
    - * + * *

    * This parser supports all the known PgSphere representations of an angle. * However, it always returns angle (coordinates, radius, width and height) in degrees. *

    - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (11/2014) * @since 1.3 @@ -399,7 +410,7 @@ /** * Exception sent when the end of the expression * (EOE = End Of Expression) is reached. - * + * * @author Grégory Mantelet (ARI) * @version 1.3 (11/2014) * @since 1.3 @@ -420,7 +431,7 @@ /** * Prepare the parser in order to read the given PgSphere expression. - * + * * @param newStcs New PgSphere expression to parse from now. */ private void init(final String newExpr){ @@ -433,8 +444,8 @@ /** * Finalize the parsing. * No more characters (except eventually some space characters) should remain in the PgSphere expression to parse. - * - * @throws ParseException If other non-space characters remains. + * + * @throws ParseException If other non-space characters remains. */ private void end() throws ParseException{ // Skip all spaces: @@ -451,7 +462,7 @@ } /** - * Tool function which skips all next space characters until the next meaningful characters. + * Tool function which skips all next space characters until the next meaningful characters. */ private void skipSpaces(){ while(pos < expr.length() && Character.isWhitespace(expr.charAt(pos))) @@ -461,12 +472,12 @@ /** *

    Get the next meaningful word. This word can be a numeric, any string constant or a separator. * This function returns this token but also stores it in the class attribute {@link #token}.

    - * + * *

    * In case the end of the expression is reached before getting any meaningful character, * an {@link EOEException} is thrown. *

    - * + * * @return The full read word/token, or NULL if the end has been reached. */ private String nextToken() throws EOEException{ @@ -496,12 +507,12 @@ /** *

    Tell whether the given character is a separator defined in the syntax.

    - * + * *

    Here, the following characters are considered as separators/specials: * ',', 'd', 'h', 'm', 's', '(', ')', '<', '>', '{' and '}'.

    - * + * * @param c Character to test. - * + * * @return true if the given character must be considered as a separator, false otherwise. */ private static boolean isSyntaxSeparator(final char c){ @@ -511,9 +522,9 @@ /** * Get the next character and ensure it is the same as the character given in parameter. * If the read character is not matching the expected one, a {@link ParseException} is thrown. - * + * * @param expected Expected character. - * + * * @throws ParseException If the next character is not matching the given one. */ private void nextToken(final char expected) throws ParseException{ @@ -536,11 +547,11 @@ /** * Parse the given PgSphere geometry as a point. - * + * * @param pgsphereExpr The PgSphere expression to parse as a point. - * + * * @return A {@link Region} implementing a STC Position region. - * + * * @throws ParseException If the PgSphere syntax of the given expression is wrong or does not correspond to a point. */ public Region parsePoint(final String pgsphereExpr) throws ParseException{ @@ -555,12 +566,12 @@ } /** - * Internal spoint parsing function. It parses the PgSphere expression stored in this parser as a point. - * + * Internal spoint parsing function. It parses the PgSphere expression stored in this parser as a point. + * * @return The ra and dec coordinates (in degrees) of the parsed point. - * + * * @throws ParseException If the PgSphere syntax of the given expression is wrong or does not correspond to a point. - * + * * @see #parseAngle() * @see #parsePoint(String) */ @@ -575,11 +586,11 @@ /** * Parse the given PgSphere geometry as a circle. - * + * * @param pgsphereExpr The PgSphere expression to parse as a circle. - * + * * @return A {@link Region} implementing a STC Circle region. - * + * * @throws ParseException If the PgSphere syntax of the given expression is wrong or does not correspond to a circle. */ public Region parseCircle(final String pgsphereExpr) throws ParseException{ @@ -602,11 +613,11 @@ /** * Parse the given PgSphere geometry as a box. - * + * * @param pgsphereExpr The PgSphere expression to parse as a box. - * + * * @return A {@link Region} implementing a STC Box region. - * + * * @throws ParseException If the PgSphere syntax of the given expression is wrong or does not correspond to a box. */ public Region parseBox(final String pgsphereExpr) throws ParseException{ @@ -624,18 +635,19 @@ end(); // Build the STC Box region: - double width = Math.abs(northeast[0] - southwest[0]), height = Math.abs(northeast[1] - southwest[1]); + double width = Math.abs(northeast[0] - southwest[0]), + height = Math.abs(northeast[1] - southwest[1]); double[] center = new double[]{northeast[0] - width / 2,northeast[1] - height / 2}; return new Region(null, center, width, height); } /** * Parse the given PgSphere geometry as a point. - * + * * @param pgsphereExpr The PgSphere expression to parse as a point. - * + * * @return A {@link Region} implementing a STC Position region. - * + * * @throws ParseException If the PgSphere syntax of the given expression is wrong or does not correspond to a point. */ public Region parsePolygon(final String pgsphereExpr) throws ParseException{ @@ -667,7 +679,7 @@ /** *

    Read the next tokens as an angle expression and returns the corresponding angle in degrees.

    - * + * *

    This function supports the 4 following syntaxes:

    *
      *
    • RAD: {number}
    • @@ -675,9 +687,9 @@ *
    • DMS: {number}d {number}m {number}s
    • *
    • HMS: {number}h {number}m {number}s
    • *
    - * + * * @return The corresponding angle in degrees. - * + * * @throws ParseException If the angle syntax is wrong or not supported. */ private double parseAngle() throws ParseException{ diff -Nru adql-1.3/src/adql/translator/PostgreSQLTranslator.java adql-1.4/src/adql/translator/PostgreSQLTranslator.java --- adql-1.3/src/adql/translator/PostgreSQLTranslator.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/adql/translator/PostgreSQLTranslator.java 2018-01-12 14:11:36.000000000 +0000 @@ -2,21 +2,21 @@ /* * This file is part of ADQLLibrary. - * + * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . - * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * + * Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -26,6 +26,7 @@ import adql.parser.ParseException; import adql.query.IdentifierField; import adql.query.operand.StringConstant; +import adql.query.operand.function.ADQLFunction; import adql.query.operand.function.MathFunction; import adql.query.operand.function.geometry.AreaFunction; import adql.query.operand.function.geometry.BoxFunction; @@ -41,23 +42,36 @@ import adql.query.operand.function.geometry.RegionFunction; /** - *

    Translates all ADQL objects into an SQL interrogation query designed for PostgreSQL.

    - * + * Translates all ADQL objects into an SQL interrogation query designed for + * PostgreSQL. + * + *

    + * It overwrites the translation of mathematical functions whose some have + * a different name or signature. Besides, it is also implementing the + * translation of the geometrical functions. However, it does not really + * translate them. It is just returning the ADQL expression (by calling + * {@link #getDefaultADQLFunction(ADQLFunction)}). And so, of course, the + * execution of a SQL query containing geometrical functions and translated + * using this translator will not work. It is just a default implementation in + * case there is no interest of these geometrical functions. + *

    + * *

    Important: * The geometrical functions are translated exactly as in ADQL. - * You will probably need to extend this translator to correctly manage the geometrical functions. - * An extension is already available for PgSphere: {@link PgSphereTranslator}. + * You will probably need to extend this translator to correctly manage the + * geometrical functions. An extension is already available for PgSphere: + * {@link PgSphereTranslator}. *

    - * + * * @author Grégory Mantelet (CDS;ARI) - * @version 1.3 (11/2014) - * + * @version 1.4 (08/2016) + * * @see PgSphereTranslator */ public class PostgreSQLTranslator extends JDBCTranslator { /**

    Indicate the case sensitivity to apply to each SQL identifier (only SCHEMA, TABLE and COLUMN).

    - * + * *

    Note: * In this implementation, this field is set by the constructor and never modified elsewhere. * It would be better to never modify it after the construction in order to keep a certain consistency. @@ -76,8 +90,8 @@ /** * Builds a PostgreSQLTranslator which always translates in SQL all identifiers (schema, table and column) in the specified case sensitivity ; * in other words, schema, table and column names will all be surrounded or not by double quotes in the SQL translation. - * - * @param allCaseSensitive true to translate all identifiers in a case sensitive manner (surrounded by double quotes), false for case insensitivity. + * + * @param allCaseSensitive true to translate all identifiers in a case sensitive manner (surrounded by double quotes), false for case insensitivity. */ public PostgreSQLTranslator(final boolean allCaseSensitive){ caseSensitivity = allCaseSensitive ? (byte)0x0F : (byte)0x00; @@ -85,7 +99,7 @@ /** * Builds a PostgreSQLTranslator which will always translate in SQL identifiers with the defined case sensitivity. - * + * * @param catalog true to translate catalog names with double quotes (case sensitive in the DBMS), false otherwise. * @param schema true to translate schema names with double quotes (case sensitive in the DBMS), false otherwise. * @param table true to translate table names with double quotes (case sensitive in the DBMS), false otherwise. @@ -120,15 +134,34 @@ public String translate(MathFunction fct) throws TranslationException{ switch(fct.getType()){ case LOG: - return "ln(" + ((fct.getNbParameters() >= 1) ? translate(fct.getParameter(0)) : "") + ")"; + return "ln(" + ((fct.getNbParameters() >= 1) ? "CAST(" + translate(fct.getParameter(0)) + " AS numeric)" : "") + ")"; case LOG10: - return "log(10, " + ((fct.getNbParameters() >= 1) ? translate(fct.getParameter(0)) : "") + ")"; + return "log(10, " + ((fct.getNbParameters() >= 1) ? "CAST(" + translate(fct.getParameter(0)) + " AS numeric)" : "") + ")"; case RAND: return "random()"; case TRUNCATE: - return "trunc(" + ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1))) : "") + ")"; - default: + if (fct.getNbParameters() >= 2) + return "trunc(CAST(" + translate(fct.getParameter(0)) + " AS numeric), " + translate(fct.getParameter(1)) + ")"; + else if (fct.getNbParameters() >= 1) + return "trunc(CAST(" + translate(fct.getParameter(0)) + " AS numeric)" + ")"; + else + return "trunc()"; + case ROUND: + if (fct.getNbParameters() >= 2) + return "round(CAST(" + translate(fct.getParameter(0)) + " AS numeric), " + translate(fct.getParameter(1)) + ")"; + else if (fct.getNbParameters() >= 1) + return "round(CAST(" + translate(fct.getParameter(0)) + " AS numeric))"; + else + return "round()"; + case PI: return getDefaultADQLFunction(fct); + default: + String sql = fct.getName() + "("; + + for(int i = 0; i < fct.getNbParameters(); i++) + sql += ((i == 0) ? "" : ", ") + "CAST(" + translate(fct.getParameter(i)) + " AS numeric)"; + + return sql + ")"; } } @@ -196,7 +229,7 @@ public DBType convertTypeFromDB(final int dbmsType, final String rawDbmsTypeName, String dbmsTypeName, final String[] params){ // If no type is provided return VARCHAR: if (dbmsTypeName == null || dbmsTypeName.trim().length() == 0) - return new DBType(DBDatatype.VARCHAR, DBType.NO_LENGTH); + return null; // Put the dbmsTypeName in lower case for the following comparisons: dbmsTypeName = dbmsTypeName.toLowerCase(); @@ -222,7 +255,7 @@ else if (dbmsTypeName.equals("real") || dbmsTypeName.equals("float4")) return new DBType(DBDatatype.REAL); // DOUBLE - else if (dbmsTypeName.equals("double precision") || dbmsTypeName.equals("float8")) + else if (dbmsTypeName.equals("double precision") || dbmsTypeName.equals("float8") || dbmsTypeName.equals("numeric")) return new DBType(DBDatatype.DOUBLE); // BINARY else if (dbmsTypeName.equals("bit")) @@ -247,7 +280,7 @@ return new DBType(DBDatatype.TIMESTAMP); // Default: else - return new DBType(DBDatatype.VARCHAR, DBType.NO_LENGTH); + return null; } @Override diff -Nru adql-1.3/src/adql/translator/SQLServerTranslator.java adql-1.4/src/adql/translator/SQLServerTranslator.java --- adql-1.3/src/adql/translator/SQLServerTranslator.java 1970-01-01 00:00:00.000000000 +0000 +++ adql-1.4/src/adql/translator/SQLServerTranslator.java 2017-11-03 17:18:00.000000000 +0000 @@ -0,0 +1,457 @@ +package adql.translator; + +import java.util.Iterator; + +import adql.db.DBColumn; +import adql.db.DBType; +import adql.db.DBType.DBDatatype; +import adql.db.STCS.Region; +import adql.db.SearchColumnList; +import adql.db.exception.UnresolvedJoinException; +import adql.parser.ParseException; +import adql.parser.SQLServer_ADQLQueryFactory; +import adql.query.ADQLQuery; +import adql.query.ClauseSelect; +import adql.query.IdentifierField; +import adql.query.from.ADQLJoin; +import adql.query.from.ADQLTable; +import adql.query.from.FromContent; +import adql.query.operand.ADQLColumn; +import adql.query.operand.function.MathFunction; +import adql.query.operand.function.geometry.AreaFunction; +import adql.query.operand.function.geometry.BoxFunction; +import adql.query.operand.function.geometry.CentroidFunction; +import adql.query.operand.function.geometry.CircleFunction; +import adql.query.operand.function.geometry.ContainsFunction; +import adql.query.operand.function.geometry.DistanceFunction; +import adql.query.operand.function.geometry.ExtractCoord; +import adql.query.operand.function.geometry.ExtractCoordSys; +import adql.query.operand.function.geometry.IntersectsFunction; +import adql.query.operand.function.geometry.PointFunction; +import adql.query.operand.function.geometry.PolygonFunction; +import adql.query.operand.function.geometry.RegionFunction; + +/** + *

    MS SQL Server translator.

    + * + *

    Important: + * This translator works correctly ONLY IF {@link SQLServer_ADQLQueryFactory} has been used + * to create any ADQL query this translator is asked to translate. + *

    + * + * TODO See how case sensitivity is supported by MS SQL Server and modify this translator accordingly. + * + * TODO Extend this class for each MS SQL Server extension supporting geometry and particularly + * {@link #translateGeometryFromDB(Object)}, {@link #translateGeometryToDB(adql.db.STCS.Region)} and all this other + * translate(...) functions for the ADQL's geometrical functions. + * + * TODO Check MS SQL Server datatypes (see {@link #convertTypeFromDB(int, String, String, String[])}, + * {@link #convertTypeToDB(DBType)}). + * + *

    Important note: + * Geometrical functions are not translated ; the translation returned for them is their ADQL expression. + *

    + * + * @author Grégory Mantelet (ARI) + * @version 1.4 (09/2017) + * @since 1.4 + * + * @see SQLServer_ADQLQueryFactory + */ +public class SQLServerTranslator extends JDBCTranslator { + + /**

    Indicate the case sensitivity to apply to each SQL identifier (only SCHEMA, TABLE and COLUMN).

    + * + *

    Note: + * In this implementation, this field is set by the constructor and never modified elsewhere. + * It would be better to never modify it after the construction in order to keep a certain consistency. + *

    + */ + protected byte caseSensitivity = 0x00; + + /** + * Builds an SQLServerTranslator which always translates in SQL all identifiers (schema, table and column) in a case sensitive manner ; + * in other words, schema, table and column names will be surrounded by double quotes in the SQL translation. + */ + public SQLServerTranslator(){ + caseSensitivity = 0x0F; + } + + /** + * Builds an SQLServerTranslator which always translates in SQL all identifiers (schema, table and column) in the specified case sensitivity ; + * in other words, schema, table and column names will all be surrounded or not by double quotes in the SQL translation. + * + * @param allCaseSensitive true to translate all identifiers in a case sensitive manner (surrounded by double quotes), false for case insensitivity. + */ + public SQLServerTranslator(final boolean allCaseSensitive){ + caseSensitivity = allCaseSensitive ? (byte)0x0F : (byte)0x00; + } + + /** + * Builds an SQLServerTranslator which will always translate in SQL identifiers with the defined case sensitivity. + * + * @param catalog true to translate catalog names with double quotes (case sensitive in the DBMS), false otherwise. + * @param schema true to translate schema names with double quotes (case sensitive in the DBMS), false otherwise. + * @param table true to translate table names with double quotes (case sensitive in the DBMS), false otherwise. + * @param column true to translate column names with double quotes (case sensitive in the DBMS), false otherwise. + */ + public SQLServerTranslator(final boolean catalog, final boolean schema, final boolean table, final boolean column){ + caseSensitivity = IdentifierField.CATALOG.setCaseSensitive(caseSensitivity, catalog); + caseSensitivity = IdentifierField.SCHEMA.setCaseSensitive(caseSensitivity, schema); + caseSensitivity = IdentifierField.TABLE.setCaseSensitive(caseSensitivity, table); + caseSensitivity = IdentifierField.COLUMN.setCaseSensitive(caseSensitivity, column); + } + + @Override + public boolean isCaseSensitive(final IdentifierField field){ + return field == null ? false : field.isCaseSensitive(caseSensitivity); + } + + /** + * For SQL Server, {@link #translate(ClauseSelect)} must be overridden for + * TOP/LIMIT handling. We must not add the LIMIT at the end of the query, it + * must go in the SELECT. + * + * @see #translate(ClauseSelect) + */ + @Override + public String translate(ADQLQuery query) throws TranslationException{ + StringBuffer sql = new StringBuffer(translate(query.getSelect())); + + sql.append("\nFROM ").append(translate(query.getFrom())); + + if (!query.getWhere().isEmpty()) + sql.append('\n').append(translate(query.getWhere())); + + if (!query.getGroupBy().isEmpty()) + sql.append('\n').append(translate(query.getGroupBy())); + + if (!query.getHaving().isEmpty()) + sql.append('\n').append(translate(query.getHaving())); + + if (!query.getOrderBy().isEmpty()) + sql.append('\n').append(translate(query.getOrderBy())); + + return sql.toString(); + } + + @Override + public String translate(ClauseSelect clause) throws TranslationException{ + String sql = null; + + for(int i = 0; i < clause.size(); i++){ + if (i == 0){ + sql = clause.getName() + (clause.distinctColumns() ? " DISTINCT" : "") + (clause.hasLimit() ? " TOP " + clause.getLimit() + " " : ""); + }else + sql += " " + clause.getSeparator(i); + + sql += " " + translate(clause.get(i)); + } + + return sql; + } + + @Override + public String translate(final ADQLJoin join) throws TranslationException{ + StringBuffer sql = new StringBuffer(translate(join.getLeftTable())); + + sql.append(' ').append(join.getJoinType()).append(' ').append(translate(join.getRightTable())).append(' '); + + // CASE: NATURAL + if (join.isNatural()){ + try{ + StringBuffer buf = new StringBuffer(); + + // Find duplicated items between the two lists and translate them as ON conditions: + DBColumn rightCol; + SearchColumnList leftList = join.getLeftTable().getDBColumns(); + SearchColumnList rightList = join.getRightTable().getDBColumns(); + for(DBColumn leftCol : leftList){ + // search for at most one column with the same name in the RIGHT list + // and throw an exception is there are several matches: + rightCol = ADQLJoin.findAtMostOneColumn(leftCol.getADQLName(), (byte)0, rightList, false); + // if there is one... + if (rightCol != null){ + // ...check there is only one column with this name in the LEFT list, + // and throw an exception if it is not the case: + ADQLJoin.findExactlyOneColumn(leftCol.getADQLName(), (byte)0, leftList, true); + // ...append the corresponding join condition: + if (buf.length() > 0) + buf.append(" AND "); + buf.append(translate(generateJoinColumn(join.getLeftTable(), leftCol, new ADQLColumn(leftCol.getADQLName())))); + buf.append("="); + buf.append(translate(generateJoinColumn(join.getRightTable(), rightCol, new ADQLColumn(rightCol.getADQLName())))); + } + } + + sql.append("ON ").append(buf.toString()); + }catch(UnresolvedJoinException uje){ + throw new TranslationException("Impossible to resolve the NATURAL JOIN between " + join.getLeftTable().toADQL() + " and " + join.getRightTable().toADQL() + "!", uje); + } + } + // CASE: USING + else if (join.hasJoinedColumns()){ + try{ + StringBuffer buf = new StringBuffer(); + + // For each columns of usingList, check there is in each list exactly one matching column, and then, translate it as ON condition: + DBColumn leftCol, rightCol; + ADQLColumn usingCol; + SearchColumnList leftList = join.getLeftTable().getDBColumns(); + SearchColumnList rightList = join.getRightTable().getDBColumns(); + Iterator itCols = join.getJoinedColumns(); + while(itCols.hasNext()){ + usingCol = itCols.next(); + // search for exactly one column with the same name in the LEFT list + // and throw an exception if there is none, or if there are several matches: + leftCol = ADQLJoin.findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), leftList, true); + // item in the RIGHT list: + rightCol = ADQLJoin.findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), rightList, false); + // append the corresponding join condition: + if (buf.length() > 0) + buf.append(" AND "); + buf.append(translate(generateJoinColumn(join.getLeftTable(), leftCol, usingCol))); + buf.append("="); + buf.append(translate(generateJoinColumn(join.getRightTable(), rightCol, usingCol))); + } + + sql.append("ON ").append(buf.toString()); + }catch(UnresolvedJoinException uje){ + throw new TranslationException("Impossible to resolve the JOIN USING between " + join.getLeftTable().toADQL() + " and " + join.getRightTable().toADQL() + "!", uje); + } + } + // DEFAULT CASE: + else if (join.getJoinCondition() != null) + sql.append(translate(join.getJoinCondition())); + + return sql.toString(); + } + + /** + * Generate an ADQL column of the given table and with the given metadata. + * + * @param table Parent table of the column to generate. + * @param colMeta DB metadata of the column to generate. + * @param joinedColumn The joined column (i.e. the ADQL column listed in a + * USING) from which the generated column should + * derive. + * If NULL, an {@link ADQLColumn} instance will be + * created from scratch using the ADQL name of the + * given DB metadata. + * + * @return The generated column. + */ + protected ADQLColumn generateJoinColumn(final FromContent table, final DBColumn colMeta, final ADQLColumn joinedColumn){ + ADQLColumn newCol = (joinedColumn == null ? new ADQLColumn(colMeta.getADQLName()) : new ADQLColumn(joinedColumn)); + if (table != null){ + if (table instanceof ADQLTable) + newCol.setAdqlTable((ADQLTable)table); + else + newCol.setAdqlTable(new ADQLTable(table.getName())); + } + newCol.setDBLink(colMeta); + return newCol; + } + + @Override + public String translate(final ExtractCoord extractCoord) throws TranslationException{ + return getDefaultADQLFunction(extractCoord); + } + + @Override + public String translate(final ExtractCoordSys extractCoordSys) throws TranslationException{ + return getDefaultADQLFunction(extractCoordSys); + } + + @Override + public String translate(final AreaFunction areaFunction) throws TranslationException{ + return getDefaultADQLFunction(areaFunction); + } + + @Override + public String translate(final CentroidFunction centroidFunction) throws TranslationException{ + return getDefaultADQLFunction(centroidFunction); + } + + @Override + public String translate(final DistanceFunction fct) throws TranslationException{ + return getDefaultADQLFunction(fct); + } + + @Override + public String translate(final ContainsFunction fct) throws TranslationException{ + return getDefaultADQLFunction(fct); + } + + @Override + public String translate(final IntersectsFunction fct) throws TranslationException{ + return getDefaultADQLFunction(fct); + } + + @Override + public String translate(final PointFunction point) throws TranslationException{ + return getDefaultADQLFunction(point); + } + + @Override + public String translate(final CircleFunction circle) throws TranslationException{ + return getDefaultADQLFunction(circle); + } + + @Override + public String translate(final BoxFunction box) throws TranslationException{ + return getDefaultADQLFunction(box); + } + + @Override + public String translate(final PolygonFunction polygon) throws TranslationException{ + return getDefaultADQLFunction(polygon); + } + + @Override + public String translate(final RegionFunction region) throws TranslationException{ + return getDefaultADQLFunction(region); + } + + @Override + public String translate(MathFunction fct) throws TranslationException{ + switch(fct.getType()){ + case TRUNCATE: + // third argument to round nonzero means do a truncate + return "round(convert(float, " + ((fct.getNbParameters() >= 2) ? (translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1))) : "") + "),1)"; + case MOD: + return ((fct.getNbParameters() >= 2) ? ("convert(float, " + translate(fct.getParameter(0)) + ") % convert(float, " + translate(fct.getParameter(1)) + ")") : ""); + case ATAN2: + return "ATN2(" + translate(fct.getParameter(0)) + ", " + translate(fct.getParameter(1)) + ")"; + + /* In MS-SQLServer, the following functions returns a value of the + * same type as the given argument. However, ADQL requires that an + * SQLServer float (so a double in ADQL) is returned. So, in order + * to follow the ADQL standard, the given parameter must be + * converted into a float: */ + case ABS: + return "abs(convert(float, " + translate(fct.getParameter(0)) + "))"; + case CEILING: + return "ceiling(convert(float, " + translate(fct.getParameter(0)) + "))"; + case DEGREES: + return "degrees(convert(float, " + translate(fct.getParameter(0)) + "))"; + case FLOOR: + return "floor(convert(float, " + translate(fct.getParameter(0)) + "))"; + case RADIANS: + return "radians(convert(float, " + translate(fct.getParameter(0)) + "))"; + case ROUND: + return "round(convert(float, " + translate(fct.getParameter(0)) + ")" + ", " + translate(fct.getParameter(1)) + ")"; + + default: + return getDefaultADQLFunction(fct); + } + } + + @Override + public DBType convertTypeFromDB(final int dbmsType, final String rawDbmsTypeName, String dbmsTypeName, final String[] params){ + // If no type is provided return VARCHAR: + if (dbmsTypeName == null || dbmsTypeName.trim().length() == 0) + return null; + + // Put the dbmsTypeName in lower case for the following comparisons: + dbmsTypeName = dbmsTypeName.toLowerCase(); + + // Extract the length parameter (always the first one): + int lengthParam = DBType.NO_LENGTH; + if (params != null && params.length > 0){ + try{ + lengthParam = Integer.parseInt(params[0]); + }catch(NumberFormatException nfe){} + } + + // SMALLINT + if (dbmsTypeName.equals("smallint") || dbmsTypeName.equals("tinyint") || dbmsTypeName.equals("bit")) + return new DBType(DBDatatype.SMALLINT); + // INTEGER + else if (dbmsTypeName.equals("int")) + return new DBType(DBDatatype.INTEGER); + // BIGINT + else if (dbmsTypeName.equals("bigint")) + return new DBType(DBDatatype.BIGINT); + // REAL (cf https://msdn.microsoft.com/fr-fr/library/ms173773(v=sql.120).aspx) + else if (dbmsTypeName.equals("real") || (dbmsTypeName.equals("float") && lengthParam >= 1 && lengthParam <= 24)) + return new DBType(DBDatatype.REAL); + // DOUBLE (cf https://msdn.microsoft.com/fr-fr/library/ms173773(v=sql.120).aspx) + else if (dbmsTypeName.equals("float") || dbmsTypeName.equals("decimal") || dbmsTypeName.equals("numeric")) + return new DBType(DBDatatype.DOUBLE); + // BINARY + else if (dbmsTypeName.equals("binary")) + return new DBType(DBDatatype.BINARY, lengthParam); + // VARBINARY + else if (dbmsTypeName.equals("varbinary")) + return new DBType(DBDatatype.VARBINARY, lengthParam); + // CHAR + else if (dbmsTypeName.equals("char") || dbmsTypeName.equals("nchar")) + return new DBType(DBDatatype.CHAR, lengthParam); + // VARCHAR + else if (dbmsTypeName.equals("varchar") || dbmsTypeName.equals("nvarchar")) + return new DBType(DBDatatype.VARCHAR, lengthParam); + // BLOB + else if (dbmsTypeName.equals("image")) + return new DBType(DBDatatype.BLOB); + // CLOB + else if (dbmsTypeName.equals("text") || dbmsTypeName.equals("ntext")) + return new DBType(DBDatatype.CLOB); + // TIMESTAMP + else if (dbmsTypeName.equals("timestamp") || dbmsTypeName.equals("datetime") || dbmsTypeName.equals("datetime2") || dbmsTypeName.equals("datetimeoffset") || dbmsTypeName.equals("smalldatetime") || dbmsTypeName.equals("time") || dbmsTypeName.equals("date") || dbmsTypeName.equals("date")) + return new DBType(DBDatatype.TIMESTAMP); + // Default: + else + return null; + } + + @Override + public String convertTypeToDB(final DBType type){ + if (type == null) + return "varchar"; + + switch(type.type){ + + case SMALLINT: + case REAL: + case BIGINT: + case CHAR: + case VARCHAR: + case BINARY: + case VARBINARY: + return type.type.toString().toLowerCase(); + + case INTEGER: + return "int"; + + // (cf https://msdn.microsoft.com/fr-fr/library/ms173773(v=sql.120).aspx) + case DOUBLE: + return "float(53)"; + + case TIMESTAMP: + return "datetime"; + + case BLOB: + return "image"; + + case CLOB: + return "text"; + + case POINT: + case REGION: + default: + return "varchar"; + } + } + + @Override + public Region translateGeometryFromDB(final Object jdbcColValue) throws ParseException{ + throw new ParseException("Unsupported geometrical value! The value \"" + jdbcColValue + "\" can not be parsed as a region."); + } + + @Override + public Object translateGeometryToDB(final Region region) throws ParseException{ + throw new ParseException("Geometries can not be uploaded in the database in this implementation!"); + } + +} diff -Nru adql-1.3/src/cds/utils/TextualSearchList.java adql-1.4/src/cds/utils/TextualSearchList.java --- adql-1.3/src/cds/utils/TextualSearchList.java 2015-01-23 16:17:54.000000000 +0000 +++ adql-1.4/src/cds/utils/TextualSearchList.java 2017-11-03 17:18:00.000000000 +0000 @@ -16,13 +16,14 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see . * - * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; /** *

    A TextualSearchList is an {@link ArrayList} with a textual search capability.

    @@ -39,7 +40,7 @@ * * @param Type of object to manage in this list. * @author Grégory Mantelet (CDS;ARI) - * @version 1.1 (11/2013) + * @version 1.4 (09/2017) */ public class TextualSearchList< E > extends ArrayList { private static final long serialVersionUID = 1L; @@ -173,7 +174,7 @@ * * @return The corresponding object or null. */ - public final ArrayList get(final String key){ + public final List get(final String key){ return get(key, false); } @@ -186,7 +187,7 @@ * @return All the objects whose the key is the same as the given one. */ @SuppressWarnings("unchecked") - public ArrayList get(final String key, final boolean caseSensitive){ + public List get(final String key, final boolean caseSensitive){ if (key == null) return new ArrayList(0); @@ -419,7 +420,7 @@ * @param The type of objects managed in the given map. */ private static final < E > void removeFromMap(final HashMap> map, final String key, final E value){ - ArrayList lst = map.get(key); + List lst = map.get(key); if (lst != null){ lst.remove(value); if (lst.isEmpty())