public OptExpression next() {
        // For logic scan to physical scan, we only need to match once
        if (isPatternWithoutChildren && groupExpressionIndex.get(0) > 0) {
            return null;
        }

        OptExpression expression;
        do {
            this.groupTraceKey = 0;

            // Match with the next groupExpression of the last group node
            int lastNode = this.groupExpressionIndex.size() - 1;
            int lastNodeIndex = this.groupExpressionIndex.get(lastNode);
            this.groupExpressionIndex.set(lastNode, lastNodeIndex + 1);

            expression = match(pattern, groupExpression);
        } while (expression == null && this.groupExpressionIndex.size() != 1);

        nextIdx++;
        return expression;
    }
@Test
    public void testBinderOne() {
        OptExpression expr = OptExpression.create(new MockOperator(OperatorType.LOGICAL_JOIN));

        Pattern pattern = Pattern.create(OperatorType.LOGICAL_JOIN);

        Memo memo = new Memo();
        Binder binder = new Binder(pattern, memo.init(expr));
        OptExpression result = binder.next();

        assertEquals(OperatorType.LOGICAL_JOIN, result.getOp().getOpType());

        assertNull(binder.next());
    }