diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/TupleTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/TupleTests.java index 91cf081ace..e3597003da 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/TupleTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/TupleTests.java @@ -46,14 +46,19 @@ import static org.jooq.SQLDialect.INGRES; import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; import static org.jooq.SQLDialect.SYBASE; +import static org.jooq.impl.Factory.currentDate; import static org.jooq.impl.Factory.inline; +import static org.jooq.impl.Factory.not; import static org.jooq.impl.Factory.tuple; import static org.jooq.impl.Factory.val; +import java.sql.Date; + import org.jooq.TableRecord; import org.jooq.UpdatableRecord; import org.jooq.test.BaseTest; import org.jooq.test.jOOQAbstractTest; +import org.jooq.types.DayToSecond; import org.junit.Test; @@ -141,4 +146,52 @@ extends BaseTest OVERLAPS predicate - + +

+ When comparing dates, the SQL standard allows for using a special OVERLAPS predicate, which checks whether two date ranges overlap each other. The following can be said: +

+ + + +

The OVERLAPS predicate in jOOQ

+

+ jOOQ supports the OVERLAPS predicate on . The following methods are contained in : +

+ + t1, Field t2); +Condition overlaps(Tuple2 tuple);]]> + +

+ This allows for expressing the above predicates as such: +

+ + + +

jOOQ's extensions to the standard

+

+ Unlike the standard (or any database implementing the standard), jOOQ also supports the OVERLAPS predicate for comparing arbitrary . For instance, (1, 3) OVERLAPS (2, 4) will yield true in jOOQ. This is simulated as such +

