mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
Distinguish between exists and in subquery
This commit is contained in:
1 parent
12b8b4b955
commit
1a2aba3f56
11 files changed
+37
-18
No files matched your search
@@ -8,6 +8,7 @@ import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
import io.ebeaninternal.server.core.SpiResultSet;
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -149,7 +150,7 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanCollect
|
||||
/**
|
||||
* Compile a query.
|
||||
*/
|
||||
<T> CQuery<T> compileQuery(Query<T> query, Transaction t);
|
||||
<T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t);
|
||||
|
||||
/**
|
||||
* Execute the findId's query but without copying the query.
|
||||
|
||||
@@ -92,9 +92,14 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
COUNT(FIND_COUNT, "findCount"),
|
||||
|
||||
/**
|
||||
* A subquery used as part of a where clause.
|
||||
* A subquery used as part of an exists where clause.
|
||||
*/
|
||||
SUBQUERY(FIND_SUBQUERY, "subquery"),
|
||||
SQ_EXISTS(FIND_SUBQUERY, "sqExists"),
|
||||
|
||||
/**
|
||||
* A subquery used as part of an in where clause.
|
||||
*/
|
||||
SQ_IN(FIND_SUBQUERY, "sqIn"),
|
||||
|
||||
/**
|
||||
* Delete query.
|
||||
|
||||
@@ -526,8 +526,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
* Compile a query. Only valid for ORM queries.
|
||||
*/
|
||||
@Override
|
||||
public <T> CQuery<T> compileQuery(Query<T> query, Transaction t) {
|
||||
SpiOrmQueryRequest<T> qr = createQueryRequest(Type.SUBQUERY, query, t);
|
||||
public <T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t) {
|
||||
SpiOrmQueryRequest<T> qr = createQueryRequest(type, query, t);
|
||||
OrmQueryRequest<T> orm = (OrmQueryRequest<T>) qr;
|
||||
return cqueryEngine.buildQuery(orm);
|
||||
}
|
||||
|
||||
+2
-1
@@ -9,6 +9,7 @@ import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.api.SpiExpressionValidation;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.query.CQuery;
|
||||
|
||||
@@ -82,7 +83,7 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress
|
||||
*/
|
||||
protected CQuery<?> compileSubQuery(BeanQueryRequest<?> queryRequest) {
|
||||
SpiEbeanServer ebeanServer = (SpiEbeanServer) queryRequest.getEbeanServer();
|
||||
return ebeanServer.compileQuery(subQuery, queryRequest.getTransaction());
|
||||
return ebeanServer.compileQuery(Type.SQ_EXISTS, subQuery, queryRequest.getTransaction());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
import io.ebeaninternal.server.query.CQuery;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -69,7 +70,7 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor
|
||||
private CQuery<?> compileSubQuery(BeanQueryRequest<?> queryRequest) {
|
||||
|
||||
SpiEbeanServer ebeanServer = (SpiEbeanServer) queryRequest.getEbeanServer();
|
||||
return ebeanServer.compileQuery(subQuery, queryRequest.getTransaction());
|
||||
return ebeanServer.compileQuery(Type.SQ_IN, subQuery, queryRequest.getTransaction());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -101,6 +101,7 @@ class SqlTree {
|
||||
* Return the String for the actual SQL.
|
||||
*/
|
||||
String getSelectSql() {
|
||||
assert selectSql != null : "selectSql was null";
|
||||
return selectSql;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,11 @@ public final class SqlTreeBuilder {
|
||||
this.query = request.getQuery();
|
||||
this.temporalMode = SpiQuery.TemporalMode.of(query);
|
||||
this.disableLazyLoad = query.isDisableLazyLoading();
|
||||
this.subQuery = Type.SUBQUERY == query.getType() || Type.ID_LIST == query.getType() || Type.DELETE == query.getType() || query.isCountDistinct();
|
||||
this.subQuery = Type.SQ_EXISTS == query.getType()
|
||||
|| Type.SQ_IN == query.getType()
|
||||
|| Type.ID_LIST == query.getType()
|
||||
|| Type.DELETE == query.getType()
|
||||
|| query.isCountDistinct();
|
||||
this.includeJoin = query.getM2mIncludeJoin();
|
||||
this.manyWhereJoins = query.getManyWhereJoins();
|
||||
this.queryDetail = query.getDetail();
|
||||
@@ -146,6 +150,10 @@ public final class SqlTreeBuilder {
|
||||
if (rawSql) {
|
||||
return "Not Used";
|
||||
}
|
||||
if (query.getType() ==Type.SQ_EXISTS) {
|
||||
// effective query is "where exists (select 1 from ...)"
|
||||
return "1";
|
||||
}
|
||||
rootNode.appendSelect(ctx, subQuery);
|
||||
return trimComma(ctx.getContent());
|
||||
}
|
||||
|
||||
@@ -565,7 +565,8 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
* Limit the number of fetch joins to Many properties, mark as query joins as needed.
|
||||
*/
|
||||
private void markQueryJoins() {
|
||||
detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type != Type.ATTRIBUTE && type != Type.SUBQUERY);
|
||||
detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(),
|
||||
type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN);
|
||||
}
|
||||
|
||||
private boolean isAllowOneManyFetch() {
|
||||
@@ -578,7 +579,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public void setDefaultSelectClause() {
|
||||
if (type != Type.ATTRIBUTE && type != Type.SUBQUERY) {
|
||||
if (type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN) {
|
||||
detail.setDefaultSelectClause(beanDescriptor);
|
||||
} else if (!detail.hasSelectClause()) {
|
||||
// explicit empty select when single attribute query on non-root fetch path
|
||||
|
||||
@@ -45,6 +45,7 @@ import io.ebean.plugin.Property;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
import io.ebeaninternal.server.core.SpiResultSet;
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -54,7 +55,6 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Clock;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -256,7 +256,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> CQuery<T> compileQuery(Query<T> query, Transaction t) {
|
||||
public <T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedType(Type genericType) {
|
||||
public boolean isSupportedType(java.lang.reflect.Type genericType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@ public class SqlQueryCancelTest extends BaseTestCase {
|
||||
doCancelOrmAtBegin(Query::findOne);
|
||||
doCancelOrmAtBegin(q -> q.setMaxRows(1000).findPagedList().getList()); // untested
|
||||
doCancelOrmAtBegin(Query::findSet);
|
||||
doCancelOrmAtBegin(Query::findSingleAttribute);
|
||||
doCancelOrmAtBegin(Query::findSingleAttributeList);
|
||||
doCancelOrmAtBegin(q -> q.select("name").findSingleAttribute());
|
||||
doCancelOrmAtBegin(q -> q.select("name").findSingleAttributeList());
|
||||
doCancelOrmAtBegin(Query::findStream);
|
||||
// testDuringRun(Query::findVersions);
|
||||
// EBasic has no history support, but it should work if @History is added
|
||||
@@ -138,8 +138,8 @@ public class SqlQueryCancelTest extends BaseTestCase {
|
||||
// findOne cannot be tested, as H2 does the cancel check every 128 rows only
|
||||
doCancelOrmDuringRun(q -> q.setMaxRows(1000).findPagedList().getList()); // untested
|
||||
doCancelOrmDuringRun(Query::findSet);
|
||||
doCancelOrmDuringRun(Query::findSingleAttribute);
|
||||
doCancelOrmDuringRun(Query::findSingleAttributeList);
|
||||
doCancelOrmDuringRun(q -> q.select("name").findSingleAttribute());
|
||||
doCancelOrmDuringRun(q -> q.select("name").findSingleAttributeList());
|
||||
doCancelOrmDuringRun(Query::findStream);
|
||||
// testDuringRun(Query::findVersions);
|
||||
// EBasic has no history support, but it should work if @History is added
|
||||
|
||||
Reference in new issue
Block a user