mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
Partition lists when needed
This commit is contained in:
parent
a2c7b2dcb0
commit
a8034ab226
@ -13,13 +13,12 @@
|
||||
*/
|
||||
package com.mysema.query.types;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mysema.query.QueryException;
|
||||
|
||||
@ -389,6 +388,34 @@ public final class ExpressionUtils {
|
||||
return PredicateOperation.create(Ops.NE, left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an left not in right expression
|
||||
*
|
||||
* @param <D>
|
||||
* @param left
|
||||
* @param right
|
||||
* @return
|
||||
*/
|
||||
public static <D> Predicate notIn(Expression<D> left, CollectionExpression<?,? extends D> right) {
|
||||
return PredicateOperation.create(Ops.NOT_IN, left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an left not in right expression
|
||||
*
|
||||
* @param <D>
|
||||
* @param left
|
||||
* @param right
|
||||
* @return
|
||||
*/
|
||||
public static <D> Predicate notIn(Expression<D> left, Collection<? extends D> right) {
|
||||
if (right.size() == 1) {
|
||||
return neConst(left, right.iterator().next());
|
||||
} else {
|
||||
return PredicateOperation.create(Ops.NOT_IN, left, ConstantImpl.create(right));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a left or right expression
|
||||
*
|
||||
|
||||
@ -68,6 +68,7 @@ public class OracleTemplates extends SQLTemplates {
|
||||
setBatchCountViaGetUpdateCount(true);
|
||||
setWithRecursive("with ");
|
||||
setCountViaAnalytics(true);
|
||||
setListMaxSize(1000);
|
||||
|
||||
add(Ops.ALIAS, "{0} {1}");
|
||||
add(SQLOps.NEXTVAL, "{0s}.nextval");
|
||||
|
||||
@ -18,13 +18,11 @@ import java.util.*;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mysema.commons.lang.Pair;
|
||||
import com.mysema.query.JoinExpression;
|
||||
import com.mysema.query.JoinFlag;
|
||||
import com.mysema.query.QueryFlag;
|
||||
import com.mysema.query.*;
|
||||
import com.mysema.query.QueryFlag.Position;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.sql.types.Null;
|
||||
import com.mysema.query.support.Expressions;
|
||||
import com.mysema.query.support.SerializerBase;
|
||||
@ -828,6 +826,7 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
|
||||
|
||||
@Override
|
||||
protected void visitOperation(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) {
|
||||
boolean pathAdded = false;
|
||||
if (args.size() == 2
|
||||
&& !useLiterals
|
||||
&& args.get(0) instanceof Path<?>
|
||||
@ -838,6 +837,7 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
|
||||
for (Element element : templates.getTemplate(operator).getElements()) {
|
||||
if (element instanceof Template.ByIndex && ((Template.ByIndex)element).getIndex() == 1) {
|
||||
constantPaths.add((Path<?>)args.get(0));
|
||||
pathAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -877,10 +877,29 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
|
||||
|
||||
} else if ((operator == Ops.IN || operator == Ops.NOT_IN)
|
||||
&& args.get(0) instanceof Path
|
||||
&& args.get(1) instanceof Constant
|
||||
&& ((Constant<Collection>)args.get(1)).getConstant().isEmpty()) {
|
||||
super.visitOperation(type, operator == Ops.IN ? Ops.EQ : Ops.NE,
|
||||
ImmutableList.of(NumberTemplate.ONE, NumberTemplate.TWO));
|
||||
&& args.get(1) instanceof Constant) {
|
||||
Collection<Object> coll = ((Constant<Collection>)args.get(1)).getConstant();
|
||||
if (coll.isEmpty()) {
|
||||
super.visitOperation(type, operator == Ops.IN ? Ops.EQ : Ops.NE,
|
||||
ImmutableList.of(NumberTemplate.ONE, NumberTemplate.TWO));
|
||||
} else {
|
||||
if (templates.getListMaxSize() == 0 || coll.size() <= templates.getListMaxSize()) {
|
||||
super.visitOperation(type, operator, args);
|
||||
} else {
|
||||
if (!constantPaths.isEmpty()) {
|
||||
constantPaths.removeLast();
|
||||
}
|
||||
BooleanBuilder b = new BooleanBuilder();
|
||||
for (List part : Iterables.partition(coll, templates.getListMaxSize())) {
|
||||
if (operator == Ops.IN) {
|
||||
b.or(ExpressionUtils.in(args.get(0), part));
|
||||
} else {
|
||||
b.and(ExpressionUtils.notIn(args.get(0), part));
|
||||
}
|
||||
}
|
||||
b.getValue().accept(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (operator == SQLOps.WITH_COLUMNS) {
|
||||
boolean oldSkipParent = skipParent;
|
||||
|
||||
@ -13,11 +13,12 @@
|
||||
*/
|
||||
package com.mysema.query.sql;
|
||||
|
||||
import static com.google.common.base.CharMatcher.inRange;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Types;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@ -31,6 +32,7 @@ import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.QueryModifiers;
|
||||
import com.mysema.query.sql.types.Type;
|
||||
import com.mysema.query.types.*;
|
||||
import static com.google.common.base.CharMatcher.inRange;
|
||||
|
||||
/**
|
||||
* SQLTemplates extends Templates to provides SQL specific extensions
|
||||
@ -273,6 +275,8 @@ public class SQLTemplates extends Templates {
|
||||
|
||||
private boolean arraysSupported = true;
|
||||
|
||||
private int listMaxSize = 0;
|
||||
|
||||
@Deprecated
|
||||
protected SQLTemplates(String quoteStr, char escape, boolean useQuotes) {
|
||||
this(SQL_RESERVED_WORDS, quoteStr, escape, useQuotes);
|
||||
@ -787,6 +791,10 @@ public class SQLTemplates extends Templates {
|
||||
return arraysSupported;
|
||||
}
|
||||
|
||||
public int getListMaxSize() {
|
||||
return listMaxSize;
|
||||
}
|
||||
|
||||
protected void newLineToSingleSpace() {
|
||||
for (Class<?> cl : Arrays.<Class<?>>asList(getClass(), SQLTemplates.class)) {
|
||||
for (Field field : cl.getDeclaredFields()) {
|
||||
@ -1147,4 +1155,7 @@ public class SQLTemplates extends Templates {
|
||||
this.arraysSupported = b;
|
||||
}
|
||||
|
||||
protected void setListMaxSize(int i ) {
|
||||
listMaxSize = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,6 +623,28 @@ public class SelectBase extends AbstractBaseTest {
|
||||
query().from(employee).where(employee.id.in(Arrays.asList(1,2))).list(employee);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExcludeIn(SQLITE)
|
||||
public void In_Long_List() {
|
||||
List<Integer> ids = Lists.newArrayList();
|
||||
for (int i = 0; i < 20000; i++) {
|
||||
ids.add(i);
|
||||
}
|
||||
assertEquals(
|
||||
query().from(employee).count(),
|
||||
query().from(employee).where(employee.id.in(ids)).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExcludeIn(SQLITE)
|
||||
public void NotIn_Long_List() {
|
||||
List<Integer> ids = Lists.newArrayList();
|
||||
for (int i = 0; i < 20000; i++) {
|
||||
ids.add(i);
|
||||
}
|
||||
assertEquals(0, query().from(employee).where(employee.id.notIn(ids)).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void In_Empty() {
|
||||
assertEquals(0, query().from(employee).where(employee.id.in(ImmutableList.<Integer>of())).count());
|
||||
|
||||
@ -27,6 +27,7 @@ import com.mysema.query.sql.domain.QEmployeeNoPK;
|
||||
import com.mysema.query.sql.domain.QSurvey;
|
||||
import com.mysema.query.support.Expressions;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.ExpressionUtils;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.expr.Wildcard;
|
||||
@ -110,6 +111,30 @@ public class SQLSerializerTest {
|
||||
"where \"user\".id = ?)", serializer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void In() {
|
||||
StringPath path = Expressions.stringPath("str");
|
||||
Expression<?> expr = ExpressionUtils.in(path, Arrays.asList("1", "2", "3"));
|
||||
|
||||
SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT);
|
||||
serializer.handle(expr);
|
||||
assertEquals(Arrays.asList(path, path, path), serializer.getConstantPaths());
|
||||
assertEquals(3, serializer.getConstants().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Or_In() {
|
||||
StringPath path = Expressions.stringPath("str");
|
||||
Expression<?> expr = ExpressionUtils.anyOf(
|
||||
ExpressionUtils.in(path, Arrays.asList("1", "2", "3")),
|
||||
ExpressionUtils.in(path, Arrays.asList("4", "5", "6")));
|
||||
|
||||
SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT);
|
||||
serializer.handle(expr);
|
||||
assertEquals(Arrays.asList(path, path, path, path, path, path), serializer.getConstantPaths());
|
||||
assertEquals(6, serializer.getConstants().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Some() {
|
||||
//select some((e.FIRSTNAME is not null)) from EMPLOYEE
|
||||
|
||||
Loading…
Reference in New Issue
Block a user