/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.metamodel; import java.nio.channels.UnsupportedAddressTypeException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.table.TableModel; import org.apache.metamodel.data.DataSet; import org.apache.metamodel.data.DataSetHeader; import org.apache.metamodel.data.DataSetTableModel; import org.apache.metamodel.data.DefaultRow; import org.apache.metamodel.data.EmptyDataSet; import org.apache.metamodel.data.InMemoryDataSet; import org.apache.metamodel.data.Row; import org.apache.metamodel.data.SimpleDataSetHeader; import org.apache.metamodel.query.CompiledQuery; import org.apache.metamodel.query.FilterItem; import org.apache.metamodel.query.FromItem; import org.apache.metamodel.query.FunctionType; import org.apache.metamodel.query.GroupByItem; import org.apache.metamodel.query.JoinType; import org.apache.metamodel.query.OperatorType; import org.apache.metamodel.query.OrderByItem; import org.apache.metamodel.query.OrderByItem.Direction; import org.apache.metamodel.query.Query; import org.apache.metamodel.query.QueryParameter; import org.apache.metamodel.query.SelectItem; import org.apache.metamodel.schema.Column; import org.apache.metamodel.schema.MutableColumn; import org.apache.metamodel.schema.MutableSchema; import org.apache.metamodel.schema.MutableTable; import org.apache.metamodel.schema.Relationship; import org.apache.metamodel.schema.Schema; import org.apache.metamodel.schema.Table; public class QueryPostprocessDataContextTest extends MetaModelTestCase { private final Schema schema = getExampleSchema(); private final Table table1 = schema.getTableByName(TABLE_CONTRIBUTOR); private final Table table2 = schema.getTableByName(TABLE_ROLE); public void testQueryMaxRows0() throws Exception { final MockDataContext dc = new MockDataContext("sch", "tab", "1"); final Table table = dc.getDefaultSchema().getTables()[0]; final DataSet dataSet = dc.query().from(table).selectAll().limit(0).execute(); assertTrue(dataSet instanceof EmptyDataSet); assertFalse(dataSet.next()); dataSet.close(); } // see issue METAMODEL-100 public void testSelectFromColumnsWithSameName() throws Exception { final MutableTable table = new MutableTable("table"); table.addColumn(new MutableColumn("foo", table).setColumnNumber(0)); table.addColumn(new MutableColumn("foo", table).setColumnNumber(1)); table.addColumn(new MutableColumn("bar", table).setColumnNumber(2)); final QueryPostprocessDataContext dc = new QueryPostprocessDataContext() { @Override protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) { Object[] values = new Object[columns.length]; for (int i = 0; i < columns.length; i++) { values[i] = columns[i].getColumnNumber(); } DataSetHeader header = new SimpleDataSetHeader(columns); DefaultRow row = new DefaultRow(header, values); return new InMemoryDataSet(row); } @Override protected String getMainSchemaName() throws MetaModelException { return "sch"; } @Override protected Schema getMainSchema() throws MetaModelException { MutableSchema schema = new MutableSchema(getMainSchemaName()); schema.addTable(table); table.setSchema(schema); return schema; } }; DataSet ds = dc.query().from(table).selectAll().execute(); assertTrue(ds.next()); assertEquals("Row[values=[0, 1, 2]]", ds.getRow().toString()); assertFalse(ds.next()); ds.close(); } public void testAggregateQueryNoWhereClause() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table table = dc.getDefaultSchema().getTables()[0]; assertSingleRowResult("Row[values=[4]]", dc.query().from(table).selectCount().execute()); } public void testAggregateQueryRegularWhereClause() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table table = dc.getDefaultSchema().getTables()[0]; assertSingleRowResult("Row[values=[3]]", dc.query().from(table).selectCount().where("baz").eq("world") .execute()); } public void testApplyFunctionToNullValues() throws Exception { QueryPostprocessDataContext dataContext = new QueryPostprocessDataContext() { @Override public DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) { if (table == table1) { Column[] columns1 = table1.getColumns(); SelectItem[] selectItems = new SelectItem[columns1.length]; for (int i = 0; i < selectItems.length; i++) { SelectItem selectItem = new SelectItem(columns1[i]); selectItems[i] = selectItem; } List<Object[]> data = new ArrayList<Object[]>(); data.add(new Object[] { 1, "no nulls", 1 }); data.add(new Object[] { 2, "onlynull", null }); data.add(new Object[] { 3, "mixed", null }); data.add(new Object[] { 4, "mixed", "" }); data.add(new Object[] { 5, "mixed", 2 }); data.add(new Object[] { 6, "mixed", " \n \t " }); if (maxRows != -1) { for (int i = data.size() - 1; i >= maxRows; i--) { data.remove(i); } } return createDataSet(selectItems, data); } throw new IllegalArgumentException("This test only accepts table1 and table2"); } @Override protected String getMainSchemaName() throws MetaModelException { return schema.getName(); } @Override protected Schema getMainSchema() throws MetaModelException { return schema; } }; DataSet dataSet = dataContext.query().from(TABLE_CONTRIBUTOR) .select(FunctionType.SUM, COLUMN_CONTRIBUTOR_COUNTRY).select(COLUMN_CONTRIBUTOR_NAME) .groupBy(COLUMN_CONTRIBUTOR_NAME).orderBy(COLUMN_CONTRIBUTOR_NAME).execute(); assertTrue(dataSet.next()); assertEquals("Row[values=[2.0, mixed]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[1.0, no nulls]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[0.0, onlynull]]", dataSet.getRow().toString()); assertFalse(dataSet.next()); dataSet.close(); } public void testGroupByNulls() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", null); Table table = dc.getDefaultSchema().getTables()[0]; DataSet dataSet = dc.query().from(table).select(FunctionType.SUM, "foo").select("baz").groupBy("baz").execute(); assertTrue(dataSet.next()); assertEquals("Row[values=[7.0, world]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[3.0, null]]", dataSet.getRow().toString()); assertFalse(dataSet.next()); dataSet.close(); } public void testNewAggregateFunctions() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", null); Table table = dc.getDefaultSchema().getTables()[0]; DataSet dataSet = dc.query().from(table).select(FunctionType.FIRST, "foo").select(FunctionType.LAST, "foo") .select(FunctionType.RANDOM, "foo").execute(); assertTrue(dataSet.next()); final Row row = dataSet.getRow(); assertEquals("1", row.getValue(0)); assertEquals("4", row.getValue(1)); final Object randomValue = row.getValue(2); assertTrue(Arrays.asList("1", "2", "3", "4").contains(randomValue)); assertFalse(dataSet.next()); dataSet.close(); } public void testAggregateQueryWhereClauseExcludingAll() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); assertSingleRowResult("Row[values=[0]]", dc.query().from("tab").selectCount().where("baz").eq("non_existing_value").execute()); } public void testMixedAggregateAndRawQueryOnEmptyTable() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table emptyTable = dc.getTableByQualifiedLabel("an_empty_table"); assertSingleRowResult("Row[values=[0, null]]", dc.query().from(emptyTable).selectCount().and("foo").execute()); } private void assertSingleRowResult(String rowStr, DataSet ds) { assertTrue("DataSet had no rows", ds.next()); Row row = ds.getRow(); assertEquals(rowStr, row.toString()); assertFalse("DataSet had more than a single row!", ds.next()); ds.close(); } public void testMixedAggregateAndRawQuery() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table table = dc.getDefaultSchema().getTables()[0]; Column[] columns = table.getColumns(); Query query = dc.query().from(table).select(FunctionType.MAX, columns[0]).and(columns[1]).toQuery(); assertEquals("SELECT MAX(tab.foo), tab.bar FROM sch.tab", query.toSql()); DataSet ds = dc.executeQuery(query); assertTrue(ds.next()); assertEquals("Row[values=[4, hello]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[4, 1]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[4, hi]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[4, yo]]", ds.getRow().toString()); assertFalse(ds.next()); } public void testScalarFunctionSelect() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table table = dc.getDefaultSchema().getTables()[0]; Query query = dc.query().from(table).select("foo").select(FunctionType.TO_NUMBER, "foo").select("bar") .select(FunctionType.TO_STRING, "bar").select(FunctionType.TO_NUMBER, "bar").toQuery(); assertEquals( "SELECT tab.foo, TO_NUMBER(tab.foo), tab.bar, TO_STRING(tab.bar), TO_NUMBER(tab.bar) FROM sch.tab", query.toSql()); DataSet ds = dc.executeQuery(query); assertTrue(ds.next()); Row row; row = ds.getRow(); assertEquals("Row[values=[1, 1, hello, hello, null]]", row.toString()); Object value1 = row.getValue(1); assertEquals(Integer.class, value1.getClass()); assertTrue(ds.next()); row = ds.getRow(); assertEquals("Row[values=[2, 2, 1, 1, 1]]", row.toString()); Object value2 = row.getValue(1); assertEquals(Integer.class, value2.getClass()); Object value3 = row.getValue(4); assertEquals(Integer.class, value3.getClass()); assertTrue(ds.next()); ds.close(); } public void testScalarFunctionWhere() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table table = dc.getDefaultSchema().getTables()[0]; Query query = dc.query().from(table).select("foo").where(FunctionType.TO_NUMBER, "bar").eq(1).toQuery(); assertEquals("SELECT tab.foo FROM sch.tab WHERE TO_NUMBER(tab.bar) = 1", query.toSql()); DataSet ds = dc.executeQuery(query); assertTrue(ds.next()); Row row; row = ds.getRow(); assertEquals("Row[values=[2]]", row.toString()); assertFalse(ds.next()); ds.close(); } public void testSelectItemReferencesToFromItems() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "1"); Table table = dc.getDefaultSchema().getTables()[0]; Query q = new Query(); FromItem fromItem1 = q.from(table, "t1").getFromClause().getItem(0); FromItem fromItem2 = q.from(table, "t2").getFromClause().getItem(1); q.select(table.getColumnByName("foo"), fromItem1); q.select(table.getColumnByName("foo"), fromItem2); q.where(q.getSelectClause().getItem(0), OperatorType.EQUALS_TO, "2"); assertEquals("SELECT t1.foo, t2.foo FROM sch.tab t1, sch.tab t2 WHERE t1.foo = '2'", q.toSql()); DataSet ds = dc.executeQuery(q); SelectItem[] selectItems = ds.getSelectItems(); assertEquals(2, selectItems.length); assertEquals("t1.foo", selectItems[0].toSql()); assertEquals("t2.foo", selectItems[1].toSql()); assertTrue(ds.next()); assertEquals("Row[values=[2, 1]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[2, 2]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[2, 3]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[2, 4]]", ds.getRow().toString()); assertFalse(ds.next()); ds.close(); } private DataContext getDataContext() { QueryPostprocessDataContext dataContext = new QueryPostprocessDataContext() { @Override public DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) { if (table == table1) { Column[] columns1 = table1.getColumns(); SelectItem[] selectItems = new SelectItem[columns1.length]; for (int i = 0; i < selectItems.length; i++) { SelectItem selectItem = new SelectItem(columns1[i]); selectItems[i] = selectItem; } List<Object[]> data = new ArrayList<Object[]>(); data.add(new Object[] { 1, "kasper", "denmark" }); data.add(new Object[] { 2, "asbjorn", "denmark" }); data.add(new Object[] { 3, "johny", "israel" }); data.add(new Object[] { 4, "daniel", "canada" }); data.add(new Object[] { 5, "sasidhar", "unknown" }); data.add(new Object[] { 6, "jesper", "denmark" }); if (maxRows != -1) { for (int i = data.size() - 1; i >= maxRows; i--) { data.remove(i); } } return createDataSet(selectItems, data); } else if (table == table2) { Column[] columns2 = table2.getColumns(); SelectItem[] selectItems = new SelectItem[columns2.length]; for (int i = 0; i < selectItems.length; i++) { SelectItem selectItem = new SelectItem(columns2[i]); selectItems[i] = selectItem; } List<Object[]> data = new ArrayList<Object[]>(); data.add(new Object[] { 1, 1, "founder" }); data.add(new Object[] { 1, 1, "developer" }); data.add(new Object[] { 1, 2, "developer" }); data.add(new Object[] { 2, 1, "developer" }); data.add(new Object[] { 2, 3, "developer" }); data.add(new Object[] { 4, 1, "advisor" }); data.add(new Object[] { 5, 2, "developer" }); data.add(new Object[] { 6, 1, "founder" }); if (maxRows != -1) { for (int i = data.size() - 1; i >= maxRows; i--) { data.remove(i); } } return createDataSet(selectItems, data); } throw new IllegalArgumentException("This test only accepts table1 and table2"); } @Override protected String getMainSchemaName() throws MetaModelException { return schema.getName(); } @Override protected Schema getMainSchema() throws MetaModelException { return schema; } }; return dataContext; } public void testDistinct() throws Exception { Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME); Query q = new Query().select(roleColumn).from(table2).orderBy(roleColumn); q.getSelectClause().setDistinct(true); DataContext dc = getDataContext(); DataSet data = dc.executeQuery(q); assertTrue(data.next()); assertEquals("advisor", data.getRow().getValue(roleColumn)); assertTrue(data.next()); assertEquals("developer", data.getRow().getValue(roleColumn)); assertTrue(data.next()); assertEquals("founder", data.getRow().getValue(roleColumn)); assertFalse(data.next()); } public void testInformationSchema() throws Exception { DataContext dc = getDataContext(); assertEquals("[information_schema, MetaModelSchema]", Arrays.toString(dc.getSchemaNames())); Schema informationSchema = dc.getSchemaByName("information_schema"); assertEquals( "[Table[name=tables,type=TABLE,remarks=null], Table[name=columns,type=TABLE,remarks=null], Table[name=relationships,type=TABLE,remarks=null]]", Arrays.toString(informationSchema.getTables())); assertEquals( "[Relationship[primaryTable=tables,primaryColumns=[name],foreignTable=columns,foreignColumns=[table]], " + "Relationship[primaryTable=tables,primaryColumns=[name],foreignTable=relationships,foreignColumns=[primary_table]], " + "Relationship[primaryTable=tables,primaryColumns=[name],foreignTable=relationships,foreignColumns=[foreign_table]], " + "Relationship[primaryTable=columns,primaryColumns=[name],foreignTable=relationships,foreignColumns=[primary_column]], " + "Relationship[primaryTable=columns,primaryColumns=[name],foreignTable=relationships,foreignColumns=[foreign_column]]]", Arrays.toString(informationSchema.getRelationships())); Table tablesTable = informationSchema.getTableByName("tables"); assertEquals( "[Column[name=name,columnNumber=0,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], " + "Column[name=type,columnNumber=1,type=VARCHAR,nullable=true,nativeType=null,columnSize=null], " + "Column[name=num_columns,columnNumber=2,type=INTEGER,nullable=true,nativeType=null,columnSize=null], " + "Column[name=remarks,columnNumber=3,type=VARCHAR,nullable=true,nativeType=null,columnSize=null]]", Arrays.toString(tablesTable.getColumns())); Table columnsTable = informationSchema.getTableByName("columns"); assertEquals( "[Column[name=name,columnNumber=0,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], " + "Column[name=type,columnNumber=1,type=VARCHAR,nullable=true,nativeType=null,columnSize=null], " + "Column[name=native_type,columnNumber=2,type=VARCHAR,nullable=true,nativeType=null,columnSize=null], " + "Column[name=size,columnNumber=3,type=INTEGER,nullable=true,nativeType=null,columnSize=null], " + "Column[name=nullable,columnNumber=4,type=BOOLEAN,nullable=true,nativeType=null,columnSize=null], " + "Column[name=indexed,columnNumber=5,type=BOOLEAN,nullable=true,nativeType=null,columnSize=null], " + "Column[name=table,columnNumber=6,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], " + "Column[name=remarks,columnNumber=7,type=VARCHAR,nullable=true,nativeType=null,columnSize=null]]", Arrays.toString(columnsTable.getColumns())); Table relationshipsTable = informationSchema.getTableByName("relationships"); assertEquals( "[Column[name=primary_table,columnNumber=0,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], " + "Column[name=primary_column,columnNumber=1,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], " + "Column[name=foreign_table,columnNumber=2,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], " + "Column[name=foreign_column,columnNumber=3,type=VARCHAR,nullable=false,nativeType=null,columnSize=null]]", Arrays.toString(relationshipsTable.getColumns())); DataSet dataSet = dc.query().from(tablesTable).select(tablesTable.getColumns()).execute(); assertTrue(dataSet.next()); assertEquals("Row[values=[contributor, TABLE, 3, null]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[project, TABLE, 4, null]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[role, TABLE, 3, null]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[project_contributor, VIEW, 3, null]]", dataSet.getRow().toString()); assertFalse(dataSet.next()); dataSet.close(); Relationship relationship = tablesTable.getRelationships(columnsTable)[0]; FromItem joinFromItem = new FromItem(JoinType.INNER, relationship); Query q = new Query().select(tablesTable.getColumnByName("name")).select(columnsTable.getColumnByName("name")) .select(columnsTable.getBooleanColumns()).from(joinFromItem); assertEquals("SELECT tables.name, columns.name, columns.nullable, columns.indexed " + "FROM information_schema.tables INNER JOIN information_schema.columns " + "ON tables.name = columns.table", q.toString()); dataSet = dc.executeQuery(q); assertTrue(dataSet.next()); assertEquals("Row[values=[contributor, contributor_id, false, true]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[contributor, name, false, false]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[contributor, country, true, false]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[project, project_id, false, false]]", dataSet.getRow().toString()); assertTrue(dataSet.next()); assertEquals("Row[values=[project, name, false, false]]", dataSet.getRow().toString()); dataSet.close(); } public void testOrderByWithoutSelecting() throws Exception { Query q = new Query(); q.from(new FromItem(table2).setAlias("r")); Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME); Column projectIdColumn = table2.getColumnByName(COLUMN_ROLE_PROJECT_ID); q.select(new SelectItem(projectIdColumn)); q.orderBy(roleColumn); assertEquals("SELECT r.project_id FROM MetaModelSchema.role r ORDER BY r.name ASC", q.toString()); DataContext dc = getDataContext(); DataSet data = dc.executeQuery(q); assertEquals(1, data.getSelectItems().length); @SuppressWarnings("deprecation") TableModel tableModel = data.toTableModel(); // should correspond to these lines: // data.add(new Object[] { 4, 1, "advisor" }); // data.add(new Object[] { 1, 1, "developer" }); // data.add(new Object[] { 1, 2, "developer" }); // data.add(new Object[] { 2, 1, "developer" }); // data.add(new Object[] { 2, 3, "developer" }); // data.add(new Object[] { 5, 2, "developer" }); // data.add(new Object[] { 1, 1, "founder" }); // data.add(new Object[] { 6, 1, "founder" }); assertEquals(8, tableModel.getRowCount()); assertEquals(1, tableModel.getColumnCount()); assertEquals(1, tableModel.getValueAt(0, 0)); assertEquals(1, tableModel.getValueAt(1, 0)); assertEquals(2, tableModel.getValueAt(2, 0)); assertEquals(1, tableModel.getValueAt(3, 0)); assertEquals(3, tableModel.getValueAt(4, 0)); assertEquals(2, tableModel.getValueAt(5, 0)); assertEquals(1, tableModel.getValueAt(6, 0)); assertEquals(1, tableModel.getValueAt(7, 0)); } public void testGroupByWithoutSelecting() throws Exception { Query q = new Query(); q.from(new FromItem(table2).setAlias("r")); Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME); Column projectIdColumn = table2.getColumnByName(COLUMN_ROLE_PROJECT_ID); q.select(new SelectItem(FunctionType.SUM, projectIdColumn)); q.groupBy(new GroupByItem(new SelectItem(roleColumn))); q.orderBy(roleColumn); assertEquals("SELECT SUM(r.project_id) FROM MetaModelSchema.role r GROUP BY r.name ORDER BY r.name ASC", q.toString()); DataContext dc = getDataContext(); DataSet data = dc.executeQuery(q); assertEquals(1, data.getSelectItems().length); assertEquals("SUM(r.project_id)", data.getSelectItems()[0].toString()); @SuppressWarnings("deprecation") TableModel tableModel = data.toTableModel(); assertEquals(3, tableModel.getRowCount()); assertEquals(1, tableModel.getColumnCount()); assertEquals(1.0, tableModel.getValueAt(0, 0)); assertEquals(9.0, tableModel.getValueAt(1, 0)); assertEquals(2.0, tableModel.getValueAt(2, 0)); q = dc.query().from(table2).select("name").orderBy("name").toQuery(); q.getSelectClause().setDistinct(true); tableModel = new DataSetTableModel(dc.executeQuery(q)); assertEquals(3, tableModel.getRowCount()); assertEquals(1, tableModel.getColumnCount()); assertEquals("advisor", tableModel.getValueAt(0, 0)); assertEquals("developer", tableModel.getValueAt(1, 0)); assertEquals("founder", tableModel.getValueAt(2, 0)); } public void testSimpleGroupBy() throws Exception { Query q = new Query(); q.from(new FromItem(table2).setAlias("r")); Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME); q.select(new SelectItem(roleColumn)); q.groupBy(new GroupByItem(new SelectItem(roleColumn))); assertEquals("SELECT r.name FROM MetaModelSchema.role r GROUP BY r.name", q.toString()); DataContext dc = getDataContext(); DataSet data = dc.executeQuery(q); assertEquals(1, data.getSelectItems().length); assertEquals("r.name", data.getSelectItems()[0].toString()); TableModel tableModel = new DataSetTableModel(data); assertEquals(3, tableModel.getRowCount()); q.select(new SelectItem(FunctionType.COUNT, "*", "c")); q.where(new FilterItem(new SelectItem(roleColumn), OperatorType.EQUALS_TO, "founder")); data = dc.executeQuery(q); assertEquals(2, data.getSelectItems().length); assertEquals("r.name", data.getSelectItems()[0].toString()); assertEquals("COUNT(*) AS c", data.getSelectItems()[1].toString()); tableModel = new DataSetTableModel(data); assertEquals(1, tableModel.getRowCount()); assertEquals("founder", tableModel.getValueAt(0, 0)); assertEquals(2l, tableModel.getValueAt(0, 1)); q.select(new SelectItem(FunctionType.SUM, table2.getColumns()[0])); assertEquals( "SELECT r.name, COUNT(*) AS c, SUM(r.contributor_id) FROM MetaModelSchema.role r WHERE r.name = 'founder' GROUP BY r.name", q.toString()); data = dc.executeQuery(q); assertEquals(3, data.getSelectItems().length); assertEquals("r.name", data.getSelectItems()[0].toString()); assertEquals("COUNT(*) AS c", data.getSelectItems()[1].toString()); assertEquals("SUM(r.contributor_id)", data.getSelectItems()[2].toString()); tableModel = new DataSetTableModel(data); assertEquals(1, tableModel.getRowCount()); assertEquals("founder", tableModel.getValueAt(0, 0)); assertEquals(2l, tableModel.getValueAt(0, 1)); assertEquals(7.0, tableModel.getValueAt(0, 2)); } public void testSimpleHaving() throws Exception { Query q = new Query(); q.from(table2, "c"); Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME); Column contributorIdColumn = table2.getColumnByName(COLUMN_ROLE_CONTRIBUTOR_ID); q.groupBy(roleColumn); SelectItem countSelectItem = new SelectItem(FunctionType.COUNT, contributorIdColumn).setAlias("my_count"); q.select(new SelectItem(roleColumn), countSelectItem); q.having(new FilterItem(countSelectItem, OperatorType.GREATER_THAN, 1)); q.orderBy(new OrderByItem(countSelectItem)); assertEquals( "SELECT c.name, COUNT(c.contributor_id) AS my_count FROM MetaModelSchema.role c GROUP BY c.name HAVING COUNT(c.contributor_id) > 1 ORDER BY COUNT(c.contributor_id) ASC", q.toString()); DataSet data = getDataContext().executeQuery(q); assertTrue(data.next()); assertEquals("Row[values=[founder, 2]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[developer, 5]]", data.getRow().toString()); assertFalse(data.next()); } public void testHavingFunctionNotSelected() throws Exception { Query q = new Query(); q.from(table2, "c"); Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME); Column contributorIdColumn = table2.getColumnByName(COLUMN_ROLE_CONTRIBUTOR_ID); q.groupBy(roleColumn); SelectItem countSelectItem = new SelectItem(FunctionType.COUNT, contributorIdColumn).setAlias("my_count"); q.select(new SelectItem(roleColumn)); q.having(new FilterItem(countSelectItem, OperatorType.GREATER_THAN, 3)); assertEquals("SELECT c.name FROM MetaModelSchema.role c GROUP BY c.name HAVING COUNT(c.contributor_id) > 3", q.toString()); DataSet data = getDataContext().executeQuery(q); assertTrue(data.next()); assertEquals("Row[values=[developer]]", data.getRow().toString()); assertFalse(data.next()); data.close(); q.getHavingClause().removeItems(); q.having(new FilterItem(SelectItem.getCountAllItem(), OperatorType.GREATER_THAN, 3)); assertEquals("SELECT c.name FROM MetaModelSchema.role c GROUP BY c.name HAVING COUNT(*) > 3", q.toString()); data = getDataContext().executeQuery(q); assertTrue(data.next()); assertEquals("Row[values=[developer]]", data.getRow().toString()); assertFalse(data.next()); data.close(); } public void testCompiledQueryParameterInWhereClause() throws Exception { DataContext dc = getDataContext(); QueryParameter param1 = new QueryParameter(); CompiledQuery compiledQuery = dc.query().from(table1).select("name").where(COLUMN_CONTRIBUTOR_COUNTRY) .eq(param1).compile(); try { assertEquals(1, compiledQuery.getParameters().size()); assertSame(param1, compiledQuery.getParameters().get(0)); DataSet ds = dc.executeQuery(compiledQuery, "denmark"); try { assertTrue(ds.next()); assertEquals("Row[values=[kasper]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[asbjorn]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[jesper]]", ds.getRow().toString()); assertFalse(ds.next()); } finally { ds.close(); } try { ds = dc.executeQuery(compiledQuery, "canada"); assertTrue(ds.next()); assertEquals("Row[values=[daniel]]", ds.getRow().toString()); assertFalse(ds.next()); } finally { ds.close(); } } finally { compiledQuery.close(); } } public void testCompiledQueryParameterInSubQuery() throws Exception { final DataContext dc = getDataContext(); final QueryParameter param1 = new QueryParameter(); final Query subQuery = dc.query().from(table1).select("name").where(COLUMN_CONTRIBUTOR_COUNTRY).eq(param1) .toQuery(); final FromItem subQueryFromItem = new FromItem(subQuery); final Query query = new Query().select(new SelectItem(subQuery.getSelectClause().getItem(0), subQueryFromItem)) .from(subQueryFromItem); final CompiledQuery compiledQuery = dc.compileQuery(query); try { assertEquals(1, compiledQuery.getParameters().size()); assertSame(param1, compiledQuery.getParameters().get(0)); DataSet ds = dc.executeQuery(compiledQuery, "denmark"); List<Object[]> objectArrays = ds.toObjectArrays(); assertEquals(3, objectArrays.size()); } finally { compiledQuery.close(); } } public void testSelectCount() throws Exception { DataContext dc = getDataContext(); Query q = new Query(); q.from(table1); q.selectCount(); Row row = MetaModelHelper.executeSingleRowQuery(dc, q); assertEquals("6", row.getValue(0).toString()); } public void testSimpleSelect() throws Exception { DataContext dc = getDataContext(); Query q = new Query(); q.from(table1); q.select(table1.getColumns()); DataSet dataSet = dc.executeQuery(q); assertTrue(dataSet.next()); Row row = dataSet.getRow(); assertEquals("Row[values=[1, kasper, denmark]]", row.toString()); assertTrue(dataSet.next()); assertTrue(dataSet.next()); assertTrue(dataSet.next()); assertTrue(dataSet.next()); assertTrue(dataSet.next()); assertFalse(dataSet.next()); } public void testCarthesianProduct() throws Exception { DataContext dc = getDataContext(); Query q = new Query(); q.from(table1); q.from(table2); q.select(table1.getColumns()); q.select(table2.getColumns()); DataSet data = dc.executeQuery(q); assertEquals(table1.getColumnCount() + table2.getColumnCount(), data.getSelectItems().length); for (int i = 0; i < 6 * 8; i++) { assertTrue(data.next()); if (i == 0) { assertEquals("Row[values=[1, kasper, denmark, 1, 1, founder]]", data.getRow().toString()); } else if (i == 1) { assertEquals("Row[values=[1, kasper, denmark, 1, 1, developer]]", data.getRow().toString()); } } assertFalse(data.next()); } public void testJoinAndFirstRow() throws Exception { DataSet data; DataContext dc = getDataContext(); Query q = new Query(); q.from(table1); q.from(table2); q.select(table1.getColumns()); q.select(table2.getColumns()); data = dc.executeQuery(q); assertEquals(48, data.toObjectArrays().size()); q.setFirstRow(3); data = dc.executeQuery(q); assertEquals(46, data.toObjectArrays().size()); } public void testSimpleWhere() throws Exception { DataContext dc = getDataContext(); Query q = new Query(); q.from(table1); q.select(table1.getColumns()); SelectItem countrySelectItem = q.getSelectClause().getSelectItem( table1.getColumnByName(COLUMN_CONTRIBUTOR_COUNTRY)); q.where(new FilterItem(countrySelectItem, OperatorType.EQUALS_TO, "denmark")); DataSet data = dc.executeQuery(q); for (int i = 0; i < 3; i++) { assertTrue("Assertion failed at i=" + i, data.next()); } assertFalse(data.next()); } public void testMaxRows() throws Exception { DataContext dc = getDataContext(); Query q = new Query(); q.from(table1); q.select(table1.getColumns()); q.setMaxRows(3); DataSet data1 = dc.executeQuery(q); assertTrue(data1.next()); assertEquals("Row[values=[1, kasper, denmark]]", data1.getRow().toString()); assertTrue(data1.next()); assertEquals("Row[values=[2, asbjorn, denmark]]", data1.getRow().toString()); assertTrue(data1.next()); assertEquals("Row[values=[3, johny, israel]]", data1.getRow().toString()); assertFalse(data1.next()); data1.close(); q = new Query(); q.from(table1); q.select(table1.getColumns()); q.setFirstRow(2); q.setMaxRows(2); DataSet data2 = dc.executeQuery(q); assertTrue(data2.next()); assertEquals("Row[values=[2, asbjorn, denmark]]", data2.getRow().toString()); assertTrue(data2.next()); assertEquals("Row[values=[3, johny, israel]]", data2.getRow().toString()); assertFalse(data2.next()); data2.close(); } public void testCarthesianProductWithWhere() throws Exception { DataContext dc = getDataContext(); SelectItem s1 = new SelectItem(table1.getColumnByName(COLUMN_CONTRIBUTOR_NAME)); SelectItem s2 = new SelectItem(table2.getColumnByName(COLUMN_ROLE_ROLE_NAME)); FromItem f1 = new FromItem(table1); FromItem f2 = new FromItem(table2); Query q = new Query(); q.select(s1); q.select(s2); q.from(f1); q.from(f2); SelectItem s3 = new SelectItem(table1.getColumnByName(COLUMN_CONTRIBUTOR_CONTRIBUTOR_ID)); SelectItem s4 = new SelectItem(table2.getColumnByName(COLUMN_ROLE_CONTRIBUTOR_ID)); q.where(new FilterItem(s3, OperatorType.EQUALS_TO, s4)); assertEquals( "SELECT contributor.name, role.name FROM MetaModelSchema.contributor, MetaModelSchema.role WHERE contributor.contributor_id = role.contributor_id", q.toString()); DataSet data = dc.executeQuery(q); assertEquals(2, data.getSelectItems().length); assertTrue(data.next()); assertEquals("Row[values=[kasper, founder]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[kasper, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[kasper, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[daniel, advisor]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[sasidhar, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[jesper, founder]]", data.getRow().toString()); assertFalse(data.next()); } public void testSelectDistinct() throws Exception { // there will be three distinct values in bar column: hello (x2), hi, // howdy MockDataContext dc = new MockDataContext("sch", "tab", "hello"); Table table = dc.getTableByQualifiedLabel("sch.tab"); Query q = dc.query().from(table).select("bar").toQuery(); q.getSelectClause().setDistinct(true); q.orderBy(table.getColumnByName("bar")); DataSet ds = dc.executeQuery(q); assertTrue(ds.next()); assertEquals("Row[values=[hello]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[hi]]", ds.getRow().toString()); assertTrue(ds.next()); assertEquals("Row[values=[yo]]", ds.getRow().toString()); assertFalse(ds.next()); } public void testSubSelectionAndInnerJoin() throws Exception { DataContext dc = getDataContext(); SelectItem s1 = new SelectItem(table1.getColumnByName(COLUMN_CONTRIBUTOR_NAME)); SelectItem s2 = new SelectItem(table2.getColumnByName(COLUMN_ROLE_ROLE_NAME)); FromItem fromItem = new FromItem(JoinType.INNER, table1.getRelationships(table2)[0]); Query q = new Query(); q.select(s1); q.select(s2); q.from(fromItem); assertEquals( "SELECT contributor.name, role.name FROM MetaModelSchema.contributor INNER JOIN MetaModelSchema.role ON contributor.contributor_id = role.contributor_id", q.toString()); DataSet data = dc.executeQuery(q); assertEquals(2, data.getSelectItems().length); assertTrue(data.next()); assertEquals("Row[values=[kasper, founder]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[kasper, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[kasper, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[daniel, advisor]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[sasidhar, developer]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[jesper, founder]]", data.getRow().toString()); assertFalse(data.next()); } public void testSubquery() throws Exception { Query q1 = new Query(); q1.from(table1); q1.select(table1.getColumns()); Query q2 = new Query(); FromItem fromItem = new FromItem(q1); q2.from(fromItem); SelectItem selectItem = new SelectItem(q1.getSelectClause().getItems().get(1), fromItem); selectItem.setAlias("e"); q2.select(selectItem); assertEquals( "SELECT name AS e FROM (SELECT contributor.contributor_id, contributor.name, contributor.country FROM MetaModelSchema.contributor)", q2.toString()); fromItem.setAlias("c"); assertEquals( "SELECT c.name AS e FROM (SELECT contributor.contributor_id, contributor.name, contributor.country FROM MetaModelSchema.contributor) c", q2.toString()); DataContext dc = getDataContext(); DataSet data = dc.executeQuery(q2); assertEquals(1, data.getSelectItems().length); assertTrue(data.next()); assertEquals("Row[values=[kasper]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[asbjorn]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[johny]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[daniel]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[sasidhar]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[jesper]]", data.getRow().toString()); assertFalse(data.next()); // Create a sub-query for a sub-query Query q3 = new Query(); fromItem = new FromItem(q2); q3.from(fromItem); selectItem = new SelectItem(q2.getSelectClause().getItems().get(0), fromItem); selectItem.setAlias("f"); q3.select(selectItem); fromItem.setAlias("d"); assertEquals( "SELECT d.e AS f FROM (SELECT c.name AS e FROM (SELECT contributor.contributor_id, contributor.name, contributor.country FROM MetaModelSchema.contributor) c) d", q3.toString()); data = dc.executeQuery(q3); assertEquals(1, data.getSelectItems().length); assertTrue(data.next()); assertEquals("Row[values=[kasper]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[asbjorn]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[johny]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[daniel]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[sasidhar]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[jesper]]", data.getRow().toString()); assertFalse(data.next()); } public void testOrderBy() throws Exception { Query q = new Query(); q.from(new FromItem(table1).setAlias("c")); q.select(table1.getColumns()); OrderByItem countryOrderBy = new OrderByItem(q.getSelectClause().getItem(2), Direction.DESC); OrderByItem nameOrderBy = new OrderByItem(q.getSelectClause().getItem(1)); q.orderBy(countryOrderBy, nameOrderBy); assertEquals( "SELECT c.contributor_id, c.name, c.country FROM MetaModelSchema.contributor c ORDER BY c.country DESC, c.name ASC", q.toString()); DataSet data = getDataContext().executeQuery(q); assertTrue(data.next()); assertEquals("Row[values=[5, sasidhar, unknown]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[3, johny, israel]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[2, asbjorn, denmark]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[6, jesper, denmark]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[1, kasper, denmark]]", data.getRow().toString()); assertTrue(data.next()); assertEquals("Row[values=[4, daniel, canada]]", data.getRow().toString()); assertFalse(data.next()); } public void testExecuteCount() throws Exception { QueryPostprocessDataContext dc = new QueryPostprocessDataContext() { @Override protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) { throw new UnsupportedOperationException(); } @Override protected Number executeCountQuery(Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) { return 1337; } @Override protected String getMainSchemaName() throws MetaModelException { return "sch"; } @Override protected Schema getMainSchema() throws MetaModelException { MutableSchema schema = new MutableSchema(getMainSchemaName()); MutableTable table = new MutableTable("tabl").setSchema(schema); return schema.addTable(table.addColumn(new MutableColumn("col").setTable(table))); } }; DataSet ds = dc.query().from("sch.tabl").selectCount().execute(); assertTrue(ds.next()); assertEquals("Row[values=[1337]]", ds.getRow().toString()); assertFalse(ds.next()); } public void testExecutePrimaryKeyLookupQuery() throws Exception { QueryPostprocessDataContext dc = new QueryPostprocessDataContext() { @Override protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) { throw new UnsupportedAddressTypeException(); } @Override protected Number executeCountQuery(Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) { return null; } @Override protected String getMainSchemaName() throws MetaModelException { return "sch"; } @Override protected Row executePrimaryKeyLookupQuery(Table table, List<SelectItem> selectItems, Column primaryKeyColumn, Object keyValue) { assertEquals("foo", keyValue); return new DefaultRow(new SimpleDataSetHeader(selectItems), new Object[] { "hello world" }); } @Override protected Schema getMainSchema() throws MetaModelException { MutableSchema schema = new MutableSchema(getMainSchemaName()); MutableTable table = new MutableTable("tabl").setSchema(schema); table.addColumn(new MutableColumn("col1").setTable(table).setPrimaryKey(true)); table.addColumn(new MutableColumn("col2").setTable(table)); return schema.addTable(table); } }; DataSet result = dc.query().from("tabl").select("col2").where("col1").eq("foo").execute(); assertTrue(result.next()); assertEquals("Row[values=[hello world]]", result.getRow().toString()); assertFalse(result.next()); } public void testQueryWithDotInTableName() throws Exception { MockDataContext dc = new MockDataContext("folder", "file.csv", "foo"); Table table = dc.getDefaultSchema().getTableByName("file.csv"); assertNotNull(table); Query q = dc.parseQuery("SELECT foo FROM file.csv WHERE \r\nfoo='bar'"); assertNotNull(q); FilterItem item = q.getWhereClause().getItem(0); assertNull(item.getExpression()); assertEquals("file.csv.foo = 'bar'", item.toSql()); } public void testQueryWithMultipleColumnsInExpression() { Query query1 = new Query().from(table1).select("contributor_id,name"); DataSet set = getDataContext().executeQuery(query1); assertEquals(true, set.next()); assertEquals("Row[values=[1, kasper]]", set.getRow().toString()); Query query2 = new Query().from(table1).select("Greatest(1,2,3),max(contributer_id)", true); assertEquals("SELECT Greatest(1,2,3), MAX(contributer_id) FROM MetaModelSchema.contributor", query2.toString()); Query query3 = new Query().from(table1).select("*,count(*)"); assertEquals("SELECT contributor.contributor_id, contributor.name, contributor.country, COUNT(*)" + " FROM MetaModelSchema.contributor", query3.toString()); } public void testOrderOnAggregationValue() throws Exception { MockDataContext dc = new MockDataContext("sch", "tab", "hello"); Query query = dc.parseQuery("SELECT MAX(baz) AS X FROM tab GROUP BY baz ORDER BY X"); DataSet ds = dc.executeQuery(query); List<String> values = new ArrayList<String>(); while (ds.next()) { final String value = (String) ds.getRow().getValue(0); values.add(value); } ds.close(); // this should be alphabetically sorted assertEquals("[hello, world]", values.toString()); } }