docs: @Override
      AbstractPlanNode nextPlan() {
          if (!m_generatedPlans) {
              assert (m_parsedStmt.m_joinTree != null);
              // Clone the node to make make sure that analyze expression is called
              // only once on the node.
              JoinNode tableNode = (JoinNode) m_parsedStmt.m_joinTree.clone();
              // Analyze join conditions
              tableNode.analyzeJoinExpressions(m_parsedStmt.m_noTableSelectionList);
              // these just shouldn't happen right?
              assert(m_parsedStmt.m_noTableSelectionList.size() == 0);
  
              m_generatedPlans = true;
              // This is either UPDATE or DELETE statement. Consolidate all expressions
              // into the WHERE list.
              tableNode.m_whereInnerList.addAll(tableNode.m_joinInnerList);
              tableNode.m_joinInnerList.clear();
              tableNode.m_accessPaths.addAll(getRelevantAccessPathsForTable(tableNode.getTableScan(),
                      null,
                      tableNode.m_whereInnerList,
                      null));
  
              for (AccessPath path : tableNode.m_accessPaths) {
                  tableNode.m_currentAccessPath = path;
  
                  AbstractPlanNode plan = getAccessPlanForTable(tableNode);
                  m_plans.add(plan);
              }
  
          }
          return m_plans.poll();
      }