Fix modulo normalization

This commit is contained in:
Timo Westkämper 2016-01-20 21:22:34 +02:00
parent b7a4c16282
commit 4c7bf609cf
4 changed files with 24 additions and 5 deletions

View File

@ -27,11 +27,11 @@ public final class Normalization {
// TODO simplify
private static final Pattern FULL_OPERATION = Pattern.compile(
"(?<![\\d*/\"?' ])" + "(\\b|\\(|\\s+)" +
"(" + NUMBER + WS + "[+\\-/*]" + WS + ")+" + NUMBER + WS +
"(" + NUMBER + WS + "[+\\-/*%]" + WS + ")+" + NUMBER + WS +
"(?![\\d*/\"' ])");
private static final Pattern[] OPERATIONS = {
Pattern.compile(NUMBER + WS + "([*/])" + WS + NUMBER),
Pattern.compile(NUMBER + WS + "([*/%])" + WS + NUMBER),
Pattern.compile(NUMBER + WS + "([+-])" + WS + NUMBER),
};
@ -47,6 +47,7 @@ public final class Normalization {
switch (operator) {
case '*': result = first.multiply(second); break;
case '/': result = first.divide(second, 10, RoundingMode.HALF_UP); break;
case '%': result = first.remainder(second); break;
case '+': result = first.add(second); break;
case '-': result = first.subtract(second); break;
default: throw new IllegalStateException();
@ -78,7 +79,7 @@ public final class Normalization {
private static boolean hasOperators(String queryString) {
for (int i = 0; i < queryString.length(); i++) {
char ch = queryString.charAt(i);
if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%') {
return true;
}
}

View File

@ -68,6 +68,12 @@ public class NormalizationTest {
assertEquals("where 2.6 = 2.6", Normalization.normalize("where 5.2 / 2 = 2.6"));
}
@Test
public void Normalize_Modulo() {
assertEquals("1", Normalization.normalize("4%3"));
assertEquals("3", Normalization.normalize("2 + 4%3"));
}
@Test
public void Mixed() {
assertEquals("13", Normalization.normalize("2 * 5 + 3"));

View File

@ -17,8 +17,6 @@ import java.sql.*;
import java.util.Map;
import java.util.Properties;
import org.hsqldb.types.Types;
import com.google.common.collect.Maps;
import com.mysema.query.ddl.CreateTableClause;
import com.mysema.query.ddl.DropTableClause;

View File

@ -1112,6 +1112,20 @@ public class SelectBase extends AbstractBaseTest {
assertEquals(Math.tanh(0.5), singleResult(MathExpressions.tanh(expr)), 0.001);
}
@Test
@ExcludeIn(DERBY) // Derby doesn't support mod with decimal operands
public void Math2() {
// 1.0 + 2.0 * 3.0 - 4.0 / 5.0 + 6.0 % 3.0
NumberExpression<Double> one = Expressions.numberTemplate(Double.class, "1.0");
NumberExpression<Double> two = Expressions.numberTemplate(Double.class, "2.0");
NumberExpression<Double> three = Expressions.numberTemplate(Double.class, "3.0");
NumberExpression<Double> four = Expressions.numberTemplate(Double.class, "4.0");
NumberExpression<Double> five = Expressions.numberTemplate(Double.class, "5.0");
NumberExpression<Double> six = Expressions.numberTemplate(Double.class, "6.0");
Double num = query().singleResult(one.add(two.multiply(three)).subtract(four.divide(five)).add(six.mod(three)));
assertEquals(6.2, num, 0.001);
}
@Test
public void Nested_Tuple_Projection() {
Concatenation concat = new Concatenation(employee.firstname, employee.lastname);