@Override
    protected Scope visitValues(Values node, Optional<Scope> scope) {
      checkState(!node.getRows().isEmpty());

      List<Type> rowTypes =
          node.getRows().stream()
              .map(row -> analyzeExpression(row, createScope(scope)).getType(row))
              .map(
                  type -> {
                    if (type instanceof RowType) {
                      return type;
                    }
                    return RowType.anonymousRow(type);
                  })
              .collect(toImmutableList());

      int fieldCount = rowTypes.get(0).getTypeParameters().size();
      Type commonSuperType = rowTypes.get(0);
      for (Type rowType : rowTypes) {
        // check field count consistency for rows
        if (rowType.getTypeParameters().size() != fieldCount) {
          throw new SemanticException(
              String.format(
                  "Values rows have mismatched sizes: %s vs %s",
                  fieldCount, rowType.getTypeParameters().size()));
        }

        // determine common super type of the rows
        //        commonSuperType = typeCoercion.getCommonSuperType(rowType, commonSuperType)
        //            .orElseThrow(() -> semanticException(TYPE_MISMATCH,
        //                node,
        //                "Values rows have mismatched types: %s vs %s",
        //                rowTypes.get(0),
        //                rowType));
      }

      // add coercions
      int rowIndex = 0;
      for (Expression row : node.getRows()) {
        Type actualType = analysis.getType(row);
        if (row instanceof Row) {
          // coerce Row by fields to preserve Row structure and enable optimizations based on this
          // structure, e.g.pruning, predicate extraction
          // TODO coerce the whole Row and add an Optimizer rule that converts CAST(ROW(...) AS
          // ...)into ROW (CAST(...),CAST(...), ...).
          //  The rule would also handle Row-type expressions that were specified as CAST(ROW).It
          // should support multiple casts over a ROW.
          for (int i = 0; i < actualType.getTypeParameters().size(); i++) {
            //            Expression item = ((Row) row).getItems().get(i);
            Type actualItemType = actualType.getTypeParameters().get(i);
            Type expectedItemType = commonSuperType.getTypeParameters().get(i);
            if (!actualItemType.equals(expectedItemType)) {
              throw new SemanticException(
                  String.format(
                      "Type of row %d column %d is mismatched, expected: %s, actual: %s",
                      rowIndex, i, expectedItemType, actualItemType));
              //              analysis.addCoercion(item, expectedItemType,
              //                  typeCoercion.isTypeOnlyCoercion(actualItemType,
              // expectedItemType));
            }
          }
        } else if (actualType instanceof RowType) {
          // coerce row-type expression as a whole
          //          if (!actualType.equals(commonSuperType)) {
          //            analysis.addCoercion(row, commonSuperType,
          //                typeCoercion.isTypeOnlyCoercion(actualType, commonSuperType));
          //          }

          throw new SemanticException(
              String.format(
                  "Type of row %d is mismatched, expected: %s, actual: %s",
                  rowIndex, commonSuperType, actualType));
        } else {
          // coerce field. it will be wrapped in Row by Planner
          Type superType = getOnlyElement(commonSuperType.getTypeParameters());
          if (!actualType.equals(superType)) {
            //            analysis.addCoercion(row, superType,
            // typeCoercion.isTypeOnlyCoercion(actualType,
            //                superType));
            throw new SemanticException(
                String.format(
                    "Type of row %d is mismatched, expected: %s, actual: %s",
                    rowIndex, superType, actualType));
          }
        }
        rowIndex++;
      }

      List<Field> fields =
          commonSuperType.getTypeParameters().stream()
              .map(
                  valueType ->
                      Field.newUnqualified(
                          Optional.empty(), valueType, TsTableColumnCategory.FIELD))
              .collect(toImmutableList());

      return createAndAssignScope(node, scope, fields);
    }
Check if there is Columns function in expression, and verify they are same if there are multi
Column functions.

@param expression input expression
@return if there is Columns function in expression
@throws SemanticException if there are multi Columns functions but different
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java