chunweilei commented on a change in pull request #1138: [CALCITE-1581] UDTF like in hive URL: https://github.com/apache/calcite/pull/1138#discussion_r314559370
########## File path: core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java ########## @@ -4175,6 +4197,113 @@ private void handleScalarSubQuery( fieldList.add(Pair.of(alias, nodeType)); } + /** + * Process table function found in select list.Checks that is + * actually a table function and validate the table function + * count in Select list. + * @param parentSelect Base SqlSelect + * @param selectItem Child select items from select list + * @param expandedSelectItems Select items after processing + * @param aliases Built from user or system values + * @param fields Built up entries for each select list entry + */ + private void handleTableFunctionInSelect( + SqlSelect parentSelect, + SqlBasicCall selectItem, + List<SqlNode> expandedSelectItems, + Set<String> aliases, + List<Map.Entry<String, RelDataType>> fields) { + SqlBasicCall functionCall = (SqlBasicCall) selectItem.getOperands()[0]; + SqlFunction function = (SqlFunction) functionCall.getOperator(); + // Check whether there are more than one table function in select list. + for (SqlNode item : parentSelect.getSelectList()) { + if (SqlUtil.isTableFunctionInSelect(item) + && item != selectItem) { + throw newValidationError(parentSelect.getSelectList(), + RESOURCE.onlyOneTableFunctionAllowedInSelect()); + } + } + + // Change the function category to USER_DEFINED_TABLE_FUNCTION. + // It is because that in sql-select list, the SqlFunctionCategory is USER_DEFINED_FUNCTION + // for a SqlUnresolvedFunction. + if (function instanceof SqlUnresolvedFunction) { + if (!function.getFunctionType().isTableFunction()) { + SqlFunction newFunction = + new SqlUnresolvedFunction(function.getNameAsId(), + function.getReturnTypeInference(), + function.getOperandTypeInference(), + function.getOperandTypeChecker(), + function.getParamTypes(), + SqlFunctionCategory.USER_DEFINED_TABLE_FUNCTION); + functionCall.setOperator(newFunction); + function = newFunction; + } + } + // Check functionCall whether is a table function + List<SqlOperator> overloads = new ArrayList<>(); + opTab.lookupOperatorOverloads(function.getNameAsId(), + function.getFunctionType(), + function.getSyntax(), overloads, catalogReader.nameMatcher()); + if (overloads.size() == 0) { + throw newValidationError(functionCall, + RESOURCE.exceptTableFunction(function.getName())); + } + // Check the parent select whether is a aggregate statement + if (isAggregate(parentSelect)) { + throw newValidationError(functionCall, + RESOURCE.notAllowTableFunctionInAggregate()); + } Review comment: We should do this check at the beginning. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services