+ + +
diff --git a/jOOQ/src/main/java/org/jooq/Tuple.java b/jOOQ/src/main/java/org/jooq/Tuple.java index c2f54b3853..c137c030ff 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple.java +++ b/jOOQ/src/main/java/org/jooq/Tuple.java @@ -45,4 +45,13 @@ package org.jooq; */ public interface Tuple extends QueryPart { + /** + * Get the degree of this tuple + */ + int getDegree(); + + /** + * Get a field at a given index + */ + Field getField(int index); } diff --git a/jOOQ/src/main/java/org/jooq/Tuple1.java b/jOOQ/src/main/java/org/jooq/Tuple1.java index 52488d5420..0f1819cfd3 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple1.java +++ b/jOOQ/src/main/java/org/jooq/Tuple1.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 1 + * A model type for a tuple with degree 1 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,19 @@ import java.util.Collection; */ public interface Tuple1 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +226,7 @@ public interface Tuple1 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +260,7 @@ public interface Tuple1 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/Tuple2.java b/jOOQ/src/main/java/org/jooq/Tuple2.java index d20b7581ea..3c7a3ab0d2 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple2.java +++ b/jOOQ/src/main/java/org/jooq/Tuple2.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 2 + * A model type for a tuple with degree 2 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,24 @@ import java.util.Collection; */ public interface Tuple2 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +231,7 @@ public interface Tuple2 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,10 +265,76 @@ public interface Tuple2 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @Support({ CUBRID, DB2, HSQLDB, MYSQL, ORACLE, POSTGRES }) Condition notIn(Select select); + + /** + * Check if this tuple overlaps another tuple + *

+ * The SQL standard specifies a temporal OVERLAPS predicate, + * which comes in two flavours: + *

+ *

+ * jOOQ also supports arbitrary 2-degree tuple comparisons, by simulating + * them as such

+     * -- This predicate
+     * (A, B) OVERLAPS (C, D)
+     *
+     * -- can be simulated as such
+     * (C <= B) AND (A <= D)
+     * 
+ */ + @Support + Condition overlaps(T1 t1, T2 t2); + + /** + * Check if this tuple overlaps another tuple + *

+ * The SQL standard specifies a temporal OVERLAPS predicate, + * which comes in two flavours: + *

+ *

+ * jOOQ also supports arbitrary 2-degree tuple comparisons, by simulating + * them as such

+     * -- This predicate
+     * (A, B) OVERLAPS (C, D)
+     *
+     * -- can be simulated as such
+     * (C <= B) AND (A <= D)
+     * 
+ */ + @Support + Condition overlaps(Field t1, Field t2); + + /** + * Check if this tuple overlaps another tuple + *

+ * The SQL standard specifies a temporal OVERLAPS predicate, + * which comes in two flavours: + *

    + *
  • (DATE, DATE) OVERLAPS (DATE, DATE)
  • + *
  • (DATE, INTERVAL) OVERLAPS (DATE, INTERVAL)
  • + *
+ *

+ * jOOQ also supports arbitrary 2-degree tuple comparisons, by simulating + * them as such

+     * -- This predicate
+     * (A, B) OVERLAPS (C, D)
+     *
+     * -- can be simulated as such
+     * (C <= B) AND (A <= D)
+     * 
+ */ + @Support + Condition overlaps(Tuple2 tuple); } diff --git a/jOOQ/src/main/java/org/jooq/Tuple3.java b/jOOQ/src/main/java/org/jooq/Tuple3.java index c46097a1e6..cdc498a7c0 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple3.java +++ b/jOOQ/src/main/java/org/jooq/Tuple3.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 3 + * A model type for a tuple with degree 3 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,29 @@ import java.util.Collection; */ public interface Tuple3 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + /** + * Get the third field + */ + Field field3(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +236,7 @@ public interface Tuple3 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +270,7 @@ public interface Tuple3 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/Tuple4.java b/jOOQ/src/main/java/org/jooq/Tuple4.java index 5fd506ffe8..3597516443 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple4.java +++ b/jOOQ/src/main/java/org/jooq/Tuple4.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 4 + * A model type for a tuple with degree 4 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,34 @@ import java.util.Collection; */ public interface Tuple4 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + /** + * Get the third field + */ + Field field3(); + + /** + * Get the fourth field + */ + Field field4(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +241,7 @@ public interface Tuple4 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +275,7 @@ public interface Tuple4 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/Tuple5.java b/jOOQ/src/main/java/org/jooq/Tuple5.java index 8a08f837a7..b62d679620 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple5.java +++ b/jOOQ/src/main/java/org/jooq/Tuple5.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 5 + * A model type for a tuple with degree 5 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,39 @@ import java.util.Collection; */ public interface Tuple5 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + /** + * Get the third field + */ + Field field3(); + + /** + * Get the fourth field + */ + Field field4(); + + /** + * Get the fifth field + */ + Field field5(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +246,7 @@ public interface Tuple5 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +280,7 @@ public interface Tuple5 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/Tuple6.java b/jOOQ/src/main/java/org/jooq/Tuple6.java index 7a51915885..8f7c01413d 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple6.java +++ b/jOOQ/src/main/java/org/jooq/Tuple6.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 6 + * A model type for a tuple with degree 6 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,44 @@ import java.util.Collection; */ public interface Tuple6 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + /** + * Get the third field + */ + Field field3(); + + /** + * Get the fourth field + */ + Field field4(); + + /** + * Get the fifth field + */ + Field field5(); + + /** + * Get the sixth field + */ + Field field6(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +251,7 @@ public interface Tuple6 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +285,7 @@ public interface Tuple6 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/Tuple7.java b/jOOQ/src/main/java/org/jooq/Tuple7.java index ba4feddd89..b55fb2603e 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple7.java +++ b/jOOQ/src/main/java/org/jooq/Tuple7.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 7 + * A model type for a tuple with degree 7 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,49 @@ import java.util.Collection; */ public interface Tuple7 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + /** + * Get the third field + */ + Field field3(); + + /** + * Get the fourth field + */ + Field field4(); + + /** + * Get the fifth field + */ + Field field5(); + + /** + * Get the sixth field + */ + Field field6(); + + /** + * Get the seventh field + */ + Field field7(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +256,7 @@ public interface Tuple7 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +290,7 @@ public interface Tuple7 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/Tuple8.java b/jOOQ/src/main/java/org/jooq/Tuple8.java index 2376ca437f..7c90a68865 100644 --- a/jOOQ/src/main/java/org/jooq/Tuple8.java +++ b/jOOQ/src/main/java/org/jooq/Tuple8.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity 8 + * A model type for a tuple with degree 8 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -54,6 +54,54 @@ import java.util.Collection; */ public interface Tuple8 extends Tuple { + // ------------------------------------------------------------------------ + // Field accessors + // ------------------------------------------------------------------------ + + /** + * Get the first field + */ + Field field1(); + + /** + * Get the second field + */ + Field field2(); + + /** + * Get the third field + */ + Field field3(); + + /** + * Get the fourth field + */ + Field field4(); + + /** + * Get the fifth field + */ + Field field5(); + + /** + * Get the sixth field + */ + Field field6(); + + /** + * Get the seventh field + */ + Field field7(); + + /** + * Get the eight field + */ + Field field8(); + + // ------------------------------------------------------------------------ + // Tuple DSL API + // ------------------------------------------------------------------------ + /** * Compare this tuple with another tuple for equality *

@@ -213,7 +261,7 @@ public interface Tuple8 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +295,7 @@ public interface Tuple8 extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/TupleN.java b/jOOQ/src/main/java/org/jooq/TupleN.java index a323d8c94d..693fefc1a9 100644 --- a/jOOQ/src/main/java/org/jooq/TupleN.java +++ b/jOOQ/src/main/java/org/jooq/TupleN.java @@ -45,7 +45,7 @@ import static org.jooq.SQLDialect.POSTGRES; import java.util.Collection; /** - * A model type for a tuple with arity N > 8 + * A model type for a tuple with degree N > 8 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for details. @@ -213,7 +213,7 @@ public interface TupleN extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ @@ -247,7 +247,7 @@ public interface TupleN extends Tuple { /** * Compare this tuple with a subselect for equality *

- * Note that the subquery must return a table of the same arity as this + * Note that the subquery must return a table of the same degree as this * tuple. This is not checked by jOOQ and will result in syntax errors in * the database, if not used correctly. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/Factory.java b/jOOQ/src/main/java/org/jooq/impl/Factory.java index 95a6845e22..a5dd2f2186 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Factory.java +++ b/jOOQ/src/main/java/org/jooq/impl/Factory.java @@ -5844,7 +5844,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 1 + * Create a tuple of degree 1 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5856,7 +5856,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 2 + * Create a tuple of degree 2 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5868,7 +5868,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 3 + * Create a tuple of degree 3 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5880,7 +5880,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 4 + * Create a tuple of degree 4 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5892,7 +5892,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 5 + * Create a tuple of degree 5 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5904,7 +5904,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 6 + * Create a tuple of degree 6 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5916,7 +5916,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 7 + * Create a tuple of degree 7 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5928,7 +5928,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 8 + * Create a tuple of degree 8 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5940,7 +5940,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity N > 8 + * Create a tuple of degree N > 8 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5952,7 +5952,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 1 + * Create a tuple of degree 1 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5964,7 +5964,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 2 + * Create a tuple of degree 2 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5976,7 +5976,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 3 + * Create a tuple of degree 3 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -5988,7 +5988,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 4 + * Create a tuple of degree 4 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -6000,7 +6000,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 5 + * Create a tuple of degree 5 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -6012,7 +6012,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 6 + * Create a tuple of degree 6 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -6024,7 +6024,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 7 + * Create a tuple of degree 7 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -6036,7 +6036,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity 8 + * Create a tuple of degree 8 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for @@ -6048,7 +6048,7 @@ public class Factory implements FactoryOperations { } /** - * Create a tuple of arity N > 8 + * Create a tuple of degree N > 8 *

* Note: Not all databases support tuples, but many tuple operations can be * simulated on all databases. See relevant tuple method Javadocs for diff --git a/jOOQ/src/main/java/org/jooq/impl/TupleImpl.java b/jOOQ/src/main/java/org/jooq/impl/TupleImpl.java index 8643977e95..f7707c858b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TupleImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TupleImpl.java @@ -39,10 +39,14 @@ import static java.util.Arrays.asList; import static org.jooq.Comparator.EQUALS; import static org.jooq.Comparator.NOT_EQUALS; import static org.jooq.SQLDialect.ASE; +import static org.jooq.SQLDialect.CUBRID; import static org.jooq.SQLDialect.DB2; import static org.jooq.SQLDialect.DERBY; import static org.jooq.SQLDialect.FIREBIRD; +import static org.jooq.SQLDialect.H2; +import static org.jooq.SQLDialect.HSQLDB; import static org.jooq.SQLDialect.INGRES; +import static org.jooq.SQLDialect.MYSQL; import static org.jooq.SQLDialect.ORACLE; import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; @@ -59,6 +63,7 @@ import org.jooq.BindContext; import org.jooq.Comparator; import org.jooq.Condition; import org.jooq.Configuration; +import org.jooq.DataType; import org.jooq.Field; import org.jooq.Operator; import org.jooq.QueryPart; @@ -74,7 +79,6 @@ import org.jooq.Tuple6; import org.jooq.Tuple7; import org.jooq.Tuple8; import org.jooq.TupleN; -import org.jooq.exception.DataAccessException; /** * @author Lukas Eder @@ -132,7 +136,69 @@ implements } // ------------------------------------------------------------------------ - // XXX: Tuple API + // XXX: Tuple accessor API + // ------------------------------------------------------------------------ + + @Override + public final int getDegree() { + return fields.length; + } + + @Override + public final Field getField(int index) { + return fields[index]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field1() { + return (Field) fields[0]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field2() { + return (Field) fields[1]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field3() { + return (Field) fields[2]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field4() { + return (Field) fields[3]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field5() { + return (Field) fields[4]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field6() { + return (Field) fields[5]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field7() { + return (Field) fields[6]; + } + + @SuppressWarnings("unchecked") + @Override + public final Field field8() { + return (Field) fields[7]; + } + + // ------------------------------------------------------------------------ + // XXX: Tuple DSL API // ------------------------------------------------------------------------ @Override @@ -789,10 +855,118 @@ implements return new InSubquery(select, InOperator.NOT_IN); } + // ------------------------------------------------------------------------ + // XXX: Tuple2 API + // ------------------------------------------------------------------------ + + @Override + public final Condition overlaps(T1 t1, T2 t2) { + return overlaps(tuple(t1, t2)); + } + + @Override + public final Condition overlaps(Field t1, Field t2) { + return overlaps(tuple(t1, t2)); + } + + @Override + public final Condition overlaps(Tuple2 tuple) { + return new Overlaps(tuple); + } + // ------------------------------------------------------------------------ // XXX: Implementation classes // ------------------------------------------------------------------------ + private class Overlaps extends AbstractCondition { + + /** + * Generated UID + */ + private static final long serialVersionUID = 85887551884667824L; + + private final TupleImpl other; + + @SuppressWarnings("unchecked") + Overlaps(Tuple2 other) { + this.other = (TupleImpl) other; + } + + @Override + public final void toSQL(RenderContext context) { + delegate(context).toSQL(context); + } + + @Override + public final void bind(BindContext context) { + delegate(context).bind(context); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private final QueryPartInternal delegate(Configuration configuration) { + DataType type0 = fields[0].getDataType(); + DataType type1 = fields[1].getDataType(); + + // The SQL standard only knows temporal OVERLAPS predicates: + // (DATE, DATE) OVERLAPS (DATE, DATE) + // (DATE, INTERVAL) OVERLAPS (DATE, INTERVAL) + boolean standardOverlaps = type0.isDateTime() && type1.isTemporal(); + boolean intervalOverlaps = type0.isDateTime() && (type1.isInterval() || type1.isNumeric()); + + // The non-standard OVERLAPS predicate is always simulated + if (!standardOverlaps || asList(ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, INGRES, MYSQL, SQLSERVER, SQLITE, SYBASE).contains(configuration.getDialect())) { + + // Interval OVERLAPS predicates need some additional arithmetic + if (intervalOverlaps) { + return (QueryPartInternal) + other.fields[0].le((Field) fields[0].add(fields[1])).and( + fields[0].le((Field) other.fields[0].add(other.fields[1]))); + } + + // All other OVERLAPS predicates can be simulated simply + else { + return (QueryPartInternal) + other.fields[0].le((Field) fields[1]).and( + fields[0].le((Field) other.fields[1])); + } + } + + // These dialects seem to have trouble with INTERVAL OVERLAPS predicates + else if (intervalOverlaps && asList(HSQLDB).contains(configuration.getDialect())) { + return (QueryPartInternal) + other.fields[0].le((Field) fields[0].add(fields[1])).and( + fields[0].le((Field) other.fields[0].add(other.fields[1]))); + } + + // Everyone else can handle OVERLAPS (Postgres, Oracle) + else { + return new Native(); + } + } + + private class Native extends AbstractCondition { + + /** + * Generated UID + */ + private static final long serialVersionUID = -1552476981094856727L; + + @Override + public final void toSQL(RenderContext context) { + context.sql("(") + .sql(TupleImpl.this) + .keyword(" overlaps ") + .sql(other) + .sql(")"); + } + + @Override + public final void bind(BindContext context) { + context.bind(TupleImpl.this).bind(other); + } + } + } + private class Compare extends AbstractCondition { /** @@ -815,7 +989,7 @@ implements } @Override - public final void bind(BindContext context) throws DataAccessException { + public final void bind(BindContext context) { delegate(context).bind(context); } @@ -874,7 +1048,7 @@ implements } @Override - public final void bind(BindContext context) throws DataAccessException { + public final void bind(BindContext context) { context.bind(TupleImpl.this).bind(other); } } @@ -901,7 +1075,7 @@ implements } @Override - public final void bind(BindContext context) throws DataAccessException { + public final void bind(BindContext context) { delegate(context).bind(context); } @@ -944,7 +1118,7 @@ implements } @Override - public final void bind(BindContext context) throws DataAccessException { + public final void bind(BindContext context) { context.bind(TupleImpl.this).bind((QueryPart) other); } @@ -986,7 +1160,7 @@ implements } @Override - public final void bind(BindContext context) throws DataAccessException { + public final void bind(BindContext context) { context.bind(TupleImpl.this).bind(other); } } diff --git a/jOOQ/src/test/java/org/jooq/test/jOOQTest.java b/jOOQ/src/test/java/org/jooq/test/jOOQTest.java index 6abaa6d87b..3ef3db949e 100644 --- a/jOOQ/src/test/java/org/jooq/test/jOOQTest.java +++ b/jOOQ/src/test/java/org/jooq/test/jOOQTest.java @@ -100,6 +100,15 @@ import org.jooq.SelectQuery; import org.jooq.SimpleSelectQuery; import org.jooq.Table; import org.jooq.Truncate; +import org.jooq.Tuple1; +import org.jooq.Tuple2; +import org.jooq.Tuple3; +import org.jooq.Tuple4; +import org.jooq.Tuple5; +import org.jooq.Tuple6; +import org.jooq.Tuple7; +import org.jooq.Tuple8; +import org.jooq.TupleN; import org.jooq.UpdateQuery; import org.jooq.conf.RenderKeywordStyle; import org.jooq.conf.RenderNameStyle; @@ -595,24 +604,91 @@ public class jOOQTest { @Test public void testTuples() throws Exception { - assertEquals("(?)", r_ref().render(tuple(1))); - assertEquals("(1)", r_refI().render(tuple(1))); - assertEquals("(?, ?)", r_ref().render(tuple(1, "2"))); - assertEquals("(1, '2')", r_refI().render(tuple(1, "2"))); - assertEquals("(?, ?, ?)", r_ref().render(tuple(1, "2", 3))); - assertEquals("(1, '2', 3)", r_refI().render(tuple(1, "2", 3))); - assertEquals("(?, ?, ?, ?)", r_ref().render(tuple(1, "2", 3, "4"))); - assertEquals("(1, '2', 3, '4')", r_refI().render(tuple(1, "2", 3, "4"))); - assertEquals("(?, ?, ?, ?, ?)", r_ref().render(tuple(1, "2", 3, "4", 5))); - assertEquals("(1, '2', 3, '4', 5)", r_refI().render(tuple(1, "2", 3, "4", 5))); - assertEquals("(?, ?, ?, ?, ?, ?)", r_ref().render(tuple(1, "2", 3, "4", 5, "6"))); - assertEquals("(1, '2', 3, '4', 5, '6')", r_refI().render(tuple(1, "2", 3, "4", 5, "6"))); - assertEquals("(?, ?, ?, ?, ?, ?, ?)", r_ref().render(tuple(1, "2", 3, "4", 5, "6", 7))); - assertEquals("(1, '2', 3, '4', 5, '6', 7)", r_refI().render(tuple(1, "2", 3, "4", 5, "6", 7))); - assertEquals("(?, ?, ?, ?, ?, ?, ?, ?)", r_ref().render(tuple(1, "2", 3, "4", 5, "6", 7, "8"))); - assertEquals("(1, '2', 3, '4', 5, '6', 7, '8')", r_refI().render(tuple(1, "2", 3, "4", 5, "6", 7, "8"))); - assertEquals("(?, ?, ?, ?, ?, ?, ?, ?, ?)", r_ref().render(tuple(1, "2", 3, "4", 5, "6", 7, "8", 9))); - assertEquals("(1, '2', 3, '4', 5, '6', 7, '8', 9)", r_refI().render(tuple(1, "2", 3, "4", 5, "6", 7, "8", 9))); + Tuple1 t1 = tuple(1); + Tuple2 t2 = tuple(1, "2"); + Tuple3 t3 = tuple(1, "2", 3); + Tuple4 t4 = tuple(1, "2", 3, "4"); + Tuple5 t5 = tuple(1, "2", 3, "4", 5); + Tuple6 t6 = tuple(1, "2", 3, "4", 5, "6"); + Tuple7 t7 = tuple(1, "2", 3, "4", 5, "6", 7); + Tuple8 t8 = tuple(1, "2", 3, "4", 5, "6", 7, "8"); + TupleN t9 = tuple(1, "2", 3, "4", 5, "6", 7, "8", 9); + + // General info + assertEquals(1, t1.getDegree()); + assertEquals(2, t2.getDegree()); + assertEquals(3, t3.getDegree()); + assertEquals(4, t4.getDegree()); + assertEquals(5, t5.getDegree()); + assertEquals(6, t6.getDegree()); + assertEquals(7, t7.getDegree()); + assertEquals(8, t8.getDegree()); + assertEquals(9, t9.getDegree()); + + // Accessors + assertEquals(val(1), t1.field1()); + + assertEquals(val(1), t2.field1()); + assertEquals(val("2"), t2.field2()); + + assertEquals(val(1), t3.field1()); + assertEquals(val("2"), t3.field2()); + assertEquals(val(3), t3.field3()); + + assertEquals(val(1), t4.field1()); + assertEquals(val("2"), t4.field2()); + assertEquals(val(3), t4.field3()); + assertEquals(val("4"), t4.field4()); + + assertEquals(val(1), t5.field1()); + assertEquals(val("2"), t5.field2()); + assertEquals(val(3), t5.field3()); + assertEquals(val("4"), t5.field4()); + assertEquals(val(5), t5.field5()); + + assertEquals(val(1), t6.field1()); + assertEquals(val("2"), t6.field2()); + assertEquals(val(3), t6.field3()); + assertEquals(val("4"), t6.field4()); + assertEquals(val(5), t6.field5()); + assertEquals(val("6"), t6.field6()); + + assertEquals(val(1), t7.field1()); + assertEquals(val("2"), t7.field2()); + assertEquals(val(3), t7.field3()); + assertEquals(val("4"), t7.field4()); + assertEquals(val(5), t7.field5()); + assertEquals(val("6"), t7.field6()); + assertEquals(val(7), t7.field7()); + + assertEquals(val(1), t8.field1()); + assertEquals(val("2"), t8.field2()); + assertEquals(val(3), t8.field3()); + assertEquals(val("4"), t8.field4()); + assertEquals(val(5), t8.field5()); + assertEquals(val("6"), t8.field6()); + assertEquals(val(7), t8.field7()); + assertEquals(val("8"), t8.field8()); + + // Rendering + assertEquals("(?)", r_ref().render(t1)); + assertEquals("(1)", r_refI().render(t1)); + assertEquals("(?, ?)", r_ref().render(t2)); + assertEquals("(1, '2')", r_refI().render(t2)); + assertEquals("(?, ?, ?)", r_ref().render(t3)); + assertEquals("(1, '2', 3)", r_refI().render(t3)); + assertEquals("(?, ?, ?, ?)", r_ref().render(t4)); + assertEquals("(1, '2', 3, '4')", r_refI().render(t4)); + assertEquals("(?, ?, ?, ?, ?)", r_ref().render(t5)); + assertEquals("(1, '2', 3, '4', 5)", r_refI().render(t5)); + assertEquals("(?, ?, ?, ?, ?, ?)", r_ref().render(t6)); + assertEquals("(1, '2', 3, '4', 5, '6')", r_refI().render(t6)); + assertEquals("(?, ?, ?, ?, ?, ?, ?)", r_ref().render(t7)); + assertEquals("(1, '2', 3, '4', 5, '6', 7)", r_refI().render(t7)); + assertEquals("(?, ?, ?, ?, ?, ?, ?, ?)", r_ref().render(t8)); + assertEquals("(1, '2', 3, '4', 5, '6', 7, '8')", r_refI().render(t8)); + assertEquals("(?, ?, ?, ?, ?, ?, ?, ?, ?)", r_ref().render(t9)); + assertEquals("(1, '2', 3, '4', 5, '6', 7, '8', 9)", r_refI().render(t9)); context.checking(new Expectations() {{ int i = 0; @@ -628,7 +704,7 @@ public class jOOQTest { oneOf(statement).setInt(++i, i); }}); - assertEquals(10, b_ref().bind(tuple(1, "2", 3, "4", 5, "6", 7, "8", 9)).peekIndex()); + assertEquals(10, b_ref().bind(t9).peekIndex()); context.assertIsSatisfied(); }