diff --git a/src/main/java/io/ebeaninternal/server/deploy/DeployParser.java b/src/main/java/io/ebeaninternal/server/deploy/DeployParser.java index e61e5f144..ff693b1ec 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/DeployParser.java +++ b/src/main/java/io/ebeaninternal/server/deploy/DeployParser.java @@ -37,6 +37,8 @@ public abstract class DeployParser { protected int pos; + protected String priorWord; + protected String word; protected char wordTerminator; @@ -45,7 +47,6 @@ public abstract class DeployParser { public abstract String getDeployWord(String expression); - /** * Return the join includes. */ @@ -67,8 +68,14 @@ public abstract class DeployParser { this.sb = new StringBuilder(source.length() + 20); while (nextWord()) { - String deployWord = convertWord(); - sb.append(deployWord); + if (skipWordConvert()) { + sb.append(word); + priorWord = word; + } else { + String deployWord = convertWord(); + sb.append(deployWord); + priorWord = deployWord; + } if (pos < sourceLength) { sb.append(wordTerminator); if (wordTerminator == SINGLE_QUOTE) { @@ -80,6 +87,10 @@ public abstract class DeployParser { return sb.toString(); } + protected boolean skipWordConvert() { + return false; + } + private boolean nextWord() { if (!findWordStart()) { diff --git a/src/main/java/io/ebeaninternal/server/deploy/DeployPropertyParser.java b/src/main/java/io/ebeaninternal/server/deploy/DeployPropertyParser.java index a698b9f9e..108e8f2d7 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/DeployPropertyParser.java +++ b/src/main/java/io/ebeaninternal/server/deploy/DeployPropertyParser.java @@ -14,12 +14,15 @@ import java.util.Set; */ public final class DeployPropertyParser extends DeployParser { + private static final String JOIN = "join"; + + private static final String FROM = "from"; private final BeanDescriptor beanDescriptor; private final Set includes = new HashSet<>(); - public DeployPropertyParser(BeanDescriptor beanDescriptor) { + DeployPropertyParser(BeanDescriptor beanDescriptor) { this.beanDescriptor = beanDescriptor; } @@ -28,6 +31,13 @@ public final class DeployPropertyParser extends DeployParser { return includes; } + /** + * Skip if in raw sql expression with from tableName or join tableName. + */ + protected boolean skipWordConvert() { + return FROM.equalsIgnoreCase(priorWord) || JOIN.equalsIgnoreCase(priorWord); + } + @Override public String getDeployWord(String expression) { ElPropertyDeploy elProp = beanDescriptor.getElPropertyDeploy(expression); diff --git a/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java b/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java index b49f65a59..98fe40941 100644 --- a/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java +++ b/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java @@ -1,6 +1,5 @@ package io.ebeaninternal.server.query; -import io.ebeaninternal.server.rawsql.SpiRawSql; import io.ebeaninternal.api.BindParams; import io.ebeaninternal.api.SpiExpressionList; import io.ebeaninternal.api.SpiQuery; @@ -12,6 +11,7 @@ import io.ebeaninternal.server.expression.DefaultExpressionRequest; import io.ebeaninternal.server.persist.Binder; import io.ebeaninternal.server.querydefn.OrmQueryProperties; import io.ebeaninternal.server.querydefn.OrmUpdateProperties; +import io.ebeaninternal.server.rawsql.SpiRawSql; import io.ebeaninternal.server.type.DataBind; import io.ebeaninternal.server.util.BindParamsParser; import org.slf4j.Logger; @@ -318,15 +318,9 @@ public class CQueryPredicates { } private String parse(String expr, DeployParser deployParser) { - - StringBuilder sb = new StringBuilder(); - if (!isEmpty(expr)) { - if (sb.length() > 0) { - sb.append(" and "); - } - sb.append(deployParser.parse(expr)); - } - return sb.toString(); + if (expr == null) return ""; + if (expr.isEmpty()) return expr; + return deployParser.parse(expr); } private String deriveHaving(DeployParser deployParser) { diff --git a/src/test/java/io/ebeaninternal/server/deploy/DeployPropertyParserTest.java b/src/test/java/io/ebeaninternal/server/deploy/DeployPropertyParserTest.java index a6be2b9f7..1d6a9cafa 100644 --- a/src/test/java/io/ebeaninternal/server/deploy/DeployPropertyParserTest.java +++ b/src/test/java/io/ebeaninternal/server/deploy/DeployPropertyParserTest.java @@ -11,6 +11,11 @@ public class DeployPropertyParserTest extends BaseTestCase { private final BeanDescriptor descriptor = getBeanDescriptor(Customer.class); + @Test + public void from_prefix_expect_unchanged() { + assertThat(parser().parse("(select x from status join status)")).isEqualTo("(select x from status join status)"); + } + @Test public void depth0_path() { assertThat(parser().parse("pre status post")).isEqualTo("pre ${}status post"); diff --git a/src/test/java/org/tests/m2m/softdelete/MsManyA.java b/src/test/java/org/tests/m2m/softdelete/MsManyA.java index 193eb5b0c..0b9cf1f24 100644 --- a/src/test/java/org/tests/m2m/softdelete/MsManyA.java +++ b/src/test/java/org/tests/m2m/softdelete/MsManyA.java @@ -18,6 +18,16 @@ public class MsManyA { @SoftDelete boolean deleted; + /** + * Name clash with M2M intersection table name. + */ + boolean ms_many_a_many_b; + + /** + * Name clash with other side table name. + */ + boolean ms_many_b; + @ManyToMany List manybs;