diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java index 8e716223da..2ed3746ed5 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/ExoticTests.java @@ -40,6 +40,7 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static org.jooq.impl.Factory.avg; import static org.jooq.impl.Factory.count; +import static org.jooq.impl.Factory.field; import static org.jooq.impl.Factory.literal; import static org.jooq.impl.Factory.max; import static org.jooq.impl.Factory.sum; @@ -49,6 +50,7 @@ import static org.jooq.impl.Factory.val; import org.jooq.Field; import org.jooq.Record; import org.jooq.Result; +import org.jooq.Table; import org.jooq.TableRecord; import org.jooq.UpdatableRecord; import org.jooq.test.BaseTest; @@ -208,4 +210,40 @@ extends BaseTest notAllBookStores = + create().select() + .from(TBookStore()) + .where(TBookStore_NAME().notEqual("Buchhandlung im Volkshaus")) + .asTable("not_all_bookstores"); + + Result result = + create().select() + .from(TBookToBookStore() + .divideBy(notAllBookStores) + .on(TBookToBookStore_BOOK_STORE_NAME().equal(notAllBookStores.getField(TBookStore_NAME()))) + .returning(TBookToBookStore_BOOK_ID(), field("'abc'").as("abc"))) + .orderBy(1) + .fetch(); + + assertEquals(asList((Object) 1, "abc"), asList(result.get(0).intoArray())); + assertEquals(asList((Object) 3, "abc"), asList(result.get(1).intoArray())); + } } diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java index 4ce2b2f8ef..060669ded2 100644 --- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java @@ -1345,6 +1345,11 @@ public abstract class jOOQAbstractTest< new ExoticTests(this).testPivotClause(); } + @Test + public void testRelationalDivision() throws Exception { + new ExoticTests(this).testRelationalDivision(); + } + @Test public void testExecuteListenerOnResultQuery() throws Exception { new ExecuteListenerTests(this).testExecuteListenerOnResultQuery(); diff --git a/jOOQ/src/main/java/org/jooq/DivideByOnConditionStep.java b/jOOQ/src/main/java/org/jooq/DivideByOnConditionStep.java new file mode 100644 index 0000000000..aac117dbd6 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/DivideByOnConditionStep.java @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq; + +import org.jooq.impl.Factory; + +/** + * An intermediate type for the construction of a relational division. This type + * can be used as a convenience type for connecting more conditions. + * + * @author Lukas Eder + */ +public interface DivideByOnConditionStep extends DivideByReturningStep { + + /** + * Combine the currently assembled conditions with another one using the + * {@link Operator#AND} operator. + */ + @Support + DivideByOnConditionStep and(Condition condition); + + /** + * Combine the currently assembled conditions with another one using the + * {@link Operator#AND} operator. + *

+ * NOTE: When inserting plain SQL into jOOQ objects, you must + * guarantee syntax integrity. You may also create the possibility of + * malicious SQL injection. Be sure to properly use bind variables and/or + * escape literals when concatenated into SQL clauses! + * + * @see Factory#condition(String) + */ + @Support + DivideByOnConditionStep and(String sql); + + /** + * Combine the currently assembled conditions with another one using the + * {@link Operator#AND} operator. + *

+ * NOTE: When inserting plain SQL into jOOQ objects, you must + * guarantee syntax integrity. You may also create the possibility of + * malicious SQL injection. Be sure to properly use bind variables and/or + * escape literals when concatenated into SQL clauses! + * + * @see Factory#condition(String, Object...) + */ + @Support + DivideByOnConditionStep and(String sql, Object... bindings); + + /** + * Combine the currently assembled conditions with a negated other one using + * the {@link Operator#AND} operator. + */ + @Support + DivideByOnConditionStep andNot(Condition condition); + + /** + * Combine the currently assembled conditions with an EXISTS + * clause using the {@link Operator#AND} operator. + */ + @Support + DivideByOnConditionStep andExists(Select select); + + /** + * Combine the currently assembled conditions with a NOT EXISTS + * clause using the {@link Operator#AND} operator. + */ + @Support + DivideByOnConditionStep andNotExists(Select select); + + /** + * Combine the currently assembled conditions with another one using the + * {@link Operator#OR} operator. + */ + @Support + DivideByOnConditionStep or(Condition condition); + + /** + * Combine the currently assembled conditions with another one using the + * {@link Operator#OR} operator. + *

+ * NOTE: When inserting plain SQL into jOOQ objects, you must + * guarantee syntax integrity. You may also create the possibility of + * malicious SQL injection. Be sure to properly use bind variables and/or + * escape literals when concatenated into SQL clauses! + * + * @see Factory#condition(String) + */ + @Support + DivideByOnConditionStep or(String sql); + + /** + * Combine the currently assembled conditions with another one using the + * {@link Operator#OR} operator. + *

+ * NOTE: When inserting plain SQL into jOOQ objects, you must + * guarantee syntax integrity. You may also create the possibility of + * malicious SQL injection. Be sure to properly use bind variables and/or + * escape literals when concatenated into SQL clauses! + * + * @see Factory#condition(String, Object...) + */ + @Support + DivideByOnConditionStep or(String sql, Object... bindings); + + /** + * Combine the currently assembled conditions with a negated other one using + * the {@link Operator#OR} operator. + */ + @Support + DivideByOnConditionStep orNot(Condition condition); + + /** + * Combine the currently assembled conditions with an EXISTS + * clause using the {@link Operator#OR} operator. + */ + @Support + DivideByOnConditionStep orExists(Select select); + + /** + * Combine the currently assembled conditions with a NOT EXISTS + * clause using the {@link Operator#OR} operator. + */ + @Support + DivideByOnConditionStep orNotExists(Select select); +} diff --git a/jOOQ/src/main/java/org/jooq/DivideByOnStep.java b/jOOQ/src/main/java/org/jooq/DivideByOnStep.java new file mode 100644 index 0000000000..b9d03d4a2c --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/DivideByOnStep.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq; + +import org.jooq.impl.Factory; + +/** + * An intermediate type for the construction of a relational division + * + * @author Lukas Eder + */ +public interface DivideByOnStep { + + /** + * Add a division condition to the DIVIDE BY clause + */ + @Support + DivideByOnConditionStep on(Condition... conditions); + + /** + * Add a division condition to the DIVIDE BY clause + *

+ * NOTE: When inserting plain SQL into jOOQ objects, you must + * guarantee syntax integrity. You may also create the possibility of + * malicious SQL injection. Be sure to properly use bind variables and/or + * escape literals when concatenated into SQL clauses! + * + * @see Factory#condition(String) + */ + @Support + DivideByOnConditionStep on(String sql); + + /** + * Add a division condition to the DIVIDE BY clause + *

+ * NOTE: When inserting plain SQL into jOOQ objects, you must + * guarantee syntax integrity. You may also create the possibility of + * malicious SQL injection. Be sure to properly use bind variables and/or + * escape literals when concatenated into SQL clauses! + * + * @see Factory#condition(String, Object...) + */ + @Support + DivideByOnConditionStep on(String sql, Object... bindings); +} diff --git a/jOOQ/src/main/java/org/jooq/DivideByReturningStep.java b/jOOQ/src/main/java/org/jooq/DivideByReturningStep.java new file mode 100644 index 0000000000..9fa1d8797f --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/DivideByReturningStep.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq; + +import java.util.Collection; + +/** + * An intermediate type for the construction of a relational division + * + * @author Lukas Eder + */ +public interface DivideByReturningStep { + + /** + * Specify the fields that you want the division to return from the dividend + */ + @Support + Table returning(Field... fields); + + /** + * Specify the fields that you want the division to return from the dividend + */ + @Support + Table returning(Collection> fields); +} diff --git a/jOOQ/src/main/java/org/jooq/Table.java b/jOOQ/src/main/java/org/jooq/Table.java index 583cb42b1a..66a4cb785d 100644 --- a/jOOQ/src/main/java/org/jooq/Table.java +++ b/jOOQ/src/main/java/org/jooq/Table.java @@ -132,6 +132,55 @@ public interface Table extends Type, AliasProvider @Support({ ORACLE }) PivotForStep pivot(Collection> aggregateFunctions); + /** + * Create a new TABLE reference from this table, applying + * relational division. + *

+ * Relational division is the inverse of a cross join operation. The + * following is an approximate definition of a relational division: + *

+     * Assume the following cross join / cartesian product
+     * C = A × B
+     *
+     * Then it can be said that
+     * A = C ÷ B
+     * B = C ÷ A
+     * 
+ *

+ * With jOOQ, you can simplify using relational divisions by using the + * following syntax:

+     * C.divideBy(B).on(C.ID.equal(B.C_ID)).returning(C.TEXT)
+     * 
+ *

+ * The above roughly translates to

+     * SELECT DISTINCT C.TEXT FROM C "c1"
+     * WHERE NOT EXISTS (
+     *   SELECT 1 FROM B
+     *   WHERE NOT EXISTS (
+     *     SELECT 1 FROM C "c2"
+     *     WHERE "c2".TEXT = "c1".TEXT
+     *     AND "c2".ID = B.C_ID
+     *   )
+     * )
+     * 
+ *

+ * Or in plain text: Find those TEXT values in C whose ID's correspond to + * all ID's in B. + *

+ * For more information about relational division and some nice, real-life + * examples, see + *

+ *

+ * This has been observed to work with all dialects + */ + DivideByOnStep divideBy(Table divisor); + /** * INNER JOIN a table to this table. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java index 0b1acdff33..e714e4fd94 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java @@ -43,6 +43,7 @@ import java.util.Collections; import java.util.List; import org.jooq.DataType; +import org.jooq.DivideByOnStep; import org.jooq.Field; import org.jooq.ForeignKey; import org.jooq.Identity; @@ -71,7 +72,7 @@ abstract class AbstractTable extends AbstractType implement } // ------------------------------------------------------------------------ - // TableLike API + // XXX: TableLike API // ------------------------------------------------------------------------ @Override @@ -85,7 +86,7 @@ abstract class AbstractTable extends AbstractType implement } // ------------------------------------------------------------------------ - // Table API + // XXX: Table API // ------------------------------------------------------------------------ /** @@ -137,7 +138,7 @@ abstract class AbstractTable extends AbstractType implement } // ------------------------------------------------------------------------ - // PIVOT API + // XXX: PIVOT API // ------------------------------------------------------------------------ @Override @@ -151,7 +152,16 @@ abstract class AbstractTable extends AbstractType implement } // ------------------------------------------------------------------------ - // JOIN API + // XXX: DIVISION API + // ------------------------------------------------------------------------ + + @Override + public final DivideByOnStep divideBy(Table divisor) { + return new DivideBy(this, divisor); + } + + // ------------------------------------------------------------------------ + // XXX: JOIN API // ------------------------------------------------------------------------ @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/DivideBy.java b/jOOQ/src/main/java/org/jooq/impl/DivideBy.java new file mode 100644 index 0000000000..67c4bc0b04 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/DivideBy.java @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq.impl; + +import static org.jooq.impl.Factory.condition; +import static org.jooq.impl.Factory.exists; +import static org.jooq.impl.Factory.notExists; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.jooq.Attachable; +import org.jooq.BindContext; +import org.jooq.Condition; +import org.jooq.ConditionProvider; +import org.jooq.Configuration; +import org.jooq.DivideByOnConditionStep; +import org.jooq.DivideByOnStep; +import org.jooq.Field; +import org.jooq.Operator; +import org.jooq.Record; +import org.jooq.RenderContext; +import org.jooq.Select; +import org.jooq.Table; + +/** + * @author Lukas Eder + */ +class DivideBy +extends AbstractTable +implements + DivideByOnStep, + DivideByOnConditionStep { + + /** + * Generated UID + */ + private static final long serialVersionUID = -4999896035630325449L; + + private final Table dividend; + private final Table divisor; + private final ConditionProviderImpl condition; + private final FieldList returning; + + DivideBy(Table dividend, Table divisor) { + super("division"); + + this.dividend = dividend; + this.divisor = divisor; + + this.condition = new ConditionProviderImpl(); + this.returning = new FieldList(); + } + + // ------------------------------------------------------------------------ + // XXX: Table API + // ------------------------------------------------------------------------ + + @Override + public final Class getRecordType() { + return RecordImpl.class; + } + + @Override + public final boolean declaresTables() { + return true; + } + + @Override + public final void toSQL(RenderContext context) { + context.sql(table(context)); + } + + @Override + public final void bind(BindContext context) { + context.bind(table(context)); + } + + /** + * Transform the relational division operation into SQL. + *

+ * Various nice examples of how this can be achieved are found here: http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the- + * sql-of-relational-division/ + */ + private final Table table(Configuration configuration) { + Factory create = create(configuration); + + ConditionProviderImpl selfJoin = new ConditionProviderImpl(); + FieldList select = new FieldList(); + Table outer = dividend.as("dividend"); + + for (Field field : returning) { + Field outerField = outer.getField(field); + + // Fields from the RETURNING clause are added AS-IS to the SELECT + // statement, if they're not contained in the dividend table + if (outerField == null) { + select.add(field); + } + + // Fields from the RETURNING clause need proper aliasing if they're + // contained in the dividend table + else { + select.add(outerField); + selfJoin(selfJoin, outer, dividend, field); + } + } + + // Apply relational division using double-nested NOT EXISTS clauses + // There are more efficient ways to express division in SQL, but those + // are hard to simulate with jOOQ + return create.selectDistinct(select) + .from(outer) + .whereNotExists(create + .selectOne() + .from(divisor) + .whereNotExists(create + .selectOne() + .from(dividend) + .where(selfJoin) + .and(condition))) + .asTable(); + } + + /** + * Extracted method for type-safety + */ + private final void selfJoin(ConditionProvider selfJoin, Table outer, Table inner, Field field) { + Field outerField = outer.getField(field); + Field innerField = inner.getField(field); + + if (outerField == null || innerField == null) { + return; + } + else { + selfJoin.addConditions(outerField.equal(innerField)); + } + } + + @Override + public final Table as(String alias) { + return new TableAlias(this, alias, true); + } + + @Override + protected final FieldList getFieldList() { + return new FieldList(); + } + + @Override + protected final List getAttachables0() { + return getAttachables(dividend, divisor, condition, returning); + } + + // ------------------------------------------------------------------------ + // XXX: DivideBy API + // ------------------------------------------------------------------------ + + @Override + public final DivideBy on(Condition... conditions) { + condition.addConditions(conditions); + return this; + } + + @Override + public final DivideBy on(String sql) { + and(sql); + return this; + } + + @Override + public final DivideBy on(String sql, Object... bindings) { + and(sql, bindings); + return this; + } + + @Override + public final DivideBy returning(Field... fields) { + return returning(Arrays.asList(fields)); + } + + @Override + public final DivideBy returning(Collection> fields) { + returning.addAll(fields); + return this; + } + + @Override + public final DivideBy and(Condition c) { + condition.addConditions(c); + return this; + } + + @Override + public final DivideBy and(String sql) { + return and(condition(sql)); + } + + @Override + public final DivideBy and(String sql, Object... bindings) { + return and(condition(sql, bindings)); + } + + @Override + public final DivideBy andNot(Condition c) { + return and(c.not()); + } + + @Override + public final DivideBy andExists(Select select) { + return and(exists(select)); + } + + @Override + public final DivideBy andNotExists(Select select) { + return and(notExists(select)); + } + + @Override + public final DivideBy or(Condition c) { + condition.addConditions(Operator.OR, c); + return this; + } + + @Override + public final DivideBy or(String sql) { + return or(condition(sql)); + } + + @Override + public final DivideBy or(String sql, Object... bindings) { + return or(condition(sql, bindings)); + } + + @Override + public final DivideBy orNot(Condition c) { + return or(c.not()); + } + + @Override + public final DivideBy orExists(Select select) { + return or(exists(select)); + } + + @Override + public final DivideBy orNotExists(Select select) { + return or(notExists(select)); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/Pivot.java b/jOOQ/src/main/java/org/jooq/impl/Pivot.java index c27f7bec54..f886a58b8e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Pivot.java +++ b/jOOQ/src/main/java/org/jooq/impl/Pivot.java @@ -89,7 +89,7 @@ implements } // ------------------------------------------------------------------------ - // Table API + // XXX: Table API // ------------------------------------------------------------------------ @Override @@ -318,7 +318,7 @@ implements } // ------------------------------------------------------------------------ - // Pivot API + // XXX: Pivot API // ------------------------------------------------------------------------ @SuppressWarnings("unchecked")