From f78f4ea64a1d2ae9a0c85536fc518059ba230f0c Mon Sep 17 00:00:00 2001 From: Ryszard-Trojnacki Date: Wed, 18 Mar 2015 10:28:54 +0100 Subject: [PATCH] Added ability to set alias for root table of sql query. --- src/main/java/com/avaje/ebean/Query.java | 5 +++ .../com/avaje/ebeaninternal/api/SpiQuery.java | 5 +++ .../server/query/SqlTreeBuilder.java | 2 +- .../server/querydefn/DefaultOrmQuery.java | 17 +++++++++ .../com/avaje/tests/query/TestQueryAlias.java | 35 +++++++++++++++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/avaje/tests/query/TestQueryAlias.java diff --git a/src/main/java/com/avaje/ebean/Query.java b/src/main/java/com/avaje/ebean/Query.java index 5ab23a0e9..9315cf790 100644 --- a/src/main/java/com/avaje/ebean/Query.java +++ b/src/main/java/com/avaje/ebean/Query.java @@ -1230,4 +1230,9 @@ public interface Query extends Serializable { * Return true if this query has forUpdate set. */ public boolean isForUpdate(); + + /** + * Set root table alias. + */ + public Query alias(String alias); } diff --git a/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java b/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java index a998d4956..7ae485ee6 100644 --- a/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/api/SpiQuery.java @@ -611,4 +611,9 @@ public interface SpiQuery extends Query { * Return true if this query has been cancelled. */ public boolean isCancelled(); + + /** + * Return root table alias set by {@link #alias(String)} command. + */ + public String getAlias(); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java index c70070d49..a9d3cd6fb 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeBuilder.java @@ -104,7 +104,7 @@ public class SqlTreeBuilder { this.queryDetail = query.getDetail(); this.predicates = predicates; - this.alias = new SqlTreeAlias(request.getBeanDescriptor().getBaseTableAlias()); + this.alias = new SqlTreeAlias(request.getQuery().getAlias()==null?request.getBeanDescriptor().getBaseTableAlias():request.getQuery().getAlias()); this.ctx = new DefaultDbSqlContext(alias, tableAliasPlaceHolder, columnAliasPrefix, !subQuery); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java index e31691929..ed042b0fb 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -190,6 +190,11 @@ public class DefaultOrmQuery implements SpiQuery { private boolean autoFetchTuned; private boolean logSecondaryQuery; + + /** + * Root table alias. For {@link Query#alias(String)} command. + */ + private String rootTableAlias=null; /** * The node of the bean or collection that fired lazy loading. Not null if profiling is on and @@ -680,6 +685,7 @@ public class DefaultOrmQuery implements SpiQuery { builder.add(id != null); builder.add(rawSql == null ? 0 : rawSql.queryHash()); builder.add(includeTableJoin != null ? includeTableJoin.queryHash() : 0); + builder.add(rootTableAlias); if (detail != null) { detail.queryPlanHash(request, builder); @@ -1284,6 +1290,17 @@ public class DefaultOrmQuery implements SpiQuery { this.cancelableQuery = cancelableQuery; } } + + @Override + public Query alias(String alias) { + this.rootTableAlias=alias; + return this; + } + + @Override + public String getAlias() { + return rootTableAlias; + } public void cancel() { synchronized (this) { diff --git a/src/test/java/com/avaje/tests/query/TestQueryAlias.java b/src/test/java/com/avaje/tests/query/TestQueryAlias.java new file mode 100644 index 000000000..04e21be76 --- /dev/null +++ b/src/test/java/com/avaje/tests/query/TestQueryAlias.java @@ -0,0 +1,35 @@ +package com.avaje.tests.query; + +import org.junit.Assert; +import org.junit.Test; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.ebean.Query; +import com.avaje.tests.model.basic.CKeyParent; +import com.avaje.tests.model.basic.ResetBasicData; + +public class TestQueryAlias extends BaseTestCase { + @Test + public void testExists() { + ResetBasicData.reset(); + + Query sq = Ebean.createQuery(CKeyParent.class).select("id.oneKey").alias("st0") + .setAutofetch(false).where().query(); + + Query pq = Ebean.find(CKeyParent.class).alias("myt0").where().in("id.oneKey", sq).query(); + + pq.findList(); + + String sql = pq.getGeneratedSql(); + + System.out.println(sql); + // Without alias command is should be: + // select t0.one_key c0, t0.two_key c1, t0.name c2, t0.version c3, t0.assoc_id c4 from ckey_parent t0 where (t0.one_key) in (select t0.one_key from ckey_parent t0) + // but with alias command SQL should look like this: + // select myt0.one_key c0, myt0.two_key c1, myt0.name c2, myt0.version c3, myt0.assoc_id c4 from ckey_parent myt0 where (myt0.one_key) in (select st0.one_key from ckey_parent st0) + + Assert.assertTrue(sql.indexOf("ckey_parent myt0")>0); + Assert.assertTrue(sql.indexOf("in (select st0.one_key from ckey_parent st0)")>0); + } +}