private void findSubQueries()

in flink-table/flink-table-planner/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java [2083:2189]


    private void findSubQueries(
            Blackboard bb,
            SqlNode node,
            RelOptUtil.Logic logic,
            boolean registerOnlyScalarSubQueries,
            SqlImplementor.Clause clause) {
        final SqlKind kind = node.getKind();
        switch (kind) {
            case EXISTS:
            case UNIQUE:
            case SELECT:
            case MULTISET_QUERY_CONSTRUCTOR:
            case MULTISET_VALUE_CONSTRUCTOR:
            case ARRAY_QUERY_CONSTRUCTOR:
            case MAP_QUERY_CONSTRUCTOR:
            case CURSOR:
            case SET_SEMANTICS_TABLE:
            case SCALAR_QUERY:
                if (!registerOnlyScalarSubQueries || (kind == SqlKind.SCALAR_QUERY)) {
                    bb.registerSubQuery(node, RelOptUtil.Logic.TRUE_FALSE, clause);
                }
                return;
            case IN:
                break;
            case NOT_IN:
            case NOT:
                logic = logic.negate();
                break;
            default:
                break;
        }
        if (node instanceof SqlCall) {
            switch (kind) {
                // Do no change logic for AND, IN and NOT IN expressions;
                // but do change logic for OR, NOT and others;
                // EXISTS was handled already.
                case AND:
                case IN:
                case NOT_IN:
                    break;
                default:
                    logic = RelOptUtil.Logic.TRUE_FALSE_UNKNOWN;
                    break;
            }
            for (SqlNode operand : ((SqlCall) node).getOperandList()) {
                if (operand != null) {
                    // In the case of an IN expression, locate scalar
                    // sub-queries so we can convert them to constants
                    findSubQueries(
                            bb,
                            operand,
                            logic,
                            kind == SqlKind.IN
                                    || kind == SqlKind.NOT_IN
                                    || kind == SqlKind.SOME
                                    || kind == SqlKind.ALL
                                    || registerOnlyScalarSubQueries,
                            clause);
                }
            }
        } else if (node instanceof SqlNodeList) {
            for (SqlNode child : (SqlNodeList) node) {
                findSubQueries(
                        bb,
                        child,
                        logic,
                        kind == SqlKind.IN
                                || kind == SqlKind.NOT_IN
                                || kind == SqlKind.SOME
                                || kind == SqlKind.ALL
                                || registerOnlyScalarSubQueries,
                        clause);
            }
        }

        // Now that we've located any scalar sub-queries inside the IN
        // expression, register the IN expression itself.  We need to
        // register the scalar sub-queries first so they can be converted
        // before the IN expression is converted.
        switch (kind) {
            case IN:
            case NOT_IN:
            case SOME:
            case ALL:
                switch (logic) {
                    case TRUE_FALSE_UNKNOWN:
                        RelDataType type = validator().getValidatedNodeTypeIfKnown(node);
                        if (type == null) {
                            // The node might not be validated if we still don't know type of the
                            // node.
                            // Therefore return directly.
                            return;
                        } else {
                            break;
                        }
                    case UNKNOWN_AS_FALSE:
                        logic = RelOptUtil.Logic.TRUE;
                        break;
                    default:
                        break;
                }
                bb.registerSubQuery(node, logic, clause);
                break;
            default:
                break;
        }
    }