private boolean parseTableList()

in src/main/java/com/google/cloud/spanner/pgadapter/statements/TableParser.java [108:193]


  private boolean parseTableList(
      ImmutableMap<TableOrIndexName, TableOrIndexName> detectAndReplaceMap,
      Set<TableOrIndexName> replacedTables,
      ImmutableSet.Builder<TableOrIndexName> detectedTablesBuilder,
      boolean multipleTables) {
    boolean detectedOrReplacedTable = false;
    boolean wasJoin = false;
    do {
      if (parser.eatToken("(")) {
        int startPosition = parser.getPos();
        String subExpression = parser.eatSubExpression();
        TableParser subParser = new TableParser(Statement.of(subExpression));
        Tuple<Set<TableOrIndexName>, Statement> subResult =
            subParser.detectAndReplaceTables(
                detectAndReplaceMap,
                replacedTables,
                subParser.parser.peekKeyword("select") || subParser.parser.peekKeyword("with"));
        if (!subResult.x().isEmpty()) {
          detectedOrReplacedTable = true;
          detectedTablesBuilder.addAll(subResult.x());
          parser.setSql(
              parser.getSql().substring(0, startPosition)
                  + subResult.y().getSql()
                  + parser.getSql().substring(parser.getPos()));
          // Set the position of the parser to after the replaced sub-expression.
          parser.setPos(startPosition + subResult.y().getSql().length());
          parser.eatToken(")");
        }
      } else {
        // Skip all whitespaces to get the actual position before the next table name.
        parser.skipWhitespaces();
        int positionBeforeName = parser.getPos();
        TableOrIndexName tableOrIndexName = parser.readTableOrIndexName();
        if (tableOrIndexName == null) {
          break;
        }
        if (detectAndReplaceMap.containsKey(tableOrIndexName)) {
          detectedOrReplacedTable = true;
          // Add the translated table name to the set of discovered tables so that a CTE can be
          // added for it.
          detectedTablesBuilder.add(
              Objects.requireNonNull(detectAndReplaceMap.get(tableOrIndexName)));
          replacedTables.add(tableOrIndexName);
          // Check if the entry in the table map contains a different replacement value than the
          // original. Some tables may be added to the map of replacements with the same replacement
          // value as the original with the sole purpose of detecting the use of the table.
          if (!Objects.equals(detectAndReplaceMap.get(tableOrIndexName), tableOrIndexName)) {
            parser.setSql(
                parser.getSql().substring(0, positionBeforeName)
                    + detectAndReplaceMap.get(tableOrIndexName)
                    + parser.getSql().substring(parser.getPos()));
            // Set the position of the parser to after the replaced table name.
            parser.setPos(
                positionBeforeName
                    + Objects.requireNonNull(detectAndReplaceMap.get(tableOrIndexName))
                        .toString()
                        .length());
          }
        }
      }
      // Skip any aliases.
      if (multipleTables && !parser.peekJoinKeyword()) {
        parser.eatKeyword("as");
        parser.readIdentifierPart();
      }
      if (wasJoin) {
        // Skip the join condition.
        int positionBeforeJoinCondition = parser.getPos();
        parser.eatJoinCondition();
        // Replace fully-qualified table names with unqualified table names in the join condition.
        String joinCondition =
            replaceFullyQualifiedColumnNames(
                detectAndReplaceMap, replacedTables, positionBeforeJoinCondition, parser.getPos());
        if (joinCondition != null) {
          parser.setSql(
              parser.getSql().substring(0, positionBeforeJoinCondition)
                  + joinCondition
                  + parser.getSql().substring(parser.getPos()));
          // Set the position of the parser to after the replaced join condition.
          parser.setPos(positionBeforeJoinCondition + joinCondition.length());
        }
      }
    } while (multipleTables && (parser.eatToken(",") || (wasJoin = parser.eatJoinType())));

    return detectedOrReplacedTable;
  }