Skip to content

Commit

Permalink
IGNITE-22991 SQL Calcite: Update Calcite version to 1.37 - Fixes #11478.
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksey Plekhanov <plehanov.alex@gmail.com>
  • Loading branch information
alex-plekhanov committed Sep 19, 2024
1 parent dfa3854 commit d6b3036
Show file tree
Hide file tree
Showing 21 changed files with 24,416 additions and 22,620 deletions.
2 changes: 1 addition & 1 deletion docs/_docs/SQL/sql-calcite.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ The Calcite-based SQL engine currently supports:
|`UPPER`, `LOWER`, `INITCAP`, `TO_BASE64`, `FROM_BASE64`, `MD5`, `SHA1`, `SUBSTRING`, `LEFT`, `RIGHT`, `REPLACE`, `TRANSLATE`, `CHR`, `CHAR_LENGTH`, `CHARACTER_LENGTH`, `LENGTH`, `CONCAT`, `OVERLAY`, `POSITION`, `ASCII`, `REPEAT`, `SPACE`, `STRCMP`, `SOUNDEX`, `DIFFERENCE`, `REVERSE`, `TRIM`, `LTRIM`, `RTRIM`, `REGEXP_REPLACE`

|Math functions
|`MOD`, `EXP`, `POWER`, `LN`, `LOG10`, `ABS`, `RAND`, `RAND_INTEGER`, `ACOS`, `ASIN`, `ATAN`, `ATAN2`, `SQRT`, `CBRT`, `COS`, `COSH`, `COT`, `DEGREES`, `RADIANS`, `ROUND`, `SIGN`, `SIN`, `SINH`, `TAN`, `TANH`, `TRUNCATE`, `PI`
|`MOD`, `EXP`, `POWER`, `LN`, `LOG10`, `ABS`, `RAND`, `RAND_INTEGER`, `ACOS`, `ACOSH`, `ASIN`, `ASINH`, `ATAN`, `ATANH`, `ATAN2`, `SQRT`, `CBRT`, `COS`, `COSH`, `COT`, `COTH`, `DEGREES`, `RADIANS`, `ROUND`, `SIGN`, `SIN`, `SINH`, `TAN`, `TANH`, `SEC`, `SECH`, `CSC`, `CSCH`, `TRUNCATE`, `PI`

