public FixResult fix()

in tools/automatic_query_fixer/src/main/java/com/google/cloud/bigquery/utils/queryfixer/fixer/TableNotFoundFixer.java [48:91]


  public FixResult fix() {
    TableId incorrectTableId = constructTableId(err.getTableName());
    List<String> tableNames =
        bigQueryService.listTableNames(
            incorrectTableId.getProject(), incorrectTableId.getDataset());

    StringUtil.SimilarStrings similarTables =
        StringUtil.findMostSimilarWords(
            tableNames, incorrectTableId.getTable(), /*caseSensitive=*/ false);

    // This is an arbitrary standard. It requires the candidate table should share at least 50%
    // similarity as the incorrect table typo.
    // TODO: this could be user configurable in future.
    int editDistanceThreshold = (incorrectTableId.getTable().length() + 1) / 2;

    if (similarTables.getStrings().isEmpty()
        || similarTables.getDistance() > editDistanceThreshold) {
      return FixResult.failure(query, err, "No similar table was found.");
    }

    // This method only finds the first occurrence of the incorrect table. It is possible that this
    // table exists in multiple positions of this query.
    StringView incorrectTableView = findSubstringViewOfIncorrectTable(incorrectTableId);
    if (incorrectTableView == null) {
      return FixResult.failure(query, err, "Cannot locate the incorrect table position.");
    }
    Position errorPosition = queryPositionConverter.indexToPos(incorrectTableView.getStart());
    this.err.setErrorPosition(errorPosition);

    List<FixOption> fixOptions =
        similarTables.getStrings().stream()
            .map(
                table -> {
                  String fullTableName =
                      constructFullTableName(
                          incorrectTableId.getProject(), incorrectTableId.getDataset(), table);
                  String fixedQuery = replaceTable(fullTableName, incorrectTableView);
                  return FixOption.of(String.format("Change to `%s`", fullTableName), fixedQuery);
                })
            .collect(Collectors.toList());

    String approach = String.format("Replace the table name `%s`", err.getTableName());
    return FixResult.success(query, approach, fixOptions, err, /*isConfident=*/ true);
  }