Skip to content

Commit dedfbc5

Browse files
committed
Refactor aggregation function type checks to improve input validation
1 parent c31dda4 commit dedfbc5

2 files changed

Lines changed: 38 additions & 65 deletions

File tree

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java

Lines changed: 9 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -361,50 +361,6 @@ public TSDataType visitFunctionExpression(
361361
}
362362

363363
if (functionExpression.isBuiltInAggregationFunctionExpression()) {
364-
// Additional type check for multi-input aggregation functions
365-
String funcName = functionExpression.getFunctionName().toLowerCase();
366-
if (funcName.equals(SqlConstant.CORR)
367-
|| funcName.equals(SqlConstant.COVAR_POP)
368-
|| funcName.equals(SqlConstant.COVAR_SAMP)
369-
|| funcName.equals(SqlConstant.REGR_SLOPE)
370-
|| funcName.equals(SqlConstant.REGR_INTERCEPT)) {
371-
// Check both input parameters are numeric or timestamp
372-
if (inputExpressions.size() >= 1) {
373-
TSDataType firstInputType = expressionTypes.get(NodeRef.of(inputExpressions.get(0)));
374-
if (firstInputType != null
375-
&& !firstInputType.isNumeric()
376-
&& firstInputType != TSDataType.TIMESTAMP) {
377-
throw new SemanticException(
378-
String.format(
379-
"Aggregate functions [%s] only support numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]",
380-
functionExpression.getFunctionName().toUpperCase()));
381-
}
382-
}
383-
if (inputExpressions.size() >= 2) {
384-
TSDataType secondInputType = expressionTypes.get(NodeRef.of(inputExpressions.get(1)));
385-
if (secondInputType != null
386-
&& !secondInputType.isNumeric()
387-
&& secondInputType != TSDataType.TIMESTAMP) {
388-
throw new SemanticException(
389-
String.format(
390-
"Aggregate functions [%s] only support numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]",
391-
functionExpression.getFunctionName().toUpperCase()));
392-
}
393-
}
394-
}
395-
if (funcName.equals(SqlConstant.SKEWNESS) || funcName.equals(SqlConstant.KURTOSIS)) {
396-
if (!inputExpressions.isEmpty()) {
397-
TSDataType firstInputType = expressionTypes.get(NodeRef.of(inputExpressions.get(0)));
398-
if (firstInputType != null
399-
&& !firstInputType.isNumeric()
400-
&& firstInputType != TSDataType.TIMESTAMP) {
401-
throw new SemanticException(
402-
String.format(
403-
"Aggregate functions [%s] only support numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]",
404-
functionExpression.getFunctionName().toUpperCase()));
405-
}
406-
}
407-
}
408364

409365
return setExpressionType(
410366
functionExpression,
@@ -587,15 +543,20 @@ private TSDataType getInputExpressionTypeForAggregation(
587543
case SqlConstant.VARIANCE:
588544
case SqlConstant.VAR_POP:
589545
case SqlConstant.VAR_SAMP:
546+
case SqlConstant.SKEWNESS:
547+
case SqlConstant.KURTOSIS:
548+
case SqlConstant.MAX_BY:
549+
case SqlConstant.MIN_BY:
550+
return expressionTypes.get(NodeRef.of(inputExpressions.get(0)));
590551
case SqlConstant.CORR:
591552
case SqlConstant.COVAR_POP:
592553
case SqlConstant.COVAR_SAMP:
593554
case SqlConstant.REGR_SLOPE:
594555
case SqlConstant.REGR_INTERCEPT:
595-
case SqlConstant.SKEWNESS:
596-
case SqlConstant.KURTOSIS:
597-
case SqlConstant.MAX_BY:
598-
case SqlConstant.MIN_BY:
556+
TypeInferenceUtils.verifyIsAggregationDataTypeMatchedForBothInputs(
557+
aggregateFunctionName,
558+
expressionTypes.get(NodeRef.of(inputExpressions.get(0))),
559+
expressionTypes.get(NodeRef.of(inputExpressions.get(1))));
599560
return expressionTypes.get(NodeRef.of(inputExpressions.get(0)));
600561
default:
601562
throw new IllegalArgumentException(

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/TypeInferenceUtils.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -200,23 +200,6 @@ private static void verifyIsAggregationDataTypeMatched(String aggrFuncName, TSDa
200200
"Aggregate functions [AVG, SUM, EXTREME, STDDEV, STDDEV_POP, STDDEV_SAMP, "
201201
+ "VARIANCE, VAR_POP, VAR_SAMP] only support "
202202
+ "numeric data types [INT32, INT64, FLOAT, DOUBLE]");
203-
case SqlConstant.CORR:
204-
case SqlConstant.COVAR_POP:
205-
case SqlConstant.COVAR_SAMP:
206-
if (dataType.isNumeric() || TSDataType.TIMESTAMP.equals(dataType)) {
207-
return;
208-
}
209-
throw new SemanticException(
210-
"Aggregate functions [CORR, COVAR_POP, COVAR_SAMP] only support "
211-
+ "numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]");
212-
case SqlConstant.REGR_SLOPE:
213-
case SqlConstant.REGR_INTERCEPT:
214-
if (dataType.isNumeric() || TSDataType.TIMESTAMP.equals(dataType)) {
215-
return;
216-
}
217-
throw new SemanticException(
218-
"Aggregate functions [REGR_SLOPE, REGR_INTERCEPT] only support "
219-
+ "numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]");
220203
case SqlConstant.SKEWNESS:
221204
case SqlConstant.KURTOSIS:
222205
if (dataType.isNumeric() || TSDataType.TIMESTAMP.equals(dataType)) {
@@ -225,6 +208,11 @@ private static void verifyIsAggregationDataTypeMatched(String aggrFuncName, TSDa
225208
throw new SemanticException(
226209
"Aggregate functions [SKEWNESS, KURTOSIS] only support "
227210
+ "numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]");
211+
case SqlConstant.CORR:
212+
case SqlConstant.COVAR_POP:
213+
case SqlConstant.COVAR_SAMP:
214+
case SqlConstant.REGR_SLOPE:
215+
case SqlConstant.REGR_INTERCEPT:
228216
case SqlConstant.COUNT:
229217
case SqlConstant.COUNT_TIME:
230218
case SqlConstant.MIN_TIME:
@@ -249,6 +237,30 @@ private static void verifyIsAggregationDataTypeMatched(String aggrFuncName, TSDa
249237
}
250238
}
251239

240+
public static void verifyIsAggregationDataTypeMatchedForBothInputs(
241+
String aggrFuncName, TSDataType firstDataType, TSDataType secondDataType) {
242+
switch (aggrFuncName.toLowerCase()) {
243+
case SqlConstant.CORR:
244+
case SqlConstant.COVAR_POP:
245+
case SqlConstant.COVAR_SAMP:
246+
case SqlConstant.REGR_SLOPE:
247+
case SqlConstant.REGR_INTERCEPT:
248+
if ((firstDataType != null
249+
&& !firstDataType.isNumeric()
250+
&& !TSDataType.TIMESTAMP.equals(firstDataType))
251+
|| (secondDataType != null
252+
&& !secondDataType.isNumeric()
253+
&& !TSDataType.TIMESTAMP.equals(secondDataType))) {
254+
throw new SemanticException(
255+
"Aggregate functions [CORR, COVAR_POP, COVAR_SAMP, REGR_SLOPE, REGR_INTERCEPT] only support "
256+
+ "numeric data types [INT32, INT64, FLOAT, DOUBLE, TIMESTAMP]");
257+
}
258+
return;
259+
default:
260+
break;
261+
}
262+
}
263+
252264
/**
253265
* Bind Type for non-series input Expressions of AggregationFunction and check Semantic
254266
*

0 commit comments

Comments
 (0)