|Date and time functions
|`EXTRACT`, `FLOOR`, `CEIL`, `TIMESTAMPADD`, `TIMESTAMPDIFF`, `LAST_DATE`, `DAYNAME`, `MONTHNAME`, `DAYOFMONTH`, `DAYOFWEEK`, `DAYOFYEAR`, `YEAR`, `QUARTER`, `MONTH`, `WEEK`, `HOUR`, `MINUTE`, `SECOND`, `TIMESTAMP_SECONDS`, `TIMESTAMP_MILLIS`, `TIMESTAMP_MICROS`, `UNIX_SECONDS`, `UNIX_MILLIS`, `UNIX_MICROS`, `UNIX_DATE`, `DATE_FROM_UNIX_DATE`, `DATE`, `TIME`, `DATETIME`, `CURRENT_TIME`, `CURRENT_TIMESTAMP`, `CURRENT_DATE`, `LOCALTIME`, `LOCALTIMESTAMP`
Expand Down
2 changes: 1 addition & 1 deletion modules/calcite/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<!-- Module specific package versions -->
<properties>
<avatica.version>1.23.0</avatica.version>
<calcite.version>1.34.0</calcite.version>
<calcite.version>1.37.0</calcite.version>
<checker.version>3.10.0</checker.version>
<failureaccess.version>1.0.1</failureaccess.version>
<immutables.version>2.8.2</immutables.version>
Expand Down
6 changes: 6 additions & 0 deletions modules/calcite/src/main/codegen/config.fmpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ data: {
"JSON_OBJECT"
"JSON_OBJECTAGG"
"JSON_QUERY"
"JSON_SCOPE"
"JSON_VALUE"
"LAG"
"LANGUAGE"
Expand Down Expand Up @@ -273,6 +274,7 @@ data: {
"ONE"
"ONLY"
"OPEN"
"ORDINAL"
"OUT"
"OVER"
"OVERLAPS"
Expand Down Expand Up @@ -324,6 +326,9 @@ data: {
"ROWS"
"ROW_NUMBER"
"RUNNING"
"SAFE_CAST"
"SAFE_OFFSET"
"SAFE_ORDINAL"
"SAVEPOINT"
"SCOPE"
"SCROLL"
Expand Down Expand Up @@ -371,6 +376,7 @@ data: {
"TRIM"
"TRIM_ARRAY"
"TRUNCATE"
"TRY_CAST"
"UESCAPE"
"UNIQUE"
"UNKNOWN"
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
import org.apache.calcite.rex.RexDynamicParam;
import org.apache.calcite.rex.RexFieldAccess;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLambda;
import org.apache.calcite.rex.RexLambdaRef;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexLocalRef;
import org.apache.calcite.rex.RexNode;
Expand Down Expand Up @@ -929,6 +931,22 @@ private static Expression scaleIntervalToNumber(
return deref(localRef).accept(this);
}

/** {@inheritDoc} */
@Override public Result visitLambdaRef(RexLambdaRef ref) {
final ParameterExpression valVariable =
Expressions.parameter(
typeFactory.getJavaClass(ref.getType()), ref.getName());

// Generate one line of code to check whether lambdaRef is null, e.g.,
// "final boolean input_isNull = $0 == null;"
final Expression isNullExpression = checkNull(valVariable);
final ParameterExpression isNullVariable =
Expressions.parameter(
Boolean.TYPE, list.newName("input_isNull"));
list.add(Expressions.declare(Modifier.FINAL, isNullVariable, isNullExpression));
return new Result(isNullVariable, valVariable);
}

/**
* Visit {@code RexLiteral}. If it has never been visited before, {@code RexToLixTranslator} will generate two lines
* of code. For example, when visiting a primitive int (10), the generated code snippet is: {@code final int
Expand Down Expand Up @@ -1284,6 +1302,43 @@ private Result toInnerStorageType(final Result result, final Type storageType) {
return visitInputRef(fieldRef);
}

/** {@inheritDoc} */
@Override public Result visitLambda(RexLambda lambda) {
final RexNode expression = lambda.getExpression();
final List<RexLambdaRef> rexLambdaRefs = lambda.getParameters();

// Prepare parameter expressions for lambda expression
final ParameterExpression[] paramExpressions =
new ParameterExpression[rexLambdaRefs.size()];
for (int i = 0; i < rexLambdaRefs.size(); i++) {
final RexLambdaRef rexLambdaRef = rexLambdaRefs.get(i);
paramExpressions[i] =
Expressions.parameter(
typeFactory.getJavaClass(rexLambdaRef.getType()), rexLambdaRef.getName());
}

// Generate code for lambda expression body
final RexToLixTranslator exprTranslator = setBlock(new BlockBuilder());
final Result exprResult = expression.accept(exprTranslator);
exprTranslator.list.add(
Expressions.return_(null, exprResult.valueVariable));

// Generate code for lambda expression
final Expression functionExpression =
Expressions.lambda(exprTranslator.list.toBlock(), paramExpressions);
final ParameterExpression valVariable =
Expressions.parameter(functionExpression.getType(), list.newName("function_value"));
list.add(Expressions.declare(Modifier.FINAL, valVariable, functionExpression));

// Generate code for checking whether lambda expression is null
final Expression isNullExpression = checkNull(valVariable);
final ParameterExpression isNullVariable =
Expressions.parameter(Boolean.TYPE, list.newName("function_isNull"));
list.add(Expressions.declare(Modifier.FINAL, isNullVariable, isNullExpression));

return new Result(isNullVariable, valVariable);
}

/** */
Expression checkNull(Expression expr) {
if (Primitive.flavor(expr.getType()) == Primitive.Flavor.PRIMITIVE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler;
import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
Expand Down Expand Up @@ -84,6 +86,8 @@ private static <Row> Supplier<Accumulator<Row>> accumulatorFunctionFactory(
return maxFactory(call, hnd);
case "SINGLE_VALUE":
return () -> new SingleVal<>(call, hnd);
case "LITERAL_AGG":
return () -> new LiteralVal<>(call, hnd);
case "ANY_VALUE":
return () -> new AnyVal<>(call, hnd);
case "LISTAGG":
Expand Down Expand Up @@ -312,6 +316,48 @@ private static class SingleVal<Row> extends AnyVal<Row> {
}
}

/**
* LITERAL_AGG accumulator, returns predefined literal value.
* Calcite`s implementation RexImpTable#LiteralAggImplementor.
*/
private static class LiteralVal<Row> extends AbstractAccumulator<Row> {
/** */
public LiteralVal(AggregateCall aggCall, RowHandler<Row> hnd) {
super(aggCall, hnd);
}

/** {@inheritDoc} */
@Override public void add(Row row) {
// No-op.
}

/** {@inheritDoc} */
@Override public void apply(Accumulator<Row> other) {
// No-op.
}

/** {@inheritDoc} */
@Override public Object end() {
assert !F.isEmpty(aggregateCall().rexList) : "aggregateCall().rexList is empty for LITERAL_AGG";

RexNode rexNode = aggregateCall().rexList.get(0);

assert rexNode instanceof RexLiteral;

return ((RexLiteral)rexNode).getValue();
}

/** {@inheritDoc} */
@Override public List<RelDataType> argumentTypes(IgniteTypeFactory typeFactory) {
return F.asList(typeFactory.createTypeWithNullability(typeFactory.createSqlType(ANY), true));
}

/** {@inheritDoc} */
@Override public RelDataType returnType(IgniteTypeFactory typeFactory) {
return aggregateCall().getType();
}
}

/** */
private static class AnyVal<Row> extends AbstractAccumulator<Row> {
/** */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,7 @@ private Object toJson(AggregateCall node) {
map.put("filter", node.filterArg);
map.put("name", node.getName());
map.put("coll", toJson(node.getCollation()));
map.put("rexList", toJson(node.rexList));
return map;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.query.calcite.externalize;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.LinkedHashMap;
Expand All @@ -40,6 +41,7 @@
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.runtime.SqlFunctions;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Pair;
Expand Down Expand Up @@ -220,6 +222,11 @@ private RelInputImpl(Map<String, Object> jsonRel) {
return ((Number)jsonRel.get(tag)).floatValue();
}

/** {@inheritDoc} */
@Override public BigDecimal getBigDecimal(String tag) {
return SqlFunctions.toBigDecimal(jsonRel.get(tag));
}

/** {@inheritDoc} */
@Override public boolean getBoolean(String tag, boolean default_) {
Boolean b = (Boolean)jsonRel.get(tag);
Expand Down Expand Up @@ -331,10 +338,13 @@ private AggregateCall toAggCall(Map<String, Object> jsonAggCall) {
Boolean distinct = (Boolean)jsonAggCall.get("distinct");
List<Integer> operands = (List<Integer>)jsonAggCall.get("operands");
Integer filterOperand = (Integer)jsonAggCall.get("filter");
RelDataType type = relJson.toType(Commons.typeFactory(Commons.emptyCluster()), jsonAggCall.get("type"));
RelDataType type = relJson.toType(Commons.typeFactory(), jsonAggCall.get("type"));
String name = (String)jsonAggCall.get("name");
RelCollation collation = relJson.toCollation((List<Map<String, Object>>)jsonAggCall.get("coll"));
return AggregateCall.create(aggregation, distinct, false, false, operands,
List<RexNode> rexList = Commons.transform((List<Object>)jsonAggCall.get("rexList"),
node -> relJson.toRex(this, node));

return AggregateCall.create(aggregation, distinct, false, false, rexList, operands,
filterOperand == null ? -1 : filterOperand, null, collation, type, name);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ public enum PlannerPhase {
// Works also as CoreRules#JOIN_COMMUTE and overrides it if defined after.
CoreRules.JOIN_COMMUTE_OUTER,

PruneEmptyRules.CORRELATE_LEFT_INSTANCE,
PruneEmptyRules.CORRELATE_RIGHT_INSTANCE,

// Useful of this rule is not clear now.
// CoreRules.AGGREGATE_REDUCE_FUNCTIONS,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.ignite.internal.processors.query.calcite.sql.fun;

import org.apache.calcite.sql.fun.SqlInternalOperators;
import org.apache.calcite.sql.fun.SqlLibraryOperators;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.util.ReflectiveSqlOperatorTable;
Expand Down Expand Up @@ -157,14 +158,18 @@ public IgniteStdSqlOperatorTable() {
register(SqlStdOperatorTable.RAND); // Random.
register(SqlStdOperatorTable.RAND_INTEGER); // Integer random.
register(SqlStdOperatorTable.ACOS); // Arc cosine.
register(SqlLibraryOperators.ACOSH); // Hyperbolic arc cosine.
register(SqlStdOperatorTable.ASIN); // Arc sine.
register(SqlLibraryOperators.ASINH); // Hyperbolic arc sine.
register(SqlStdOperatorTable.ATAN); // Arc tangent.
register(SqlStdOperatorTable.ATAN2); // Angle from coordinates.
register(SqlLibraryOperators.ATANH); // Hyperbolic arc tangent.
register(SqlStdOperatorTable.SQRT); // Square root.
register(SqlStdOperatorTable.CBRT); // Cube root.
register(SqlStdOperatorTable.COS); // Cosine
register(SqlLibraryOperators.COSH); // Hyperbolic cosine.
register(SqlStdOperatorTable.COT); // Cotangent.
register(SqlLibraryOperators.COTH); // Hyperbolic cotangent.
register(SqlStdOperatorTable.DEGREES); // Radians to degrees.
register(SqlStdOperatorTable.RADIANS); // Degrees to radians.
register(SqlStdOperatorTable.ROUND);
Expand All @@ -173,6 +178,10 @@ public IgniteStdSqlOperatorTable() {
register(SqlLibraryOperators.SINH); // Hyperbolic sine.
register(SqlStdOperatorTable.TAN); // Tangent.
register(SqlLibraryOperators.TANH); // Hyperbolic tangent.
register(SqlLibraryOperators.SEC); // Secant.
register(SqlLibraryOperators.SECH); // Hyperbolic secant.
register(SqlLibraryOperators.CSC); // Cosecant.
register(SqlLibraryOperators.CSCH); // Hyperbolic cosecant.
register(SqlStdOperatorTable.TRUNCATE);
register(SqlStdOperatorTable.PI);

Expand Down Expand Up @@ -291,6 +300,9 @@ public IgniteStdSqlOperatorTable() {
register(SqlStdOperatorTable.IS_NOT_JSON_ARRAY);
register(SqlStdOperatorTable.IS_NOT_JSON_SCALAR);

// Aggregate functions.
register(SqlInternalOperators.LITERAL_AGG); // Internal operator, not implemented, required for serialization.

// Current time functions.
register(SqlStdOperatorTable.CURRENT_TIME);
register(SqlStdOperatorTable.CURRENT_TIMESTAMP);
Expand Down
Loading

0 comments on commit d6b3036

Please sign in to comment.