[#1844] Add Table<Record> Table.join(TableLike<?>, JoinType) to allow

for dynamic joining
This commit is contained in:
Lukas Eder 2012-09-26 22:38:44 +02:00
parent 20d9d02cdc
commit a15c83fc25
8 changed files with 289 additions and 103 deletions

View File

@ -55,6 +55,7 @@ import static org.jooq.impl.Factory.zero;
import java.util.List;
import org.jooq.Field;
import org.jooq.JoinType;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SQLDialect;
@ -277,6 +278,19 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
assertEquals(
asList(1, 2, 1, 2),
result.getValues(0 + TAuthor().getFields().size(), Integer.class));
// [#1844] Cross joins can be achieved by omitting the ON clause, too
assertEquals(8, (int)
create().selectCount()
.from(TAuthor()
.join(TBook(), JoinType.JOIN))
.fetchOne(0, int.class));
assertEquals(8, (int)
create().selectCount()
.from(TAuthor())
.join(TBook(), JoinType.CROSS_JOIN)
.fetchOne(0, int.class));
}
@Test

View File

@ -61,7 +61,7 @@ import org.jooq.impl.Factory;
* -- more than five books in German in the last three years
* -- (from 2011), and sort those authors by last names
* -- limiting results to the second and third row
*
*
* SELECT T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME, COUNT(*)
* FROM T_AUTHOR
* JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
@ -90,15 +90,27 @@ import org.jooq.impl.Factory;
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
*
* @author Lukas Eder
*/
public interface SelectJoinStep extends SelectWhereStep {
/**
* Convenience method to join a table to the last table added to the
* <code>FROM</code> clause using {@link Table#join(TableLike, JoinType)}
* <p>
* Depending on the <code>JoinType</code>, a subsequent
* {@link SelectOnStep#on(Condition...)} or
* {@link SelectOnStep#using(Field...)} clause is required. If it is
* required but omitted, the JOIN clause will be ignored
*/
@Support
SelectOptionalOnStep join(TableLike<?> table, JoinType type);
/**
* Convenience method to <code>INNER JOIN</code> a table to the last table
* added to the <code>FROM</code> clause using {@link Table#join(TableLike)}
*
*
* @see Table#join(TableLike)
*/
@Support
@ -112,7 +124,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#join(String)
*/
@ -128,7 +140,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#join(String, Object...)
*/
@ -144,7 +156,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#join(String, QueryPart...)
*/
@ -162,7 +174,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* A cross join B
* A join B on 1 = 1
* </pre></code>
*
*
* @see Table#crossJoin(TableLike)
*/
@Support
@ -184,7 +196,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#crossJoin(String)
*/
@ -207,7 +219,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#crossJoin(String, Object...)
*/
@ -230,7 +242,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#crossJoin(String, QueryPart...)
*/
@ -241,7 +253,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* Convenience method to <code>LEFT OUTER JOIN</code> a table to the last
* table added to the <code>FROM</code> clause using
* {@link Table#leftOuterJoin(TableLike)}
*
*
* @see Table#leftOuterJoin(TableLike)
*/
@Support
@ -256,7 +268,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#leftOuterJoin(String)
*/
@ -272,7 +284,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#leftOuterJoin(String, Object...)
*/
@ -288,7 +300,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#leftOuterJoin(String, QueryPart...)
*/
@ -301,7 +313,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* {@link Table#rightOuterJoin(TableLike)}
* <p>
* This is only possible where the underlying RDBMS supports it
*
*
* @see Table#rightOuterJoin(TableLike)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -318,7 +330,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#rightOuterJoin(String)
*/
@ -336,7 +348,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#rightOuterJoin(String, Object...)
*/
@ -354,7 +366,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#rightOuterJoin(String, QueryPart...)
*/
@ -367,7 +379,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* {@link Table#fullOuterJoin(TableLike)}
* <p>
* This is only possible where the underlying RDBMS supports it
*
*
* @see Table#fullOuterJoin(TableLike)
*/
@Support({ DB2, FIREBIRD, HSQLDB, INGRES, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -384,7 +396,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#fullOuterJoin(String)
*/
@ -402,7 +414,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#fullOuterJoin(String, Object...)
*/
@ -420,7 +432,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#fullOuterJoin(String, QueryPart...)
*/
@ -434,7 +446,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* <p>
* Natural joins are supported by most RDBMS. If they aren't supported, they
* are simulated if jOOQ has enough information.
*
*
* @see Table#naturalJoin(TableLike)
*/
@Support
@ -452,7 +464,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#naturalJoin(String)
*/
@ -471,7 +483,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#naturalJoin(String, Object...)
*/
@ -490,7 +502,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#naturalJoin(String, QueryPart...)
*/
@ -504,7 +516,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* <p>
* Natural joins are supported by most RDBMS. If they aren't supported, they
* are simulated if jOOQ has enough information.
*
*
* @see Table#naturalLeftOuterJoin(TableLike)
*/
@Support
@ -522,7 +534,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#naturalLeftOuterJoin(String)
*/
@ -541,7 +553,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#naturalLeftOuterJoin(String, Object...)
*/
@ -560,7 +572,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#naturalLeftOuterJoin(String, QueryPart...)
*/
@ -574,7 +586,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* <p>
* Natural joins are supported by most RDBMS. If they aren't supported, they
* are simulated if jOOQ has enough information.
*
*
* @see Table#naturalRightOuterJoin(TableLike)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -592,7 +604,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String)
* @see Table#naturalRightOuterJoin(String)
*/
@ -611,7 +623,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, Object...)
* @see Table#naturalRightOuterJoin(String, Object...)
*/
@ -630,7 +642,7 @@ public interface SelectJoinStep extends SelectWhereStep {
* 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#table(String, QueryPart...)
* @see Table#naturalRightOuterJoin(String, QueryPart...)
*/

View File

@ -0,0 +1,82 @@
/**
* 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;
/**
* This type is used for the {@link Select}'s DSL API when selecting generic
* {@link Record} types.
* <p>
* Example: <code><pre>
* -- get all authors' first and last names, and the number
* -- of books they've written in German, if they have written
* -- more than five books in German in the last three years
* -- (from 2011), and sort those authors by last names
* -- limiting results to the second and third row
*
* SELECT T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME, COUNT(*)
* FROM T_AUTHOR
* JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
* WHERE T_BOOK.LANGUAGE = 'DE'
* AND T_BOOK.PUBLISHED > '2008-01-01'
* GROUP BY T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME
* HAVING COUNT(*) > 5
* ORDER BY T_AUTHOR.LAST_NAME ASC NULLS FIRST
* LIMIT 2
* OFFSET 1
* FOR UPDATE
* OF FIRST_NAME, LAST_NAME
* NO WAIT
* </pre></code> Its equivalent in jOOQ <code><pre>
* create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
* .from(T_AUTHOR)
* .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
* .where(TBook.LANGUAGE.equal("DE"))
* .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
* .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .having(create.count().greaterThan(5))
* .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
* .limit(2)
* .offset(1)
* .forUpdate()
* .of(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
* .noWait();
* </pre></code> Refer to the manual for more details
*
* @author Lukas Eder
*/
public interface SelectOptionalOnStep extends SelectJoinStep, SelectJoinPartitionByStep {
}

View File

@ -57,7 +57,7 @@ import org.jooq.impl.Factory;
/**
* A table to be used in queries
*
*
* @param <R> The record type associated with this table
* @author Lukas Eder
*/
@ -78,7 +78,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
/**
* Create an alias for this table
*
*
* @param alias The alias name
* @return The table alias
*/
@ -101,7 +101,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* <p>
* Note: Unfortunately, this is not supported in the Oracle dialect, where
* identities simulated by triggers cannot be formally detected.
*
*
* @return The table's <code>IDENTITY</code> information, or
* <code>null</code>, if no such information is available.
*/
@ -109,7 +109,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
/**
* Get the list of <code>FOREIGN KEY</code>'s of this table
*
*
* @return This table's <code>FOREIGN KEY</code>'s. This is never
* <code>null</code>.
*/
@ -118,7 +118,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
/**
* Get a list of <code>FOREIGN KEY</code>'s of this table, referencing a
* specific table.
*
*
* @param <O> The other table's record type
* @param other The other table of the foreign key relationship
* @return This table's <code>FOREIGN KEY</code>'s towards an other table.
@ -137,7 +137,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* <li>Other dialects by using some means of simulation (not yet officially
* supported)</li>
* </ul>
*
*
* @param aggregateFunctions The aggregate functions used for pivoting.
* @return A DSL object to create the <code>PIVOT</code> expression
*/
@ -149,7 +149,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* into another form
* <p>
* For more details, see {@link #pivot(Field...)}
*
*
* @param aggregateFunctions The aggregate functions used for pivoting.
* @return A DSL object to create the <code>PIVOT</code> expression
* @see #pivot(Field...)
@ -166,7 +166,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* <code><pre>
* Assume the following cross join / cartesian product
* C = A × B
*
*
* Then it can be said that
* A = C ÷ B
* B = C ÷ A
@ -199,10 +199,12 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* examples, see
* <ul>
* <li><a
* href="http://en.wikipedia.org/wiki/Relational_algebra#Division">http://en.wikipedia.org/wiki/Relational_algebra#Division</a></li>
* href="http://en.wikipedia.org/wiki/Relational_algebra#Division">http
* ://en.wikipedia.org/wiki/Relational_algebra#Division</a></li>
* <li><a href=
* "http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/"
* >http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/</a></li>
* >http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-
* sql-of-relational-division/</a></li>
* </ul>
* <p>
* This has been observed to work with all dialects
@ -210,6 +212,18 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
@Support
DivideByOnStep divideBy(Table<?> divisor);
/**
* Join a table to this table using a {@link JoinType}
* <p>
* Depending on the <code>JoinType</code>, a subsequent
* {@link TableOnStep#on(Condition...)} or
* {@link TableOnStep#using(Field...)} clause is required. If it is required
* but omitted, a {@link Factory#trueCondition()}, i.e. <code>1 = 1</code>
* condition will be rendered
*/
@Support
TableOptionalOnStep join(TableLike<?> table, JoinType type);
/**
* <code>INNER JOIN</code> a table to this table.
*/
@ -223,7 +237,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support
@ -236,7 +250,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support
@ -249,7 +263,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support
@ -268,7 +282,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support
@ -281,7 +295,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support
@ -294,7 +308,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support
@ -317,7 +331,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -332,7 +346,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -347,7 +361,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -370,7 +384,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support({ DB2, FIREBIRD, HSQLDB, INGRES, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -385,7 +399,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support({ DB2, FIREBIRD, HSQLDB, INGRES, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -400,7 +414,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support({ DB2, FIREBIRD, HSQLDB, INGRES, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -433,7 +447,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support
@ -453,7 +467,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support
@ -473,7 +487,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support
@ -498,7 +512,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support
@ -514,7 +528,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support
@ -530,7 +544,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support
@ -555,7 +569,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support
@ -571,7 +585,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support
@ -587,7 +601,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support
@ -612,7 +626,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -628,7 +642,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, Object...)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })
@ -644,7 +658,7 @@ public interface Table<R extends Record> extends org.jooq.Type<R>, AliasProvider
* 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#table(String, QueryPart...)
*/
@Support({ ASE, CUBRID, DB2, DERBY, FIREBIRD, H2, HSQLDB, INGRES, MYSQL, ORACLE, POSTGRES, SQLSERVER, SYBASE })

View File

@ -0,0 +1,48 @@
/**
* 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;
/**
* An intermediate type for the construction of a <code>JOIN</code> clause,
* where there may optionally be a join criteria added using an <code>ON</code>
* clause (with a {@link Condition}), or using a <code>USING</code> clause (with
* a list of {@link Field})
*
* @author Lukas Eder
*/
public interface TableOptionalOnStep extends TablePartitionByStep, Table<Record> {
}

View File

@ -56,6 +56,7 @@ import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.TableLike;
import org.jooq.TableOnStep;
import org.jooq.TableOptionalOnStep;
import org.jooq.TablePartitionByStep;
abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQueryPart<R> implements Table<R> {
@ -185,9 +186,14 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
// XXX: JOIN API
// ------------------------------------------------------------------------
@Override
public TableOptionalOnStep join(TableLike<?> table, JoinType type) {
return new JoinTable(this, table, type);
}
@Override
public final TableOnStep join(TableLike<?> table) {
return new JoinTable(this, table, JoinType.JOIN);
return join(table, JoinType.JOIN);
}
@Override
@ -207,7 +213,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final TablePartitionByStep leftOuterJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.LEFT_OUTER_JOIN);
return join(table, JoinType.LEFT_OUTER_JOIN);
}
@Override
@ -227,7 +233,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final TablePartitionByStep rightOuterJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.RIGHT_OUTER_JOIN);
return join(table, JoinType.RIGHT_OUTER_JOIN);
}
@Override
@ -247,7 +253,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final TableOnStep fullOuterJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.FULL_OUTER_JOIN);
return join(table, JoinType.FULL_OUTER_JOIN);
}
@Override
@ -267,7 +273,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final Table<Record> crossJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.CROSS_JOIN);
return join(table, JoinType.CROSS_JOIN);
}
@Override
@ -287,7 +293,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final Table<Record> naturalJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.NATURAL_JOIN);
return join(table, JoinType.NATURAL_JOIN);
}
@Override
@ -307,7 +313,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final Table<Record> naturalLeftOuterJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.NATURAL_LEFT_OUTER_JOIN);
return join(table, JoinType.NATURAL_LEFT_OUTER_JOIN);
}
@Override
@ -327,7 +333,7 @@ abstract class AbstractTable<R extends Record> extends AbstractFieldProviderQuer
@Override
public final Table<Record> naturalRightOuterJoin(TableLike<?> table) {
return new JoinTable(this, table, JoinType.NATURAL_RIGHT_OUTER_JOIN);
return join(table, JoinType.NATURAL_RIGHT_OUTER_JOIN);
}
@Override

