Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: better null handling for unary tests involving special character ? #882

Closed
wants to merge 2 commits into from

Conversation

spearsandshields
Copy link

Description

This PR is drafted to address null value handling in unary test, especially when special charactor ? is involved.

Gist of the fix:
Whenever something evaluates to null, due to errors. Such as not-comaparable data types, we need a way to embed/box that information, and pass it along to the callers. So the callers can determine how they want to handle these special values.

Therefore, I created a artifact valueType called ErroredVal, this is different from ValError, as ValError results in not-resumable error. ErroredValue allow the logic to continue, and callers can decide when/how to handle it at their choosing.
Adding this mechanism allow me to swap some ValNull to boxed ErroredVal.

After this, we need to ensure the ErroredVal does not affect the final result. In order to achieve that, I moved logic from eval to evalInternal, and made eval function behave like a wrapper than returns the unboxed ErroredVal. (this allow tests to pass as normal)

With the additional of this new mechanism, I made some changes to unaryTestExpression:

  1. add expression as additional method parameter. As we need to check the tokens and see if ? is used in the expression.
  2. when it is used, check for ErroredVal and handle them accordingly.

Related issues

#864

closes #

@CLAassistant
Copy link

CLAassistant commented Aug 1, 2024

CLA assistant check
All committers have signed the CLA.

@saig0
Copy link
Member

saig0 commented Aug 12, 2024

@spearsandshields thank you for your contribution. 🎉

I'll review your PR this week. 👀

@spearsandshields
Copy link
Author

@saig0 , thanks.
I just pushed out a fix to ensure the tests are passing.
Let me know if there is anything you need from me :)

Copy link
Member

@saig0 saig0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spearsandshields the solution solves the concrete issue. 👍 However, I don't see a solution for the general issue with the unary-tests (see the examples in the comment).

I would aim for a general solution that reflects the description of the DMN specification (i.e. an expression with ? must evaluate to true).

At the moment, I can't share a concrete design. But, this is not the way, sorry.

Comment on lines +747 to +756
expression match {
case comparison: Comparison =>
if (comparison.x == ConstInputValue || comparison.y == ConstInputValue) {
x match {
case ErroredVal(value, _) => return value
case _ => // Continue
}
}
case _ => // Continue if not a Comparison or ConstInputValue not found
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ This modification solves the case for the comparison (? > null). However, it doesn't solve the issue in general.

The following expressions still return true instead of null:

// for ? = null
? > 20 and ? < 40
// output: true 

? > 20 or ? < 40
// output: true

?
// output: true

Comment on lines +47 to +52
val result = evalInternal(expression)
result match {
case ErroredVal(value, _) =>
value
case _ => result
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 Having two different evaluation methods with the same signature makes the code harder to understand and could lead to issues.

Comment on lines +291 to +293
case class ErroredVal(value: Val, errorType: EvaluationFailureType) extends Val {
override def toString: String = value.toString
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ The new type is only used in combination with ValNull. It seems like the failure type should be an additional property of ValNull. And, it is used only within the interpreter.

@saig0
Copy link
Member

saig0 commented Aug 20, 2024

Close this PR in favor of #887.

@spearsandshields thank you for your attempt. 🙇

@saig0 saig0 closed this Aug 20, 2024
@spearsandshields
Copy link
Author

spearsandshields commented Aug 28, 2024

Thanks for drafting this more thorough fix. @saig0
I see the backport prs etc, but unsure what we need to do to receive these updates. Is it merged into the latest version of the camunda engine yet?

@saig0
Copy link
Member

saig0 commented Aug 29, 2024

I see the backport prs etc, but unsure what we need to do to receive these updates. Is it merged into the latest version of the camunda engine yet?

@spearsandshields I will build new patch releases of the FEEL engine soon. So, the fix will be included in the upcoming Camunda patch releases. 🏗️

@spearsandshields
Copy link
Author

@saig0 , thanks and this is huge!

Is there a rough timeline where I can expect the patch release?

@saig0
Copy link
Member

saig0 commented Sep 3, 2024

@spearsandshields you can expect the next patch release in the next few weeks. 🚧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants