pengzhiwei2018 commented on a change in pull request #1138: [CALCITE-1581] UDTF 
like in hive
URL: https://github.com/apache/calcite/pull/1138#discussion_r315984639
 
 

 ##########
 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:
   Well this check only happened after the check of table function exists in 
the select statement.So It cannot be placed somewhere before here.

----------------------------------------------------------------
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:
[email protected]


With regards,
Apache Git Services

Reply via email to