View File

@ -73,7 +73,7 @@ import org.jooq.TableField;
import org.jooq.TableLike;
import org.jooq.TableOnConditionStep;
import org.jooq.TableOnStep;
import org.jooq.TablePartitionByStep;
import org.jooq.TableOptionalOnStep;
import org.jooq.exception.DataAccessException;
/**
@ -81,7 +81,7 @@ import org.jooq.exception.DataAccessException;
*
* @author Lukas Eder
*/
class JoinTable extends AbstractTable<Record> implements TableOnConditionStep, TablePartitionByStep {
class JoinTable extends AbstractTable<Record> implements TableOptionalOnStep, TableOnConditionStep {
/**
* Generated UID

View File

@ -57,11 +57,11 @@ import org.jooq.SelectConditionStep;
import org.jooq.SelectConnectByConditionStep;
import org.jooq.SelectForUpdateOfStep;
import org.jooq.SelectHavingConditionStep;
import org.jooq.SelectJoinPartitionByStep;
import org.jooq.SelectJoinStep;
import org.jooq.SelectOffsetStep;
import org.jooq.SelectOnConditionStep;
import org.jooq.SelectOnStep;
import org.jooq.SelectOptionalOnStep;
import org.jooq.SelectQuery;
import org.jooq.SelectSelectStep;
import org.jooq.SortField;
@ -79,7 +79,7 @@ class SelectImpl extends AbstractDelegatingSelect<Record> implements
// Cascading interface implementations for Select behaviour
SelectSelectStep,
SelectJoinPartitionByStep,
SelectOptionalOnStep,
SelectOnConditionStep,
SelectConditionStep,
SelectConnectByConditionStep,
@ -689,59 +689,69 @@ class SelectImpl extends AbstractDelegatingSelect<Record> implements
@Override
public final SelectImpl join(TableLike<?> table) {
return join0(table, JoinType.JOIN);
return join(table, JoinType.JOIN);
}
@Override
public final SelectImpl leftOuterJoin(TableLike<?> table) {
return join0(table, JoinType.LEFT_OUTER_JOIN);
return join(table, JoinType.LEFT_OUTER_JOIN);
}
@Override
public final SelectImpl rightOuterJoin(TableLike<?> table) {
return join0(table, JoinType.RIGHT_OUTER_JOIN);
return join(table, JoinType.RIGHT_OUTER_JOIN);
}
@Override
public final SelectOnStep fullOuterJoin(TableLike<?> table) {
return join0(table, JoinType.FULL_OUTER_JOIN);
return join(table, JoinType.FULL_OUTER_JOIN);
}
private final SelectImpl join0(TableLike<?> table, JoinType type) {
conditionStep = ConditionStep.ON;
joinTable = table;
joinType = type;
joinPartitionBy = null;
joinConditions = null;
return this;
@Override
public final SelectImpl join(TableLike<?> table, JoinType type) {
switch (type) {
case CROSS_JOIN:
case NATURAL_JOIN:
case NATURAL_LEFT_OUTER_JOIN:
case NATURAL_RIGHT_OUTER_JOIN: {
getQuery().addJoin(table, type);
joinTable = null;
joinPartitionBy = null;
joinType = null;
return this;
}
default: {
conditionStep = ConditionStep.ON;
joinTable = table;
joinType = type;
joinPartitionBy = null;
joinConditions = null;
return this;
}
}
}
@Override
public final SelectJoinStep crossJoin(TableLike<?> table) {
return simpleJoin0(table, JoinType.CROSS_JOIN);
return join(table, JoinType.CROSS_JOIN);
}
@Override
public final SelectImpl naturalJoin(TableLike<?> table) {
return simpleJoin0(table, JoinType.NATURAL_JOIN);
return join(table, JoinType.NATURAL_JOIN);
}
@Override
public final SelectImpl naturalLeftOuterJoin(TableLike<?> table) {
return simpleJoin0(table, JoinType.NATURAL_LEFT_OUTER_JOIN);
return join(table, JoinType.NATURAL_LEFT_OUTER_JOIN);
}
@Override
public final SelectImpl naturalRightOuterJoin(TableLike<?> table) {
return simpleJoin0(table, JoinType.NATURAL_RIGHT_OUTER_JOIN);
}
private final SelectImpl simpleJoin0(TableLike<?> table, JoinType type) {
getQuery().addJoin(table, type);
joinTable = null;
joinPartitionBy = null;
joinType = null;
return this;
return join(table, JoinType.NATURAL_RIGHT_OUTER_JOIN);
}
@Override