mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1100 - Refactor OrmQueryPlanKey to use string expression for where
This commit is contained in:
@@ -35,7 +35,7 @@ public class BindParams implements Serializable {
|
||||
* Bind hash and count used to detect when the bind values have changed such
|
||||
* that the generated SQL (with named parameters) needs to be recalculated.
|
||||
*/
|
||||
private int[] bindHash;
|
||||
private String bindHash;
|
||||
|
||||
public BindParams() {
|
||||
}
|
||||
@@ -56,32 +56,29 @@ public class BindParams implements Serializable {
|
||||
* taken into account when calculating the query hash.
|
||||
* </p>
|
||||
*/
|
||||
public void buildQueryPlanHash(HashQueryPlanBuilder builder) {
|
||||
int[] vals = calcQueryPlanHash();
|
||||
builder.add(vals[0]).bind(vals[1]);
|
||||
public String calcQueryPlanHash() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
buildQueryPlanHash(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and return a query plan bind hash with total bind count.
|
||||
*/
|
||||
public int[] calcQueryPlanHash() {
|
||||
public void buildQueryPlanHash(StringBuilder builder) {
|
||||
int tempBindCount;
|
||||
int bc = 0;
|
||||
int hc = 92821;
|
||||
for (Param param : positionedParameters) {
|
||||
tempBindCount = param.queryBindCount();
|
||||
bc += tempBindCount;
|
||||
hc = hc * 92821 + tempBindCount;
|
||||
builder.append("p").append(bc).append(" ?:").append(tempBindCount).append(",");
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Param> entry : namedParameters.entrySet()) {
|
||||
tempBindCount = entry.getValue().queryBindCount();
|
||||
bc += tempBindCount;
|
||||
hc = hc * 92821 + entry.getKey().hashCode();
|
||||
hc = hc * 92821 + tempBindCount;
|
||||
builder.append("n").append(bc).append(" k:").append(entry.getKey()).append(" ?:").append(tempBindCount).append(",");
|
||||
}
|
||||
|
||||
return new int[]{hc, bc};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,9 +274,9 @@ public class BindParams implements Serializable {
|
||||
bindHash = calcQueryPlanHash();
|
||||
return false;
|
||||
}
|
||||
int[] oldPlan = bindHash;
|
||||
String oldPlan = bindHash;
|
||||
bindHash = calcQueryPlanHash();
|
||||
return bindHash[0] == oldPlan[0] && bindHash[1] == oldPlan[1];
|
||||
return bindHash.equals(oldPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,18 +48,13 @@ public interface SpiExpression extends Expression {
|
||||
* from an AutoTune perspective and get different tuning.
|
||||
* </p>
|
||||
*/
|
||||
void queryPlanHash(HashQueryPlanBuilder builder);
|
||||
void queryPlanHash(StringBuilder builder);
|
||||
|
||||
/**
|
||||
* Return the hash value for the values that will be bound.
|
||||
*/
|
||||
int queryBindHash();
|
||||
|
||||
/**
|
||||
* Return true if the expression is the same without taking into account bind values.
|
||||
*/
|
||||
boolean isSameByPlan(SpiExpression other);
|
||||
|
||||
/**
|
||||
* Return true if the expression is the same with respect to bind values.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
|
||||
@@ -12,7 +11,7 @@ import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
*/
|
||||
public abstract class AbstractTextExpression extends AbstractExpression {
|
||||
|
||||
protected AbstractTextExpression(String propName) {
|
||||
AbstractTextExpression(String propName) {
|
||||
super(propName);
|
||||
}
|
||||
|
||||
@@ -33,7 +32,7 @@ public abstract class AbstractTextExpression extends AbstractExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
// do nothing, only execute against document store
|
||||
}
|
||||
|
||||
@@ -42,12 +41,6 @@ public abstract class AbstractTextExpression extends AbstractExpression {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
// do not compare by plan / bind values (this way)
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
// do not compare by plan / bind values (this way)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -105,16 +104,21 @@ class AllEqualsExpression extends NonPrepareExpression {
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
|
||||
builder.add(AllEqualsExpression.class);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
|
||||
builder.append("AllEquals[");
|
||||
for (Entry<String, Object> entry : propMap.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
String propName = entry.getKey();
|
||||
builder.add(propName).add(value == null ? 0 : 1);
|
||||
builder.bindIfNotNull(value);
|
||||
builder.append(propName);
|
||||
if (value == null) {
|
||||
builder.append(" isNull");
|
||||
} else {
|
||||
builder.append(" =?");
|
||||
}
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,16 +132,6 @@ class AllEqualsExpression extends NonPrepareExpression {
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof AllEqualsExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AllEqualsExpression that = (AllEqualsExpression) other;
|
||||
return isSameByValue(that, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
if (!(other instanceof AllEqualsExpression)) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
|
||||
@@ -15,7 +14,7 @@ public class ArrayContainsExpression extends AbstractExpression {
|
||||
|
||||
private final Object[] values;
|
||||
|
||||
protected ArrayContainsExpression(String propName, boolean contains, Object... values) {
|
||||
ArrayContainsExpression(String propName, boolean contains, Object... values) {
|
||||
super(propName);
|
||||
this.contains = contains;
|
||||
this.values = values;
|
||||
@@ -43,9 +42,10 @@ public class ArrayContainsExpression extends AbstractExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(ArrayContainsExpression.class).add(propName).add(contains);
|
||||
builder.bind(values.length);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("ArrayContains[").append(propName)
|
||||
.append(" b:").append(contains)
|
||||
.append(" ?:").append(values.length).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,17 +57,6 @@ public class ArrayContainsExpression extends AbstractExpression {
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof ArrayContainsExpression)) {
|
||||
return false;
|
||||
}
|
||||
ArrayContainsExpression that = (ArrayContainsExpression) other;
|
||||
return this.propName.equals(that.propName)
|
||||
&& this.contains == that.contains
|
||||
&& this.values.length == that.values.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
ArrayContainsExpression that = (ArrayContainsExpression) other;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
|
||||
@@ -13,7 +12,7 @@ public class ArrayIsEmptyExpression extends AbstractExpression {
|
||||
|
||||
private final boolean empty;
|
||||
|
||||
protected ArrayIsEmptyExpression(String propName, boolean empty) {
|
||||
ArrayIsEmptyExpression(String propName, boolean empty) {
|
||||
super(propName);
|
||||
this.empty = empty;
|
||||
}
|
||||
@@ -24,8 +23,13 @@ public class ArrayIsEmptyExpression extends AbstractExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(ArrayIsEmptyExpression.class).add(propName);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
if (empty) {
|
||||
builder.append("ArrayIsEmpty[");
|
||||
} else {
|
||||
builder.append("ArrayIsNotEmpty[");
|
||||
}
|
||||
builder.append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,15 +37,6 @@ public class ArrayIsEmptyExpression extends AbstractExpression {
|
||||
return empty ? 0 : 92821;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof ArrayIsEmptyExpression)) {
|
||||
return false;
|
||||
}
|
||||
ArrayIsEmptyExpression that = (ArrayIsEmptyExpression) other;
|
||||
return this.propName.equals(that.propName) && this.empty == that.empty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
|
||||
@@ -41,14 +40,12 @@ class BetweenExpression extends AbstractExpression {
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request) {
|
||||
|
||||
request.append(propName).append(BETWEEN).append(" ? and ? ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(BetweenExpression.class).add(propName);
|
||||
builder.bind(2);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Between[").append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,16 +55,6 @@ class BetweenExpression extends AbstractExpression {
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof BetweenExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BetweenExpression that = (BetweenExpression) other;
|
||||
return this.propName.equals(that.propName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
BetweenExpression that = (BetweenExpression) other;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -85,9 +84,8 @@ class BetweenPropertyExpression extends NonPrepareExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(BetweenPropertyExpression.class).add(lowProperty).add(highProperty);
|
||||
builder.bind(1);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("BetweenProperties[").append("low:").append(lowProperty).append(" high:").append(highProperty).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,16 +93,6 @@ class BetweenPropertyExpression extends NonPrepareExpression {
|
||||
return val().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof BetweenPropertyExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BetweenPropertyExpression that = (BetweenPropertyExpression) other;
|
||||
return lowProperty.equals(that.lowProperty) && highProperty.equals(that.highProperty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
BetweenPropertyExpression that = (BetweenPropertyExpression) other;
|
||||
|
||||
+2
-14
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -51,9 +50,8 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(CaseInsensitiveEqualExpression.class).add(propName);
|
||||
builder.bind(1);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Ieq[").append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,16 +59,6 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression {
|
||||
return val().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof CaseInsensitiveEqualExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CaseInsensitiveEqualExpression that = (CaseInsensitiveEqualExpression) other;
|
||||
return this.propName.equals(that.propName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
CaseInsensitiveEqualExpression that = (CaseInsensitiveEqualExpression) other;
|
||||
|
||||
@@ -4,7 +4,6 @@ import io.ebean.ExampleExpression;
|
||||
import io.ebean.LikeType;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -214,12 +213,14 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
* Return a hash for AutoTune query identification.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
|
||||
builder.add(DefaultExampleExpression.class);
|
||||
builder.append("Example[");
|
||||
for (SpiExpression aList : list) {
|
||||
aList.queryPlanHash(builder);
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,24 +235,6 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof DefaultExampleExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultExampleExpression that = (DefaultExampleExpression) other;
|
||||
if (this.list.size() != that.list.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (!list.get(i).isSameByPlan(that.list.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
DefaultExampleExpression that = (DefaultExampleExpression) other;
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.ExpressionFactory;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.FetchPath;
|
||||
import io.ebean.FutureIds;
|
||||
import io.ebean.FutureList;
|
||||
import io.ebean.FutureRowCount;
|
||||
import io.ebean.Junction;
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebean.PagedList;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.QueryIterator;
|
||||
import io.ebean.Version;
|
||||
import io.ebean.*;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebean.search.Match;
|
||||
import io.ebean.search.MultiMatch;
|
||||
import io.ebean.search.TextCommonTerms;
|
||||
import io.ebean.search.TextQueryString;
|
||||
import io.ebean.search.TextSimple;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionList;
|
||||
@@ -559,11 +546,19 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
* values.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(DefaultExpressionList.class);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("List[");
|
||||
if (textRoot) {
|
||||
builder.append("textRoot:true ");
|
||||
}
|
||||
if (allDocNestedPath != null) {
|
||||
builder.append("path:").append(allDocNestedPath).append(" ");
|
||||
}
|
||||
for (SpiExpression aList : list) {
|
||||
aList.queryPlanHash(builder);
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -578,24 +573,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof DefaultExpressionList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultExpressionList<?> that = (DefaultExpressionList<?>) other;
|
||||
if (list.size() != that.list.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0, size = list.size(); i < size; i++) {
|
||||
if (!list.get(i).isSameByPlan(that.list.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
DefaultExpressionList<?> that = (DefaultExpressionList<?>) other;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
@@ -24,7 +23,7 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress
|
||||
|
||||
protected String sql;
|
||||
|
||||
public ExistsQueryExpression(SpiQuery<?> subQuery, boolean not) {
|
||||
ExistsQueryExpression(SpiQuery<?> subQuery, boolean not) {
|
||||
this.subQuery = subQuery;
|
||||
this.not = not;
|
||||
}
|
||||
@@ -74,9 +73,9 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(ExistsQueryExpression.class).add(not);
|
||||
builder.add(sql).add(bindParams.size());
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("ExistsQuery[").append(" not:").append(not);
|
||||
builder.append(" sql:").append(sql).append(" ?:").append(bindParams.size()).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,18 +102,6 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof ExistsQueryExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExistsQueryExpression that = (ExistsQueryExpression) other;
|
||||
return this.sql.equals(that.sql)
|
||||
&& this.not == that.not
|
||||
&& this.bindParams.size() == that.bindParams.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
ExistsQueryExpression that = (ExistsQueryExpression) other;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -68,9 +67,8 @@ class IdExpression extends NonPrepareExpression implements SpiExpression {
|
||||
* No properties so this is just a unique static number.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(IdExpression.class);
|
||||
builder.bind(1);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Id[]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,11 +76,6 @@ class IdExpression extends NonPrepareExpression implements SpiExpression {
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
return other instanceof IdExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
IdExpression that = (IdExpression) other;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -13,7 +12,7 @@ import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Slightly redundant as Query.setId() ultimately also does the same job.
|
||||
* In a collection of Id values.
|
||||
*/
|
||||
public class IdInExpression extends NonPrepareExpression {
|
||||
|
||||
@@ -92,9 +91,8 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
* Incorporates the number of Id values to bind.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(IdInExpression.class).add(idCollection.size());
|
||||
builder.bind(idCollection.size());
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("IdIn[").append("?").append(idCollection.size()).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,16 +100,6 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
return idCollection.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof IdInExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IdInExpression that = (IdInExpression) other;
|
||||
return this.idCollection.size() == that.idCollection.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
IdInExpression that = (IdInExpression) other;
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -115,9 +114,14 @@ class InExpression extends AbstractExpression {
|
||||
* Based on the number of values in the in clause.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(InExpression.class).add(propName).add(bindValues.length).add(not);
|
||||
builder.bind(bindValues.length);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
if (not) {
|
||||
builder.append("NotIn[");
|
||||
} else {
|
||||
builder.append("In[");
|
||||
}
|
||||
builder.append(propName);
|
||||
builder.append(" ?").append(bindValues.length).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,18 +133,6 @@ class InExpression extends AbstractExpression {
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof InExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InExpression that = (InExpression) other;
|
||||
return propName.equals(that.propName)
|
||||
&& not == that.not
|
||||
&& bindValues.length == that.bindValues.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
InExpression that = (InExpression) other;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -57,9 +56,10 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(InQueryExpression.class).add(propName).add(not);
|
||||
builder.add(sql).add(bindParams.size());
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("InQuery[").append(propName)
|
||||
.append(" not:").append(not).append(" sql:").append(sql)
|
||||
.append(" ?:").append(bindParams.size()).append("]");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,19 +96,6 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof InQueryExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InQueryExpression that = (InQueryExpression) other;
|
||||
return propName.equals(that.propName)
|
||||
&& sql.equals(that.sql)
|
||||
&& not == that.not
|
||||
&& bindParams.size() == that.bindParams.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
InQueryExpression that = (InQueryExpression) other;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -94,8 +93,13 @@ class IsEmptyExpression extends AbstractExpression {
|
||||
* Based on the type and propertyName.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(IsEmptyExpression.class).add(propName);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
if (empty) {
|
||||
builder.append("IsEmpty[");
|
||||
} else {
|
||||
builder.append("IsNotEmpty[");
|
||||
}
|
||||
builder.append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,16 +107,6 @@ class IsEmptyExpression extends AbstractExpression {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof IsEmptyExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IsEmptyExpression that = (IsEmptyExpression) other;
|
||||
return this.propName.equals(that.propName) && this.empty == that.empty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
return (other instanceof IsEmptyExpression);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
|
||||
@@ -70,10 +69,16 @@ class JsonPathExpression extends AbstractExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(JsonPathExpression.class).add(propName).add(path).add(operator);
|
||||
builder.bindIfNotNull(value);
|
||||
builder.bindIfNotNull(upperValue);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("JsonPath[");
|
||||
builder.append(propName).append(" path:").append(path).append(" op:").append(operator);
|
||||
if (value != null) {
|
||||
builder.append(" ?1");
|
||||
}
|
||||
if (upperValue != null) {
|
||||
builder.append(" ?2");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,20 +88,6 @@ class JsonPathExpression extends AbstractExpression {
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof JsonPathExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonPathExpression that = (JsonPathExpression) other;
|
||||
return propName.equals(that.propName)
|
||||
&& operator == that.operator
|
||||
&& Same.sameByValue(path, that.path)
|
||||
&& Same.sameByNull(value, that.value)
|
||||
&& Same.sameByNull(upperValue, that.upperValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
JsonPathExpression that = (JsonPathExpression) other;
|
||||
|
||||
@@ -1,24 +1,12 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.FetchPath;
|
||||
import io.ebean.FutureIds;
|
||||
import io.ebean.FutureList;
|
||||
import io.ebean.FutureRowCount;
|
||||
import io.ebean.Junction;
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebean.PagedList;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.QueryIterator;
|
||||
import io.ebean.Version;
|
||||
import io.ebean.*;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebean.search.Match;
|
||||
import io.ebean.search.MultiMatch;
|
||||
import io.ebean.search.TextCommonTerms;
|
||||
import io.ebean.search.TextQueryString;
|
||||
import io.ebean.search.TextSimple;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -194,12 +182,14 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
||||
* Based on Junction type and all the expression contained.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(JunctionExpression.class).add(type);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append(type).append("[");
|
||||
List<SpiExpression> list = exprList.internalList();
|
||||
for (SpiExpression aList : list) {
|
||||
aList.queryPlanHash(builder);
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -212,17 +202,6 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
|
||||
if (!(other instanceof JunctionExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JunctionExpression that = (JunctionExpression) other;
|
||||
return type == that.type && exprList.isSameByPlan(that.exprList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
JunctionExpression that = (JunctionExpression) other;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.LikeType;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -63,9 +62,11 @@ class LikeExpression extends AbstractValueExpression {
|
||||
* Based on caseInsensitive and the property name.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(LikeExpression.class).add(caseInsensitive).add(propName);
|
||||
builder.bind(1);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
if (caseInsensitive){
|
||||
builder.append("I");
|
||||
}
|
||||
builder.append("Like[").append(type).append(" ").append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,18 +74,6 @@ class LikeExpression extends AbstractValueExpression {
|
||||
return strValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof LikeExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LikeExpression that = (LikeExpression) other;
|
||||
return this.propName.equals(that.propName)
|
||||
&& this.caseInsensitive == that.caseInsensitive
|
||||
&& this.type == that.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
LikeExpression that = (LikeExpression) other;
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.expression;
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.Junction;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -137,10 +136,12 @@ abstract class LogicExpression implements SpiExpression {
|
||||
* Based on the joinType plus the two expressions.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(LogicExpression.class).add(joinType);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Logic").append(joinType).append("[");
|
||||
expOne.queryPlanHash(builder);
|
||||
builder.append(",");
|
||||
expTwo.queryPlanHash(builder);
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,19 +151,6 @@ abstract class LogicExpression implements SpiExpression {
|
||||
return hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
|
||||
if (!(other instanceof LogicExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogicExpression that = (LogicExpression) other;
|
||||
return this.joinType.equals(that.joinType)
|
||||
&& this.expOne.isSameByPlan(that.expOne)
|
||||
&& this.expTwo.isSameByPlan(that.expTwo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
LogicExpression that = (LogicExpression) other;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.LikeType;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -50,9 +49,8 @@ class NativeILikeExpression extends AbstractExpression {
|
||||
* Based on caseInsensitive and the property name.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(NativeILikeExpression.class).add(propName);
|
||||
builder.bind(1);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("NativeILike[").append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,16 +58,6 @@ class NativeILikeExpression extends AbstractExpression {
|
||||
return val.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof NativeILikeExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NativeILikeExpression that = (NativeILikeExpression) other;
|
||||
return this.propName.equals(that.propName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
NativeILikeExpression that = (NativeILikeExpression) other;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -58,8 +57,13 @@ class NestedPathWrapperExpression implements SpiExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("NestedPath[");
|
||||
if (nestedPath != null){
|
||||
builder.append("path:").append(nestedPath).append(" ");
|
||||
}
|
||||
delegate.queryPlanHash(builder);
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,16 +71,6 @@ class NestedPathWrapperExpression implements SpiExpression {
|
||||
return delegate.queryBindHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (other instanceof NestedPathWrapperExpression) {
|
||||
NestedPathWrapperExpression that = (NestedPathWrapperExpression) other;
|
||||
return nestedPath.equals(that.nestedPath)
|
||||
&& delegate.isSameByPlan(that.delegate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
return delegate.isSameByBind(other);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -58,8 +57,8 @@ class NoopExpression implements SpiExpression {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(NoopExpression.class);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Noop[]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,11 +77,6 @@ class NoopExpression implements SpiExpression {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
return other instanceof NoopExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
return true;
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -81,9 +80,10 @@ final class NotExpression implements SpiExpression {
|
||||
* Based on the expression.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(NotExpression.class);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Not[");
|
||||
exp.queryPlanHash(builder);
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,15 +91,6 @@ final class NotExpression implements SpiExpression {
|
||||
return exp.queryBindHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof NotExpression)) {
|
||||
return false;
|
||||
}
|
||||
NotExpression that = (NotExpression) other;
|
||||
return exp.isSameByPlan(that.exp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
NotExpression that = (NotExpression) other;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -72,17 +71,6 @@ class NullExpression extends AbstractExpression {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof NullExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NullExpression that = (NullExpression) other;
|
||||
return this.propName.equals(that.propName)
|
||||
&& this.notNull == that.notNull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
// no bind values so always true
|
||||
@@ -93,8 +81,13 @@ class NullExpression extends AbstractExpression {
|
||||
* Based on notNull flag and the propertyName.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(NullExpression.class).add(notNull).add(propName);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
if (notNull) {
|
||||
builder.append("NotNull[");
|
||||
} else {
|
||||
builder.append("Null[");
|
||||
}
|
||||
builder.append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.ManyWhereJoins;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -58,8 +57,12 @@ class RawExpression extends NonPrepareExpression {
|
||||
* Based on the sql.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(RawExpression.class).add(sql);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append("Raw[").append(sql);
|
||||
if (values != null) {
|
||||
builder.append(" ?").append(values.length);
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,15 +70,6 @@ class RawExpression extends NonPrepareExpression {
|
||||
return sql.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof RawExpression)) {
|
||||
return false;
|
||||
}
|
||||
RawExpression that = (RawExpression) other;
|
||||
return sql.equals(that.sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
if (!(other instanceof RawExpression)) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.plugin.ExpressionPath;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -106,9 +105,8 @@ public class SimpleExpression extends AbstractValueExpression {
|
||||
* Based on the type and propertyName.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(SimpleExpression.class).add(propName).add(type.name());
|
||||
builder.bind(1);
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
builder.append(type.name()).append("[").append(propName).append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,16 +114,6 @@ public class SimpleExpression extends AbstractValueExpression {
|
||||
return value().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof SimpleExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleExpression that = (SimpleExpression) other;
|
||||
return this.propName.equals(that.propName) && this.type == that.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
SimpleExpression that = (SimpleExpression) other;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebeaninternal.server.querydefn;
|
||||
|
||||
import io.ebean.FetchConfig;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.el.ElPropertyDeploy;
|
||||
@@ -56,16 +55,10 @@ public class OrmQueryDetail implements Serializable {
|
||||
return copy;
|
||||
}
|
||||
|
||||
public int queryPlanHash() {
|
||||
HashQueryPlanBuilder builder = new HashQueryPlanBuilder();
|
||||
queryPlanHash(builder);
|
||||
return builder.getPlanHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the hash for the query plan.
|
||||
*/
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
baseProps.queryPlanHash(builder);
|
||||
if (fetchPaths != null) {
|
||||
for (OrmQueryProperties p : fetchPaths.values()) {
|
||||
@@ -74,36 +67,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the details are the same for query plan purposes.
|
||||
*/
|
||||
public boolean isSameByPlan(OrmQueryDetail otherDetail) {
|
||||
if (!isSameByPlan(baseProps, otherDetail.baseProps)) {
|
||||
return false;
|
||||
}
|
||||
if (fetchPaths == null) {
|
||||
return otherDetail.fetchPaths == null;
|
||||
}
|
||||
if (fetchPaths.size() != otherDetail.fetchPaths.size()) {
|
||||
return false;
|
||||
}
|
||||
// check with ordering being important
|
||||
Iterator<Map.Entry<String, OrmQueryProperties>> thisIt = fetchPaths.entrySet().iterator();
|
||||
Iterator<Map.Entry<String, OrmQueryProperties>> thatIt = otherDetail.fetchPaths.entrySet().iterator();
|
||||
while (thisIt.hasNext() && thatIt.hasNext()) {
|
||||
Map.Entry<String, OrmQueryProperties> thisEntry = thisIt.next();
|
||||
Map.Entry<String, OrmQueryProperties> thatEntry = thatIt.next();
|
||||
if (!thisEntry.getKey().equals(thatEntry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (!thisEntry.getValue().isSameByPlan(thatEntry.getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if equal in terms of autoTune (select and fetch without property ordering).
|
||||
*/
|
||||
@@ -133,10 +96,6 @@ public class OrmQueryDetail implements Serializable {
|
||||
return p1 == null ? p2 == null : p1.isSameByAutoTune(p2);
|
||||
}
|
||||
|
||||
private boolean isSameByPlan(OrmQueryProperties p1, OrmQueryProperties p2) {
|
||||
return p1 == null ? p2 == null : p1.isSameByPlan(p2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return asString();
|
||||
@@ -312,7 +271,7 @@ public class OrmQueryDetail implements Serializable {
|
||||
public void sortFetchPaths(BeanDescriptor<?> d) {
|
||||
sortFetchPaths(d, true);
|
||||
}
|
||||
|
||||
|
||||
private void sortFetchPaths(BeanDescriptor<?> d, boolean addIds) {
|
||||
|
||||
if (!fetchPaths.isEmpty()) {
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.ebean.Query;
|
||||
import io.ebean.RawSql;
|
||||
import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.CQueryPlanKey;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
@@ -15,16 +14,11 @@ import io.ebeaninternal.server.deploy.TableJoin;
|
||||
*/
|
||||
class OrmQueryPlanKey implements CQueryPlanKey {
|
||||
|
||||
private final SpiExpression where;
|
||||
private final SpiExpression having;
|
||||
private final RawSql.Key rawSqlKey;
|
||||
private final int maxRows;
|
||||
private final int firstRow;
|
||||
private final OrmUpdateProperties updateProperties;
|
||||
|
||||
private final int planHash;
|
||||
private final int bindCount;
|
||||
private final String options;
|
||||
private final String description;
|
||||
|
||||
OrmQueryPlanKey(String discValue, TableJoin m2mIncludeTable, SpiQuery.Type type, OrmQueryDetail detail, int maxRows, int firstRow, boolean disableLazyLoading,
|
||||
OrderBy<?> orderBy, boolean distinct, boolean sqlDistinct, String mapKey, Object id, BindParams bindParams,
|
||||
@@ -68,43 +62,46 @@ class OrmQueryPlanKey implements CQueryPlanKey {
|
||||
if (mapKey != null) {
|
||||
sb.append(",mapKey:").append(mapKey);
|
||||
}
|
||||
this.options = sb.toString();
|
||||
this.maxRows = maxRows;
|
||||
this.firstRow = firstRow;
|
||||
this.where = (whereExpressions == null) ? null : whereExpressions.copyForPlanKey();
|
||||
this.having = (havingExpressions == null) ? null : havingExpressions.copyForPlanKey();
|
||||
this.updateProperties = updateProperties;
|
||||
this.rawSqlKey = (rawSql == null) ? null : rawSql.getKey();
|
||||
|
||||
// exclude bind values and things unrelated to the sql being generated
|
||||
HashQueryPlanBuilder builder = new HashQueryPlanBuilder();
|
||||
builder.add(options.hashCode());
|
||||
builder.add(firstRow).add(maxRows);
|
||||
builder.add(rawSqlKey == null ? 0 : rawSqlKey.hashCode());
|
||||
|
||||
if (detail != null) {
|
||||
detail.queryPlanHash(builder);
|
||||
sb.append(" detail[");
|
||||
detail.queryPlanHash(sb);
|
||||
sb.append("]");
|
||||
}
|
||||
if (bindParams != null) {
|
||||
bindParams.buildQueryPlanHash(builder);
|
||||
sb.append(" bindParams[");
|
||||
bindParams.buildQueryPlanHash(sb);
|
||||
sb.append("]");
|
||||
}
|
||||
if (where != null) {
|
||||
where.queryPlanHash(builder);
|
||||
if (whereExpressions != null) {
|
||||
sb.append(" where[");
|
||||
whereExpressions.queryPlanHash(sb);
|
||||
sb.append("]");
|
||||
}
|
||||
if (having != null) {
|
||||
having.queryPlanHash(builder);
|
||||
if (havingExpressions != null) {
|
||||
sb.append(" having[");
|
||||
havingExpressions.queryPlanHash(sb);
|
||||
sb.append("]");
|
||||
}
|
||||
if (updateProperties != null) {
|
||||
updateProperties.buildQueryPlanHash(builder);
|
||||
sb.append(" update[");
|
||||
updateProperties.buildQueryPlanHash(sb);
|
||||
sb.append("]");
|
||||
}
|
||||
|
||||
this.planHash = builder.getPlanHash();
|
||||
this.bindCount = builder.getBindCount();
|
||||
this.description = sb.toString();
|
||||
int hc = description.hashCode();
|
||||
hc = hc * 92821 + (maxRows);
|
||||
hc = hc * 92821 + (firstRow);
|
||||
this.planHash = hc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPartialKey() {
|
||||
return planHash + "_" + bindCount;
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,14 +116,9 @@ class OrmQueryPlanKey implements CQueryPlanKey {
|
||||
|
||||
OrmQueryPlanKey that = (OrmQueryPlanKey) o;
|
||||
|
||||
if (planHash != that.planHash) return false;
|
||||
if (bindCount != that.bindCount) return false;
|
||||
if (maxRows != that.maxRows) return false;
|
||||
if (firstRow != that.firstRow) return false;
|
||||
if (!options.equals(that.options)) return false;
|
||||
if (where != null ? !where.isSameByPlan(that.where) : that.where != null) return false;
|
||||
if (having != null ? !having.isSameByPlan(that.having) : that.having != null) return false;
|
||||
if (updateProperties != null ? !updateProperties.isSameByPlan(that.updateProperties) : that.updateProperties != null) return false;
|
||||
if (!description.equals(that.description)) return false;
|
||||
return rawSqlKey != null ? rawSqlKey.equals(that.rawSqlKey) : that.rawSqlKey == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,12 @@ import io.ebean.ExpressionFactory;
|
||||
import io.ebean.FetchConfig;
|
||||
import io.ebean.OrderBy;
|
||||
import io.ebean.Query;
|
||||
import io.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import io.ebeaninternal.api.SpiExpression;
|
||||
import io.ebeaninternal.api.SpiExpressionFactory;
|
||||
import io.ebeaninternal.api.SpiExpressionList;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.expression.FilterExprPath;
|
||||
import io.ebeaninternal.server.expression.FilterExpressionList;
|
||||
import io.ebeaninternal.server.expression.Same;
|
||||
import io.ebeaninternal.server.query.SplitName;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -476,33 +474,30 @@ public class OrmQueryProperties implements Serializable {
|
||||
return included.equals(p2.included);
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties are the same for query plan purposes.
|
||||
*/
|
||||
public boolean isSameByPlan(OrmQueryProperties p2) {
|
||||
|
||||
if (!Same.sameByValue(secondaryQueryJoins, p2.secondaryQueryJoins)) return false;
|
||||
if (!Same.sameByValue(included, p2.included)) return false;
|
||||
if (!Same.sameByNull(filterMany, p2.filterMany)) return false;
|
||||
if (filterMany != null && !filterMany.isSameByPlan(p2.filterMany)) return false;
|
||||
|
||||
return fetchConfig.equals(p2.fetchConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the query plan hash.
|
||||
*/
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
public void queryPlanHash(StringBuilder builder) {
|
||||
|
||||
builder.add(path);
|
||||
builder.addOrdered(included);
|
||||
builder.add(secondaryQueryJoins);
|
||||
|
||||
builder.add(filterMany != null);
|
||||
if (filterMany != null) {
|
||||
filterMany.queryPlanHash(builder);
|
||||
builder.append("qpp[");
|
||||
builder.append(path);
|
||||
if (included != null){
|
||||
builder.append(" included:").append(included);
|
||||
}
|
||||
builder.add(fetchConfig.hashCode());
|
||||
if (secondaryQueryJoins != null) {
|
||||
builder.append(" secondary:").append(secondaryQueryJoins);
|
||||
}
|
||||
|
||||
if (filterMany != null) {
|
||||
builder.append(" filterMany[");
|
||||
filterMany.queryPlanHash(builder);
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
if (fetchConfig != null) {
|
||||
builder.append(" config:").append(fetchConfig.hashCode());
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -149,23 +149,14 @@ public class OrmUpdateProperties {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this update has the same logical set clause.
|
||||
*/
|
||||
public boolean isSameByPlan(OrmUpdateProperties that) {
|
||||
return that.values.size() == values.size()
|
||||
&& logicalSetClause().equals(that.logicalSetClause());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the hash for the query plan caching.
|
||||
*/
|
||||
void buildQueryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(OrmUpdateProperties.class);
|
||||
void buildQueryPlanHash(StringBuilder builder) {
|
||||
Set<Map.Entry<String, Value>> entries = values.entrySet();
|
||||
for (Map.Entry<String, Value> entry : entries) {
|
||||
builder.add(entry.getKey());
|
||||
builder.bind(entry.getValue().getBindCount());
|
||||
builder.append("key:").append(entry.getKey());
|
||||
builder.append(" ?:").append(entry.getValue().getBindCount());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user