private <T extends Expression> boolean process(List<T> actuals, List<T> expecteds) {
    if (actuals.size() != expecteds.size()) {
      return false;
    }
    for (int i = 0; i < actuals.size(); i++) {
      if (!process(actuals.get(i), expecteds.get(i))) {
        return false;
      }
    }
    return true;
  }
Expression visitor which verifies if given expression (actual) is matching other expression given
as context (expected). Visitor returns true if plans match to each other.

<p>Note that actual expression is using real name references (table columns etc) while expected
expression is using symbol aliases. Given symbol alias can point only to one real name reference.

<p>Example:

<pre>
NOT (orderkey = 3 AND custkey = 3 AND orderkey < 10)
</pre>

will match to:

<pre>
NOT (X = 3 AND Y = 3 AND X < 10)
</pre>

, but will not match to:

<pre>
NOT (X = 3 AND Y = 3 AND Z < 10)
</pre>

nor to

<pre>
NOT (X = 3 AND X = 3 AND X < 10)
</pre>
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/ExpressionVerifier.java