diff --git a/src/adql/db/DBChecker.java b/src/adql/db/DBChecker.java index 9bbb80fa368365ad63cadf1b8beccf18db4570f0..7c8463a6a97cfbaf3f32b7e92cb17690b6007d4e 100644 --- a/src/adql/db/DBChecker.java +++ b/src/adql/db/DBChecker.java @@ -108,7 +108,7 @@ import adql.search.SimpleSearchHandler; * </i></p> * * @author Grégory Mantelet (CDS;ARI) - * @version 2.0 (09/2019) + * @version 2.0 (11/2019) */ public class DBChecker implements QueryChecker { @@ -464,15 +464,6 @@ public class DBChecker implements QueryChecker { // Update the context: context.cteTables.add(adqlTable.getDBLink()); - - // Check the number of columns: - if (withItem.getColumnLabels() != null) { - DBColumn[] columns = withItem.getResultingColumns(); - if (withItem.getColumnLabels().size() > columns.length) - errors.addException(new ParseException("The WITH query \"" + withItem.getLabel() + "\" specifies MORE columns (" + withItem.getColumnLabels().size() + ") than available (" + columns.length + ")!", withItem.getPosition())); - else if (withItem.getColumnLabels().size() < columns.length) - errors.addException(new ParseException("The WITH query \"" + withItem.getLabel() + "\" specifies LESS columns (" + withItem.getColumnLabels().size() + ") than available (" + columns.length + ")!", withItem.getPosition())); - } } // Check the existence of all tables in the FROM clause: diff --git a/src/adql/parser/ADQLQueryFactory.java b/src/adql/parser/ADQLQueryFactory.java index 42c55029fe8083b1815e5d7a9dfed2cec2fdeb73..5507f7ac93c5d186bf20e5aedd26b54d2f5a643c 100644 --- a/src/adql/parser/ADQLQueryFactory.java +++ b/src/adql/parser/ADQLQueryFactory.java @@ -208,8 +208,8 @@ public class ADQLQueryFactory { } /** @since 2.0 */ - public WithItem createWithItem(final IdentifierItem queryLabel, final ADQLQuery query, final Collection<ADQLColumn> colLabels) throws Exception { - WithItem item = new WithItem(queryLabel.identifier, query, colLabels); + public WithItem createWithItem(final IdentifierItem queryLabel, final ADQLQuery query) throws Exception { + WithItem item = new WithItem(queryLabel.identifier, query); item.setLabelCaseSensitive(queryLabel.caseSensitivity); return item; } diff --git a/src/adql/parser/grammar/adqlGrammar201.jj b/src/adql/parser/grammar/adqlGrammar201.jj index 65c07fe376c7b1510998ee5d1785f62765813c22..32426687742314cd92183bb8fd9caff629c066f8 100644 --- a/src/adql/parser/grammar/adqlGrammar201.jj +++ b/src/adql/parser/grammar/adqlGrammar201.jj @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see <http://www.gnu.org/licenses/>. * - * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS) */ /* @@ -31,7 +31,7 @@ * ParseException is thrown. * * Author: Grégory Mantelet (CDS) -* Version: 2.0 (11/2019) +* Version: 2.0 (03/2020) */ /* ########### */ @@ -68,7 +68,7 @@ package adql.parser.grammar; * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see <http://www.gnu.org/licenses/>. * - * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS) + * Copyright 2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS) */ import java.util.Vector; @@ -107,7 +107,7 @@ import adql.query.operand.function.geometry.GeometryFunction.GeometryValue; * @see ADQLParser * * @author Grégory Mantelet (CDS) - * @version 2.0 (11/2019) + * @version 2.0 (03/2020) * @since 2.0 */ public class ADQLGrammar201 extends ADQLGrammarBase { @@ -476,22 +476,20 @@ ADQLQuery SubQueryExpression(): {ADQLQuery q = null; Token start, end;} { } } -ClauseADQL<WithItem> With(): { ClauseADQL<WithItem> withClause = query.getWith(); WithItem withItem; Token start,end; IdentifierItem id, colId; ArrayList<ADQLColumn> colLabels = new ArrayList<ADQLColumn>(10); ADQLQuery query; } { +ClauseADQL<WithItem> With(): { ClauseADQL<WithItem> withClause = query.getWith(); WithItem withItem; Token start,end; IdentifierItem id, colId; ADQLQuery query; } { try { - start=<WITH> id=Identifier() [<LEFT_PAR> colId=Identifier() { colLabels.add(queryFactory.createColumn(colId)); } (<COMMA> colId=Identifier() { colLabels.add(queryFactory.createColumn(colId)); })* <RIGHT_PAR>] <AS> <LEFT_PAR> query=QueryExpression() end=<RIGHT_PAR> + start=<WITH> id=Identifier() <AS> <LEFT_PAR> query=QueryExpression() end=<RIGHT_PAR> { - withItem = queryFactory.createWithItem(id, query, colLabels); + withItem = queryFactory.createWithItem(id, query); withItem.setPosition(new TextPosition(id.position, new TextPosition(end))); withClause.add(withItem); - colLabels.clear(); } ( - <COMMA> id=Identifier() [<LEFT_PAR> colId=Identifier() { colLabels.add(queryFactory.createColumn(colId)); } (<COMMA> colId=Identifier() { colLabels.add(queryFactory.createColumn(colId)); })* <RIGHT_PAR>] <AS> <LEFT_PAR> query=QueryExpression() end=<RIGHT_PAR> + <COMMA> id=Identifier() <AS> <LEFT_PAR> query=QueryExpression() end=<RIGHT_PAR> { - withItem = queryFactory.createWithItem(id, query, colLabels); + withItem = queryFactory.createWithItem(id, query); withItem.setPosition(new TextPosition(id.position, new TextPosition(end))); withClause.add(withItem); - colLabels.clear(); } )* { diff --git a/src/adql/query/ADQLQuery.java b/src/adql/query/ADQLQuery.java index 02e92628f56fd422b66e09c937cb30512301ee96..7c81aaf1e9ac371384a8fe845998fc958e675586 100644 --- a/src/adql/query/ADQLQuery.java +++ b/src/adql/query/ADQLQuery.java @@ -486,7 +486,10 @@ public class ADQLQuery implements ADQLObject { if (operand instanceof ADQLColumn && ((ADQLColumn)operand).getDBLink() != null) { DBColumn formerCol = ((ADQLColumn)operand).getDBLink(); // keep the same ADQL and DB name ; just change the table: - col = formerCol.copy(formerCol.getDBName(), (formerCol.isCaseSensitive() ? DBIdentifier.denormalize(formerCol.getADQLName(), true) : formerCol.getADQLName().toLowerCase()), formerCol.getTable()); + if (formerCol.isCaseSensitive()) + col = formerCol.copy(formerCol.getADQLName(), DBIdentifier.denormalize(formerCol.getADQLName(), true), formerCol.getTable()); + else + col = formerCol.copy(formerCol.getADQLName().toLowerCase(), formerCol.getADQLName().toLowerCase(), formerCol.getTable()); } else col = new DefaultDBColumn((item.isCaseSensitive() ? DBIdentifier.denormalize(item.getName(), true) : item.getName().toLowerCase()), null); } diff --git a/src/adql/query/WithItem.java b/src/adql/query/WithItem.java index 8300bdb37d3f060be599f3cd357b3794211b2fc4..e1e4c621e8087564d101ad4cda9e670bce834f9e 100644 --- a/src/adql/query/WithItem.java +++ b/src/adql/query/WithItem.java @@ -1,34 +1,11 @@ package adql.query; -/* - * 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 <http://www.gnu.org/licenses/>. - * - * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS) - */ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import java.util.NoSuchElementException; import adql.db.DBColumn; import adql.db.DBIdentifier; import adql.db.DBTable; import adql.parser.feature.LanguageFeature; -import adql.query.operand.ADQLColumn; /** * Object representation of the definition of a Common Table Expression (CTE). @@ -54,12 +31,6 @@ public class WithItem implements ADQLObject { /** Flag indicating whether the table name is case sensitive or not. */ protected boolean caseSensitive = false; - /** Labels of the resulting columns. - * <p><i><b>Note:</b> - * If NULL or empty, the default output column names must be used. - * </i></p> */ - protected List<ADQLColumn> columnLabels = null; - /** ADQL query providing the CTE's content. */ protected ADQLQuery query; @@ -70,29 +41,12 @@ public class WithItem implements ADQLObject { protected DBTable dbLink = null; /** - * Create a WITH item with the minimum mandatory information. + * Create a WITH item. * * @param label Name of the resulting table/CTE. * @param query ADQL query returning the content of this CTE. */ public WithItem(final String label, final ADQLQuery query) { - this(label, query, null); - } - - /** - * Create a WITH item with column labels. - * - * <p><i><b>Warning:</b> - * If the given list is NULL or empty, the default output column names will - * be used. However, if not NULL, the given list should contain as many - * elements as columns returned by the given query. - * </i></p> - * - * @param label Name of the resulting table/CTE. - * @param query ADQL query returning the content of this CTE. - * @param columnLabels Labels of the output columns. - */ - public WithItem(final String label, final ADQLQuery query, final Collection<ADQLColumn> columnLabels) { if (label == null || label.trim().isEmpty()) throw new NullPointerException("Missing label of the WITH item!"); @@ -101,7 +55,6 @@ public class WithItem implements ADQLObject { setLabel(label); this.query = query; - this.columnLabels = (columnLabels == null || columnLabels.isEmpty()) ? null : new ArrayList<>(columnLabels); } @@ -114,11 +67,6 @@ public class WithItem implements ADQLObject { label = toCopy.label; query = toCopy.query; position = toCopy.position; - if (columnLabels != null) { - columnLabels = new ArrayList<>(toCopy.columnLabels.size()); - for(ADQLColumn colLabel : toCopy.columnLabels) - columnLabels.add(colLabel); - } } @Override @@ -184,27 +132,6 @@ public class WithItem implements ADQLObject { this.caseSensitive = caseSensitive; } - /** - * Get the specified labels of the output columns of this CTE. - * - * @return CTE's columns labels, - * or NULL if none is specified. - */ - public final List<ADQLColumn> getColumnLabels() { - return columnLabels; - } - - /** - * Specify the tables of all the output columns. - * - * @param newColumnLabels New labels of the CTE's output columns, - * or NULL (or an empty list) to use the default - * column names instead. - */ - public final void setColumnLabels(final Collection<ADQLColumn> newColumnLabels) { - columnLabels = (newColumnLabels == null || newColumnLabels.isEmpty()) ? null : new ArrayList<>(newColumnLabels); - } - /** * Get the query corresponding to this CTE. * @@ -292,62 +219,16 @@ public class WithItem implements ADQLObject { @Override public String toADQL() { - // Serialize the list of output columns: - StringBuffer bufOutColumns = new StringBuffer(); - if (columnLabels != null && !columnLabels.isEmpty()) { - for(ADQLColumn col : columnLabels) { - bufOutColumns.append(bufOutColumns.length() == 0 ? '(' : ','); - bufOutColumns.append(DBIdentifier.denormalize(col.getColumnName(), col.isCaseSensitive(IdentifierField.COLUMN))); - } - bufOutColumns.append(')'); - } - // And now serialize the whole WithItem: - return DBIdentifier.denormalize(label, caseSensitive) + bufOutColumns.toString() + " AS (\n" + query.toADQL() + "\n)"; + return DBIdentifier.denormalize(label, caseSensitive) + " AS (\n" + query.toADQL() + "\n)"; } /** * Get the description of all output columns. * - * <p><i><b>Note 1:</b> - * All resulting columns are returned, even if no column's label is - * provided. - * </i></p> - * - * <p><i><b>Note 2:</b> - * List generated on the fly! - * </i></p> - * * @return List and description of all output columns. */ public DBColumn[] getResultingColumns() { - // Fetch all resulting columns from the query: - DBColumn[] dbColumns = query.getResultingColumns(); - - // Force the writing of the column names: - boolean caseSensitive; - String newColLabel; - for(int i = 0; i < dbColumns.length; i++) { - // fetch the default column name and case sensitivity: - caseSensitive = dbColumns[i].isCaseSensitive(); - newColLabel = dbColumns[i].getADQLName(); - - // if an explicit label is given, use it instead: - if (columnLabels != null && i < columnLabels.size()) { - caseSensitive = columnLabels.get(i).isCaseSensitive(IdentifierField.COLUMN); - newColLabel = columnLabels.get(i).getColumnName(); - } - - // reformat the column label in function of its case sensitivity: - if (caseSensitive) - newColLabel = DBIdentifier.denormalize(newColLabel, true); - else - newColLabel = newColLabel.toLowerCase(); - - // finally, copy the original column with this new name: - dbColumns[i] = dbColumns[i].copy(newColLabel, newColLabel, dbColumns[i].getTable()); - } - - return dbColumns; + return query.getResultingColumns(); } } diff --git a/src/adql/translator/JDBCTranslator.java b/src/adql/translator/JDBCTranslator.java index 5c1dbf3c473b589dcd3ff90f9dce68790c2d71ff..1c38047f86a10c2b0cc370157367dff09897210e 100644 --- a/src/adql/translator/JDBCTranslator.java +++ b/src/adql/translator/JDBCTranslator.java @@ -21,7 +21,6 @@ package adql.translator; */ import java.util.Iterator; -import java.util.List; import adql.db.DBColumn; import adql.db.DBIdentifier; @@ -493,28 +492,6 @@ public abstract class JDBCTranslator implements ADQLTranslator { else appendIdentifier(translation, (item.isLabelCaseSensitive() ? item.getLabel() : item.getLabel().toLowerCase()), true); - // output column labels (if any): - if (item.getDBLink() != null) { - boolean firstDone = false; - for(DBColumn dbCol : item.getDBLink()) { - translation.append(firstDone ? ',' : '('); - appendIdentifier(translation, dbCol.getADQLName(), true); - firstDone = true; - } - translation.append(')'); - } else { - List<ADQLColumn> colLabels = item.getColumnLabels(); - if (colLabels != null && !colLabels.isEmpty()) { - boolean firstDone = false; - for(ADQLColumn col : colLabels) { - translation.append(firstDone ? ',' : '('); - appendIdentifier(translation, (col.isCaseSensitive(IdentifierField.COLUMN) ? col.getColumnName() : col.getColumnName().toLowerCase()), true); - firstDone = true; - } - translation.append(')'); - } - } - // query itself: translation.append(" AS (\n").append(translate(item.getQuery())).append("\n)"); diff --git a/test/adql/db/TestDBChecker.java b/test/adql/db/TestDBChecker.java index 7d5288f7ea214fb26a6bc5c91745ff0e19e81288..012decc255cbb64b9bc10cbe27900d209df7b5f0 100644 --- a/test/adql/db/TestDBChecker.java +++ b/test/adql/db/TestDBChecker.java @@ -89,9 +89,6 @@ public class TestDBChecker { assertNotNull(parser.parseQuery("WITH \"MyFoo\" AS (SELECT * FROM foo) SELECT * FROM \"MyFoo\"")); assertNotNull(parser.parseQuery("WITH \"MyFoo\" AS (SELECT * FROM foo) SELECT * FROM MyFoo")); - // CASE: correct number of column labels - assertNotNull(parser.parseQuery("WITH MyFoo(col1, col2, col3) AS (SELECT * FROM foo) SELECT * FROM MyFoo")); - // CASE: reference between WITH clause in the correct order assertNotNull(parser.parseQuery("WITH MyFoo AS (SELECT * FROM foo), MyOtherFoo AS (SELECT * FROM MyFoo WHERE colS IS NULL) SELECT * FROM MyOtherFoo")); @@ -109,23 +106,6 @@ public class TestDBChecker { assertEquals("1 unresolved identifiers: myfoo [l.1 c.51 - l.1 c.58]!\n - Unknown table \"\"myfoo\"\" !", ex.getMessage()); } - // CASE: less column labels than available columns - try { - parser.parseQuery("WITH MyFoo(col1) AS (SELECT * FROM foo) SELECT * FROM MyFoo"); - fail("WITH item's label is case sensitive....references to this CTE should also be case sensitive."); - } catch(Exception ex) { - assertEquals(UnresolvedIdentifiersException.class, ex.getClass()); - assertEquals("1 unresolved identifiers!\n - The WITH query \"MyFoo\" specifies LESS columns (1) than available (3)!", ex.getMessage()); - } - // CASE: more column labels than available columns - try { - parser.parseQuery("WITH MyFoo(col1, col2, col3, col4) AS (SELECT * FROM foo) SELECT * FROM MyFoo"); - fail("WITH item's label is case sensitive....references to this CTE should also be case sensitive."); - } catch(Exception ex) { - assertEquals(UnresolvedIdentifiersException.class, ex.getClass()); - assertEquals("1 unresolved identifiers!\n - The WITH query \"MyFoo\" specifies MORE columns (4) than available (3)!", ex.getMessage()); - } - } @Test diff --git a/test/adql/db/TestIdentifierCaseSensitivity.java b/test/adql/db/TestIdentifierCaseSensitivity.java index dc7a0b77142b5638259b807e53c2b6ec0ced7e24..d93ee4c23ac10fad0e809f97dbf255bf1bf40c3c 100644 --- a/test/adql/db/TestIdentifierCaseSensitivity.java +++ b/test/adql/db/TestIdentifierCaseSensitivity.java @@ -378,8 +378,8 @@ public class TestIdentifierCaseSensitivity { try { ADQLQuery query = parser.parseQuery("WITH t1 AS (SELECT * FROM table1) SELECT * FROM t1"); assertEquals("WITH t1 AS (\nSELECT *\nFROM table1\n)\nSELECT *\nFROM t1", query.toADQL()); - assertEquals("WITH \"t1\"(\"col1\") AS (\nSELECT \"dbTable1\".\"col1\" AS \"col1\"\nFROM \"dbTable1\"\n)\nSELECT \"t1\".\"col1\" AS \"col1\"\nFROM \"t1\"", trCS.translate(query)); - assertEquals("WITH \"t1\"(\"col1\") AS (\nSELECT dbTable1.col1 AS \"col1\"\nFROM dbTable1\n)\nSELECT t1.col1 AS \"col1\"\nFROM t1", trCI.translate(query)); + assertEquals("WITH \"t1\" AS (\nSELECT \"dbTable1\".\"col1\" AS \"col1\"\nFROM \"dbTable1\"\n)\nSELECT \"t1\".\"col1\" AS \"col1\"\nFROM \"t1\"", trCS.translate(query)); + assertEquals("WITH \"t1\" AS (\nSELECT dbTable1.col1 AS \"col1\"\nFROM dbTable1\n)\nSELECT t1.col1 AS \"col1\"\nFROM t1", trCI.translate(query)); } catch(Exception ex) { ex.printStackTrace(); fail("Unexpected exception! (see console for more details)"); @@ -389,8 +389,8 @@ public class TestIdentifierCaseSensitivity { try { ADQLQuery query = parser.parseQuery("WITH T1 AS (SELECT * FROM table1) SELECT * FROM t1"); assertEquals("WITH T1 AS (\nSELECT *\nFROM table1\n)\nSELECT *\nFROM t1", query.toADQL()); - assertEquals("WITH \"t1\"(\"col1\") AS (\nSELECT \"dbTable1\".\"col1\" AS \"col1\"\nFROM \"dbTable1\"\n)\nSELECT \"t1\".\"col1\" AS \"col1\"\nFROM \"t1\"", trCS.translate(query)); - assertEquals("WITH \"t1\"(\"col1\") AS (\nSELECT dbTable1.col1 AS \"col1\"\nFROM dbTable1\n)\nSELECT t1.col1 AS \"col1\"\nFROM t1", trCI.translate(query)); + assertEquals("WITH \"t1\" AS (\nSELECT \"dbTable1\".\"col1\" AS \"col1\"\nFROM \"dbTable1\"\n)\nSELECT \"t1\".\"col1\" AS \"col1\"\nFROM \"t1\"", trCS.translate(query)); + assertEquals("WITH \"t1\" AS (\nSELECT dbTable1.col1 AS \"col1\"\nFROM dbTable1\n)\nSELECT t1.col1 AS \"col1\"\nFROM t1", trCI.translate(query)); } catch(Exception ex) { ex.printStackTrace(); fail("Unexpected exception! (see console for more details)"); @@ -400,8 +400,8 @@ public class TestIdentifierCaseSensitivity { try { ADQLQuery query = parser.parseQuery("WITH \"T1\" AS (SELECT * FROM table1) SELECT * FROM t1"); assertEquals("WITH \"T1\" AS (\nSELECT *\nFROM table1\n)\nSELECT *\nFROM t1", query.toADQL()); - assertEquals("WITH \"T1\"(\"col1\") AS (\nSELECT \"dbTable1\".\"col1\" AS \"col1\"\nFROM \"dbTable1\"\n)\nSELECT \"T1\".\"col1\" AS \"col1\"\nFROM \"T1\"", trCS.translate(query)); - assertEquals("WITH \"T1\"(\"col1\") AS (\nSELECT dbTable1.col1 AS \"col1\"\nFROM dbTable1\n)\nSELECT T1.col1 AS \"col1\"\nFROM T1", trCI.translate(query)); + assertEquals("WITH \"T1\" AS (\nSELECT \"dbTable1\".\"col1\" AS \"col1\"\nFROM \"dbTable1\"\n)\nSELECT \"T1\".\"col1\" AS \"col1\"\nFROM \"T1\"", trCS.translate(query)); + assertEquals("WITH \"T1\" AS (\nSELECT dbTable1.col1 AS \"col1\"\nFROM dbTable1\n)\nSELECT T1.col1 AS \"col1\"\nFROM T1", trCI.translate(query)); } catch(Exception ex) { ex.printStackTrace(); fail("Unexpected exception! (see console for more details)"); @@ -438,8 +438,8 @@ public class TestIdentifierCaseSensitivity { try { ADQLQuery query = parser.parseQuery("SELECT * FROM (SELECT col1, col2, col1 AS Col3, col2 AS \"COL4\" FROM table1) AS table2"); assertEquals("SELECT *\nFROM (SELECT col1 , col2 , col1 AS Col3 , col2 AS \"COL4\"\nFROM table1) AS table2", query.toADQL()); - assertEquals("SELECT \"table2\".\"Col1\" AS \"col1\" , \"table2\".\"Col2\" AS \"Col2\" , \"table2\".\"col3\" AS \"col3\" , \"table2\".\"COL4\" AS \"COL4\"\nFROM (SELECT \"dbTable1\".\"Col1\" AS \"col1\" , \"dbTable1\".\"Col2\" AS \"Col2\" , \"dbTable1\".\"Col1\" AS \"col3\" , \"dbTable1\".\"Col2\" AS \"COL4\"\nFROM \"dbTable1\") AS \"table2\"", trCS.translate(query)); - assertEquals("SELECT table2.Col1 AS \"col1\" , table2.Col2 AS \"Col2\" , table2.col3 AS \"col3\" , table2.COL4 AS \"COL4\"\nFROM (SELECT dbTable1.Col1 AS \"col1\" , dbTable1.Col2 AS \"Col2\" , dbTable1.Col1 AS \"col3\" , dbTable1.Col2 AS \"COL4\"\nFROM dbTable1) AS \"table2\"", trCI.translate(query)); + assertEquals("SELECT \"table2\".\"col1\" AS \"col1\" , \"table2\".\"Col2\" AS \"Col2\" , \"table2\".\"col3\" AS \"col3\" , \"table2\".\"COL4\" AS \"COL4\"\nFROM (SELECT \"dbTable1\".\"Col1\" AS \"col1\" , \"dbTable1\".\"Col2\" AS \"Col2\" , \"dbTable1\".\"Col1\" AS \"col3\" , \"dbTable1\".\"Col2\" AS \"COL4\"\nFROM \"dbTable1\") AS \"table2\"", trCS.translate(query)); + assertEquals("SELECT table2.col1 AS \"col1\" , table2.Col2 AS \"Col2\" , table2.col3 AS \"col3\" , table2.COL4 AS \"COL4\"\nFROM (SELECT dbTable1.Col1 AS \"col1\" , dbTable1.Col2 AS \"Col2\" , dbTable1.Col1 AS \"col3\" , dbTable1.Col2 AS \"COL4\"\nFROM dbTable1) AS \"table2\"", trCI.translate(query)); } catch(Exception ex) { ex.printStackTrace(); fail("Unexpected exception! (see console for more details)"); @@ -450,8 +450,8 @@ public class TestIdentifierCaseSensitivity { try { ADQLQuery query = parser.parseQuery("WITH table3 AS (SELECT COL1, col2, col1 AS \"SuperCol\" FROM table1) SELECT * FROM table3"); assertEquals("WITH table3 AS (\nSELECT COL1 , col2 , col1 AS \"SuperCol\"\nFROM table1\n)\nSELECT *\nFROM table3", query.toADQL()); - assertEquals("WITH \"table3\"(\"col1\",\"Col2\",\"SuperCol\") AS (\nSELECT \"dbTable1\".\"Col1\" AS \"col1\" , \"dbTable1\".\"Col2\" AS \"Col2\" , \"dbTable1\".\"Col1\" AS \"SuperCol\"\nFROM \"dbTable1\"\n)\nSELECT \"table3\".\"col1\" AS \"col1\" , \"table3\".\"Col2\" AS \"Col2\" , \"table3\".\"SuperCol\" AS \"SuperCol\"\nFROM \"table3\"", trCS.translate(query)); - assertEquals("WITH \"table3\"(\"col1\",\"Col2\",\"SuperCol\") AS (\nSELECT dbTable1.Col1 AS \"col1\" , dbTable1.Col2 AS \"Col2\" , dbTable1.Col1 AS \"SuperCol\"\nFROM dbTable1\n)\nSELECT table3.col1 AS \"col1\" , table3.Col2 AS \"Col2\" , table3.SuperCol AS \"SuperCol\"\nFROM table3", trCI.translate(query)); + assertEquals("WITH \"table3\" AS (\nSELECT \"dbTable1\".\"Col1\" AS \"col1\" , \"dbTable1\".\"Col2\" AS \"Col2\" , \"dbTable1\".\"Col1\" AS \"SuperCol\"\nFROM \"dbTable1\"\n)\nSELECT \"table3\".\"col1\" AS \"col1\" , \"table3\".\"Col2\" AS \"Col2\" , \"table3\".\"SuperCol\" AS \"SuperCol\"\nFROM \"table3\"", trCS.translate(query)); + assertEquals("WITH \"table3\" AS (\nSELECT dbTable1.Col1 AS \"col1\" , dbTable1.Col2 AS \"Col2\" , dbTable1.Col1 AS \"SuperCol\"\nFROM dbTable1\n)\nSELECT table3.col1 AS \"col1\" , table3.Col2 AS \"Col2\" , table3.SuperCol AS \"SuperCol\"\nFROM table3", trCI.translate(query)); } catch(Exception ex) { ex.printStackTrace(); fail("Unexpected exception! (see console for more details)"); diff --git a/test/adql/parser/TestADQLParser.java b/test/adql/parser/TestADQLParser.java index 68ead6866e1f5f787b4fa806f802b3ecbd80bbe3..2a449963c626b14649029aaf1ae497ea4daa5d58 100644 --- a/test/adql/parser/TestADQLParser.java +++ b/test/adql/parser/TestADQLParser.java @@ -3,7 +3,6 @@ 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; @@ -77,52 +76,43 @@ public class TestADQLParser { WithItem item = query.getWith().get(0); assertEquals("foo", item.getLabel()); assertFalse(item.isLabelCaseSensitive()); - assertNull(item.getColumnLabels()); assertEquals("SELECT *\nFROM bar", item.getQuery().toADQL()); - // CASE: WITH clause with column labels => OK - query = parser.parseQuery("WITH foo(id, ra, dec) AS (SELECT col1, col2, col3 FROM bar) SELECT * FROM foo"); + // CASE: WITH clause with a column set => OK + query = parser.parseQuery("WITH foo AS (SELECT col1, col2, col3 FROM bar) SELECT * FROM foo"); assertNotNull(query.getWith()); assertEquals(1, query.getWith().size()); item = query.getWith().get(0); assertEquals("foo", item.getLabel()); assertFalse(item.isLabelCaseSensitive()); - assertNotNull(item.getColumnLabels()); - assertEquals(3, item.getColumnLabels().size()); assertEquals("SELECT col1 , col2 , col3\nFROM bar", item.getQuery().toADQL()); // CASE: more than 1 WITH clause + CTE's label case sensitivity - query = parser.parseQuery("WITH foo(id, ra, dec) AS (SELECT col1, col2, col3 FROM bar), \"Foo2\" AS (SELECT * FROM bar2) SELECT * FROM foo NATURAL JOIN \"Foo2\""); + query = parser.parseQuery("WITH foo AS (SELECT col1, col2, col3 FROM bar), \"Foo2\" AS (SELECT * FROM bar2) SELECT * FROM foo NATURAL JOIN \"Foo2\""); assertNotNull(query.getWith()); assertEquals(2, query.getWith().size()); item = query.getWith().get(0); assertEquals("foo", item.getLabel()); assertFalse(item.isLabelCaseSensitive()); - assertNotNull(item.getColumnLabels()); - assertEquals(3, item.getColumnLabels().size()); assertEquals("SELECT col1 , col2 , col3\nFROM bar", item.getQuery().toADQL()); item = query.getWith().get(1); assertEquals("Foo2", item.getLabel()); assertTrue(item.isLabelCaseSensitive()); - assertNull(item.getColumnLabels()); assertEquals("SELECT *\nFROM bar2", item.getQuery().toADQL()); // CASE: WITH clause inside a WITH clause => OK - query = parser.parseQuery("WITH foo(id, ra, dec) AS (WITH innerFoo AS (SELECT col1, col2, col3 FROM bar) SELECT * FROM stars NATURAL JOIN innerFoo) SELECT * FROM foo"); + query = parser.parseQuery("WITH foo AS (WITH innerFoo AS (SELECT col1, col2, col3 FROM bar) SELECT * FROM stars NATURAL JOIN innerFoo) SELECT * FROM foo"); assertNotNull(query.getWith()); assertEquals(1, query.getWith().size()); item = query.getWith().get(0); assertEquals("foo", item.getLabel()); assertFalse(item.isLabelCaseSensitive()); - assertNotNull(item.getColumnLabels()); - assertEquals(3, item.getColumnLabels().size()); assertEquals("WITH innerFoo AS (\nSELECT col1 , col2 , col3\nFROM bar\n)\nSELECT *\nFROM stars NATURAL INNER JOIN innerFoo", item.getQuery().toADQL()); assertNotNull(query.getWith().get(0).getQuery().getWith()); assertEquals(1, query.getWith().get(0).getQuery().getWith().size()); item = query.getWith().get(0).getQuery().getWith().get(0); assertEquals("innerFoo", item.getLabel()); assertFalse(item.isLabelCaseSensitive()); - assertNull(item.getColumnLabels()); assertEquals("SELECT col1 , col2 , col3\nFROM bar", item.getQuery().toADQL()); } catch(Exception ex) { diff --git a/test/adql/query/TestWithItem.java b/test/adql/query/TestWithItem.java index 57ca9ed00969c77313e9806cf2585320be126fb8..11d7da03b015e15c6fd84371270ed6608947c062 100644 --- a/test/adql/query/TestWithItem.java +++ b/test/adql/query/TestWithItem.java @@ -3,19 +3,15 @@ package adql.query; 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 org.junit.Test; import adql.db.DBColumn; import adql.parser.ADQLParser; import adql.parser.ADQLParser.ADQLVersion; import adql.parser.grammar.ParseException; -import adql.query.operand.ADQLColumn; public class TestWithItem { @@ -48,53 +44,12 @@ public class TestWithItem { assertEquals(WITH_LABEL, item.getLabel()); assertFalse(item.isLabelCaseSensitive()); assertNotNull(item.getQuery()); - assertNull(item.getColumnLabels()); // CASE: label + query => OK! item = new WithItem("\"" + WITH_LABEL + "\"", new ADQLQuery()); assertEquals(WITH_LABEL, item.getLabel()); assertTrue(item.isLabelCaseSensitive()); assertNotNull(item.getQuery()); - assertNull(item.getColumnLabels()); - } - - @Test - public void testWithItemStringADQLQueryCollectionOfIdentifierItem() { - - // CASE: No label => ERROR! - String[] toTest = new String[]{ null, "", " " }; - for(String label : toTest) { - try { - new WithItem(label, null, null); - fail("It should be impossible to create a WithItem without a label!"); - } catch(Exception ex) { - assertEquals(NullPointerException.class, ex.getClass()); - assertEquals("Missing label of the WITH item!", ex.getMessage()); - } - } - - // CASE: No query => ERROR! - try { - new WithItem("query", null, null); - fail("It should be impossible to create a WithItem without a query!"); - } catch(Exception ex) { - assertEquals(NullPointerException.class, ex.getClass()); - assertEquals("Missing query of the WITH item!", ex.getMessage()); - } - - // CASE: label + query but no col. label => OK! - final String WITH_LABEL = "aNamedQuery"; - WithItem item = new WithItem(WITH_LABEL, new ADQLQuery(), null); - assertEquals(WITH_LABEL, item.getLabel()); - assertNotNull(item.getQuery()); - assertNull(item.getColumnLabels()); - - // CASE: label + query + col. labels => OK! - item = new WithItem(WITH_LABEL, new ADQLQuery(), Arrays.asList(new ADQLColumn[]{ new ADQLColumn("aColumn") })); - assertEquals(WITH_LABEL, item.getLabel()); - assertNotNull(item.getQuery()); - assertNotNull(item.getColumnLabels()); - assertEquals(1, item.getColumnLabels().size()); } @Test @@ -102,17 +57,13 @@ public class TestWithItem { try { ADQLParser parser = new ADQLParser(ADQLVersion.V2_1); - // CASE: NO column labels - WithItem item = new WithItem("myQuery", parser.parseQuery("SELECT foo FROM bar")); - assertEquals("myQuery AS (\n" + "SELECT foo\n" + "FROM bar\n" + ")", item.toADQL()); - // CASE: WITH column labels - item = new WithItem("myQuery", parser.parseQuery("SELECT foo, stuff FROM bar"), Arrays.asList(new ADQLColumn[]{ new ADQLColumn("aColumn"), new ADQLColumn("\"Another\"Column\"") })); - assertEquals("myQuery(aColumn,\"Another\"\"Column\") AS (\n" + "SELECT foo , stuff\n" + "FROM bar\n" + ")", item.toADQL()); + WithItem item = new WithItem("myQuery", parser.parseQuery("SELECT foo, stuff FROM bar")); + assertEquals("myQuery AS (\n" + "SELECT foo , stuff\n" + "FROM bar\n" + ")", item.toADQL()); // CASE: after an integral parsing - ADQLQuery query = parser.parseQuery("WITH myQuery(aColumn, \"Another\"\"Column\") AS (SELECT foo, stuff FROM bar) SELECT * FROM myQuery"); - assertEquals("WITH myQuery(aColumn,\"Another\"\"Column\") AS (\n" + "SELECT foo , stuff\n" + "FROM bar\n" + ")\nSELECT *\nFROM myQuery", query.toADQL()); + ADQLQuery query = parser.parseQuery("WITH myQuery AS (SELECT foo, stuff FROM bar) SELECT * FROM myQuery"); + assertEquals("WITH myQuery AS (\n" + "SELECT foo , stuff\n" + "FROM bar\n" + ")\nSELECT *\nFROM myQuery", query.toADQL()); } catch(ParseException ex) { ex.printStackTrace(); fail("Unexpected parsing error!"); @@ -123,8 +74,6 @@ public class TestWithItem { public void testGetResultingColumns() { try { ADQLParser parser = new ADQLParser(ADQLVersion.V2_1); - - // CASE: NO column labels WithItem item = new WithItem("myQuery", parser.parseQuery("SELECT foo FROM bar")); DBColumn[] lstCol = item.getResultingColumns(); assertNotNull(lstCol); @@ -132,19 +81,6 @@ public class TestWithItem { assertEquals("foo", lstCol[0].getADQLName()); assertEquals(lstCol[0].getADQLName(), lstCol[0].getDBName()); assertFalse(lstCol[0].isCaseSensitive()); - - // CASE: WITH column labels - item = new WithItem("myQuery", parser.parseQuery("SELECT foo, stuff FROM bar"), Arrays.asList(new ADQLColumn[]{ new ADQLColumn("aColumn"), new ADQLColumn("\"Another\"Column\"") })); - assertEquals("myQuery(aColumn,\"Another\"\"Column\") AS (\n" + "SELECT foo , stuff\n" + "FROM bar\n" + ")", item.toADQL()); - lstCol = item.getResultingColumns(); - assertNotNull(lstCol); - assertEquals(2, lstCol.length); - assertEquals("acolumn", lstCol[0].getADQLName()); - assertEquals(lstCol[0].getADQLName(), lstCol[0].getDBName()); - assertFalse(lstCol[0].isCaseSensitive()); - assertEquals("Another\"Column", lstCol[1].getADQLName()); - assertEquals(lstCol[1].getADQLName(), lstCol[1].getDBName()); - assertTrue(lstCol[1].isCaseSensitive()); } catch(ParseException ex) { ex.printStackTrace(); fail("Unexpected parsing error!"); diff --git a/test/adql/translator/TestJDBCTranslator.java b/test/adql/translator/TestJDBCTranslator.java index 83524a2ccee3916970d701927c214a4cf0b2070e..08504ee5dc8fa9b57e432924f68360e192efd940 100644 --- a/test/adql/translator/TestJDBCTranslator.java +++ b/test/adql/translator/TestJDBCTranslator.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; -import java.util.Arrays; import org.junit.Before; import org.junit.Test; @@ -27,7 +26,6 @@ import adql.query.ADQLQuery; import adql.query.ClauseADQL; import adql.query.IdentifierField; import adql.query.WithItem; -import adql.query.operand.ADQLColumn; import adql.query.operand.ADQLOperand; import adql.query.operand.NumericConstant; import adql.query.operand.StringConstant; @@ -73,11 +71,11 @@ public class TestJDBCTranslator { assertEquals("WITH \"foo\" AS (\nSELECT *\nFROM bar\n)\nSELECT *\nFROM foo", tr.translate(query)); // CASE: Several WITH items - query = parser.parseQuery("WITH foo AS (SELECT * FROM bar), Foo2(myCol) AS (SELECT aCol FROM myTable) SELECT * FROM foo JOIN foo2 ON foo.id = foo2.myCol"); + query = parser.parseQuery("WITH foo AS (SELECT * FROM bar), Foo2 AS (SELECT myCol FROM myTable) SELECT * FROM foo JOIN foo2 ON foo.id = foo2.myCol"); withClause = query.getWith(); assertEquals(2, withClause.size()); - assertEquals("WITH \"foo\" AS (\nSELECT *\nFROM bar\n) , \"foo2\"(\"mycol\") AS (\nSELECT aCol AS \"aCol\"\nFROM myTable\n)", tr.translate(withClause)); - assertEquals("WITH \"foo\" AS (\nSELECT *\nFROM bar\n) , \"foo2\"(\"mycol\") AS (\nSELECT aCol AS \"aCol\"\nFROM myTable\n)\nSELECT *\nFROM foo INNER JOIN foo2 ON foo.id = foo2.myCol", tr.translate(query)); + assertEquals("WITH \"foo\" AS (\nSELECT *\nFROM bar\n) , \"foo2\" AS (\nSELECT myCol AS \"myCol\"\nFROM myTable\n)", tr.translate(withClause)); + assertEquals("WITH \"foo\" AS (\nSELECT *\nFROM bar\n) , \"foo2\" AS (\nSELECT myCol AS \"myCol\"\nFROM myTable\n)\nSELECT *\nFROM foo INNER JOIN foo2 ON foo.id = foo2.myCol", tr.translate(query)); } catch(ParseException pe) { pe.printStackTrace(); @@ -93,19 +91,19 @@ public class TestJDBCTranslator { JDBCTranslator tr = new AJDBCTranslator(); try { - // CASE: Simple WITH item (no case sensitivity, no column labels) + // CASE: Simple WITH item (no case sensitivity) WithItem item = new WithItem("Foo", (new ADQLParser(ADQLVersion.V2_1)).parseQuery("SELECT * FROM bar")); item.setLabelCaseSensitive(false); assertEquals("\"foo\" AS (\nSELECT *\nFROM bar\n)", tr.translate(item)); - // CASE: WITH item with case sensitivity and column labels - item = new WithItem("Foo", (new ADQLParser(ADQLVersion.V2_1)).parseQuery("SELECT col1, col2 FROM bar"), Arrays.asList(new ADQLColumn[]{ new ADQLColumn("FirstColumn"), new ADQLColumn("\"SecondColumn\"") })); + // CASE: WITH item with case sensitivity + item = new WithItem("Foo", (new ADQLParser(ADQLVersion.V2_1)).parseQuery("SELECT col1, col2 FROM bar")); item.setLabelCaseSensitive(true); - assertEquals("\"Foo\"(\"firstcolumn\",\"SecondColumn\") AS (\nSELECT col1 AS \"col1\" , col2 AS \"col2\"\nFROM bar\n)", tr.translate(item)); + assertEquals("\"Foo\" AS (\nSELECT col1 AS \"col1\" , col2 AS \"col2\"\nFROM bar\n)", tr.translate(item)); // CASE: query with an inner WITH - item = new WithItem("Foo", (new ADQLParser(ADQLVersion.V2_1)).parseQuery("WITH bar(col1, col2) AS (SELECT aCol, anotherCol FROM stuff) SELECT * FROM bar")); - assertEquals("\"foo\" AS (\nWITH \"bar\"(\"col1\",\"col2\") AS (\nSELECT aCol AS \"aCol\" , anotherCol AS \"anotherCol\"\nFROM stuff\n)\nSELECT *\nFROM bar\n)", tr.translate(item)); + item = new WithItem("Foo", (new ADQLParser(ADQLVersion.V2_1)).parseQuery("WITH bar AS (SELECT aCol, anotherCol FROM stuff) SELECT * FROM bar")); + assertEquals("\"foo\" AS (\nWITH \"bar\" AS (\nSELECT aCol AS \"aCol\" , anotherCol AS \"anotherCol\"\nFROM stuff\n)\nSELECT *\nFROM bar\n)", tr.translate(item)); } catch(ParseException pe) { pe.printStackTrace();