mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Add SpiQuery.Type.defaultSelect() for ATTRIBUTE and sub-query type queries
This commit is contained in:
@@ -84,7 +84,7 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
/**
|
||||
* Find single attribute.
|
||||
*/
|
||||
ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute"),
|
||||
ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute", false, false),
|
||||
|
||||
/**
|
||||
* Find rowCount.
|
||||
@@ -94,12 +94,12 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
/**
|
||||
* A subquery used as part of an exists where clause.
|
||||
*/
|
||||
SQ_EXISTS(FIND_SUBQUERY, "sqExists"),
|
||||
SQ_EXISTS(FIND_SUBQUERY, "sqExists", false, false),
|
||||
|
||||
/**
|
||||
* A subquery used as part of an in where clause.
|
||||
*/
|
||||
SQ_IN(FIND_SUBQUERY, "sqIn"),
|
||||
SQ_IN(FIND_SUBQUERY, "sqIn", false, false),
|
||||
|
||||
/**
|
||||
* Delete query.
|
||||
@@ -112,17 +112,21 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
UPDATE(FIND_UPDATE, "update", true);
|
||||
|
||||
private final boolean update;
|
||||
private final boolean defaultSelect;
|
||||
private final String profileEventId;
|
||||
private final String label;
|
||||
|
||||
Type(String profileEventId, String label) {
|
||||
this(profileEventId, label, false);
|
||||
this(profileEventId, label, false, true);
|
||||
}
|
||||
|
||||
Type(String profileEventId, String label, boolean update) {
|
||||
this(profileEventId, label, update, true);
|
||||
}
|
||||
Type(String profileEventId, String label, boolean update, boolean defaultSelect) {
|
||||
this.profileEventId = profileEventId;
|
||||
this.label = label;
|
||||
this.update = update;
|
||||
this.defaultSelect = defaultSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,6 +136,13 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
return update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this allows default select clause.
|
||||
*/
|
||||
public boolean defaultSelect() {
|
||||
return defaultSelect;
|
||||
}
|
||||
|
||||
public String profileEventId() {
|
||||
return profileEventId;
|
||||
}
|
||||
|
||||
@@ -46,9 +46,7 @@ class CQueryBuilder {
|
||||
private final SqlLimiter sqlLimiter;
|
||||
private final CQueryBuilderRawSql rawSqlHandler;
|
||||
private final Binder binder;
|
||||
|
||||
private final boolean selectCountWithAlias;
|
||||
|
||||
private final CQueryHistorySupport historySupport;
|
||||
private final CQueryDraftSupport draftSupport;
|
||||
private final DatabasePlatform dbPlatform;
|
||||
@@ -79,7 +77,6 @@ class CQueryBuilder {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
|
||||
sb.append(name);
|
||||
sb.append(".");
|
||||
sb.append(token.trim());
|
||||
@@ -91,7 +88,6 @@ class CQueryBuilder {
|
||||
* Build the delete query.
|
||||
*/
|
||||
<T> CQueryUpdate buildUpdateQuery(boolean deleteRequest, OrmQueryRequest<T> request) {
|
||||
|
||||
SpiQuery<T> query = request.getQuery();
|
||||
String rootTableAlias = query.getAlias();
|
||||
query.setupForDeleteOrUpdate();
|
||||
@@ -105,7 +101,6 @@ class CQueryBuilder {
|
||||
}
|
||||
|
||||
predicates.prepare(true);
|
||||
|
||||
SqlTree sqlTree = createSqlTree(request, predicates);
|
||||
|
||||
String sql;
|
||||
@@ -114,7 +109,6 @@ class CQueryBuilder {
|
||||
} else {
|
||||
sql = buildUpdateSql(request, rootTableAlias, predicates, sqlTree);
|
||||
}
|
||||
|
||||
// cache the query plan
|
||||
queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql());
|
||||
request.putQueryPlan(queryPlan);
|
||||
@@ -122,7 +116,6 @@ class CQueryBuilder {
|
||||
}
|
||||
|
||||
private <T> String buildDeleteSql(OrmQueryRequest<T> request, String rootTableAlias, CQueryPredicates predicates, SqlTree sqlTree) {
|
||||
|
||||
String alias = alias(rootTableAlias);
|
||||
if (sqlTree.noJoins() && !request.getQuery().hasMaxRowsOrFirstRow()) {
|
||||
if (dbPlatform.isSupportsDeleteTableAlias()) {
|
||||
@@ -151,7 +144,6 @@ class CQueryBuilder {
|
||||
}
|
||||
|
||||
private <T> String buildUpdateSql(OrmQueryRequest<T> request, String rootTableAlias, CQueryPredicates predicates, SqlTree sqlTree) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(200);
|
||||
sb.append("update ").append(request.getBeanDescriptor().getBaseTable());
|
||||
if (rootTableAlias != null) {
|
||||
@@ -159,7 +151,6 @@ class CQueryBuilder {
|
||||
}
|
||||
sb.append(" set ").append(predicates.getDbUpdateClause());
|
||||
String updateClause = sb.toString();
|
||||
|
||||
if (sqlTree.noJoins() && request.isInlineSqlUpdateLimit()) {
|
||||
// simple - update table set ... where ...
|
||||
return aliasStrip(buildSqlUpdate(updateClause, request, predicates, sqlTree).getSql());
|
||||
@@ -186,7 +177,6 @@ class CQueryBuilder {
|
||||
}
|
||||
|
||||
CQueryFetchSingleAttribute buildFetchAttributeQuery(OrmQueryRequest<?> request) {
|
||||
|
||||
SpiQuery<?> query = request.getQuery();
|
||||
query.setSingleAttribute();
|
||||
if (!query.isIncludeSoftDeletes()) {
|
||||
@@ -218,7 +208,6 @@ class CQueryBuilder {
|
||||
* Build the find ids query.
|
||||
*/
|
||||
<T> CQueryFetchSingleAttribute buildFetchIdsQuery(OrmQueryRequest<T> request) {
|
||||
|
||||
SpiQuery<T> query = request.getQuery();
|
||||
query.setSelectId();
|
||||
BeanDescriptor<T> desc = request.getBeanDescriptor();
|
||||
@@ -246,9 +235,7 @@ class CQueryBuilder {
|
||||
* Build the row count query.
|
||||
*/
|
||||
<T> CQueryRowCount buildRowCountQuery(OrmQueryRequest<T> request) {
|
||||
|
||||
SpiQuery<T> query = request.getQuery();
|
||||
|
||||
// always set the order by to null for row count query
|
||||
query.setOrder(null);
|
||||
query.setFirstRow(0);
|
||||
@@ -310,7 +297,6 @@ class CQueryBuilder {
|
||||
// cache the query plan
|
||||
queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql());
|
||||
request.putQueryPlan(queryPlan);
|
||||
|
||||
return new CQueryRowCount(queryPlan, request, predicates);
|
||||
}
|
||||
|
||||
@@ -334,9 +320,7 @@ class CQueryBuilder {
|
||||
* names to physical deployment column names.
|
||||
*/
|
||||
<T> CQuery<T> buildQuery(OrmQueryRequest<T> request) {
|
||||
|
||||
CQueryPredicates predicates = new CQueryPredicates(binder, request);
|
||||
|
||||
CQueryPlan queryPlan = request.getQueryPlan();
|
||||
if (queryPlan != null) {
|
||||
// Reuse the query plan so skip generating SqlTree and SQL.
|
||||
@@ -370,7 +354,6 @@ class CQueryBuilder {
|
||||
boolean rawSql = request.isRawSql();
|
||||
if (rawSql) {
|
||||
queryPlan = new CQueryPlanRawSql(request, res, sqlTree, predicates.getLogWhereSql());
|
||||
|
||||
} else {
|
||||
queryPlan = new CQueryPlan(request, res, sqlTree, false, predicates.getLogWhereSql());
|
||||
}
|
||||
@@ -380,11 +363,9 @@ class CQueryBuilder {
|
||||
// log the query plan based bean type (i.e. ignoring query disabling for logging the sql/plan)
|
||||
desc.getReadAuditLogger().queryPlan(new ReadAuditQueryPlan(desc.getFullName(), queryPlan.getAuditQueryKey(), queryPlan.getSql()));
|
||||
}
|
||||
|
||||
// cache the query plan because we can reuse it and also
|
||||
// gather query performance statistics based on it.
|
||||
request.putQueryPlan(queryPlan);
|
||||
|
||||
return new CQuery<>(request, predicates, queryPlan);
|
||||
}
|
||||
|
||||
@@ -393,18 +374,15 @@ class CQueryBuilder {
|
||||
* <p>
|
||||
* The SqlTree is immutable after construction and so is safe to use by
|
||||
* concurrent threads.
|
||||
* </p>
|
||||
* <p>
|
||||
* The predicates is used to add additional joins that come from the where or
|
||||
* order by clauses that are not already included for the select clause.
|
||||
* </p>
|
||||
*/
|
||||
private SqlTree createSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates) {
|
||||
return createSqlTree(request, predicates, false);
|
||||
}
|
||||
|
||||
private SqlTree createSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates, boolean forceColumnAlias) {
|
||||
|
||||
if (request.isNativeSql()) {
|
||||
return createNativeSqlTree(request, predicates);
|
||||
}
|
||||
@@ -423,9 +401,7 @@ class CQueryBuilder {
|
||||
* Create the SqlTree by reading the ResultSetMetaData and mapping table/columns to bean property paths.
|
||||
*/
|
||||
private SqlTree createNativeSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates) {
|
||||
|
||||
SpiQuery<?> query = request.getQuery();
|
||||
|
||||
// parse named parameters returning the final sql to execute
|
||||
String sql = predicates.parseBindParams(query.getNativeSql());
|
||||
if (query.hasMaxRowsOrFirstRow()) {
|
||||
@@ -469,10 +445,8 @@ class CQueryBuilder {
|
||||
}
|
||||
|
||||
private SqlTree createRawSqlSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates) {
|
||||
|
||||
BeanDescriptor<?> descriptor = request.getBeanDescriptor();
|
||||
ColumnMapping columnMapping = request.getQuery().getRawSql().getColumnMapping();
|
||||
|
||||
PathProperties pathProps = new PathProperties();
|
||||
|
||||
// convert list of columns into (tree like) PathProperties
|
||||
@@ -498,12 +472,10 @@ class CQueryBuilder {
|
||||
}
|
||||
|
||||
OrmQueryDetail detail = new OrmQueryDetail();
|
||||
|
||||
// transfer PathProperties into OrmQueryDetail
|
||||
for (PathProperties.Props props : pathProps.getPathProps()) {
|
||||
detail.fetch(props.getPath(), props.getProperties());
|
||||
}
|
||||
|
||||
// check if @Id property included in RawSql
|
||||
boolean rawNoId = true;
|
||||
BeanProperty idProperty = descriptor.getIdProperty();
|
||||
@@ -511,7 +483,6 @@ class CQueryBuilder {
|
||||
// contains the @Id property for the root level bean
|
||||
rawNoId = false;
|
||||
}
|
||||
|
||||
// build SqlTree based on OrmQueryDetail of the RawSql
|
||||
return new SqlTreeBuilder(request, predicates, detail, rawNoId).build();
|
||||
}
|
||||
@@ -603,7 +574,6 @@ class CQueryBuilder {
|
||||
private void appendSelect() {
|
||||
if (selectClause != null) {
|
||||
sb.append(selectClause);
|
||||
|
||||
} else {
|
||||
useSqlLimiter = (query.hasMaxRowsOrFirstRow() && select.getManyProperty() == null);
|
||||
if (!useSqlLimiter) {
|
||||
|
||||
@@ -565,8 +565,7 @@ 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.SQ_EXISTS && type != Type.SQ_IN);
|
||||
detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type.defaultSelect());
|
||||
}
|
||||
|
||||
private boolean isAllowOneManyFetch() {
|
||||
@@ -579,7 +578,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public void setDefaultSelectClause() {
|
||||
if (type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN) {
|
||||
if (type.defaultSelect()) {
|
||||
detail.setDefaultSelectClause(beanDescriptor);
|
||||
} else if (!detail.hasSelectClause()) {
|
||||
// explicit empty select when single attribute query on non-root fetch path
|
||||
|
||||
Reference in New Issue
Block a user