diff --git a/querydsl-core/src/main/java/com/mysema/query/support/SerializerBase.java b/querydsl-core/src/main/java/com/mysema/query/support/SerializerBase.java index 12ebf772e..b5cc28d38 100644 --- a/querydsl-core/src/main/java/com/mysema/query/support/SerializerBase.java +++ b/querydsl-core/src/main/java/com/mysema/query/support/SerializerBase.java @@ -321,7 +321,8 @@ public abstract class SerializerBase> implements Vis for (Template.Element element : template.getElements()) { if (element.getStaticText() != null) { append(element.getStaticText()); - } else if (element.isAsString()) { + } else if (element.isAsString() && args.get(element.getIndex()) instanceof Constant) { + // serialize only constants directly appendAsString(args.get(element.getIndex())); } else { int i = element.getIndex(); diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/StringExpression.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/StringExpression.java index a05835aaf..e18847b50 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/StringExpression.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/StringExpression.java @@ -589,6 +589,30 @@ public abstract class StringExpression extends ComparableExpression { public StringExpression substring(int beginIndex, int endIndex) { return StringOperation.create(Ops.SUBSTR_2ARGS, this, ConstantImpl.create(beginIndex), ConstantImpl.create(endIndex)); } + + /** + * Get the given substring + * + * @param beginIndex + * @param endIndex + * @return this.substring(beginIndex, endIndex) + * @see java.lang.String#substring(int, int) + */ + public StringExpression substring(Expression beginIndex, int endIndex) { + return StringOperation.create(Ops.SUBSTR_2ARGS, this, beginIndex, ConstantImpl.create(endIndex)); + } + + /** + * Get the given substring + * + * @param beginIndex + * @param endIndex + * @return this.substring(beginIndex, endIndex) + * @see java.lang.String#substring(int, int) + */ + public StringExpression substring(int beginIndex, Expression endIndex) { + return StringOperation.create(Ops.SUBSTR_2ARGS, this, ConstantImpl.create(beginIndex), endIndex); + } /** * Get the given substring diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java index ace787fa7..a4d73242e 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java @@ -98,8 +98,8 @@ public class JPQLTemplates extends Templates { add(Ops.ENDS_WITH_IC, "{0l} like {%%1} escape '"+escape+"'"); add(Ops.STARTS_WITH, "{0} like {1%} escape '"+escape+"'"); add(Ops.STARTS_WITH_IC, "{0l} like {1%%} escape '"+escape+"'"); - add(Ops.INDEX_OF, "locate({1},{0}) - 1"); - add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2s}+1) - 1"); + add(Ops.INDEX_OF, "locate({1},{0})-1"); + add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2s}+1)-1"); // date time add(Ops.DateTimeOps.SYSDATE, "sysdate"); diff --git a/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java b/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java index ef0f87b18..5401c5c08 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java @@ -73,6 +73,7 @@ import com.mysema.query.jpa.domain.Show; import com.mysema.query.jpa.domain4.QBookMark; import com.mysema.query.jpa.domain4.QBookVersion; import com.mysema.query.jpa.hibernate.HibernateSubQuery; +import com.mysema.query.jpa.impl.JPASubQuery; import com.mysema.query.types.ArrayConstructorExpression; import com.mysema.query.types.Concatenation; import com.mysema.query.types.ConstructorExpression; @@ -830,6 +831,17 @@ public abstract class AbstractStandardTest { .list(cat); assertNotNull(cats); } + + @Test + public void SubQuery3() { + QCat cat = QCat.cat; + QCat other = new QCat("other"); + query().from(cat) + .where(cat.name.eq(new JPASubQuery().from(other) + .where(other.name.indexOf("B").eq(0)) + .unique(other.name))) + .list(cat); + } @Test public void Count(){ diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java index ba86a646a..d7d48c0ed 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java @@ -15,6 +15,15 @@ package com.mysema.query.jpa; import org.junit.Test; +import com.mysema.query.domain.QCat; +import com.mysema.query.support.Expressions; +import com.mysema.query.types.Expression; +import com.mysema.query.types.Ops; +import com.mysema.query.types.Path; +import com.mysema.query.types.expr.NumberOperation; +import com.mysema.query.types.expr.StringOperation; +import com.mysema.query.types.path.StringPath; + public class StringOperationsTest extends AbstractQueryTest{ @Test @@ -33,4 +42,24 @@ public class StringOperationsTest extends AbstractQueryTest{ assertToString("lower(cat.name)", cat.name.lower()); } + @Test + @SuppressWarnings("rawtypes") + public void IndexOf() { + Path path = QCat.cat.name; + Expression startIndex = Expressions.constant(0); + Expression endIndex = NumberOperation.create(Integer.class, Ops.INDEX_OF, path, Expressions.constant("x")); + Expression substr = StringOperation.create(Ops.SUBSTR_2ARGS, path, startIndex, endIndex); + assertToString("substring(cat.name,1,locate(?1,cat.name)-1)", substr); + } + + @Test + public void IndexOf2() { + StringPath str = QCat.cat.name; + assertToString("substring(cat.name,1,locate(?1,cat.name)-1)", str.substring(0, str.indexOf("x"))); + } + + @Test + public void IndexOf3() { + assertToString("substring(cat.name,2,1)", QCat.cat.name.substring(1,2)); + } } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java index c08b159d9..10e2e3038 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java @@ -185,4 +185,11 @@ public class SubQueryTest extends AbstractQueryTest{ sub().from(cat).where(cat.kittens.get(cat.id).name.eq("Kate")).count()); } + @Test + public void IndexOf() { + assertToString("(select count(cat) from Cat cat where locate(?1,cat.name) - 1 = ?2)", + + sub().from(cat).where(cat.name.indexOf("a").eq(1)).count()); + } + }