@Override
      public List<Expression> visitColumns(Columns node, Scope context) {
        // avoid redundant process
        if (expandedExpressions != null) {
          return expandedExpressions;
        }

        List<Field> requestedFields = (List<Field>) context.getRelationType().getVisibleFields();
        List<Field> fields = filterInaccessibleFields(requestedFields);
        if (fields.isEmpty()) {
          if (!requestedFields.isEmpty()) {
            throw new SemanticException("Relation not found or not allowed");
          }
          throw new SemanticException("COLUMNS not allowed for relation that has no columns");
        }

        ImmutableList.Builder<Expression> matchedColumns = ImmutableList.builder();
        ImmutableList.Builder<String> outputColumnNames = ImmutableList.builder();
        if (node.isColumnsAsterisk()) {
          for (Field field : fields) {
            String columnName = field.getName().orElse(null);
            if (columnName == null) {
              throw new SemanticException("Unknown ColumnName: " + field);
            }
            matchedColumns.add(new Identifier(columnName));
            outputColumnNames.add(alias == null ? columnName : alias.getValue());
          }
        } else {
          Pattern pattern;
          try {
            pattern = Pattern.compile(node.getPattern());
          } catch (PatternSyntaxException e) {
            throw new SemanticException(String.format("Invalid regex '%s'", node.getPattern()));
          }
          Matcher matcher = pattern.matcher("");

          for (Field field : fields) {
            String columnName = field.getName().orElse(null);
            if (columnName == null) {
              throw new SemanticException("Unknown ColumnName: " + field);
            }
            matcher.reset(columnName);
            if (matcher.matches()) {
              matchedColumns.add(new Identifier(columnName));

              // process alias
              if (alias != null) {
                try {
                  outputColumnNames.add(matcher.replaceAll(alias.getValue()));
                } catch (Exception e) {
                  throw new SemanticException(e.getMessage());
                }
              } else {
                outputColumnNames.add(columnName);
              }
            }
          }
        }
        List<Expression> result = matchedColumns.build();
        if (result.isEmpty()) {
          throw new SemanticException(
              String.format("No matching columns found that match regex '%s'", node.getPattern()));
        }
        expandedExpressions = result;
        accordingColumnNames = outputColumnNames.build();

        return result;
      }
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