mirror of
https://github.com/apache/rocketmq.git
synced 2026-08-30 18:10:44 +08:00
new feature: sql expression CONTAINS support (#6864)
This commit is contained in:
@@ -69,6 +69,90 @@ public abstract class ComparisonExpression extends BinaryExpression implements B
|
||||
return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right));
|
||||
}
|
||||
|
||||
static class ContainsExpression extends UnaryExpression implements BooleanExpression {
|
||||
|
||||
String search;
|
||||
|
||||
public ContainsExpression(Expression right, String search) {
|
||||
super(right);
|
||||
this.search = search;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "CONTAINS";
|
||||
}
|
||||
|
||||
public Object evaluate(EvaluationContext message) throws Exception {
|
||||
|
||||
if (search == null || search.length() == 0) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
Object rv = this.getRight().evaluate(message);
|
||||
|
||||
if (rv == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
if (!(rv instanceof String)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
return ((String)rv).contains(search) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
public boolean matches(EvaluationContext message) throws Exception {
|
||||
Object object = evaluate(message);
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static class NotContainsExpression extends UnaryExpression implements BooleanExpression {
|
||||
|
||||
String search;
|
||||
|
||||
public NotContainsExpression(Expression right, String search) {
|
||||
super(right);
|
||||
this.search = search;
|
||||
}
|
||||
|
||||
public String getExpressionSymbol() {
|
||||
return "NOT CONTAINS";
|
||||
}
|
||||
|
||||
public Object evaluate(EvaluationContext message) throws Exception {
|
||||
|
||||
if (search == null || search.length() == 0) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
Object rv = this.getRight().evaluate(message);
|
||||
|
||||
if (rv == null) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
if (!(rv instanceof String)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
return ((String)rv).contains(search) ? Boolean.FALSE : Boolean.TRUE;
|
||||
}
|
||||
|
||||
public boolean matches(EvaluationContext message) throws Exception {
|
||||
Object object = evaluate(message);
|
||||
return object != null && object == Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
public static BooleanExpression createContains(Expression left, String search) {
|
||||
return new ContainsExpression(left, search);
|
||||
}
|
||||
|
||||
public static BooleanExpression createNotContains(Expression left, String search) {
|
||||
return new NotContainsExpression(left, search);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static BooleanExpression createInFilter(Expression left, List elements) {
|
||||
|
||||
|
||||
@@ -202,4 +202,4 @@ public class ParseException extends Exception {
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=4c829b0daa2c9af00ddafe2441eb9097 (do not edit this line) */
|
||||
/* JavaCC - OriginalChecksum=60cf9c227a487e4be49599bc903f0a6a (do not edit this line) */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,6 @@ import org.apache.rocketmq.filter.expression.LogicExpression;
|
||||
import org.apache.rocketmq.filter.expression.MQFilterException;
|
||||
import org.apache.rocketmq.filter.expression.PropertyExpression;
|
||||
import org.apache.rocketmq.filter.expression.UnaryExpression;
|
||||
import org.apache.rocketmq.filter.util.LRUCache;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
@@ -170,6 +169,7 @@ TOKEN [IGNORE_CASE] :
|
||||
| < FALSE : "FALSE" >
|
||||
| < NULL : "NULL" >
|
||||
| < IS : "IS" >
|
||||
| < CONTAINS : "CONTAINS">
|
||||
}
|
||||
|
||||
/* Literals */
|
||||
@@ -322,6 +322,17 @@ Expression comparisonExpression() :
|
||||
{
|
||||
left = ComparisonExpression.createLessThanEqual(left, right);
|
||||
}
|
||||
|
|
||||
<CONTAINS> t = stringLitteral()
|
||||
{
|
||||
left = ComparisonExpression.createContains(left, t);
|
||||
}
|
||||
|
|
||||
LOOKAHEAD(2)
|
||||
<NOT> <CONTAINS> t = stringLitteral()
|
||||
{
|
||||
left = ComparisonExpression.createNotContains(left, t);
|
||||
}
|
||||
|
|
||||
<BETWEEN> low = unaryExpr() <AND> high = unaryExpr()
|
||||
{
|
||||
|
||||
+10
-5
@@ -75,23 +75,27 @@ public interface SelectorParserConstants {
|
||||
/**
|
||||
* RegularExpression Id.
|
||||
*/
|
||||
int DECIMAL_LITERAL = 17;
|
||||
int CONTAINS = 17;
|
||||
/**
|
||||
* RegularExpression Id.
|
||||
*/
|
||||
int FLOATING_POINT_LITERAL = 18;
|
||||
int DECIMAL_LITERAL = 18;
|
||||
/**
|
||||
* RegularExpression Id.
|
||||
*/
|
||||
int EXPONENT = 19;
|
||||
int FLOATING_POINT_LITERAL = 19;
|
||||
/**
|
||||
* RegularExpression Id.
|
||||
*/
|
||||
int STRING_LITERAL = 20;
|
||||
int EXPONENT = 20;
|
||||
/**
|
||||
* RegularExpression Id.
|
||||
*/
|
||||
int ID = 21;
|
||||
int STRING_LITERAL = 21;
|
||||
/**
|
||||
* RegularExpression Id.
|
||||
*/
|
||||
int ID = 22;
|
||||
|
||||
/**
|
||||
* Lexical state.
|
||||
@@ -119,6 +123,7 @@ public interface SelectorParserConstants {
|
||||
"\"FALSE\"",
|
||||
"\"NULL\"",
|
||||
"\"IS\"",
|
||||
"\"CONTAINS\"",
|
||||
"<DECIMAL_LITERAL>",
|
||||
"<FLOATING_POINT_LITERAL>",
|
||||
"<EXPONENT>",
|
||||
|
||||
+114
-72
@@ -59,33 +59,35 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
jjmatchedKind = 1;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 40:
|
||||
jjmatchedKind = 28;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 41:
|
||||
jjmatchedKind = 30;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 43:
|
||||
jjmatchedKind = 31;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 44:
|
||||
jjmatchedKind = 29;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 45:
|
||||
case 41:
|
||||
jjmatchedKind = 31;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 43:
|
||||
jjmatchedKind = 32;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 44:
|
||||
jjmatchedKind = 30;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 45:
|
||||
jjmatchedKind = 33;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 60:
|
||||
jjmatchedKind = 26;
|
||||
return jjMoveStringLiteralDfa1_0(0x8800000L);
|
||||
jjmatchedKind = 27;
|
||||
return jjMoveStringLiteralDfa1_0(0x11000000L);
|
||||
case 61:
|
||||
jjmatchedKind = 22;
|
||||
jjmatchedKind = 23;
|
||||
return jjMoveNfa_0(5, 0);
|
||||
case 62:
|
||||
jjmatchedKind = 24;
|
||||
return jjMoveStringLiteralDfa1_0(0x2000000L);
|
||||
jjmatchedKind = 25;
|
||||
return jjMoveStringLiteralDfa1_0(0x4000000L);
|
||||
case 65:
|
||||
return jjMoveStringLiteralDfa1_0(0x200L);
|
||||
case 66:
|
||||
return jjMoveStringLiteralDfa1_0(0x800L);
|
||||
case 67:
|
||||
return jjMoveStringLiteralDfa1_0(0x20000L);
|
||||
case 70:
|
||||
return jjMoveStringLiteralDfa1_0(0x4000L);
|
||||
case 73:
|
||||
@@ -100,6 +102,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
return jjMoveStringLiteralDfa1_0(0x200L);
|
||||
case 98:
|
||||
return jjMoveStringLiteralDfa1_0(0x800L);
|
||||
case 99:
|
||||
return jjMoveStringLiteralDfa1_0(0x20000L);
|
||||
case 102:
|
||||
return jjMoveStringLiteralDfa1_0(0x4000L);
|
||||
case 105:
|
||||
@@ -123,17 +127,17 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
}
|
||||
switch (curChar) {
|
||||
case 61:
|
||||
if ((active0 & 0x2000000L) != 0L) {
|
||||
jjmatchedKind = 25;
|
||||
if ((active0 & 0x4000000L) != 0L) {
|
||||
jjmatchedKind = 26;
|
||||
jjmatchedPos = 1;
|
||||
} else if ((active0 & 0x8000000L) != 0L) {
|
||||
jjmatchedKind = 27;
|
||||
} else if ((active0 & 0x10000000L) != 0L) {
|
||||
jjmatchedKind = 28;
|
||||
jjmatchedPos = 1;
|
||||
}
|
||||
break;
|
||||
case 62:
|
||||
if ((active0 & 0x800000L) != 0L) {
|
||||
jjmatchedKind = 23;
|
||||
if ((active0 & 0x1000000L) != 0L) {
|
||||
jjmatchedKind = 24;
|
||||
jjmatchedPos = 1;
|
||||
}
|
||||
break;
|
||||
@@ -148,7 +152,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
}
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x200L);
|
||||
case 79:
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x100L);
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x20100L);
|
||||
case 82:
|
||||
if ((active0 & 0x400L) != 0L) {
|
||||
jjmatchedKind = 10;
|
||||
@@ -174,7 +178,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
}
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x200L);
|
||||
case 111:
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x100L);
|
||||
return jjMoveStringLiteralDfa2_0(active0, 0x20100L);
|
||||
case 114:
|
||||
if ((active0 & 0x400L) != 0L) {
|
||||
jjmatchedKind = 10;
|
||||
@@ -212,6 +216,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
break;
|
||||
case 76:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0xc000L);
|
||||
case 78:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0x20000L);
|
||||
case 84:
|
||||
if ((active0 & 0x100L) != 0L) {
|
||||
jjmatchedKind = 8;
|
||||
@@ -228,6 +234,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
break;
|
||||
case 108:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0xc000L);
|
||||
case 110:
|
||||
return jjMoveStringLiteralDfa3_0(active0, 0x20000L);
|
||||
case 116:
|
||||
if ((active0 & 0x100L) != 0L) {
|
||||
jjmatchedKind = 8;
|
||||
@@ -265,6 +273,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
break;
|
||||
case 83:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x4000L);
|
||||
case 84:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x20000L);
|
||||
case 87:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x800L);
|
||||
case 101:
|
||||
@@ -281,6 +291,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
break;
|
||||
case 115:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x4000L);
|
||||
case 116:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x20000L);
|
||||
case 119:
|
||||
return jjMoveStringLiteralDfa4_0(active0, 0x800L);
|
||||
default:
|
||||
@@ -298,12 +310,16 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
return jjMoveNfa_0(5, 3);
|
||||
}
|
||||
switch (curChar) {
|
||||
case 65:
|
||||
return jjMoveStringLiteralDfa5_0(active0, 0x20000L);
|
||||
case 69:
|
||||
if ((active0 & 0x4000L) != 0L) {
|
||||
jjmatchedKind = 14;
|
||||
jjmatchedPos = 4;
|
||||
}
|
||||
return jjMoveStringLiteralDfa5_0(active0, 0x800L);
|
||||
case 97:
|
||||
return jjMoveStringLiteralDfa5_0(active0, 0x20000L);
|
||||
case 101:
|
||||
if ((active0 & 0x4000L) != 0L) {
|
||||
jjmatchedKind = 14;
|
||||
@@ -327,8 +343,12 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
switch (curChar) {
|
||||
case 69:
|
||||
return jjMoveStringLiteralDfa6_0(active0, 0x800L);
|
||||
case 73:
|
||||
return jjMoveStringLiteralDfa6_0(active0, 0x20000L);
|
||||
case 101:
|
||||
return jjMoveStringLiteralDfa6_0(active0, 0x800L);
|
||||
case 105:
|
||||
return jjMoveStringLiteralDfa6_0(active0, 0x20000L);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -349,19 +369,46 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
jjmatchedKind = 11;
|
||||
jjmatchedPos = 6;
|
||||
}
|
||||
break;
|
||||
return jjMoveStringLiteralDfa7_0(active0, 0x20000L);
|
||||
case 110:
|
||||
if ((active0 & 0x800L) != 0L) {
|
||||
jjmatchedKind = 11;
|
||||
jjmatchedPos = 6;
|
||||
}
|
||||
break;
|
||||
return jjMoveStringLiteralDfa7_0(active0, 0x20000L);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return jjMoveNfa_0(5, 6);
|
||||
}
|
||||
|
||||
private int jjMoveStringLiteralDfa7_0(long old0, long active0) {
|
||||
if (((active0 &= old0)) == 0L)
|
||||
return jjMoveNfa_0(5, 6);
|
||||
try {
|
||||
curChar = inputStream.readChar();
|
||||
} catch (java.io.IOException e) {
|
||||
return jjMoveNfa_0(5, 6);
|
||||
}
|
||||
switch (curChar) {
|
||||
case 83:
|
||||
if ((active0 & 0x20000L) != 0L) {
|
||||
jjmatchedKind = 17;
|
||||
jjmatchedPos = 7;
|
||||
}
|
||||
break;
|
||||
case 115:
|
||||
if ((active0 & 0x20000L) != 0L) {
|
||||
jjmatchedKind = 17;
|
||||
jjmatchedPos = 7;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return jjMoveNfa_0(5, 7);
|
||||
}
|
||||
|
||||
static final long[] JJ_BIT_VEC_0 = {
|
||||
0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
|
||||
};
|
||||
@@ -396,8 +443,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
if ((0x3ff000000000000L & l) != 0L)
|
||||
jjCheckNAddStates(0, 3);
|
||||
else if (curChar == 36) {
|
||||
if (kind > 21)
|
||||
kind = 21;
|
||||
if (kind > 22)
|
||||
kind = 22;
|
||||
jjCheckNAdd(28);
|
||||
} else if (curChar == 39)
|
||||
jjCheckNAddStates(4, 6);
|
||||
@@ -408,12 +455,12 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
else if (curChar == 45)
|
||||
jjstateSet[jjnewStateCnt++] = 0;
|
||||
if ((0x3fe000000000000L & l) != 0L) {
|
||||
if (kind > 17)
|
||||
kind = 17;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
jjCheckNAddTwoStates(15, 16);
|
||||
} else if (curChar == 48) {
|
||||
if (kind > 17)
|
||||
kind = 17;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
@@ -465,21 +512,21 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
jjstateSet[jjnewStateCnt++] = 6;
|
||||
break;
|
||||
case 13:
|
||||
if (curChar == 48 && kind > 17)
|
||||
kind = 17;
|
||||
if (curChar == 48 && kind > 18)
|
||||
kind = 18;
|
||||
break;
|
||||
case 14:
|
||||
if ((0x3fe000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 17)
|
||||
kind = 17;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
jjCheckNAddTwoStates(15, 16);
|
||||
break;
|
||||
case 15:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 17)
|
||||
kind = 17;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
jjCheckNAddTwoStates(15, 16);
|
||||
break;
|
||||
case 17:
|
||||
@@ -489,8 +536,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
case 18:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
if (kind > 19)
|
||||
kind = 19;
|
||||
jjCheckNAddTwoStates(18, 19);
|
||||
break;
|
||||
case 20:
|
||||
@@ -500,8 +547,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
case 21:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
if (kind > 19)
|
||||
kind = 19;
|
||||
jjCheckNAdd(21);
|
||||
break;
|
||||
case 22:
|
||||
@@ -518,21 +565,21 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
jjCheckNAddStates(4, 6);
|
||||
break;
|
||||
case 26:
|
||||
if (curChar == 39 && kind > 20)
|
||||
kind = 20;
|
||||
if (curChar == 39 && kind > 21)
|
||||
kind = 21;
|
||||
break;
|
||||
case 27:
|
||||
if (curChar != 36)
|
||||
break;
|
||||
if (kind > 21)
|
||||
kind = 21;
|
||||
if (kind > 22)
|
||||
kind = 22;
|
||||
jjCheckNAdd(28);
|
||||
break;
|
||||
case 28:
|
||||
if ((0x3ff001000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 21)
|
||||
kind = 21;
|
||||
if (kind > 22)
|
||||
kind = 22;
|
||||
jjCheckNAdd(28);
|
||||
break;
|
||||
case 29:
|
||||
@@ -546,15 +593,15 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
case 31:
|
||||
if (curChar != 46)
|
||||
break;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
if (kind > 19)
|
||||
kind = 19;
|
||||
jjCheckNAddTwoStates(32, 33);
|
||||
break;
|
||||
case 32:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
if (kind > 19)
|
||||
kind = 19;
|
||||
jjCheckNAddTwoStates(32, 33);
|
||||
break;
|
||||
case 34:
|
||||
@@ -564,8 +611,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
case 35:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
if (kind > 19)
|
||||
kind = 19;
|
||||
jjCheckNAdd(35);
|
||||
break;
|
||||
case 36:
|
||||
@@ -579,15 +626,14 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
case 39:
|
||||
if ((0x3ff000000000000L & l) == 0L)
|
||||
break;
|
||||
if (kind > 18)
|
||||
kind = 18;
|
||||
if (kind > 19)
|
||||
kind = 19;
|
||||
jjCheckNAdd(39);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (i != startsAt);
|
||||
} while (i != startsAt);
|
||||
} else if (curChar < 128) {
|
||||
long l = 1L << (curChar & 077);
|
||||
do {
|
||||
@@ -596,8 +642,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
case 28:
|
||||
if ((0x7fffffe87fffffeL & l) == 0L)
|
||||
break;
|
||||
if (kind > 21)
|
||||
kind = 21;
|
||||
if (kind > 22)
|
||||
kind = 22;
|
||||
jjCheckNAdd(28);
|
||||
break;
|
||||
case 1:
|
||||
@@ -611,8 +657,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
jjCheckNAddTwoStates(10, 8);
|
||||
break;
|
||||
case 16:
|
||||
if ((0x100000001000L & l) != 0L && kind > 17)
|
||||
kind = 17;
|
||||
if ((0x100000001000L & l) != 0L && kind > 18)
|
||||
kind = 18;
|
||||
break;
|
||||
case 19:
|
||||
if ((0x2000000020L & l) != 0L)
|
||||
@@ -632,8 +678,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (i != startsAt);
|
||||
} while (i != startsAt);
|
||||
} else {
|
||||
int hiByte = (int) (curChar >> 8);
|
||||
int i1 = hiByte >> 6;
|
||||
@@ -662,8 +707,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (i != startsAt);
|
||||
} while (i != startsAt);
|
||||
}
|
||||
if (kind != 0x7fffffff) {
|
||||
jjmatchedKind = kind;
|
||||
@@ -722,8 +766,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
*/
|
||||
public static final String[] JJ_STR_LITERAL_IMAGES = {
|
||||
"", null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, "\75", "\74\76", "\76",
|
||||
"\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55"};
|
||||
null, null, null, null, null, null, null, null, null, null, "\75", "\74\76", "\76",
|
||||
"\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55",};
|
||||
|
||||
/**
|
||||
* Lexer state names.
|
||||
@@ -732,7 +776,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
"DEFAULT",
|
||||
};
|
||||
static final long[] JJ_TO_TOKEN = {
|
||||
0x1fff7ff01L,
|
||||
0x3ffefff01L,
|
||||
};
|
||||
static final long[] JJ_TO_SKIP = {
|
||||
0xfeL,
|
||||
@@ -905,8 +949,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
private void jjAddStates(int start, int end) {
|
||||
do {
|
||||
jjstateSet[jjnewStateCnt++] = JJ_NEXT_STATES[start];
|
||||
}
|
||||
while (start++ != end);
|
||||
} while (start++ != end);
|
||||
}
|
||||
|
||||
private void jjCheckNAddTwoStates(int state1, int state2) {
|
||||
@@ -917,8 +960,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants {
|
||||
private void jjCheckNAddStates(int start, int end) {
|
||||
do {
|
||||
jjCheckNAdd(JJ_NEXT_STATES[start]);
|
||||
}
|
||||
while (start++ != end);
|
||||
} while (start++ != end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -501,4 +501,4 @@ public class SimpleCharStream {
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=af79bfe4b18b4b4ea9720ffeb7e52fc5 (do not edit this line) */
|
||||
/* JavaCC - OriginalChecksum=ea3493f692d4975c1ad70c4a750107d3 (do not edit this line) */
|
||||
|
||||
@@ -149,4 +149,4 @@ public class Token implements java.io.Serializable {
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=6b0af88eb45a551d929d3cdd9582f827 (do not edit this line) */
|
||||
/* JavaCC - OriginalChecksum=20094f1ccfbf423c6d9e770d6a7a0188 (do not edit this line) */
|
||||
|
||||
@@ -172,4 +172,4 @@ public class TokenMgrError extends Error {
|
||||
this(LexicalError(eofSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=e960778c8dcd73e167ed5bfddd59f288 (do not edit this line) */
|
||||
/* JavaCC - OriginalChecksum=de79709675790dcbad2e0d728aa630d1 (do not edit this line) */
|
||||
|
||||
@@ -46,6 +46,324 @@ public class ExpressionTest {
|
||||
private static String nullOrExpression = "a is null OR a='hello'";
|
||||
private static String stringHasString = "TAGS is not null and TAGS='''''tag'''''";
|
||||
|
||||
|
||||
@Test
|
||||
public void testConstains_has() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_has() throws Exception {
|
||||
Expression expr = genExp("value not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_has_not() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "abb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_has_not() throws Exception {
|
||||
Expression expr = genExp("value not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "abb")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_hasEmpty() throws Exception {
|
||||
Expression expr = genExp("value contains ''");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_hasEmpty() throws Exception {
|
||||
Expression expr = genExp("value not contains ''");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_null_has_1() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", null)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_null_has_1() throws Exception {
|
||||
Expression expr = genExp("value not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", null)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_null_has_2() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
// KeyValue.c("value", null)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_null_has_2() throws Exception {
|
||||
Expression expr = genExp("value not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
// KeyValue.c("value", null)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_number_has() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", 1.23)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_number_has() throws Exception {
|
||||
Expression expr = genExp("value not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", 1.23)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_boolean_has() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", Boolean.TRUE)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_boolean_has() throws Exception {
|
||||
Expression expr = genExp("value not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", Boolean.TRUE)
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_object_has() throws Exception {
|
||||
Expression expr = genExp("value contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", new Object())
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_has_not_string_1() throws Exception {
|
||||
try {
|
||||
Expression expr = genExp("value contains x"); // will throw parse exception.
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_has_not_string_1() throws Exception {
|
||||
try {
|
||||
Expression expr = genExp("value not contains x"); // will throw parse exception.
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_has_not_string_2() throws Exception {
|
||||
try {
|
||||
Expression expr = genExp("value contains 123"); // will throw parse exception.
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_has_not_string_2() throws Exception {
|
||||
try {
|
||||
Expression expr = genExp("value not contains 123"); // will throw parse exception.
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("value", "axb")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_string() throws Exception {
|
||||
Expression expr = genExp("'axb' contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_string_has_string() throws Exception {
|
||||
Expression expr = genExp("'axb' not contains 'x'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_not_string() throws Exception {
|
||||
Expression expr = genExp("'axb' contains 'u'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_string_has_not_string() throws Exception {
|
||||
Expression expr = genExp("'axb' not contains 'u'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_empty() throws Exception {
|
||||
Expression expr = genExp("'axb' contains ''");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_string_has_empty() throws Exception {
|
||||
Expression expr = genExp("'axb' not contains ''");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_space() throws Exception {
|
||||
Expression expr = genExp("' ' contains ' '");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_string_has_space() throws Exception {
|
||||
Expression expr = genExp("' ' not contains ' '");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_nothing() throws Exception {
|
||||
try {
|
||||
Expression expr = genExp("'axb' contains "); // will throw parse exception.
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_string_has_nothing() throws Exception {
|
||||
try {
|
||||
Expression expr = genExp("'axb' not contains "); // will throw parse exception.
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_special_1() throws Exception {
|
||||
Expression expr = genExp("'axb' contains '.'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_notConstains_string_has_special_1() throws Exception {
|
||||
Expression expr = genExp("'axb' not contains '.'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstains_string_has_special_2() throws Exception {
|
||||
Expression expr = genExp("'s' contains '\\'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("whatever", "whatever")
|
||||
);
|
||||
eval(expr, context, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainsAllInOne() throws Exception {
|
||||
Expression expr = genExp("a not in ('4', '4', '5') and b between 3 and 10 and c not contains 'axbc'");
|
||||
EvaluationContext context = genContext(
|
||||
KeyValue.c("a", "3"),
|
||||
KeyValue.c("b", 3),
|
||||
KeyValue.c("c", "axbdc")
|
||||
);
|
||||
eval(expr, context, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluate_stringHasString() throws Exception {
|
||||
Expression expr = genExp(stringHasString);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ParserTest {
|
||||
private static String equalNullExpression = "a is null";
|
||||
private static String notEqualNullExpression = "a is not null";
|
||||
private static String nowExpression = "a <= now";
|
||||
|
||||
private static String containsExpression = "a=3 and b contains 'xxx' and c not contains 'xxx'";
|
||||
private static String invalidExpression = "a and between 2 and 10";
|
||||
private static String illegalBetween = " a between 10 and 0";
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ParserTest {
|
||||
public void testParse_valid() {
|
||||
for (String expr : Arrays.asList(
|
||||
andExpression, orExpression, inExpression, notInExpression, betweenExpression,
|
||||
equalNullExpression, notEqualNullExpression, nowExpression
|
||||
equalNullExpression, notEqualNullExpression, nowExpression, containsExpression
|
||||
)) {
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user