Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into incubator-kie-issues#…
Browse files Browse the repository at this point in the history
…1829
  • Loading branch information
Gabriele-Cardosi committed Feb 14, 2025
2 parents f1fe7cf + 937aeab commit b2afaa0
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ private void jitAritmeticOperation(Class<?> operationType, AritmeticOperator ope
mv.visitInsn(DREM);
break;
}
} else if (operationType == BigDecimal.class || operationType == BigInteger.class) {
} else if (operationType == BigInteger.class) {
try {
switch (operator) {
case ADD:
Expand All @@ -891,6 +891,28 @@ private void jitAritmeticOperation(Class<?> operationType, AritmeticOperator ope
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
} else if (operationType == BigDecimal.class) {
try {
switch (operator) {
case ADD:
invokeBigDecimalArithmeticOperation("add");
break;
case SUB:
invokeBigDecimalArithmeticOperation("subtract");
break;
case MUL:
invokeBigDecimalArithmeticOperation("multiply");
break;
case DIV:
invokeBigDecimalArithmeticOperation("divide");
break;
case MOD:
invoke(operationType.getMethod("remainder", operationType));
break;
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException("Unknown operation type" + operationType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -774,6 +776,11 @@ protected final void invoke(int opCode, Class<?> clazz, String methodName, Class
mv.visitMethodInsn(opCode, internalName(clazz), methodName, methodDescr(returnedType, paramsType));
}

protected final void invokeBigDecimalArithmeticOperation(String operation) throws NoSuchMethodException {
mv.visitFieldInsn(GETSTATIC, "java/math/MathContext", "DECIMAL128", "Ljava/math/MathContext;");
invoke(BigDecimal.class.getMethod(operation, BigDecimal.class, MathContext.class));
}

protected final void putStaticField(String name, Class<?> type) {
mv.visitFieldInsn(PUTSTATIC, classDescriptor(), name, classGenerator.descriptorOf(type));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
package org.drools.mvel.integrationtests;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

Expand All @@ -31,13 +33,15 @@
import org.drools.testcoverage.common.util.KieUtil;
import org.drools.testcoverage.common.util.TestParametersUtil2;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.api.KieBase;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieSession;
import org.kie.internal.conf.ConstraintJittingThresholdOption;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assumptions.assumeFalse;

public class JittingTest {

Expand Down Expand Up @@ -382,4 +386,109 @@ public void testInvokeVarargsConstructor(KieBaseTestConfiguration kieBaseTestCon
ksession.insert(new Tester());
assertThat(ksession.fireAllRules()).isEqualTo(1);
}

@ParameterizedTest(name = "KieBase type={0}")
@MethodSource("parameters")
void nonTerminatingDecimal(KieBaseTestConfiguration kieBaseTestConfiguration) {
// incubator-kie-drools/issues/6249
String drl =
"package test\n" +
"import " + Person.class.getCanonicalName() + "\n" +
"\n" +
"rule R1 when \n" +
" Person( bigDecimal / 7B >= 0 )\n" +
"then \n" +
"end";

final KieModule kieModule = KieUtil.getKieModuleFromDrls("test", kieBaseTestConfiguration, drl);
final KieBase kieBase = KieBaseUtil.newKieBaseFromKieModuleWithAdditionalOptions(kieModule, kieBaseTestConfiguration, ConstraintJittingThresholdOption.get(0));
KieSession ksession = kieBase.newKieSession();
Person person = new Person();
person.setBigDecimal(new BigDecimal("15"));
ksession.insert(person);
assertThat(ksession.fireAllRules()).isEqualTo(1);
}

private static Stream<String> accuracyConstraintsForDECIMAL128() {
// These constraints require more than MathContext.DECIMAL128 accuracy.
// Because Drools/Mvel BigDecimal calculation is based on MathContext.DECIMAL128, these constraints shouldn't match.
return Stream.of(
"(bigDecimal + $bd1) == 11111111101111111110111111111011111110B",
"(bigDecimal - $bd1) == 8641975320864197532086419753208641976B",
"(bigDecimal * $bd1) == 12193263113702179522618503273386678850399329371828684651861743636654061881B"
);
}

private static Stream<Arguments> argumentsForAccuracyTest() {
List<KieBaseTestConfiguration> configurations = parameters().toList();
List<String> constraints = accuracyConstraintsForDECIMAL128().toList();
List<ConstraintJittingThresholdOption> jittingThresholds = Stream.of(0, 1).map(ConstraintJittingThresholdOption::get).toList();
return configurations.stream()
.flatMap(config -> constraints.stream()
.flatMap(constraint -> jittingThresholds.stream()
.map(jittingThreshold -> Arguments.of(config, constraint, jittingThreshold))));
}

@ParameterizedTest(name = "KieBase type={0}")
@MethodSource("argumentsForAccuracyTest")
void bigDecimalAccuracyForDECIMAL128(KieBaseTestConfiguration kieBaseTestConfiguration, String constraint, ConstraintJittingThresholdOption jittingThreshold) {
//
String drl =
"package test\n" +
"import " + Person.class.getCanonicalName() + "\n" +
"rule R1 when \n" +
" Person( name == \"person1\", $bd1 : bigDecimal )\n" +
" Person( name == \"person2\", " + constraint + " )\n" +
"then \n" +
"end";

final KieModule kieModule = KieUtil.getKieModuleFromDrls("test", kieBaseTestConfiguration, drl);
final KieBase kieBase = KieBaseUtil.newKieBaseFromKieModuleWithAdditionalOptions(kieModule, kieBaseTestConfiguration, jittingThreshold);
KieSession ksession = kieBase.newKieSession();

BigDecimal bd1 = new BigDecimal("1234567890123456789012345678901234567");
Person person1 = new Person("person1");
person1.setBigDecimal(bd1);

BigDecimal bd2 = new BigDecimal("9876543210987654321098765432109876543");
Person person2 = new Person("person2");
person2.setBigDecimal(bd2);

ksession.insert(person1);
ksession.insert(person2);
assertThat(ksession.fireAllRules()).isZero();
}

private static Stream<Arguments> argumentsArithmetic() {
List<KieBaseTestConfiguration> configurations = parameters().toList();
List<String> operators = Stream.of("+", "-", "*", "/").toList();
return configurations.stream()
.flatMap(config -> operators.stream()
.map(operator -> Arguments.of(config, operator)));
}

@ParameterizedTest(name = "KieBase type={0}")
@MethodSource("argumentsArithmetic")
void bigIntegerArithmetic(KieBaseTestConfiguration kieBaseTestConfiguration, String operator) {
assumeFalse(kieBaseTestConfiguration.isExecutableModel(),
"BigInteger arithmetic with exec-model is skipped " +
"until incubator-kie-drools/issues/6253 is fixed");

String drl =
"package test\n" +
"import " + Person.class.getCanonicalName() + "\n" +
"\n" +
"rule R1 when \n" +
" Person( bigInteger " + operator + " 7I >= 0 )\n" +
"then \n" +
"end";

final KieModule kieModule = KieUtil.getKieModuleFromDrls("test", kieBaseTestConfiguration, drl);
final KieBase kieBase = KieBaseUtil.newKieBaseFromKieModuleWithAdditionalOptions(kieModule, kieBaseTestConfiguration, ConstraintJittingThresholdOption.get(0));
KieSession ksession = kieBase.newKieSession();
Person person = new Person();
person.setBigInteger(new BigInteger("15"));
ksession.insert(person);
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
}

0 comments on commit b2afaa0

Please sign in to comment.