@Override
    public Scope process(Node node, final Optional<Scope> scope) {
      final Scope returnScope = super.process(node, scope);
      if (node instanceof PipeEnriched) {
        node = ((PipeEnriched) node).getInnerStatement();
      }
      if (node instanceof CreateOrUpdateDevice
          || node instanceof FetchDevice
          || node instanceof ShowDevice
          || node instanceof CountDevice
          || node instanceof Update
          || node instanceof DeleteDevice) {
        return returnScope;
      }
      checkState(
          returnScope.getOuterQueryParent().equals(outerQueryScope),
          "result scope should have outer query scope equal with parameter outer query scope");
      scope.ifPresent(
          value ->
              checkState(
                  hasScopeAsLocalParent(returnScope, value),
                  "return scope should have context scope as one of its ancestors"));
      return returnScope;
    }
Visitor context represents local query scope (if exists). The invariant is that the local query
scopes hierarchy should always have outer query scope (if provided) as ancestor.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java