Skip to content

Commit

Permalink
CE SQL v1 (#641)
Browse files Browse the repository at this point in the history
- add exception factory for cesql exceptions
- extend EvaluationResult to be usable internally
- expressions use results instead of a thrower interface
- functions use results instead of a thrower interface
- parser handles not equals correctly, does not eagerly evaluate when there may be an error
- parser handles integer literals properly
- updated test files to test v1 spec

Signed-off-by: Calum Murray <cmurray@redhat.com>
Co-authored-by: Pierangelo Di Pilato <pierangelodipilato@gmail.com>
  • Loading branch information
Cali0707 and pierDipi committed Jun 21, 2024
1 parent a790482 commit 010627e
Show file tree
Hide file tree
Showing 80 changed files with 839 additions and 702 deletions.
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@
<link>https://docs.spring.io/spring-framework/docs/current/javadoc-api/</link>
<link>https://jakarta.ee/specifications/platform/8/apidocs/</link>
<link>https://kafka.apache.org/30/javadoc/</link>
<link>https://qpid.apache.org/releases/qpid-proton-j-0.33.7/api/</link>
<link>https://fasterxml.github.io/jackson-databind/javadoc/2.10/</link>
</links>
<source>8</source>
Expand Down
2 changes: 1 addition & 1 deletion sql/src/main/antlr4/imports/CESQLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ FALSE: 'FALSE';

DQUOTED_STRING_LITERAL: DQUOTA_STRING;
SQUOTED_STRING_LITERAL: SQUOTA_STRING;
INTEGER_LITERAL: INT_DIGIT+;
INTEGER_LITERAL: ('+' | '-')? INT_DIGIT+;

// Identifiers

Expand Down
16 changes: 1 addition & 15 deletions sql/src/main/java/io/cloudevents/sql/EvaluationContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,5 @@ public interface EvaluationContext {
*/
String expressionText();

/**
* Append a new exception to the evaluation context.
* This exception will be propagated back in the evaluation result.
*
* @param exception exception to append
*/
void appendException(EvaluationException exception);

/**
* Append a new exception to the evaluation context.
* This exception will be propagated back in the evaluation result.
*
* @param exceptionFactory exception factory, which will automatically include expression interval and text
*/
void appendException(EvaluationException.EvaluationExceptionFactory exceptionFactory);
ExceptionFactory exceptionFactory();
}
12 changes: 8 additions & 4 deletions sql/src/main/java/io/cloudevents/sql/EvaluationException.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,27 @@ public enum ErrorKind {
/**
* An implicit or an explicit casting failed.
*/
INVALID_CAST,
CAST,
/**
* An event attribute was addressed, but missing.
*/
MISSING_ATTRIBUTE,
/**
* Error happened while dispatching a function invocation. Reasons may be invalid function name or invalid arguments number.
*/
FUNCTION_DISPATCH,
MISSING_FUNCTION,
/**
* Error happened while executing a function. This usually contains a non null cause.
*/
FUNCTION_EXECUTION,
FUNCTION_EVALUATION,
/**
* Error happened while executing a math operation. Reason may be a division by zero.
*/
MATH
MATH,
/**
* Any error that does not fall into the other error kinds
*/
GENERIC,
}

private final ErrorKind errorKind;
Expand Down
29 changes: 0 additions & 29 deletions sql/src/main/java/io/cloudevents/sql/EvaluationRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,6 @@
* The evaluation runtime takes care of the function resolution, casting and other core functionalities to execute an expression.
*/
public interface EvaluationRuntime {

/**
* Check if the cast can be executed from {@code value} to the {@code target} type.
*
* @param value the value to cast
* @param target the type cast target
* @return false if the cast trigger an error, true otherwise.
*/
boolean canCast(Object value, Type target);

/**
* Return the {@code value} casted to the {@code target} type.
*
* @param ctx the evaluation context
* @param value the value to cast
* @param target the type cast target
* @return the casted value, if the cast succeeds, otherwise the default value of the target type
*/
Object cast(EvaluationContext ctx, Object value, Type target);

/**
* Return the {@code value} casted to the {@code target} type. If fails, this is going to throw an exception without the evaluation context.
*
* @param value the value to cast
* @param target the type cast target
* @return the casted value, if the cast succeeds, otherwise the default value of the target type
*/
Object cast(Object value, Type target) throws EvaluationException;

/**
* Resolve a {@link Function} starting from its name and the concrete number of arguments.
*
Expand Down
51 changes: 51 additions & 0 deletions sql/src/main/java/io/cloudevents/sql/ExceptionFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.cloudevents.sql;

import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.ParseTree;

public interface ExceptionFactory {
EvaluationException.EvaluationExceptionFactory invalidCastTarget(Class<?> from, Class<?> to);

EvaluationException.EvaluationExceptionFactory castError(Class<?> from, Class<?> to, Throwable cause);

EvaluationException missingAttribute(Interval interval, String expression, String key);

EvaluationException cannotDispatchFunction(Interval interval, String expression, String functionName, Throwable cause);

EvaluationException.EvaluationExceptionFactory functionExecutionError(String functionName, Throwable cause);

EvaluationException divisionByZero(Interval interval, String expression, Integer dividend);

EvaluationException mathError(Interval interval, String expression, String errorMessage);

static ParseException cannotParseValue(ParseTree node, Type target, Throwable cause) {
return new ParseException(
ParseException.ErrorKind.PARSE_VALUE,
node.getSourceInterval(),
node.getText(),
"Cannot parse to " + target.name() + ": " + cause.getMessage(),
cause
);
}

static ParseException recognitionError(RecognitionException e, String msg) {
return new ParseException(
ParseException.ErrorKind.RECOGNITION,
new Interval(e.getOffendingToken().getStartIndex(), e.getOffendingToken().getStopIndex()),
e.getOffendingToken().getText(),
"Cannot parse: " + msg,
e
);
}

static ParseException cannotEvaluateConstantExpression(EvaluationException exception) {
return new ParseException(
ParseException.ErrorKind.CONSTANT_EXPRESSION_EVALUATION,
exception.getExpressionInterval(),
exception.getExpressionText(),
"Cannot evaluate the constant expression: " + exception.getExpressionText(),
exception
);
}
}
5 changes: 3 additions & 2 deletions sql/src/main/java/io/cloudevents/sql/Function.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.cloudevents.sql;

import io.cloudevents.CloudEvent;
import io.cloudevents.sql.impl.runtime.EvaluationResult;

import java.util.List;

Expand All @@ -15,9 +16,9 @@ public interface Function extends FunctionSignature {
* @param ctx the evaluation context
* @param evaluationRuntime the evaluation runtime
* @param event the expression input event
* @param arguments the arguments passed to this function. Note: the arguments are already casted to the appropriate type declared in the signature
* @param arguments the arguments passed to this function. Note: the arguments are already cast to the appropriate type declared in the signature
* @return the return value of the function
*/
Object invoke(EvaluationContext ctx, EvaluationRuntime evaluationRuntime, CloudEvent event, List<Object> arguments);
EvaluationResult invoke(EvaluationContext ctx, EvaluationRuntime evaluationRuntime, CloudEvent event, List<Object> arguments);

}
5 changes: 5 additions & 0 deletions sql/src/main/java/io/cloudevents/sql/FunctionSignature.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public interface FunctionSignature {
*/
Type typeOfParameter(int i) throws IllegalArgumentException;

/**
* @return function return type
*/
Type returnType();

/**
* @return the arity, excluding the vararg parameter if {@code isVariadic() == true}
*/
Expand Down
107 changes: 0 additions & 107 deletions sql/src/main/java/io/cloudevents/sql/impl/ExceptionFactory.java

This file was deleted.

Loading

0 comments on commit 010627e

Please sign in to comment.