This is an automated email from the ASF dual-hosted git repository.
gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 3d19b748fb SQL OperatorConversions: Introduce.aggregatorBuilder, allow
CAST-as-literal. (#14249)
3d19b748fb is described below
commit 3d19b748fb9fde49f074a8234e797a46bd894d48
Author: Gian Merlino <[email protected]>
AuthorDate: Fri Jun 23 16:25:04 2023 -0700
SQL OperatorConversions: Introduce.aggregatorBuilder, allow
CAST-as-literal. (#14249)
* SQL OperatorConversions: Introduce.aggregatorBuilder, allow
CAST-as-literal.
Four main changes:
1) Provide aggregatorBuilder, a more consistent way of defining the
SqlAggFunction we need for all of our SQL aggregators. The mechanism
is analogous to the one we already use for SQL functions
(OperatorConversions.operatorBuilder).
2) Allow CASTs of constants to be considered as "literalOperands". This
fixes an issue where various of our operators are defined with
OperandTypes.LITERAL as part of their checkers, which doesn't allow
casts. However, in these cases we generally _do_ want to allow casts.
The important piece is that the value must be reducible to a constant,
not that the SQL text is literally a literal.
3) Update DataSketches SQL aggregators to use the new aggregatorBuilder
functionality. The main user-visible effect here is [2]: the aggregators
would now accept, for example, "CAST(0.99 AS DOUBLE)" as a literal
argument. Other aggregators could be updated in a future patch.
4) Rename "requiredOperands" to "requiredOperandCount", because the
old name was confusing. (It rhymes with "literalOperands" but the
arguments mean different things.)
* Adjust method calls.
---
.../HllSketchApproxCountDistinctSqlAggregator.java | 42 +---
.../sql/HllSketchEstimateOperatorConversion.java | 2 +-
...hEstimateWithErrorBoundsOperatorConversion.java | 2 +-
.../hll/sql/HllSketchObjectSqlAggregator.java | 41 +---
.../DoublesSketchApproxQuantileSqlAggregator.java | 44 +---
.../sql/DoublesSketchObjectSqlAggregator.java | 40 +---
...hetaSketchApproxCountDistinctSqlAggregator.java | 42 +---
.../theta/sql/ThetaSketchObjectSqlAggregator.java | 40 +---
.../hll/sql/HllSketchSqlAggregatorTest.java | 10 +-
.../sql/DoublesSketchSqlAggregatorTest.java | 2 +-
.../druid/query/sql/SleepOperatorConversion.java | 2 +-
.../testing/tools/SleepOperatorConversion.java | 2 +-
.../calcite/expression/OperatorConversions.java | 226 ++++++++++++++++-----
.../builtin/BTrimOperatorConversion.java | 2 +-
.../builtin/ContainsOperatorConversion.java | 2 +-
.../builtin/DateTruncOperatorConversion.java | 2 +-
.../expression/builtin/LPadOperatorConversion.java | 2 +-
.../builtin/LTrimOperatorConversion.java | 2 +-
.../builtin/ParseLongOperatorConversion.java | 2 +-
.../expression/builtin/RPadOperatorConversion.java | 2 +-
.../builtin/RTrimOperatorConversion.java | 2 +-
.../builtin/RegexpExtractOperatorConversion.java | 2 +-
.../builtin/RegexpLikeOperatorConversion.java | 2 +-
.../builtin/RoundOperatorConversion.java | 2 +-
.../builtin/SubstringOperatorConversion.java | 2 +-
.../builtin/TextcatOperatorConversion.java | 2 +-
.../builtin/TimeCeilOperatorConversion.java | 2 +-
.../builtin/TimeExtractOperatorConversion.java | 2 +-
.../builtin/TimeFloorOperatorConversion.java | 2 +-
.../builtin/TimeFormatOperatorConversion.java | 2 +-
.../builtin/TimeParseOperatorConversion.java | 2 +-
.../builtin/TimeShiftOperatorConversion.java | 2 +-
.../builtin/TruncateOperatorConversion.java | 2 +-
.../expression/OperatorConversionsTest.java | 66 ++++--
.../calcite/planner/DruidOperatorTableTest.java | 2 +-
.../sql/calcite/planner/DruidRexExecutorTest.java | 2 +-
.../sql/calcite/schema/InformationSchemaTest.java | 6 +-
37 files changed, 324 insertions(+), 287 deletions(-)
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchApproxCountDistinctSqlAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchApproxCountDistinctSqlAggregator.java
index 461b2316f1..29f7c819be 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchApproxCountDistinctSqlAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchApproxCountDistinctSqlAggregator.java
@@ -21,24 +21,30 @@ package
org.apache.druid.query.aggregation.datasketches.hll.sql;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
-import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.type.InferTypes;
-import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.druid.query.aggregation.AggregatorFactory;
import
org.apache.druid.query.aggregation.post.FinalizingFieldAccessPostAggregator;
import org.apache.druid.sql.calcite.aggregation.Aggregation;
import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
import java.util.Collections;
public class HllSketchApproxCountDistinctSqlAggregator extends
HllSketchBaseSqlAggregator implements SqlAggregator
{
public static final String NAME = "APPROX_COUNT_DISTINCT_DS_HLL";
-
- private static final SqlAggFunction FUNCTION_INSTANCE = new
HllSketchApproxCountDistinctSqlAggFunction();
+ private static final SqlAggFunction FUNCTION_INSTANCE =
+ OperatorConversions.aggregatorBuilder(NAME)
+ .operandNames("column", "lgK", "tgtHllType")
+ .operandTypes(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC, SqlTypeFamily.STRING)
+ .operandTypeInference(InferTypes.VARCHAR_1024)
+ .requiredOperandCount(1)
+ .literalOperands(1, 2)
+ .returnTypeNonNull(SqlTypeName.BIGINT)
+ .functionCategory(SqlFunctionCategory.NUMERIC)
+ .build();
public HllSketchApproxCountDistinctSqlAggregator()
{
@@ -66,30 +72,4 @@ public class HllSketchApproxCountDistinctSqlAggregator
extends HllSketchBaseSqlA
) : null
);
}
-
- private static class HllSketchApproxCountDistinctSqlAggFunction extends
SqlAggFunction
- {
- private static final String SIGNATURE = "'" + NAME + "(column, lgK,
tgtHllType)'";
-
- HllSketchApproxCountDistinctSqlAggFunction()
- {
- super(
- NAME,
- null,
- SqlKind.OTHER_FUNCTION,
- ReturnTypes.explicit(SqlTypeName.BIGINT),
- InferTypes.VARCHAR_1024,
- OperandTypes.or(
- OperandTypes.ANY,
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE, OperandTypes.ANY,
OperandTypes.LITERAL, OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC, SqlTypeFamily.STRING)
- )
- ),
- SqlFunctionCategory.NUMERIC,
- false,
- false
- );
- }
- }
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateOperatorConversion.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateOperatorConversion.java
index fa15493353..dbc4bf8bcd 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateOperatorConversion.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateOperatorConversion.java
@@ -47,7 +47,7 @@ public class HllSketchEstimateOperatorConversion implements
SqlOperatorConversio
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder(StringUtils.toUpperCase(FUNCTION_NAME))
.operandTypes(SqlTypeFamily.ANY, SqlTypeFamily.BOOLEAN)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeInference(ReturnTypes.DOUBLE)
.build();
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateWithErrorBoundsOperatorConversion.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateWithErrorBoundsOperatorConversion.java
index 83a0ce43bf..cc89d4c7a5 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateWithErrorBoundsOperatorConversion.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchEstimateWithErrorBoundsOperatorConversion.java
@@ -46,7 +46,7 @@ public class
HllSketchEstimateWithErrorBoundsOperatorConversion implements SqlOp
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder(StringUtils.toUpperCase(FUNCTION_NAME))
.operandTypes(SqlTypeFamily.ANY, SqlTypeFamily.INTEGER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.OTHER)
.build();
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchObjectSqlAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchObjectSqlAggregator.java
index 56fdbd3381..8e695148b9 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchObjectSqlAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchObjectSqlAggregator.java
@@ -21,22 +21,29 @@ package
org.apache.druid.query.aggregation.datasketches.hll.sql;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
-import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.type.InferTypes;
-import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.druid.query.aggregation.AggregatorFactory;
import org.apache.druid.sql.calcite.aggregation.Aggregation;
import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
import java.util.Collections;
public class HllSketchObjectSqlAggregator extends HllSketchBaseSqlAggregator
implements SqlAggregator
{
- private static final SqlAggFunction FUNCTION_INSTANCE = new
HllSketchSqlAggFunction();
private static final String NAME = "DS_HLL";
+ private static final SqlAggFunction FUNCTION_INSTANCE =
+ OperatorConversions.aggregatorBuilder(NAME)
+ .operandNames("column", "lgK", "tgtHllType")
+ .operandTypes(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC, SqlTypeFamily.STRING)
+ .operandTypeInference(InferTypes.VARCHAR_1024)
+ .requiredOperandCount(1)
+ .literalOperands(1, 2)
+ .returnTypeNonNull(SqlTypeName.OTHER)
+
.functionCategory(SqlFunctionCategory.USER_DEFINED_FUNCTION)
+ .build();
public HllSketchObjectSqlAggregator()
{
@@ -61,30 +68,4 @@ public class HllSketchObjectSqlAggregator extends
HllSketchBaseSqlAggregator imp
null
);
}
-
- private static class HllSketchSqlAggFunction extends SqlAggFunction
- {
- private static final String SIGNATURE = "'" + NAME + "(column, lgK,
tgtHllType)'";
-
- HllSketchSqlAggFunction()
- {
- super(
- NAME,
- null,
- SqlKind.OTHER_FUNCTION,
- ReturnTypes.explicit(SqlTypeName.OTHER),
- InferTypes.VARCHAR_1024,
- OperandTypes.or(
- OperandTypes.ANY,
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE, OperandTypes.ANY,
OperandTypes.LITERAL, OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC, SqlTypeFamily.STRING)
- )
- ),
- SqlFunctionCategory.USER_DEFINED_FUNCTION,
- false,
- false
- );
- }
- }
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchApproxQuantileSqlAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchApproxQuantileSqlAggregator.java
index 0b4bbd7f11..7864447c49 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchApproxQuantileSqlAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchApproxQuantileSqlAggregator.java
@@ -28,8 +28,6 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.druid.java.util.common.StringUtils;
@@ -45,19 +43,27 @@ import
org.apache.druid.sql.calcite.aggregation.Aggregations;
import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
import org.apache.druid.sql.calcite.expression.DruidExpression;
import org.apache.druid.sql.calcite.expression.Expressions;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
import org.apache.druid.sql.calcite.planner.PlannerContext;
import org.apache.druid.sql.calcite.rel.VirtualColumnRegistry;
import javax.annotation.Nullable;
-
import java.util.List;
public class DoublesSketchApproxQuantileSqlAggregator implements SqlAggregator
{
public static final String CTX_APPROX_QUANTILE_DS_MAX_STREAM_LENGTH =
"approxQuantileDsMaxStreamLength";
- private static final SqlAggFunction FUNCTION_INSTANCE = new
DoublesSketchApproxQuantileSqlAggFunction();
private static final String NAME = "APPROX_QUANTILE_DS";
+ private static final SqlAggFunction FUNCTION_INSTANCE =
+ OperatorConversions.aggregatorBuilder(NAME)
+ .operandNames("column", "probability", "k")
+ .operandTypes(SqlTypeFamily.ANY, SqlTypeFamily.NUMERIC,
SqlTypeFamily.EXACT_NUMERIC)
+ .returnTypeNonNull(SqlTypeName.DOUBLE)
+ .requiredOperandCount(2)
+ .literalOperands(1, 2)
+ .functionCategory(SqlFunctionCategory.NUMERIC)
+ .build();
@Override
public SqlAggFunction calciteFunction()
@@ -212,34 +218,4 @@ public class DoublesSketchApproxQuantileSqlAggregator
implements SqlAggregator
DoublesSketchAggregatorFactory.DEFAULT_MAX_STREAM_LENGTH
);
}
-
- private static class DoublesSketchApproxQuantileSqlAggFunction extends
SqlAggFunction
- {
- private static final String SIGNATURE1 = "'" + NAME + "(column,
probability)'";
- private static final String SIGNATURE2 = "'" + NAME + "(column,
probability, k)'";
-
- DoublesSketchApproxQuantileSqlAggFunction()
- {
- super(
- NAME,
- null,
- SqlKind.OTHER_FUNCTION,
- ReturnTypes.explicit(SqlTypeName.DOUBLE),
- null,
- OperandTypes.or(
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE1, OperandTypes.ANY,
OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.NUMERIC)
- ),
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE2, OperandTypes.ANY,
OperandTypes.LITERAL, OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC, SqlTypeFamily.EXACT_NUMERIC)
- )
- ),
- SqlFunctionCategory.NUMERIC,
- false,
- false
- );
- }
- }
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchObjectSqlAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchObjectSqlAggregator.java
index b82f02fc45..049e1284a9 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchObjectSqlAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchObjectSqlAggregator.java
@@ -28,8 +28,6 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.druid.java.util.common.StringUtils;
@@ -43,17 +41,25 @@ import
org.apache.druid.sql.calcite.aggregation.Aggregations;
import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
import org.apache.druid.sql.calcite.expression.DruidExpression;
import org.apache.druid.sql.calcite.expression.Expressions;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
import org.apache.druid.sql.calcite.planner.PlannerContext;
import org.apache.druid.sql.calcite.rel.VirtualColumnRegistry;
import javax.annotation.Nullable;
-
import java.util.List;
public class DoublesSketchObjectSqlAggregator implements SqlAggregator
{
- private static final SqlAggFunction FUNCTION_INSTANCE = new
DoublesSketchSqlAggFunction();
private static final String NAME = "DS_QUANTILES_SKETCH";
+ private static final SqlAggFunction FUNCTION_INSTANCE =
+ OperatorConversions.aggregatorBuilder(NAME)
+ .operandNames("column", "k")
+ .operandTypes(SqlTypeFamily.ANY,
SqlTypeFamily.EXACT_NUMERIC)
+ .returnTypeNonNull(SqlTypeName.OTHER)
+ .requiredOperandCount(1)
+ .literalOperands(1)
+ .functionCategory(SqlFunctionCategory.NUMERIC)
+ .build();
@Override
public SqlAggFunction calciteFunction()
@@ -139,30 +145,4 @@ public class DoublesSketchObjectSqlAggregator implements
SqlAggregator
null
);
}
-
- private static class DoublesSketchSqlAggFunction extends SqlAggFunction
- {
- private static final String SIGNATURE2 = "'" + NAME + "(column, k)'";
-
- DoublesSketchSqlAggFunction()
- {
- super(
- NAME,
- null,
- SqlKind.OTHER_FUNCTION,
- ReturnTypes.explicit(SqlTypeName.OTHER),
- null,
- OperandTypes.or(
- OperandTypes.ANY,
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE2, OperandTypes.ANY,
OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY,
SqlTypeFamily.EXACT_NUMERIC)
- )
- ),
- SqlFunctionCategory.USER_DEFINED_FUNCTION,
- false,
- false
- );
- }
- }
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchApproxCountDistinctSqlAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchApproxCountDistinctSqlAggregator.java
index 70eb943a8c..eac77901f1 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchApproxCountDistinctSqlAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchApproxCountDistinctSqlAggregator.java
@@ -21,24 +21,30 @@ package
org.apache.druid.query.aggregation.datasketches.theta.sql;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
-import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.type.InferTypes;
-import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.druid.query.aggregation.AggregatorFactory;
import
org.apache.druid.query.aggregation.post.FinalizingFieldAccessPostAggregator;
import org.apache.druid.sql.calcite.aggregation.Aggregation;
import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
import java.util.Collections;
public class ThetaSketchApproxCountDistinctSqlAggregator extends
ThetaSketchBaseSqlAggregator implements SqlAggregator
{
public static final String NAME = "APPROX_COUNT_DISTINCT_DS_THETA";
-
- private static final SqlAggFunction FUNCTION_INSTANCE = new
ThetaSketchSqlAggFunction();
+ private static final SqlAggFunction FUNCTION_INSTANCE =
+ OperatorConversions.aggregatorBuilder(NAME)
+ .operandNames("column", "size")
+ .operandTypes(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC)
+ .operandTypeInference(InferTypes.VARCHAR_1024)
+ .requiredOperandCount(1)
+ .literalOperands(1)
+ .returnTypeNonNull(SqlTypeName.BIGINT)
+
.functionCategory(SqlFunctionCategory.USER_DEFINED_FUNCTION)
+ .build();
public ThetaSketchApproxCountDistinctSqlAggregator()
{
@@ -66,30 +72,4 @@ public class ThetaSketchApproxCountDistinctSqlAggregator
extends ThetaSketchBase
) : null
);
}
-
- private static class ThetaSketchSqlAggFunction extends SqlAggFunction
- {
- private static final String SIGNATURE = "'" + NAME + "(column, size)'";
-
- ThetaSketchSqlAggFunction()
- {
- super(
- NAME,
- null,
- SqlKind.OTHER_FUNCTION,
- ReturnTypes.explicit(SqlTypeName.BIGINT),
- InferTypes.VARCHAR_1024,
- OperandTypes.or(
- OperandTypes.ANY,
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE, OperandTypes.ANY,
OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.NUMERIC)
- )
- ),
- SqlFunctionCategory.NUMERIC,
- false,
- false
- );
- }
- }
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchObjectSqlAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchObjectSqlAggregator.java
index 91dd36c2fb..ac9cefd5f9 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchObjectSqlAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchObjectSqlAggregator.java
@@ -21,20 +21,28 @@ package
org.apache.druid.query.aggregation.datasketches.theta.sql;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
-import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.type.InferTypes;
-import org.apache.calcite.sql.type.OperandTypes;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.druid.query.aggregation.AggregatorFactory;
import org.apache.druid.sql.calcite.aggregation.Aggregation;
import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
import java.util.Collections;
public class ThetaSketchObjectSqlAggregator extends
ThetaSketchBaseSqlAggregator implements SqlAggregator
{
- private static final SqlAggFunction FUNCTION_INSTANCE = new
ThetaSketchObjectSqlAggFunction();
private static final String NAME = "DS_THETA";
+ private static final SqlAggFunction FUNCTION_INSTANCE =
+ OperatorConversions.aggregatorBuilder(NAME)
+ .operandNames("column", "size")
+ .operandTypes(SqlTypeFamily.ANY,
SqlTypeFamily.NUMERIC)
+ .operandTypeInference(InferTypes.VARCHAR_1024)
+ .requiredOperandCount(1)
+ .literalOperands(1)
+
.returnTypeInference(ThetaSketchSqlOperators.RETURN_TYPE_INFERENCE)
+
.functionCategory(SqlFunctionCategory.USER_DEFINED_FUNCTION)
+ .build();
public ThetaSketchObjectSqlAggregator()
{
@@ -59,30 +67,4 @@ public class ThetaSketchObjectSqlAggregator extends
ThetaSketchBaseSqlAggregator
null
);
}
-
- private static class ThetaSketchObjectSqlAggFunction extends SqlAggFunction
- {
- private static final String SIGNATURE = "'" + NAME + "(column, size)'";
-
- ThetaSketchObjectSqlAggFunction()
- {
- super(
- NAME,
- null,
- SqlKind.OTHER_FUNCTION,
- ThetaSketchSqlOperators.RETURN_TYPE_INFERENCE,
- InferTypes.VARCHAR_1024,
- OperandTypes.or(
- OperandTypes.ANY,
- OperandTypes.and(
- OperandTypes.sequence(SIGNATURE, OperandTypes.ANY,
OperandTypes.LITERAL),
- OperandTypes.family(SqlTypeFamily.ANY, SqlTypeFamily.NUMERIC)
- )
- ),
- SqlFunctionCategory.USER_DEFINED_FUNCTION,
- false,
- false
- );
- }
- }
}
diff --git
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
index 9d7c4b8c03..99c93a1ced 100644
---
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
+++
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
@@ -177,18 +177,19 @@ public class HllSketchSqlAggregatorTest extends
BaseCalciteQueryTest
+ " APPROX_COUNT_DISTINCT(SUBSTRING(dim2, 1, 1)),\n"
// on extractionFn, using generic A.C.D.
+ " COUNT(DISTINCT SUBSTRING(dim2, 1, 1) || 'x'),\n"
// on expression, using COUNT DISTINCT
+ " APPROX_COUNT_DISTINCT_DS_HLL(hllsketch_dim1, 21,
'HLL_8'),\n" // on native HllSketch column
- + " APPROX_COUNT_DISTINCT_DS_HLL(hllsketch_dim1)\n" //
on native HllSketch column
+ + " APPROX_COUNT_DISTINCT_DS_HLL(hllsketch_dim1),\n"
// on native HllSketch column
+ + " APPROX_COUNT_DISTINCT_DS_HLL(hllsketch_dim1,
CAST(21 AS BIGINT))\n" // also native column
+ "FROM druid.foo";
final List<Object[]> expectedResults;
if (NullHandling.replaceWithDefault()) {
expectedResults = ImmutableList.of(
- new Object[]{6L, 2L, 2L, 1L, 2L, 5L, 5L}
+ new Object[]{6L, 2L, 2L, 1L, 2L, 5L, 5L, 5L}
);
} else {
expectedResults = ImmutableList.of(
- new Object[]{6L, 2L, 2L, 1L, 1L, 5L, 5L}
+ new Object[]{6L, 2L, 2L, 1L, 1L, 5L, 5L, 5L}
);
}
@@ -252,7 +253,8 @@ public class HllSketchSqlAggregatorTest extends
BaseCalciteQueryTest
ROUND
),
new HllSketchMergeAggregatorFactory("a5",
"hllsketch_dim1", 21, "HLL_8", null, ROUND),
- new HllSketchMergeAggregatorFactory("a6",
"hllsketch_dim1", null, null, null, ROUND)
+ new HllSketchMergeAggregatorFactory("a6",
"hllsketch_dim1", null, null, null, ROUND),
+ new HllSketchMergeAggregatorFactory("a7",
"hllsketch_dim1", 21, "HLL_4", null, ROUND)
)
)
.context(QUERY_CONTEXT_DEFAULT)
diff --git
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
index 8f244e5302..184aba375a 100644
---
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
+++
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
@@ -207,7 +207,7 @@ public class DoublesSketchSqlAggregatorTest extends
BaseCalciteQueryTest
+ "APPROX_QUANTILE_DS(qsketch_m1, 0.01),\n"
+ "APPROX_QUANTILE_DS(qsketch_m1, 0.5, 64),\n"
+ "APPROX_QUANTILE_DS(qsketch_m1, 0.98, 256),\n"
- + "APPROX_QUANTILE_DS(qsketch_m1, 0.99),\n"
+ + "APPROX_QUANTILE_DS(qsketch_m1, CAST(0.99 AS DOUBLE)),\n"
+ "APPROX_QUANTILE_DS(qsketch_m1, 0.99) FILTER(WHERE dim1 = 'abc'),\n"
+ "APPROX_QUANTILE_DS(qsketch_m1, 0.999) FILTER(WHERE dim1 <>
'abc'),\n"
+ "APPROX_QUANTILE_DS(qsketch_m1, 0.999) FILTER(WHERE dim1 = 'abc')\n"
diff --git
a/extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java
b/extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java
index 06d841af3f..d64947d535 100644
---
a/extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java
+++
b/extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java
@@ -42,7 +42,7 @@ public class SleepOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("SLEEP")
.operandTypes(SqlTypeFamily.NUMERIC)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNullable(SqlTypeName.VARCHAR) // always null
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/integration-tests-ex/tools/src/main/java/org/apache/druid/testing/tools/SleepOperatorConversion.java
b/integration-tests-ex/tools/src/main/java/org/apache/druid/testing/tools/SleepOperatorConversion.java
index cae087cf71..abc31d3a43 100644
---
a/integration-tests-ex/tools/src/main/java/org/apache/druid/testing/tools/SleepOperatorConversion.java
+++
b/integration-tests-ex/tools/src/main/java/org/apache/druid/testing/tools/SleepOperatorConversion.java
@@ -42,7 +42,7 @@ public class SleepOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("SLEEP")
.operandTypes(SqlTypeFamily.NUMERIC)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNullable(SqlTypeName.VARCHAR) // always null
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/OperatorConversions.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/OperatorConversions.java
index c0efb14017..6e3543d737 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/OperatorConversions.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/OperatorConversions.java
@@ -32,6 +32,7 @@ import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.runtime.CalciteException;
+import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlCallBinding;
import org.apache.calcite.sql.SqlFunction;
import org.apache.calcite.sql.SqlFunctionCategory;
@@ -49,6 +50,7 @@ import org.apache.calcite.sql.type.SqlReturnTypeInference;
import org.apache.calcite.sql.type.SqlTypeFamily;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeTransforms;
+import org.apache.calcite.util.Optionality;
import org.apache.calcite.util.Static;
import org.apache.druid.java.util.common.IAE;
import org.apache.druid.java.util.common.ISE;
@@ -57,12 +59,14 @@ import org.apache.druid.query.aggregation.PostAggregator;
import org.apache.druid.query.aggregation.post.ExpressionPostAggregator;
import org.apache.druid.query.aggregation.post.FieldAccessPostAggregator;
import org.apache.druid.segment.column.RowSignature;
+import org.apache.druid.sql.calcite.aggregation.SqlAggregator;
import org.apache.druid.sql.calcite.planner.Calcites;
import org.apache.druid.sql.calcite.planner.DruidTypeSystem;
import org.apache.druid.sql.calcite.planner.PlannerContext;
import javax.annotation.Nullable;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.IntStream;
@@ -316,23 +320,33 @@ public class OperatorConversions
* Returns a builder that helps {@link SqlOperatorConversion}
implementations create the {@link SqlFunction}
* objects they need to return from {@link
SqlOperatorConversion#calciteOperator()}.
*/
- public static OperatorBuilder operatorBuilder(final String name)
+ public static OperatorBuilder<SqlFunction> operatorBuilder(final String name)
{
- return new OperatorBuilder(name);
+ return new OperatorBuilder<>(name);
}
- public static class OperatorBuilder
+ /**
+ * Returns a builder that helps {@link SqlAggregator} implementations create
the {@link SqlAggFunction} objects
+ * they need to return from {@link SqlAggregator#calciteFunction()}.
+ */
+ public static OperatorBuilder<SqlAggFunction> aggregatorBuilder(final String
name)
+ {
+ return new AggregatorBuilder(name);
+ }
+
+ public static class OperatorBuilder<T extends SqlFunction>
{
- private final String name;
- private SqlKind kind = SqlKind.OTHER_FUNCTION;
- private SqlReturnTypeInference returnTypeInference;
- private SqlFunctionCategory functionCategory =
SqlFunctionCategory.USER_DEFINED_FUNCTION;
+ protected final String name;
+ protected SqlKind kind = SqlKind.OTHER_FUNCTION;
+ protected SqlReturnTypeInference returnTypeInference;
+ protected SqlFunctionCategory functionCategory =
SqlFunctionCategory.USER_DEFINED_FUNCTION;
// For operand type checking
private SqlOperandTypeChecker operandTypeChecker;
+ private List<String> operandNames = Collections.emptyList();
private List<SqlTypeFamily> operandTypes;
- private Integer requiredOperands = null;
- private int[] literalOperands = null;
+ private Integer requiredOperandCount;
+ private int[] literalOperands;
private SqlOperandTypeInference operandTypeInference;
private OperatorBuilder(final String name)
@@ -348,7 +362,7 @@ public class OperatorConversions
* {@link #returnTypeNullableArrayWithNullableElements}, or {@link
#returnTypeInference(SqlReturnTypeInference)}
* must be used before calling {@link #build()}. These methods cannot be
mixed; you must call exactly one.
*/
- public OperatorBuilder returnTypeNonNull(final SqlTypeName typeName)
+ public OperatorBuilder<T> returnTypeNonNull(final SqlTypeName typeName)
{
Preconditions.checkState(this.returnTypeInference == null, "Cannot set
return type multiple times");
@@ -365,7 +379,7 @@ public class OperatorConversions
* {@link #returnTypeNullableArrayWithNullableElements}, or {@link
#returnTypeInference(SqlReturnTypeInference)}
* must be used before calling {@link #build()}. These methods cannot be
mixed; you must call exactly one.
*/
- public OperatorBuilder returnTypeNullable(final SqlTypeName typeName)
+ public OperatorBuilder<T> returnTypeNullable(final SqlTypeName typeName)
{
Preconditions.checkState(this.returnTypeInference == null, "Cannot set
return type multiple times");
@@ -382,7 +396,7 @@ public class OperatorConversions
* {@link #returnTypeNullableArrayWithNullableElements}, or {@link
#returnTypeInference(SqlReturnTypeInference)}
* must be used before calling {@link #build()}. These methods cannot be
mixed; you must call exactly one.
*/
- public OperatorBuilder returnTypeCascadeNullable(final SqlTypeName
typeName)
+ public OperatorBuilder<T> returnTypeCascadeNullable(final SqlTypeName
typeName)
{
Preconditions.checkState(this.returnTypeInference == null, "Cannot set
return type multiple times");
this.returnTypeInference =
ReturnTypes.cascade(ReturnTypes.explicit(typeName),
SqlTypeTransforms.TO_NULLABLE);
@@ -396,7 +410,7 @@ public class OperatorConversions
* {@link #returnTypeArrayWithNullableElements}, or {@link
#returnTypeInference(SqlReturnTypeInference)} must be
* used before calling {@link #build()}. These methods cannot be mixed;
you must call exactly one.
*/
- public OperatorBuilder returnTypeArrayWithNullableElements(final
SqlTypeName elementTypeName)
+ public OperatorBuilder<T> returnTypeArrayWithNullableElements(final
SqlTypeName elementTypeName)
{
Preconditions.checkState(this.returnTypeInference == null, "Cannot set
return type multiple times");
@@ -413,7 +427,7 @@ public class OperatorConversions
* {@link #returnTypeArrayWithNullableElements}, or {@link
#returnTypeInference(SqlReturnTypeInference)} must be
* used before calling {@link #build()}. These methods cannot be mixed;
you must call exactly one.
*/
- public OperatorBuilder returnTypeNullableArrayWithNullableElements(final
SqlTypeName elementTypeName)
+ public OperatorBuilder<T>
returnTypeNullableArrayWithNullableElements(final SqlTypeName elementTypeName)
{
this.returnTypeInference = ReturnTypes.cascade(
opBinding -> Calcites.createSqlArrayTypeWithNullability(
@@ -434,7 +448,7 @@ public class OperatorConversions
* {@link #returnTypeNullableArrayWithNullableElements}, or {@link
#returnTypeInference(SqlReturnTypeInference)}
* must be used before calling {@link #build()}. These methods cannot be
mixed; you must call exactly one.
*/
- public OperatorBuilder returnTypeInference(final SqlReturnTypeInference
returnTypeInference)
+ public OperatorBuilder<T> returnTypeInference(final SqlReturnTypeInference
returnTypeInference)
{
Preconditions.checkState(this.returnTypeInference == null, "Cannot set
return type multiple times");
@@ -447,7 +461,7 @@ public class OperatorConversions
*
* The default, if not provided, is {@link
SqlFunctionCategory#USER_DEFINED_FUNCTION}.
*/
- public OperatorBuilder functionCategory(final SqlFunctionCategory
functionCategory)
+ public OperatorBuilder<T> functionCategory(final SqlFunctionCategory
functionCategory)
{
this.functionCategory = functionCategory;
return this;
@@ -459,21 +473,32 @@ public class OperatorConversions
* One of {@link #operandTypes(SqlTypeFamily...)} or {@link
#operandTypeChecker(SqlOperandTypeChecker)} must be used
* before calling {@link #build()}. These methods cannot be mixed; you
must call exactly one.
*/
- public OperatorBuilder operandTypeChecker(final SqlOperandTypeChecker
operandTypeChecker)
+ public OperatorBuilder<T> operandTypeChecker(final SqlOperandTypeChecker
operandTypeChecker)
{
this.operandTypeChecker = operandTypeChecker;
return this;
}
+ /**
+ * Signifies that a function accepts operands with the provided names.
This is used to implement
+ * {@link SqlOperandTypeChecker#getAllowedSignatures(SqlOperator,
String)}. If not provided, the
+ * {@link #operandTypes} are used instead.
+ */
+ public OperatorBuilder<T> operandNames(final String... operandNames)
+ {
+ this.operandNames = Arrays.asList(operandNames);
+ return this;
+ }
+
/**
* Signifies that a function accepts operands of type family given by
{@param operandTypes}.
*
- * May be used in conjunction with {@link #requiredOperands(int)} and
{@link #literalOperands(int...)} in order
+ * May be used in conjunction with {@link #requiredOperandCount(int)} and
{@link #literalOperands(int...)} in order
* to further refine operand checking logic.
*
* For deeper control, use {@link
#operandTypeChecker(SqlOperandTypeChecker)} instead.
*/
- public OperatorBuilder operandTypes(final SqlTypeFamily... operandTypes)
+ public OperatorBuilder<T> operandTypes(final SqlTypeFamily... operandTypes)
{
this.operandTypes = Arrays.asList(operandTypes);
return this;
@@ -489,67 +514,97 @@ public class OperatorConversions
* Must be used in conjunction with {@link
#operandTypes(SqlTypeFamily...)}; this method is not compatible with
* {@link #operandTypeChecker(SqlOperandTypeChecker)}.
*/
- public OperatorBuilder requiredOperands(final int requiredOperands)
+ public OperatorBuilder<T> requiredOperandCount(final int
requiredOperandCount)
{
- this.requiredOperands = requiredOperands;
+ this.requiredOperandCount = requiredOperandCount;
return this;
}
+ /**
+ * Alias for {@link #requiredOperandCount(int)}. Deprecated because it
means "operand count" rather than
+ * "specific operands", and therefore the name can cause confusion with
{@link #literalOperands(int...)}. The latter
+ * really does mean "specific operands".
+ */
+ @Deprecated
+ @SuppressWarnings("unused") // For compatibility with existing extensions
+ public OperatorBuilder<T> requiredOperands(final int requiredOperands)
+ {
+ return requiredOperandCount(requiredOperands);
+ }
+
/**
* Signifies that the operands at positions given by {@code
literalOperands} must be literals.
*
* Must be used in conjunction with {@link
#operandTypes(SqlTypeFamily...)}; this method is not compatible with
* {@link #operandTypeChecker(SqlOperandTypeChecker)}.
*/
- public OperatorBuilder literalOperands(final int... literalOperands)
+ public OperatorBuilder<T> literalOperands(final int... literalOperands)
{
this.literalOperands = literalOperands;
return this;
}
- public OperatorBuilder operandTypeInference(SqlOperandTypeInference
operandTypeInference)
+ public OperatorBuilder<T> operandTypeInference(SqlOperandTypeInference
operandTypeInference)
{
this.operandTypeInference = operandTypeInference;
return this;
}
- public OperatorBuilder sqlKind(SqlKind kind)
- {
- this.kind = kind;
- return this;
- }
-
/**
* Creates a {@link SqlFunction} from this builder.
*/
- public SqlFunction build()
+ @SuppressWarnings("unchecked")
+ public T build()
+ {
+ final IntSet nullableOperands = buildNullableOperands();
+ return (T) new SqlFunction(
+ name,
+ kind,
+ Preconditions.checkNotNull(returnTypeInference,
"returnTypeInference"),
+ buildOperandTypeInference(nullableOperands),
+ buildOperandTypeChecker(nullableOperands),
+ functionCategory
+ );
+ }
+
+ protected IntSet buildNullableOperands()
{
// Create "nullableOperands" set including all optional arguments.
final IntSet nullableOperands = new IntArraySet();
- if (requiredOperands != null) {
- IntStream.range(requiredOperands,
operandTypes.size()).forEach(nullableOperands::add);
+ if (requiredOperandCount != null) {
+ IntStream.range(requiredOperandCount,
operandTypes.size()).forEach(nullableOperands::add);
}
+ return nullableOperands;
+ }
- final SqlOperandTypeChecker theOperandTypeChecker;
-
+ protected SqlOperandTypeChecker buildOperandTypeChecker(final IntSet
nullableOperands)
+ {
if (operandTypeChecker == null) {
- theOperandTypeChecker = new DefaultOperandTypeChecker(
+ return new DefaultOperandTypeChecker(
+ operandNames,
operandTypes,
- requiredOperands == null ? operandTypes.size() : requiredOperands,
+ requiredOperandCount == null ? operandTypes.size() :
requiredOperandCount,
nullableOperands,
literalOperands
);
- } else if (operandTypes == null && requiredOperands == null &&
literalOperands == null) {
- theOperandTypeChecker = operandTypeChecker;
+ } else if (operandNames.isEmpty()
+ && operandTypes == null
+ && requiredOperandCount == null
+ && literalOperands == null) {
+ return operandTypeChecker;
} else {
throw new ISE(
- "Cannot have both 'operandTypeChecker' and 'operandTypes' /
'requiredOperands' / 'literalOperands'"
+ "Cannot have both 'operandTypeChecker' and "
+ + "'operandNames' / 'operandTypes' / 'requiredOperands' /
'literalOperands'"
);
}
+ }
+ protected SqlOperandTypeInference buildOperandTypeInference(final IntSet
nullableOperands)
+ {
if (operandTypeInference == null) {
SqlOperandTypeInference defaultInference = new
DefaultOperandTypeInference(operandTypes, nullableOperands);
- operandTypeInference = (callBinding, returnType, types) -> {
+ return (callBinding, returnType, types) -> {
for (int i = 0; i < types.length; i++) {
// calcite sql validate tries to do bad things to dynamic
parameters if the type is inferred to be a string
if
(callBinding.operand(i).isA(ImmutableSet.of(SqlKind.DYNAMIC_PARAM))) {
@@ -562,15 +617,49 @@ public class OperatorConversions
}
}
};
+ } else {
+ return operandTypeInference;
}
- return new SqlFunction(
- name,
- kind,
- Preconditions.checkNotNull(returnTypeInference,
"returnTypeInference"),
- operandTypeInference,
- theOperandTypeChecker,
- functionCategory
- );
+ }
+ }
+
+ public static class AggregatorBuilder extends OperatorBuilder<SqlAggFunction>
+ {
+ public AggregatorBuilder(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Create a {@link SqlAggFunction} from this builder.
+ */
+ @Override
+ public SqlAggFunction build()
+ {
+ final IntSet nullableOperands = buildNullableOperands();
+ final SqlOperandTypeInference operandTypeInference =
buildOperandTypeInference(nullableOperands);
+ final SqlOperandTypeChecker operandTypeChecker =
buildOperandTypeChecker(nullableOperands);
+
+ class DruidSqlAggFunction extends SqlAggFunction
+ {
+ public DruidSqlAggFunction()
+ {
+ super(
+ name,
+ null,
+ AggregatorBuilder.this.kind,
+ returnTypeInference,
+ operandTypeInference,
+ operandTypeChecker,
+ functionCategory,
+ false,
+ false,
+ Optionality.FORBIDDEN
+ );
+ }
+ }
+
+ return new DruidSqlAggFunction();
}
}
@@ -655,6 +744,11 @@ public class OperatorConversions
@VisibleForTesting
static class DefaultOperandTypeChecker implements SqlOperandTypeChecker
{
+ /**
+ * Operand names for {@link #getAllowedSignatures(SqlOperator, String)}.
May be empty, in which case the
+ * {@link #operandTypes} are used instead.
+ */
+ private final List<String> operandNames;
private final List<SqlTypeFamily> operandTypes;
private final int requiredOperands;
private final IntSet nullableOperands;
@@ -662,6 +756,7 @@ public class OperatorConversions
@VisibleForTesting
DefaultOperandTypeChecker(
+ final List<String> operandNames,
final List<SqlTypeFamily> operandTypes,
final int requiredOperands,
final IntSet nullableOperands,
@@ -669,10 +764,15 @@ public class OperatorConversions
)
{
Preconditions.checkArgument(requiredOperands <= operandTypes.size() &&
requiredOperands >= 0);
+ this.operandNames = Preconditions.checkNotNull(operandNames,
"operandNames");
this.operandTypes = Preconditions.checkNotNull(operandTypes,
"operandTypes");
this.requiredOperands = requiredOperands;
this.nullableOperands = Preconditions.checkNotNull(nullableOperands,
"nullableOperands");
+ if (!operandNames.isEmpty() && operandNames.size() !=
operandTypes.size()) {
+ throw new ISE("Operand name count[%s] and type count[%s] must match",
operandNames.size(), operandTypes.size());
+ }
+
if (literalOperands == null) {
this.literalOperands = IntSets.EMPTY_SET;
} else {
@@ -688,8 +788,8 @@ public class OperatorConversions
final SqlNode operand = callBinding.operands().get(i);
if (literalOperands.contains(i)) {
- // Verify that 'operand' is a literal.
- if (!SqlUtil.isLiteral(operand)) {
+ // Verify that 'operand' is a literal. Allow CAST, since we can
reduce these away later.
+ if (!SqlUtil.isLiteral(operand, true)) {
return throwOrReturn(
throwOnFailure,
callBinding,
@@ -739,7 +839,25 @@ public class OperatorConversions
@Override
public String getAllowedSignatures(SqlOperator op, String opName)
{
- return SqlUtil.getAliasedSignature(op, opName, operandTypes);
+ final List<?> operands = !operandNames.isEmpty() ? operandNames :
operandTypes;
+ final StringBuilder ret = new StringBuilder();
+ ret.append("'");
+ ret.append(opName);
+ ret.append("(");
+ for (int i = 0; i < operands.size(); i++) {
+ if (i > 0) {
+ ret.append(", ");
+ }
+ if (i >= requiredOperands) {
+ ret.append("[");
+ }
+ ret.append("<").append(operands.get(i)).append(">");
+ }
+ for (int i = requiredOperands; i < operands.size(); i++) {
+ ret.append("]");
+ }
+ ret.append(")'");
+ return ret.toString();
}
@Override
@@ -772,7 +890,7 @@ public class OperatorConversions
{
return new DirectOperatorConversion(
operatorBuilder(sqlOperator)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.operandTypes(SqlTypeFamily.NUMERIC)
.returnTypeNullable(SqlTypeName.BIGINT)
.functionCategory(SqlFunctionCategory.NUMERIC)
@@ -785,7 +903,7 @@ public class OperatorConversions
{
return new DirectOperatorConversion(
operatorBuilder(sqlOperator)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.operandTypes(SqlTypeFamily.NUMERIC, SqlTypeFamily.NUMERIC)
.returnTypeNullable(SqlTypeName.BIGINT)
.functionCategory(SqlFunctionCategory.NUMERIC)
@@ -798,7 +916,7 @@ public class OperatorConversions
{
return new DirectOperatorConversion(
operatorBuilder(StringUtils.toUpperCase(sqlOperator))
- .requiredOperands(1)
+ .requiredOperandCount(1)
.operandTypes(SqlTypeFamily.NUMERIC)
.returnTypeNullable(SqlTypeName.DOUBLE)
.functionCategory(SqlFunctionCategory.NUMERIC)
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/BTrimOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/BTrimOperatorConversion.java
index d5a24773fe..b8ae238dcf 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/BTrimOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/BTrimOperatorConversion.java
@@ -40,7 +40,7 @@ public class BTrimOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ContainsOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ContainsOperatorConversion.java
index 98703feb02..5e8071fb90 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ContainsOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ContainsOperatorConversion.java
@@ -80,7 +80,7 @@ public class ContainsOperatorConversion extends
DirectOperatorConversion
return OperatorConversions
.operatorBuilder(StringUtils.toUpperCase(functionName))
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.literalOperands(1)
.returnTypeNonNull(SqlTypeName.BOOLEAN)
.functionCategory(SqlFunctionCategory.STRING)
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DateTruncOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DateTruncOperatorConversion.java
index b913cd32ca..361de42862 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DateTruncOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DateTruncOperatorConversion.java
@@ -67,7 +67,7 @@ public class DateTruncOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("DATE_TRUNC")
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.TIMESTAMP)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeCascadeNullable(SqlTypeName.TIMESTAMP)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LPadOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LPadOperatorConversion.java
index 2dd89e7b7d..8ccecafa3b 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LPadOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LPadOperatorConversion.java
@@ -40,7 +40,7 @@ public class LPadOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.INTEGER,
SqlTypeFamily.CHARACTER)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LTrimOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LTrimOperatorConversion.java
index 64d99e84a7..eef7584632 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LTrimOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/LTrimOperatorConversion.java
@@ -40,7 +40,7 @@ public class LTrimOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ParseLongOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ParseLongOperatorConversion.java
index 2bb00a2291..53b7b79025 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ParseLongOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ParseLongOperatorConversion.java
@@ -40,7 +40,7 @@ public class ParseLongOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.INTEGER)
.returnTypeCascadeNullable(SqlTypeName.BIGINT)
.functionCategory(SqlFunctionCategory.STRING)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RPadOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RPadOperatorConversion.java
index 68ee6537cd..8e85d7a068 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RPadOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RPadOperatorConversion.java
@@ -40,7 +40,7 @@ public class RPadOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.INTEGER,
SqlTypeFamily.CHARACTER)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RTrimOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RTrimOperatorConversion.java
index 70da7fbb4e..bf5c9b0fe9 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RTrimOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RTrimOperatorConversion.java
@@ -40,7 +40,7 @@ public class RTrimOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpExtractOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpExtractOperatorConversion.java
index 95c0e3421b..804e5cad05 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpExtractOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpExtractOperatorConversion.java
@@ -38,7 +38,7 @@ public class RegexpExtractOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("REGEXP_EXTRACT")
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER,
SqlTypeFamily.INTEGER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.literalOperands(1, 2)
.returnTypeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpLikeOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpLikeOperatorConversion.java
index b065b276cc..cc677215cb 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpLikeOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RegexpLikeOperatorConversion.java
@@ -44,7 +44,7 @@ public class RegexpLikeOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("REGEXP_LIKE")
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.literalOperands(1)
.returnTypeNonNull(SqlTypeName.BOOLEAN)
.functionCategory(SqlFunctionCategory.STRING)
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RoundOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RoundOperatorConversion.java
index 76e5dc1da9..a14e3a0f0d 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RoundOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/RoundOperatorConversion.java
@@ -35,7 +35,7 @@ public class RoundOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("ROUND")
.operandTypes(SqlTypeFamily.NUMERIC, SqlTypeFamily.INTEGER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeInference(ReturnTypes.ARG0)
.functionCategory(SqlFunctionCategory.NUMERIC)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SubstringOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SubstringOperatorConversion.java
index 4b9e35b719..ae470922c1 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SubstringOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SubstringOperatorConversion.java
@@ -43,7 +43,7 @@ public class SubstringOperatorConversion implements
SqlOperatorConversion
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.INTEGER,
SqlTypeFamily.INTEGER)
.functionCategory(SqlFunctionCategory.STRING)
.returnTypeInference(ReturnTypes.ARG0)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.build();
@Override
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TextcatOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TextcatOperatorConversion.java
index 5da41c42c8..40a13479b8 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TextcatOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TextcatOperatorConversion.java
@@ -31,7 +31,7 @@ public class TextcatOperatorConversion extends
DirectOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("textcat")
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.STRING)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeCeilOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeCeilOperatorConversion.java
index 7568005052..ffa022b0ee 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeCeilOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeCeilOperatorConversion.java
@@ -41,7 +41,7 @@ public class TimeCeilOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("TIME_CEIL")
.operandTypes(SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER,
SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeCascadeNullable(SqlTypeName.TIMESTAMP)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeExtractOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeExtractOperatorConversion.java
index 69397bc4d3..6a36bf4dad 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeExtractOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeExtractOperatorConversion.java
@@ -43,7 +43,7 @@ public class TimeExtractOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("TIME_EXTRACT")
.operandTypes(SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER,
SqlTypeFamily.CHARACTER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeCascadeNullable(SqlTypeName.BIGINT)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFloorOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFloorOperatorConversion.java
index 9f74e87c79..b0b5b69acc 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFloorOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFloorOperatorConversion.java
@@ -56,7 +56,7 @@ public class TimeFloorOperatorConversion implements
SqlOperatorConversion
public static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder(SQL_FUNCTION_NAME)
.operandTypes(SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER,
SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeCascadeNullable(SqlTypeName.TIMESTAMP)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFormatOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFormatOperatorConversion.java
index 8c07ffdf4e..60127fc209 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFormatOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeFormatOperatorConversion.java
@@ -46,7 +46,7 @@ public class TimeFormatOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("TIME_FORMAT")
.operandTypes(SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER,
SqlTypeFamily.CHARACTER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeCascadeNullable(SqlTypeName.VARCHAR)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeParseOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeParseOperatorConversion.java
index 99bc94cc8f..7e515a3516 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeParseOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeParseOperatorConversion.java
@@ -43,7 +43,7 @@ public class TimeParseOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("TIME_PARSE")
.operandTypes(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER,
SqlTypeFamily.CHARACTER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNullable(SqlTypeName.TIMESTAMP)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeShiftOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeShiftOperatorConversion.java
index d2973fb6d1..edda4d0740 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeShiftOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TimeShiftOperatorConversion.java
@@ -43,7 +43,7 @@ public class TimeShiftOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("TIME_SHIFT")
.operandTypes(SqlTypeFamily.TIMESTAMP, SqlTypeFamily.CHARACTER,
SqlTypeFamily.INTEGER, SqlTypeFamily.CHARACTER)
- .requiredOperands(3)
+ .requiredOperandCount(3)
.returnTypeCascadeNullable(SqlTypeName.TIMESTAMP)
.functionCategory(SqlFunctionCategory.TIMEDATE)
.build();
diff --git
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TruncateOperatorConversion.java
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TruncateOperatorConversion.java
index 8459bed7d7..d891823dd1 100644
---
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TruncateOperatorConversion.java
+++
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/TruncateOperatorConversion.java
@@ -37,7 +37,7 @@ public class TruncateOperatorConversion implements
SqlOperatorConversion
private static final SqlFunction SQL_FUNCTION = OperatorConversions
.operatorBuilder("TRUNCATE")
.operandTypes(SqlTypeFamily.NUMERIC, SqlTypeFamily.INTEGER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeInference(ReturnTypes.ARG0)
.functionCategory(SqlFunctionCategory.NUMERIC)
.build();
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/expression/OperatorConversionsTest.java
b/sql/src/test/java/org/apache/druid/sql/calcite/expression/OperatorConversionsTest.java
index 5f70dc5902..d3f97eed22 100644
---
a/sql/src/test/java/org/apache/druid/sql/calcite/expression/OperatorConversionsTest.java
+++
b/sql/src/test/java/org/apache/druid/sql/calcite/expression/OperatorConversionsTest.java
@@ -51,6 +51,7 @@ import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
@RunWith(Enclosed.class)
@@ -65,6 +66,7 @@ public class OperatorConversionsTest
public void testGetOperandCountRange()
{
SqlOperandTypeChecker typeChecker = new DefaultOperandTypeChecker(
+ Collections.emptyList(),
ImmutableList.of(SqlTypeFamily.INTEGER, SqlTypeFamily.INTEGER,
SqlTypeFamily.INTEGER),
2,
IntSets.EMPTY_SET,
@@ -79,6 +81,7 @@ public class OperatorConversionsTest
public void testIsOptional()
{
SqlOperandTypeChecker typeChecker = new DefaultOperandTypeChecker(
+ Collections.emptyList(),
ImmutableList.of(SqlTypeFamily.INTEGER, SqlTypeFamily.INTEGER,
SqlTypeFamily.INTEGER),
2,
IntSets.EMPTY_SET,
@@ -95,7 +98,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testAllowFullOperands")
.operandTypes(SqlTypeFamily.INTEGER, SqlTypeFamily.DATE)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -119,7 +122,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testRequiredOperandsOnly")
.operandTypes(SqlTypeFamily.INTEGER, SqlTypeFamily.DATE)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -140,7 +143,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testLiteralOperandCheckLiteral")
.operandTypes(SqlTypeFamily.INTEGER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.literalOperands(0)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
@@ -162,7 +165,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testLiteralOperandCheckLiteralThrow")
.operandTypes(SqlTypeFamily.INTEGER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.literalOperands(0)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
@@ -184,7 +187,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testAnyTypeOperand")
.operandTypes(SqlTypeFamily.ANY)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -205,7 +208,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testCastableFromDatetimeFamilyToTimestamp")
.operandTypes(SqlTypeFamily.DATETIME)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -235,7 +238,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullForNullableOperand")
.operandTypes(SqlTypeFamily.CHARACTER,
SqlTypeFamily.INTERVAL_DAY_TIME)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -259,7 +262,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullLiteralForNullableOperand")
.operandTypes(SqlTypeFamily.CHARACTER,
SqlTypeFamily.INTERVAL_DAY_TIME)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -283,7 +286,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullForNullableNonnull")
.operandTypes(SqlTypeFamily.CHARACTER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -304,7 +307,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullForNullableCascade")
.operandTypes(SqlTypeFamily.CHARACTER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeCascadeNullable(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -325,7 +328,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullForNullableNonnull")
.operandTypes(SqlTypeFamily.CHARACTER)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNullable(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -346,7 +349,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullForNonNullableOperand")
.operandTypes(SqlTypeFamily.CHARACTER,
SqlTypeFamily.INTERVAL_DAY_TIME)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -372,7 +375,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNullLiteralForNonNullableOperand")
.operandTypes(SqlTypeFamily.CHARACTER,
SqlTypeFamily.INTERVAL_DAY_TIME)
- .requiredOperands(1)
+ .requiredOperandCount(1)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -398,7 +401,7 @@ public class OperatorConversionsTest
SqlFunction function = OperatorConversions
.operatorBuilder("testNonCastableType")
.operandTypes(SqlTypeFamily.CURSOR, SqlTypeFamily.INTERVAL_DAY_TIME)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeNonNull(SqlTypeName.CHAR)
.build();
SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
@@ -418,6 +421,41 @@ public class OperatorConversionsTest
);
}
+ @Test
+ public void testSignatureWithNames()
+ {
+ SqlFunction function = OperatorConversions
+ .operatorBuilder("testSignatureWithNames")
+ .operandNames("x", "y", "z")
+ .operandTypes(SqlTypeFamily.INTEGER, SqlTypeFamily.DATE,
SqlTypeFamily.ANY)
+ .requiredOperandCount(1)
+ .returnTypeNonNull(SqlTypeName.CHAR)
+ .build();
+ SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
+
+ Assert.assertEquals(
+ "'testSignatureWithNames(<x>, [<y>, [<z>]])'",
+ typeChecker.getAllowedSignatures(function, function.getName())
+ );
+ }
+
+ @Test
+ public void testSignatureWithoutNames()
+ {
+ SqlFunction function = OperatorConversions
+ .operatorBuilder("testSignatureWithoutNames")
+ .operandTypes(SqlTypeFamily.INTEGER, SqlTypeFamily.DATE,
SqlTypeFamily.ANY)
+ .requiredOperandCount(1)
+ .returnTypeNonNull(SqlTypeName.CHAR)
+ .build();
+ SqlOperandTypeChecker typeChecker = function.getOperandTypeChecker();
+
+ Assert.assertEquals(
+ "'testSignatureWithoutNames(<INTEGER>, [<DATE>, [<ANY>]])'",
+ typeChecker.getAllowedSignatures(function, function.getName())
+ );
+ }
+
private static SqlCallBinding mockCallBinding(
SqlFunction function,
List<OperandSpec> actualOperands
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidOperatorTableTest.java
b/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidOperatorTableTest.java
index 1e14851763..02e5c522f2 100644
---
a/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidOperatorTableTest.java
+++
b/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidOperatorTableTest.java
@@ -68,7 +68,7 @@ public class DruidOperatorTableTest
final SqlOperator operator1 = OperatorConversions
.operatorBuilder("FOO")
.operandTypes(SqlTypeFamily.ANY)
- .requiredOperands(0)
+ .requiredOperandCount(0)
.returnTypeInference(
opBinding -> RowSignatures.makeComplexType(
opBinding.getTypeFactory(),
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java
b/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java
index bb5edf2d94..205f3379d7 100644
---
a/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java
+++
b/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java
@@ -69,7 +69,7 @@ public class DruidRexExecutorTest extends
InitializedNullHandlingTest
private static final SqlOperator OPERATOR = OperatorConversions
.operatorBuilder(StringUtils.toUpperCase("hyper_unique"))
.operandTypes(SqlTypeFamily.ANY)
- .requiredOperands(0)
+ .requiredOperandCount(0)
.returnTypeInference(
opBinding -> RowSignatures.makeComplexType(
opBinding.getTypeFactory(),
diff --git
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/InformationSchemaTest.java
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/InformationSchemaTest.java
index 306599b2f3..43551b3e04 100644
---
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/InformationSchemaTest.java
+++
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/InformationSchemaTest.java
@@ -136,7 +136,7 @@ public class InformationSchemaTest extends
BaseCalciteQueryTest
Assert.assertNotNull(rows);
Assert.assertEquals("There should be exactly 2 rows; any non-function
syntax operator should get filtered out",
2, rows.size());
- Object[] expectedRow1 = {"druid", "INFORMATION_SCHEMA", "FOO", "FUNCTION",
"NO", "'FOO(<ANY>)'"};
+ Object[] expectedRow1 = {"druid", "INFORMATION_SCHEMA", "FOO", "FUNCTION",
"NO", "'FOO([<ANY>])'"};
Assert.assertTrue(rows.stream().anyMatch(row -> Arrays.equals(row,
expectedRow1)));
Object[] expectedRow2 = {"druid", "INFORMATION_SCHEMA", "BAR", "FUNCTION",
"NO", "'BAR(<INTEGER>, <INTEGER>)'"};
@@ -166,7 +166,7 @@ public class InformationSchemaTest extends
BaseCalciteQueryTest
final SqlOperator operator1 = OperatorConversions
.operatorBuilder("FOO")
.operandTypes(SqlTypeFamily.ANY)
- .requiredOperands(0)
+ .requiredOperandCount(0)
.returnTypeInference(
opBinding -> RowSignatures.makeComplexType(
opBinding.getTypeFactory(),
@@ -182,7 +182,7 @@ public class InformationSchemaTest extends
BaseCalciteQueryTest
.operatorBuilder("BAR")
.operandTypes(SqlTypeFamily.NUMERIC)
.operandTypes(SqlTypeFamily.INTEGER, SqlTypeFamily.INTEGER)
- .requiredOperands(2)
+ .requiredOperandCount(2)
.returnTypeInference(
opBinding -> RowSignatures.makeComplexType(
opBinding.getTypeFactory(),
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]