docs: public void initializeSwapTablesPlanNode(Table theTable, Table otherTable) {
          String theName = theTable.getTypeName();
          setTargetTableName(theName);
          String otherName = otherTable.getTypeName();
          m_otherTargetTableName = otherName;
  
          FailureMessage failureMessage = new FailureMessage(theName, otherName);
  
          validateTableCompatibility(theName, otherName, theTable, otherTable, failureMessage);
          validateColumnCompatibility(theName, otherName, theTable, otherTable, failureMessage);
  
          // Maintain sets of indexes and index-supported (UNIQUE) constraints
          // and the primary key index found on otherTable.
          // Removing them as they are matched by indexes/constraints on theTable
          // and added to the list of swappable indexes should leave the sets empty.
          HashSet<Index> otherIndexSet = new HashSet<>();
          // The constraint set is actually a HashMap to retain the
          // defining constraint name for help with error messages.
          // Track the primary key separately since it should match one-to-one.
          HashMap<Index, String> otherConstraintIndexMap = new HashMap<>();
          Index otherPrimaryKeyIndex = null;
  
          // Collect the system-defined (internal) indexes supporting constraints
          // and the primary key index if any.
          CatalogMap<Constraint> candidateConstraints = otherTable.getConstraints();
          for (Constraint otherConstraint : candidateConstraints) {
              Index otherIndex = otherConstraint.getIndex();
              if (otherIndex == null) {
                  // Some kinds of constraints that are not index-based have no
                  // effect on the swap table plan.
                  continue;
              }
  
              // Set aside the one primary key index for special handling.
              if (otherConstraint.getType() == ConstraintType.PRIMARY_KEY.getValue()) {
                  otherPrimaryKeyIndex = otherIndex;
                  continue;
              }
  
              otherConstraintIndexMap.put(otherIndex, otherConstraint.getTypeName());
          }
  
          // Collect the user-defined (external) indexes on otherTable.  The indexes
          // in this set are removed as corresponding matches are found.
          // System-generated indexes that support constraints are checked separately,
          // so don't add them to this set.
          CatalogMap<Index> candidateIndexes = otherTable.getIndexes();
          for (Index otherIndex : candidateIndexes) {
              if (otherIndex != otherPrimaryKeyIndex &&
                      !otherConstraintIndexMap.containsKey(otherIndex)) {
                  otherIndexSet.add(otherIndex);
              }
          }
  
          // Collect the indexes that support constraints on theTable
          HashSet<Index> theConstraintIndexSet = new HashSet<>();
          Index thePrimaryKeyIndex = null;
          for (Constraint constraint : theTable.getConstraints()) {
              Index theIndex = constraint.getIndex();
              if (theIndex == null) {
                  continue;
              }
  
              if (constraint.getType() == ConstraintType.PRIMARY_KEY.getValue()) {
                  thePrimaryKeyIndex = theIndex;
                  continue;
              }
  
              theConstraintIndexSet.add(constraint.getIndex());
          }
  
          // Make sure that both either both or neither tables have primary keys, and if both,
          // make sure the indexes are swappable.
          if (thePrimaryKeyIndex != null && otherPrimaryKeyIndex != null) {
              if (indexesCanBeSwapped(thePrimaryKeyIndex, otherPrimaryKeyIndex)) {
                  m_theIndexes.add(thePrimaryKeyIndex.getTypeName());
                  m_otherIndexes.add(otherPrimaryKeyIndex.getTypeName());
              }
              else {
                  failureMessage.addReason("PRIMARY KEY constraints do not match on both tables");
              }
          }
          else if ((thePrimaryKeyIndex != null && otherPrimaryKeyIndex == null)
                  || (thePrimaryKeyIndex == null && otherPrimaryKeyIndex != null)) {
              failureMessage.addReason("one table has a PRIMARY KEY constraint and the other does not");
          }
  
          // Try to cross-reference each user-defined index on the two tables.
          for (Index theIndex : theTable.getIndexes()) {
              if (theConstraintIndexSet.contains(theIndex) || theIndex == thePrimaryKeyIndex) {
                  // Constraints are checked below.
                  continue;
              }
  
              boolean matched = false;
              for (Index otherIndex : otherIndexSet) {
                  if (indexesCanBeSwapped(theIndex, otherIndex)) {
                      m_theIndexes.add(theIndex.getTypeName());
                      m_otherIndexes.add(otherIndex.getTypeName());
                      otherIndexSet.remove(otherIndex);
                      matched = true;
                      break;
                  }
              }
              if (matched) {
                  continue;
              }
  
              // No match: look for a likely near-match based on naming
              // convention for the most helpful error message.
              // Otherwise, give a more generic error message.
              String theIndexName = theIndex.getTypeName();
              String message = "the index " + theIndexName + " on table " + theName
                      + " has no corresponding index in the other table";
              String otherIndexName = theIndexName.replace(theName, otherName);
              Index otherIndex = candidateIndexes.getIgnoreCase(otherIndexName);
              if (otherIndex != null) {
                  message += "; the closest candidate ("
                          + otherIndexName + ") has mismatches in the following attributes: "
                          + String.join(", ", diagnoseIndexMismatch(theIndex, otherIndex));
              }
              failureMessage.addReason(message);
          }
  
          // At this point, all of theTable's indexes are matched.
          // All of otherTable's indexes should also have been
          // matched along the way.
          if ( ! otherIndexSet.isEmpty()) {
              List<String> indexNames = otherIndexSet.stream().map(idx -> idx.getTypeName())
                      .collect(Collectors.toList());
              failureMessage.addReason("the table " + otherName + " contains these index(es) "
                      + "which have no corresponding indexes on " + theName + ": "
                      + "(" + String.join(", ", indexNames) + ")");
          }
  
          // Try to cross-reference each system-defined index supporting
          // constraints on the two tables.
          for (Constraint theConstraint : theTable.getConstraints()) {
              Index theIndex = theConstraint.getIndex();
              if (theIndex == null) {
                  // Some kinds of constraints that are not index-based have no
                  // effect on the swap table plan.
                  continue;
              }
  
              if (theConstraint.getType() == ConstraintType.PRIMARY_KEY.getValue()) {
                  // Primary key compatibility checked above.
                  continue;
              }
  
              boolean matched = false;
              for (Entry<Index, String> otherEntry : otherConstraintIndexMap.entrySet()) {
                  Index otherIndex = otherEntry.getKey();
                  if (indexesCanBeSwapped(theIndex, otherIndex)) {
                      m_theIndexes.add(theIndex.getTypeName());
                      m_otherIndexes.add(otherIndex.getTypeName());
                      otherConstraintIndexMap.remove(otherIndex);
                      matched = true;
                      break;
                  }
              }
              if (matched) {
                  continue;
              }
  
              String theConstraintName = theConstraint.getTypeName();
              failureMessage.addReason("the constraint " + theConstraintName + " on table " + theName + " "
                      + "has no corresponding constraint on the other table");
          }
  
          // At this point, all of theTable's index-based constraints are matched.
          // All of otherTable's index-based constraints should also have been
          // matched along the way.
          if ( ! otherConstraintIndexMap.isEmpty()) {
              StringBuilder sb = new StringBuilder();
              sb.append("these constraints (or system internal index names) on table " + otherName + " "
                      + "have no corresponding constraints on the other table: (");
              String separator = "";
              for (Entry<Index, String> remainder : otherConstraintIndexMap.entrySet()) {
                  String constraintName = remainder.getValue();
                  String description =
                          (constraintName != null && ! constraintName.equals("")) ?
                                  constraintName :
                                      ("<anonymous with system internal index name: " +
                                              remainder.getKey().getTypeName() + ">");
                  sb.append(separator).append(description);
                  separator = ", ";
              }
              sb.append(")");
              failureMessage.addReason(sb.toString());
          }
  
  
          if (failureMessage.numFailures() > 0) {
              throw new PlanningErrorException(failureMessage.getMessage());
          }
      }