[#2086] SQL syntax error when aliasing outcome of a relational division
This commit is contained in:
parent
2dd4517be0
commit
993843ccd6
@ -368,6 +368,25 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
|
||||
assertEquals(asList((Object) 3, "abc"), asList(result.get(1).intoArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasingRelationalDivision() throws Exception {
|
||||
|
||||
// Books and bookstores. There's only one book that is contained in
|
||||
// every bookstore:
|
||||
// ----------------------------------------------------------------
|
||||
Record record =
|
||||
create().select()
|
||||
.from(TBookToBookStore()
|
||||
.divideBy(TBookStore())
|
||||
.on(TBookToBookStore_BOOK_STORE_NAME().equal(TBookStore_NAME()))
|
||||
.returning(TBookToBookStore_BOOK_ID(), TBookToBookStore_BOOK_ID())
|
||||
.as("division", "x", "y"))
|
||||
.fetchOne();
|
||||
|
||||
assertEquals(3, record.getValue("x"));
|
||||
assertEquals(3, record.getValue("y"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectBySimple() throws Exception {
|
||||
switch (getDialect()) {
|
||||
|
||||
@ -1869,6 +1869,11 @@ public abstract class jOOQAbstractTest<
|
||||
new ExoticTests(this).testRelationalDivision();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAliasingRelationalDivision() throws Exception {
|
||||
new ExoticTests(this).testAliasingRelationalDivision();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectBySimple() throws Exception {
|
||||
new ExoticTests(this).testConnectBySimple();
|
||||
|
||||
@ -38,20 +38,19 @@ 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 static org.jooq.impl.Factory.selectDistinct;
|
||||
import static org.jooq.impl.Factory.selectOne;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DivideByOnConditionStep;
|
||||
import org.jooq.DivideByOnStep;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Operator;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.Select;
|
||||
import org.jooq.Table;
|
||||
|
||||
@ -59,24 +58,16 @@ import org.jooq.Table;
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DivideBy
|
||||
extends AbstractTable<Record>
|
||||
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;
|
||||
|
||||
@ -88,26 +79,6 @@ implements
|
||||
// XXX: Table API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final Class<? extends Record> 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.
|
||||
* <p>
|
||||
@ -117,9 +88,7 @@ implements
|
||||
* >http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-
|
||||
* sql-of-relational-division/</a>
|
||||
*/
|
||||
private final Table<?> table(Configuration configuration) {
|
||||
Executor create = create(configuration);
|
||||
|
||||
private final Table<Record> table() {
|
||||
ConditionProviderImpl selfJoin = new ConditionProviderImpl();
|
||||
FieldList select = new FieldList();
|
||||
Table<?> outer = dividend.as("dividend");
|
||||
@ -144,17 +113,17 @@ implements
|
||||
// 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();
|
||||
return selectDistinct(select)
|
||||
.from(outer)
|
||||
.whereNotExists(
|
||||
selectOne()
|
||||
.from(divisor)
|
||||
.whereNotExists(
|
||||
selectOne()
|
||||
.from(dividend)
|
||||
.where(selfJoin)
|
||||
.and(condition)))
|
||||
.asTable();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,21 +142,6 @@ implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<Record> as(String alias) {
|
||||
return new TableAlias<Record>(this, alias, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<Record> as(String alias, String... fieldAliases) {
|
||||
return new TableAlias<Record>(this, alias, fieldAliases, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final FieldList getFieldList() {
|
||||
return new FieldList();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: DivideBy API
|
||||
// ------------------------------------------------------------------------
|
||||
@ -224,7 +178,7 @@ implements
|
||||
@Override
|
||||
public final Table<Record> returning(Collection<? extends Field<?>> fields) {
|
||||
returning.addAll(fields);
|
||||
return this;
|
||||
return table();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
Reference in New Issue
Block a user