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);
}