liuyongvs commented on code in PR #3262:
URL: https://github.com/apache/calcite/pull/3262#discussion_r1241057944


##########
core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java:
##########
@@ -1020,12 +1022,32 @@ private static RelDataType 
arrayReturnType(SqlOperatorBinding opBinding) {
           ReturnTypes.ARG0_NULLABLE,
           OperandTypes.ARRAY.or(OperandTypes.ARRAY_BOOLEAN_LITERAL));
 
+  private static RelDataType deriveTypeMapConcat(SqlOperatorBinding opBinding) 
{
+    if (opBinding.getOperandCount() == 0) {
+      final RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
+      final RelDataType type = typeFactory.createSqlType(SqlTypeName.VARCHAR);
+      requireNonNull(type, "type");
+      return SqlTypeUtil.createMapType(typeFactory, type, type, true);
+    } else {
+      final List<RelDataType> operandTypes = opBinding.collectOperandTypes();
+      for (RelDataType operandType: operandTypes) {
+        if (!SqlTypeUtil.isMap(operandType)) {
+          throw opBinding.newError(
+              RESOURCE.typesShouldAllBeMap(
+                  opBinding.getOperator().getName(),
+                  operandType.getFullTypeString()));

Review Comment:
   comments:
   we need check every arg whether it is map. 
   
   ```
   spark-sql (default)> select map_concat(map('foo', 1), null);
   [DATATYPE_MISMATCH.MAP_CONCAT_DIFF_TYPES] Cannot resolve 
"map_concat(map(foo, 1), NULL)" due to data type mismatch: The `map_concat` 
should all be of type map, but it's ["MAP<STRING, INT>", "VOID"].; line 1 pos 7;
   'Project [unresolvedalias(map_concat(map(foo, 1), null), None)]
   +- OneRowRelation
   
   spark-sql (default)> select map_concat(map('foo', 1), cast(null as 
map<string, int>));
   NULL
   ```
   
   and i also add the tests. but we can have 2 different implementation here.
   1) check operand type in return type inference. the implementation is simple
   2) check operand type in operand type inference.
   
   ```
     public static final SqlFunction MAP_CONCAT =
         SqlBasicFunction.create(SqlKind.MAP_CONCAT,
             SqlLibraryOperators::deriveTypeMapConcat,
             OperandTypes.SAME_VARIADIC.and(OperandTypes.ALL_ARGS_MAP));
   
     private static class AllArgsMapOperandTypeChecker
         implements SqlSingleOperandTypeChecker {
       @Override public boolean checkSingleOperandType(SqlCallBinding 
callBinding,
           SqlNode node, int iFormalOperand, boolean throwOnFailure) {
         RelDataType type = SqlTypeUtil.deriveType(callBinding, node);
         boolean valid = false;
         if (type.getSqlTypeName() == SqlTypeName.MAP) {
           valid = true;
         }
         if (!valid && throwOnFailure) {
           throw callBinding.newError(
               RESOURCE.typesShouldAllBeMap(
                   callBinding.getOperator().getName(),
                   type.getFullTypeString()));
         }
         return valid;
       }
   
       @Override public SqlOperandCountRange getOperandCountRange() {
         return SqlOperandCountRanges.any();
       }
   
       @Override public String getAllowedSignatures(SqlOperator op, String 
opName) {
         ....
       }
     }
   ```



-- 
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.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to