[#2665] Implement SPI for RenderContext and BindContext listening to
allow for custom SQL transformation * Added unit tests for CONDITION clauses * Added failing unit test for CONDITION_BETWEEN_SYMMETRIC
This commit is contained in:
parent
ca106a5dfa
commit
dd2040093a
@ -121,8 +121,8 @@ public enum Clause {
|
||||
|
||||
CONDITION,
|
||||
|
||||
CONDITION_NULL,
|
||||
CONDITION_NULL_NOT,
|
||||
CONDITION_IS_NULL,
|
||||
CONDITION_IS_NOT_NULL,
|
||||
// TODO: Should operators be distinguished?
|
||||
// - LIKE predicate
|
||||
// - Subselect predicates
|
||||
@ -130,8 +130,11 @@ public enum Clause {
|
||||
// - Quantified predicates
|
||||
CONDITION_COMPARISON,
|
||||
CONDITION_BETWEEN,
|
||||
CONDITION_DISTINCT,
|
||||
CONDITION_DISTINCT_NOT,
|
||||
CONDITION_BETWEEN_SYMMETRIC,
|
||||
CONDITION_NOT_BETWEEN,
|
||||
CONDITION_NOT_BETWEEN_SYMMETRIC,
|
||||
CONDITION_IS_DISTINCT,
|
||||
CONDITION_IS_NOT_DISTINCT,
|
||||
CONDITION_OVERLAPS,
|
||||
|
||||
CONDITION_AND,
|
||||
@ -139,9 +142,9 @@ public enum Clause {
|
||||
CONDITION_NOT,
|
||||
|
||||
CONDITION_IN,
|
||||
CONDITION_IN_NOT,
|
||||
CONDITION_NOT_IN,
|
||||
CONDITION_EXISTS,
|
||||
CONDITION_EXISTS_NOT,
|
||||
CONDITION_NOT_EXISTS,
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Clauses that are used in a SELECT statement
|
||||
|
||||
@ -138,13 +138,13 @@ class BetweenCondition<T> extends AbstractCondition implements BetweenAndStep<T>
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.visit(field)
|
||||
.keyword(not ? " not" : "")
|
||||
.keyword(" between ")
|
||||
.keyword(symmetric ? "symmetric " : "")
|
||||
.visit(minValue)
|
||||
.keyword(" and ")
|
||||
.visit(maxValue);
|
||||
context.visit(field);
|
||||
if (not) context.sql(" ").keyword("not");
|
||||
context.sql(" ").keyword("between");
|
||||
if (symmetric) context.sql(" ").keyword("symmetric");
|
||||
context.sql(" ").visit(minValue);
|
||||
context.sql(" ").keyword("and");
|
||||
context.sql(" ").visit(maxValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -38,7 +38,7 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_IN;
|
||||
import static org.jooq.Clause.CONDITION_IN_NOT;
|
||||
import static org.jooq.Clause.CONDITION_NOT_IN;
|
||||
import static org.jooq.Comparator.IN;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
@ -59,7 +59,7 @@ class InCondition<T> extends AbstractCondition {
|
||||
private static final long serialVersionUID = -1653924248576930761L;
|
||||
private static final int IN_LIMIT = 1000;
|
||||
private static final Clause[] CLAUSES_IN = { CONDITION, CONDITION_IN };
|
||||
private static final Clause[] CLAUSES_IN_NOT = { CONDITION, CONDITION_IN_NOT };
|
||||
private static final Clause[] CLAUSES_IN_NOT = { CONDITION, CONDITION_NOT_IN };
|
||||
|
||||
private final Field<T> field;
|
||||
private final Field<?>[] values;
|
||||
|
||||
@ -37,8 +37,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_NULL;
|
||||
import static org.jooq.Clause.CONDITION_NULL_NOT;
|
||||
import static org.jooq.Clause.CONDITION_IS_NULL;
|
||||
import static org.jooq.Clause.CONDITION_IS_NOT_NULL;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
import org.jooq.Clause;
|
||||
@ -51,8 +51,8 @@ import org.jooq.RenderContext;
|
||||
class IsNull extends AbstractCondition {
|
||||
|
||||
private static final long serialVersionUID = -747240442279619486L;
|
||||
private static final Clause[] CLAUSES_NULL = { CONDITION, CONDITION_NULL };
|
||||
private static final Clause[] CLAUSES_NULL_NOT = { CONDITION, CONDITION_NULL_NOT };
|
||||
private static final Clause[] CLAUSES_NULL = { CONDITION, CONDITION_IS_NULL };
|
||||
private static final Clause[] CLAUSES_NULL_NOT = { CONDITION, CONDITION_IS_NOT_NULL };
|
||||
|
||||
private final Field<?> field;
|
||||
private final boolean isNull;
|
||||
|
||||
@ -736,19 +736,13 @@ implements
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
context.visit(row)
|
||||
.sql(not ? " " : "")
|
||||
.keyword(not ? "not" : "")
|
||||
.sql(" ")
|
||||
.keyword("between")
|
||||
.sql(" ")
|
||||
.keyword(symmetric ? "symmetric" : "")
|
||||
.sql(symmetric ? " " : "")
|
||||
.visit(minValue)
|
||||
.sql(" ")
|
||||
.keyword("and")
|
||||
.sql(" ")
|
||||
.visit(maxValue);
|
||||
context.visit(row);
|
||||
if (not) context.sql(" ").keyword("not");
|
||||
context.sql(" ").keyword("between");
|
||||
if (symmetric) context.sql(" ").keyword("symmetric");
|
||||
context.sql(" ").visit(minValue);
|
||||
context.sql(" ").keyword("and");
|
||||
context.sql(" ").visit(maxValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -38,7 +38,7 @@ package org.jooq.impl;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_IN;
|
||||
import static org.jooq.Clause.CONDITION_IN_NOT;
|
||||
import static org.jooq.Clause.CONDITION_NOT_IN;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.Comparator.EQUALS;
|
||||
import static org.jooq.Comparator.IN;
|
||||
@ -75,7 +75,7 @@ class RowInCondition extends AbstractCondition {
|
||||
*/
|
||||
private static final long serialVersionUID = -1806139685201770706L;
|
||||
private static final Clause[] CLAUSES_IN = { CONDITION, CONDITION_IN };
|
||||
private static final Clause[] CLAUSES_IN_NOT = { CONDITION, CONDITION_IN_NOT };
|
||||
private static final Clause[] CLAUSES_IN_NOT = { CONDITION, CONDITION_NOT_IN };
|
||||
|
||||
private final Row left;
|
||||
private final QueryPartList<? extends Row> right;
|
||||
|
||||
@ -37,8 +37,8 @@ package org.jooq.impl;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_NULL;
|
||||
import static org.jooq.Clause.CONDITION_NULL_NOT;
|
||||
import static org.jooq.Clause.CONDITION_IS_NULL;
|
||||
import static org.jooq.Clause.CONDITION_IS_NOT_NULL;
|
||||
import static org.jooq.Clause.DUMMY;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.DB2;
|
||||
@ -75,8 +75,8 @@ class RowIsNull extends AbstractCondition {
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -1806139685201770706L;
|
||||
private static final Clause[] CLAUSES_NULL = { CONDITION, CONDITION_NULL };
|
||||
private static final Clause[] CLAUSES_NULL_NOT = { CONDITION, CONDITION_NULL_NOT };
|
||||
private static final Clause[] CLAUSES_NULL = { CONDITION, CONDITION_IS_NULL };
|
||||
private static final Clause[] CLAUSES_NULL_NOT = { CONDITION, CONDITION_IS_NOT_NULL };
|
||||
|
||||
private final Row row;
|
||||
private final boolean isNull;
|
||||
|
||||
@ -38,7 +38,7 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_EXISTS;
|
||||
import static org.jooq.Clause.CONDITION_EXISTS_NOT;
|
||||
import static org.jooq.Clause.CONDITION_NOT_EXISTS;
|
||||
import static org.jooq.impl.ExistsOperator.EXISTS;
|
||||
|
||||
import org.jooq.BindContext;
|
||||
@ -53,7 +53,7 @@ class SelectQueryAsExistsCondition extends AbstractCondition {
|
||||
|
||||
private static final long serialVersionUID = 5678338161136603292L;
|
||||
private static final Clause[] CLAUSES_EXISTS = { CONDITION, CONDITION_EXISTS };
|
||||
private static final Clause[] CLAUSES_EXISTS_NOT = { CONDITION, CONDITION_EXISTS_NOT };
|
||||
private static final Clause[] CLAUSES_EXISTS_NOT = { CONDITION, CONDITION_NOT_EXISTS };
|
||||
|
||||
private final Select<?> query;
|
||||
private final ExistsOperator operator;
|
||||
|
||||
@ -39,7 +39,13 @@ import static java.util.Arrays.asList;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static org.jooq.Clause.CONDITION;
|
||||
import static org.jooq.Clause.CONDITION_AND;
|
||||
import static org.jooq.Clause.CONDITION_BETWEEN;
|
||||
import static org.jooq.Clause.CONDITION_BETWEEN_SYMMETRIC;
|
||||
import static org.jooq.Clause.CONDITION_COMPARISON;
|
||||
import static org.jooq.Clause.CONDITION_IS_NOT_NULL;
|
||||
import static org.jooq.Clause.CONDITION_IS_NULL;
|
||||
import static org.jooq.Clause.CONDITION_OR;
|
||||
import static org.jooq.Clause.FIELD;
|
||||
import static org.jooq.Clause.FIELD_REFERENCE;
|
||||
import static org.jooq.Clause.FIELD_ROW;
|
||||
@ -291,6 +297,116 @@ public class VisitContextTest extends AbstractTest {
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_simple() {
|
||||
ctx.render(FIELD_ID1.eq(1));
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_COMPARISON),
|
||||
asList(CONDITION, CONDITION_COMPARISON, FIELD),
|
||||
asList(CONDITION, CONDITION_COMPARISON, FIELD, FIELD_REFERENCE),
|
||||
asList(CONDITION, CONDITION_COMPARISON, FIELD),
|
||||
asList(CONDITION, CONDITION_COMPARISON, FIELD, FIELD_VALUE)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_AND() {
|
||||
ctx.render(FIELD_ID1.eq(1).and(FIELD_NAME1.isNotNull()));
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_AND),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_COMPARISON),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_COMPARISON, FIELD),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_COMPARISON, FIELD, FIELD_REFERENCE),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_COMPARISON, FIELD),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_COMPARISON, FIELD, FIELD_VALUE),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_IS_NOT_NULL),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_IS_NOT_NULL, FIELD),
|
||||
asList(CONDITION, CONDITION_AND, CONDITION, CONDITION_IS_NOT_NULL, FIELD, FIELD_REFERENCE)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_OR() {
|
||||
ctx.render(FIELD_ID1.eq(1).or(FIELD_NAME1.isNull()));
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_OR),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_COMPARISON),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_COMPARISON, FIELD),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_COMPARISON, FIELD, FIELD_REFERENCE),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_COMPARISON, FIELD),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_COMPARISON, FIELD, FIELD_VALUE),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_IS_NULL),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_IS_NULL, FIELD),
|
||||
asList(CONDITION, CONDITION_OR, CONDITION, CONDITION_IS_NULL, FIELD, FIELD_REFERENCE)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_NULL() {
|
||||
ctx.render(FIELD_ID1.isNull());
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_IS_NULL),
|
||||
asList(CONDITION, CONDITION_IS_NULL, FIELD),
|
||||
asList(CONDITION, CONDITION_IS_NULL, FIELD, FIELD_REFERENCE)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_NOT_NULL() {
|
||||
ctx.render(FIELD_ID1.isNotNull());
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_IS_NOT_NULL),
|
||||
asList(CONDITION, CONDITION_IS_NOT_NULL, FIELD),
|
||||
asList(CONDITION, CONDITION_IS_NOT_NULL, FIELD, FIELD_REFERENCE)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_BETWEEN() {
|
||||
ctx.render(FIELD_ID1.between(1, 2));
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_BETWEEN),
|
||||
asList(CONDITION, CONDITION_BETWEEN, FIELD),
|
||||
asList(CONDITION, CONDITION_BETWEEN, FIELD, FIELD_REFERENCE),
|
||||
asList(CONDITION, CONDITION_BETWEEN, FIELD),
|
||||
asList(CONDITION, CONDITION_BETWEEN, FIELD, FIELD_VALUE),
|
||||
asList(CONDITION, CONDITION_BETWEEN, FIELD),
|
||||
asList(CONDITION, CONDITION_BETWEEN, FIELD, FIELD_VALUE)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CONDITION_BETWEEN_SYMMETRIC() {
|
||||
ctx.render(FIELD_ID1.betweenSymmetric(1, 2));
|
||||
|
||||
assertEvents(asList(
|
||||
asList(CONDITION),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC, FIELD),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC, FIELD, FIELD_REFERENCE),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC, FIELD),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC, FIELD, FIELD_VALUE),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC, FIELD),
|
||||
asList(CONDITION, CONDITION_BETWEEN_SYMMETRIC, FIELD, FIELD_VALUE)
|
||||
));
|
||||
}
|
||||
|
||||
private void assertEvents(List<List<Clause>> expected) {
|
||||
// This assertion is a bit more verbose to be able to detect errors more easily
|
||||
for (int i = 0; i < expected.size() && i < listener.clauses.size(); i++) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user