diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java index a82766121..ca4ccb97a 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java @@ -12,6 +12,7 @@ import com.mysema.query.types.operation.Ops; /** * MySQLTemplates is an SQL dialect for MySQL + * tested with MySQL CE 5.1 * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java index a6262b122..3c915cf14 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java @@ -10,7 +10,9 @@ import java.math.BigInteger; import com.mysema.query.types.operation.Ops; /** - * OracleDialect is an Oracle specific extension of SqlOps + * OracleTemplates is an SQL dialect for Oracle + * + * tested with Oracle 10g XE * * @author tiwe * @version $Id$ @@ -29,6 +31,9 @@ public class OracleTemplates extends SQLTemplates { // String add(Ops.CONCAT, "{0} || {1}"); + add(Ops.INDEX_OF, "instrb({0},{1})-1"); + add(Ops.INDEX_OF_2ARGS, "instrb({0},{1},{2}+1)-1"); + add(Ops.MATCHES, "regexp_like({0},{1})"); add(Ops.StringOps.SPACE, "lpad('',{0},' ')"); // Number @@ -39,16 +44,18 @@ public class OracleTemplates extends SQLTemplates { // Date / time add(Ops.DateTimeOps.YEAR, "extract(year from {0})"); + add(Ops.DateTimeOps.YEAR_MONTH, "extract(year from {0}) * 100 + extract(month from {0})"); add(Ops.DateTimeOps.MONTH, "extract(month from {0})"); add(Ops.DateTimeOps.WEEK, "to_number(to_char({0},'WW'))"); add(Ops.DateTimeOps.HOUR, "to_number(to_char({0},'HH24'))"); add(Ops.DateTimeOps.MINUTE, "to_number(to_char({0},'MI'))"); add(Ops.DateTimeOps.SECOND, "to_number(to_char({0},'SS'))"); add(Ops.DateTimeOps.DAY_OF_MONTH, "to_number(to_char({0},'DD'))"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "to_number(to_char({0},'D'))"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "to_number(to_char({0},'D')) + 1"); add(Ops.DateTimeOps.DAY_OF_YEAR, "to_number(to_char({0},'DDD'))"); - + setLimitAndOffsetSymbols(false); + setRequiresWhereForPagingSymbols(true); setLimitTemplate("rownum < %1$s"); setOffsetTemplate("rownum > %1$s"); setLimitOffsetTemplate("rownum between %1$s and %3$s"); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java index 7356da89b..8936d9047 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java @@ -7,6 +7,14 @@ package com.mysema.query.sql; import com.mysema.query.types.operation.Ops; +/** + * PostgresTemplates is an SQL dialect for Postgres + * + * tested with Postgres 8.4 + * + * @author tiwe + * + */ public class PostgresTemplates extends SQLTemplates{ { // type mappings diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java index e5e7dd4ec..dd27da024 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java @@ -150,7 +150,7 @@ public class SQLSerializer extends SerializerBase { if (metadata.getModifiers().isRestricting() && !forCountRow){ Long limit = metadata.getModifiers().getLimit(); Long offset = metadata.getModifiers().getOffset(); - serializeModifiers(limit, offset); + serializeModifiers(where, limit, offset); } } @@ -208,9 +208,13 @@ public class SQLSerializer extends SerializerBase { } } - private void serializeModifiers(Long limit, Long offset) { + private void serializeModifiers(@Nullable EBoolean where, Long limit, Long offset) { if (!templates.isLimitAndOffsetSymbols()){ - append(" "); + if (where == null && templates.isRequiresWhereForPagingSymbols()){ + append(templates.getWhere()); + }else{ + append(" "); + } append(templates.getLimitOffsetCondition(limit, offset)); }else{ if (limit != null) { diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java index 20dc3a550..eecd23542 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java @@ -108,6 +108,8 @@ public class SQLTemplates extends Templates { private String values = "\nvalues "; private String where = "\nwhere "; + + private boolean requiresWhereForPagingSymbols = false; protected SQLTemplates() { // boolean @@ -523,5 +525,14 @@ public class SQLTemplates extends Templates { return ", "; } + public final boolean isRequiresWhereForPagingSymbols() { + return requiresWhereForPagingSymbols; + } + + public final void setRequiresWhereForPagingSymbols( + boolean requiresWhereForPagingSymbols) { + this.requiresWhereForPagingSymbols = requiresWhereForPagingSymbols; + } + } diff --git a/querydsl-sql/src/test/java/com/mysema/query/Connections.java b/querydsl-sql/src/test/java/com/mysema/query/Connections.java index 9cc84a02d..b84f4fb02 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/Connections.java +++ b/querydsl-sql/src/test/java/com/mysema/query/Connections.java @@ -31,6 +31,8 @@ public final class Connections { private static final String DROP_TABLE_DATETEST = "drop table date_test"; + private static final String DROP_TABLE_EMPLOYEE2 = "drop table employee2"; + private static final String DROP_TABLE_SURVEY = "drop table survey"; private static final String DROP_TABLE_TEST = "drop table test"; @@ -119,7 +121,7 @@ public final class Connections { // employee // stmt.execute("drop table employee if exists"); - safeExecute(stmt, "drop table employee2"); + safeExecute(stmt, DROP_TABLE_EMPLOYEE2); stmt.execute("create table employee2(id int, " + "firstname VARCHAR(50), " + "lastname VARCHAR(50), " @@ -238,12 +240,12 @@ public final class Connections { stmtHolder.set(stmt); // survey - safeExecute(stmt, "drop table survey"); + safeExecute(stmt, DROP_TABLE_SURVEY); stmt.execute("create table survey (id number(10,0),name varchar(30))"); stmt.execute("insert into survey values (1, 'Hello World')"); // test - safeExecute(stmt, "drop table test"); + safeExecute(stmt, DROP_TABLE_TEST); stmt.execute("create table test(name varchar(255))"); String sql = "insert into test values(?)"; PreparedStatement pstmt = c.prepareStatement(sql); @@ -254,19 +256,24 @@ public final class Connections { pstmt.executeBatch(); // employee - safeExecute(stmt, "drop table employee"); - stmt.execute("create table employee(id number(10,0), " - + "firstname VARCHAR(50), " + "lastname VARCHAR(50), " - + "salary decimal(10, 2), " + "superior_id number(10,0), " + + safeExecute(stmt, DROP_TABLE_EMPLOYEE2); + stmt.execute("create table employee2(id number(10,0), " + + "firstname VARCHAR(50), " + + "lastname VARCHAR(50), " + + "salary decimal(10, 2), " + + "datefield date, " + + "timefield timestamp, " + + "superior_id number(10,0), " + "CONSTRAINT PK_employee PRIMARY KEY (id), " + "CONSTRAINT FK_superior FOREIGN KEY (superior_id) " - + "REFERENCES employee(ID))"); + + "REFERENCES employee2(ID))"); addEmployees(); // date_test and time_test -// executeSafe("drop table time_test"); - safeExecute(stmt, "drop table date_test"); -// stmt.execute("create table time_test(time_test time)"); +// executeSafe("drop table time_test"); +// stmt.execute("create table time_test(time_test time)"); + safeExecute(stmt, DROP_TABLE_DATETEST); stmt.execute("create table date_test(date_test date)"); } @@ -298,7 +305,7 @@ public final class Connections { // employee // stmt.execute("drop table employee if exists"); - safeExecute(stmt, "drop table employee2"); + safeExecute(stmt, DROP_TABLE_EMPLOYEE2); stmt.execute("create table employee2(id int, " + "firstname VARCHAR(50), " + "lastname VARCHAR(50), " diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectBaseTest.java b/querydsl-sql/src/test/java/com/mysema/query/SelectBaseTest.java index 4d804dd6f..1b14e7aae 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectBaseTest.java +++ b/querydsl-sql/src/test/java/com/mysema/query/SelectBaseTest.java @@ -172,7 +172,7 @@ public abstract class SelectBaseTest extends AbstractBaseTest{ @Test @IncludeIn(ORACLE) public void limitAndOffsetInOracle() throws SQLException { - String prefix = "select employee.id from employee employee "; + String prefix = "select e.id from employee2 e "; // limit expectedQuery = prefix + "where rownum < 4"; diff --git a/querydsl-sql/src/test/java/com/mysema/query/oracle/SelectOracleTest.java b/querydsl-sql/src/test/java/com/mysema/query/oracle/SelectOracleTest.java index 0ed00a7ea..b78f60604 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/oracle/SelectOracleTest.java +++ b/querydsl-sql/src/test/java/com/mysema/query/oracle/SelectOracleTest.java @@ -46,23 +46,22 @@ public class SelectOracleTest extends SelectBaseTest { @Test - public void testConnectByPrior() throws SQLException{ - expectedQuery = - "select employee.id, employee.lastname, employee.superior_id " + - "from employee employee " + - "connect by prior employee.id = employee.superior_id"; + public void connectByPrior() throws SQLException{ + expectedQuery = "select e.id, e.lastname, e.superior_id " + + "from employee2 e " + + "connect by prior e.id = e.superior_id"; qo().from(employee) .connectByPrior(employee.id.eq(employee.superiorId)) .list(employee.id, employee.lastname, employee.superiorId); } @Test - public void testConnectByPrior2() throws SQLException{ + public void connectByPrior2() throws SQLException{ expectedQuery = - "select employee.id, employee.lastname, employee.superior_id " + - "from employee employee " + - "start with employee.id = ? " + - "connect by prior employee.id = employee.superior_id"; + "select e.id, e.lastname, e.superior_id " + + "from employee2 e " + + "start with e.id = ? " + + "connect by prior e.id = e.superior_id"; qo().from(employee) .startWith(employee.id.eq(1)) .connectByPrior(employee.id.eq(employee.superiorId)) @@ -70,13 +69,13 @@ public class SelectOracleTest extends SelectBaseTest { } @Test - public void testConnectByPrior3() throws SQLException{ + public void connectByPrior3() throws SQLException{ expectedQuery = - "select employee.id, employee.lastname, employee.superior_id " + - "from employee employee " + - "start with employee.id = ? " + - "connect by prior employee.id = employee.superior_id " + - "order siblings by employee.lastname"; + "select e.id, e.lastname, e.superior_id " + + "from employee2 e " + + "start with e.id = ? " + + "connect by prior e.id = e.superior_id " + + "order siblings by e.lastname"; qo().from(employee) .startWith(employee.id.eq(1)) .connectByPrior(employee.id.eq(employee.superiorId)) @@ -85,11 +84,11 @@ public class SelectOracleTest extends SelectBaseTest { } @Test - public void testConnectByPrior4() throws SQLException{ + public void connectByPrior4() throws SQLException{ expectedQuery = - "select employee.id, employee.lastname, employee.superior_id " + - "from employee employee " + - "connect by nocycle prior employee.id = employee.superior_id"; + "select e.id, e.lastname, e.superior_id " + + "from employee2 e " + + "connect by nocycle prior e.id = e.superior_id"; qo().from(employee) .connectByNocyclePrior(employee.id.eq(employee.superiorId)) .list(employee.id, employee.lastname, employee.superiorId); @@ -97,7 +96,7 @@ public class SelectOracleTest extends SelectBaseTest { @Test @Ignore - public void testConnectBy() throws SQLException{ + public void connectBy() throws SQLException{ // TODO : come up with a legal case qo().from(employee) .where(level.eq(-1)) @@ -117,10 +116,10 @@ public class SelectOracleTest extends SelectBaseTest { // 8 sum(sal) over () TotSal // 9 from emp // 10 order by deptno, sal; - expectedQuery = "select employee.lastname, employee.salary, " + - "sum(employee.salary) over (partition by employee.superior_id order by employee.lastname, employee.salary), " + - "sum(employee.salary) over ( order by employee.superior_id, employee.salary), " + - "sum(employee.salary) over () from employee employee order by employee.salary asc, employee.superior_id asc"; + expectedQuery = "select e.lastname, e.salary, " + + "sum(e.salary) over (partition by e.superior_id order by e.lastname, e.salary), " + + "sum(e.salary) over ( order by e.superior_id, e.salary), " + + "sum(e.salary) over () from employee2 e order by e.salary asc, e.superior_id asc"; qo().from(employee) .orderBy(employee.salary.asc(), employee.superiorId.asc()) .list(