package com.querydsl.sql; import static com.querydsl.core.Target.*; import static com.querydsl.sql.Constants.employee; import static org.junit.Assert.*; import java.io.IOException; import java.sql.SQLException; import java.util.Arrays; import java.util.List; import org.junit.Ignore; import org.junit.Test; import com.google.common.collect.ImmutableList; import com.mysema.commons.lang.CloseableIterator; import com.querydsl.core.Tuple; import com.querydsl.core.testutil.ExcludeIn; import com.querydsl.core.types.Expression; import com.querydsl.core.types.Projections; import com.querydsl.core.types.SubQueryExpression; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberPath; import com.querydsl.sql.domain.Employee; import com.querydsl.sql.domain.QEmployee; public class UnionBase extends AbstractBaseTest { @SuppressWarnings("unchecked") @Test @ExcludeIn({MYSQL, TERADATA}) public void in_union() { assertTrue(query().from(employee) .where(employee.id.in( query().union(query().select(Expressions.ONE), query().select(Expressions.TWO)))) .select(Expressions.ONE).fetchFirst() != null); } @Test @SuppressWarnings("unchecked") @ExcludeIn(FIREBIRD) // order is not properly supported public void union() throws SQLException { SubQueryExpression<Integer> sq1 = query().from(employee).select(employee.id.max().as("ID")); SubQueryExpression<Integer> sq2 = query().from(employee).select(employee.id.min().as("ID")); assertEquals( ImmutableList.of(query().select(employee.id.min()).from(employee).fetchFirst(), query().select(employee.id.max()).from(employee).fetchFirst()), query().union(sq1, sq2).orderBy(employee.id.asc()).fetch()); } @Test @SuppressWarnings("unchecked") public void union_list() throws SQLException { SubQueryExpression<Integer> sq1 = query().from(employee).select(employee.id.max()); SubQueryExpression<Integer> sq2 = query().from(employee).select(employee.id.min()); assertEquals( query().union(sq1, sq2).fetch(), query().union(sq1, sq2).list()); } @Test @SuppressWarnings("unchecked") public void union_all() { SubQueryExpression<Integer> sq1 = query().from(employee).select(employee.id.max()); SubQueryExpression<Integer> sq2 = query().from(employee).select(employee.id.min()); List<Integer> list = query().unionAll(sq1, sq2).fetch(); assertFalse(list.isEmpty()); } @SuppressWarnings("unchecked") @Test public void union_multiple_columns() throws SQLException { SubQueryExpression<Tuple> sq1 = query().from(employee).select(employee.firstname, employee.lastname); SubQueryExpression<Tuple> sq2 = query().from(employee).select(employee.lastname, employee.firstname); List<Tuple> list = query().union(sq1, sq2).fetch(); assertFalse(list.isEmpty()); for (Tuple row : list) { assertNotNull(row.get(0, Object.class)); assertNotNull(row.get(1, Object.class)); } } @SuppressWarnings("unchecked") @Test @ExcludeIn(DERBY) public void union_multiple_columns2() throws SQLException { SubQueryExpression<Tuple> sq1 = query().from(employee).select(employee.firstname, employee.lastname); SubQueryExpression<Tuple> sq2 = query().from(employee).select(employee.firstname, employee.lastname); SQLQuery<?> query = query(); query.union(sq1, sq2); List<String> list = query.select(employee.firstname).fetch(); assertFalse(list.isEmpty()); for (String row : list) { assertNotNull(row); } } @SuppressWarnings("unchecked") @Test @ExcludeIn(DERBY) public void union_multiple_columns3() throws SQLException { SubQueryExpression<Tuple> sq1 = query().from(employee).select(employee.firstname, employee.lastname); SubQueryExpression<Tuple> sq2 = query().from(employee).select(employee.firstname, employee.lastname); SQLQuery<?> query = query(); query.union(sq1, sq2); List<Tuple> list = query.select(employee.lastname, employee.firstname).fetch(); assertFalse(list.isEmpty()); for (Tuple row : list) { System.out.println(row.get(0, String.class) + " " + row.get(1, String.class)); } } @Test @SuppressWarnings("unchecked") public void union_empty_result() throws SQLException { SubQueryExpression<Integer> sq1 = query().from(employee).where(employee.firstname.eq("XXX")).select(employee.id); SubQueryExpression<Integer> sq2 = query().from(employee).where(employee.firstname.eq("YYY")).select(employee.id); List<Integer> list = query().union(sq1, sq2).fetch(); assertTrue(list.isEmpty()); } @Test @SuppressWarnings("unchecked") public void union2() throws SQLException { List<Integer> list = query().union( query().from(employee).select(employee.id.max()), query().from(employee).select(employee.id.min())).fetch(); assertFalse(list.isEmpty()); } @Test @SuppressWarnings("unchecked") public void union3() throws SQLException { SubQueryExpression<Tuple> sq3 = query().from(employee).select(new Expression[]{employee.id.max()}); SubQueryExpression<Tuple> sq4 = query().from(employee).select(new Expression[]{employee.id.min()}); List<Tuple> list2 = query().union(sq3, sq4).fetch(); assertFalse(list2.isEmpty()); } @SuppressWarnings("unchecked") @Test @ExcludeIn({DERBY}) public void union4() { SubQueryExpression<Tuple> sq1 = query().from(employee).select(employee.id, employee.firstname); SubQueryExpression<Tuple> sq2 = query().from(employee).select(employee.id, employee.firstname); assertEquals(1, query().union(employee, sq1, sq2).select(employee.id.count()).fetch().size()); } // FIXME for CUBRID // Teradata: The ORDER BY clause must contain only integer constants. @SuppressWarnings("unchecked") @Test @ExcludeIn({DERBY, CUBRID, FIREBIRD, TERADATA}) @Ignore // FIXME public void union5() { /* (select e.ID, e.FIRSTNAME, superior.ID as sup_id, superior.FIRSTNAME as sup_name * from EMPLOYEE e join EMPLOYEE superior on e.SUPERIOR_ID = superior.ID) * union * (select e.ID, e.FIRSTNAME, null, null from EMPLOYEE e) * order by ID asc */ QEmployee superior = new QEmployee("superior"); SubQueryExpression<Tuple> sq1 = query().from(employee) .join(employee.superiorIdKey, superior) .select(employee.id, employee.firstname, superior.id.as("sup_id"), superior.firstname.as("sup_name")); SubQueryExpression<Tuple> sq2 = query().from(employee) .select(employee.id, employee.firstname, null, null); List<Tuple> results = query().union(sq1, sq2).orderBy(employee.id.asc()).fetch(); for (Tuple result : results) { System.err.println(Arrays.asList(result)); } } @Test @ExcludeIn({FIREBIRD, TERADATA}) // The ORDER BY clause must contain only integer constants. @SuppressWarnings("unchecked") public void union_with_order() throws SQLException { SubQueryExpression<Integer> sq1 = query().from(employee).select(employee.id); SubQueryExpression<Integer> sq2 = query().from(employee).select(employee.id); List<Integer> list = query().union(sq1, sq2).orderBy(employee.id.asc()).fetch(); assertFalse(list.isEmpty()); } @SuppressWarnings("unchecked") @Test @ExcludeIn(FIREBIRD) public void union_multi_column_projection_list() throws IOException { SubQueryExpression<Tuple> sq1 = query().from(employee).select(employee.id.max(), employee.id.max().subtract(1)); SubQueryExpression<Tuple> sq2 = query().from(employee).select(employee.id.min(), employee.id.min().subtract(1)); List<Tuple> list = query().union(sq1, sq2).list(); assertEquals(2, list.size()); assertTrue(list.get(0) != null); assertTrue(list.get(1) != null); } @SuppressWarnings("unchecked") @Test @ExcludeIn(FIREBIRD) public void union_multi_column_projection_iterate() throws IOException { SubQueryExpression<Tuple> sq1 = query().from(employee).select(employee.id.max(), employee.id.max().subtract(1)); SubQueryExpression<Tuple> sq2 = query().from(employee).select(employee.id.min(), employee.id.min().subtract(1)); CloseableIterator<Tuple> iterator = query().union(sq1,sq2).iterate(); try { assertTrue(iterator.hasNext()); assertTrue(iterator.next() != null); assertTrue(iterator.next() != null); assertFalse(iterator.hasNext()); } finally { iterator.close(); } } @SuppressWarnings("unchecked") @Test public void union_single_column_projections_list() throws IOException { SubQueryExpression<Integer> sq1 = query().from(employee).select(employee.id.max()); SubQueryExpression<Integer> sq2 = query().from(employee).select(employee.id.min()); List<Integer> list = query().union(sq1, sq2).list(); assertEquals(2, list.size()); assertTrue(list.get(0) != null); assertTrue(list.get(1) != null); } @SuppressWarnings("unchecked") @Test public void union_single_column_projections_iterate() throws IOException { SubQueryExpression<Integer> sq1 = query().from(employee).select(employee.id.max()); SubQueryExpression<Integer> sq2 = query().from(employee).select(employee.id.min()); CloseableIterator<Integer> iterator = query().union(sq1,sq2).iterate(); try { assertTrue(iterator.hasNext()); assertTrue(iterator.next() != null); assertTrue(iterator.next() != null); assertFalse(iterator.hasNext()); } finally { iterator.close(); } } @SuppressWarnings("unchecked") @Test public void union_factoryExpression() { SubQueryExpression<Employee> sq1 = query().from(employee) .select(Projections.constructor(Employee.class, employee.id)); SubQueryExpression<Employee> sq2 = query().from(employee) .select(Projections.constructor(Employee.class, employee.id)); List<Employee> employees = query().union(sq1, sq2).list(); for (Employee employee : employees) { assertNotNull(employee); } } @SuppressWarnings("unchecked") @Test @ExcludeIn({DERBY, CUBRID}) public void union_clone() { NumberPath<Integer> idAlias = Expressions.numberPath(Integer.class, "id"); SubQueryExpression<Employee> sq1 = query().from(employee) .select(Projections.constructor(Employee.class, employee.id.as(idAlias))); SubQueryExpression<Employee> sq2 = query().from(employee) .select(Projections.constructor(Employee.class, employee.id.as(idAlias))); SQLQuery<?> query = query(); query.union(sq1, sq2); assertEquals(10, query.clone().select(idAlias).fetch().size()); } }