Skip to content

Commit 6383077

Browse files
authored
[b/394312229] Dump Snowflake external table metadata without the assessment flag (#828)
1 parent 628dd98 commit 6383077

File tree

7 files changed

+60
-13
lines changed

7 files changed

+60
-13
lines changed

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/snowflake/AbstractSnowflakeConnector.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@ final ImmutableList<Task<?>> getSqlTasks(
133133
private void setCurrentDatabase(@Nonnull String databaseName, @Nonnull JdbcTemplate jdbcTemplate)
134134
throws MetadataDumperUsageException {
135135
String currentDatabase =
136-
jdbcTemplate.queryForObject(
137-
String.format("USE DATABASE \"%s\";", databaseName), String.class);
136+
jdbcTemplate.queryForObject(String.format("USE DATABASE %s;", databaseName), String.class);
138137
if (currentDatabase == null) {
139138
List<String> dbNames =
140139
jdbcTemplate.query("SHOW DATABASES", (rs, rowNum) -> rs.getString("name"));
@@ -146,8 +145,7 @@ private void setCurrentDatabase(@Nonnull String databaseName, @Nonnull JdbcTempl
146145
}
147146
}
148147

149-
private String sanitizeDatabaseName(@Nonnull String databaseName)
150-
throws MetadataDumperUsageException {
148+
String sanitizeDatabaseName(@Nonnull String databaseName) throws MetadataDumperUsageException {
151149
CharMatcher doubleQuoteMatcher = CharMatcher.is('"');
152150
String trimmedName = doubleQuoteMatcher.trimFrom(databaseName);
153151
int charLengthWithQuotes = databaseName.length() + 2;

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/snowflake/HeaderTransformerUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
@ParametersAreNonnullByDefault
2929
final class HeaderTransformerUtil {
3030

31-
static ResultSetTransformer<String[]> toCamelCaseFrom(CaseFormat format) {
31+
public static ResultSetTransformer<String[]> toCamelCaseFrom(CaseFormat format) {
3232
return resultSet -> transformToCamelCase(resultSet, format);
3333
}
3434

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/snowflake/MetadataView.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum MetadataView {
2020
DATABASES("databases"),
2121
SCHEMATA("schemata"),
2222
TABLES("tables"),
23+
EXTERNAL_TABLES("externalTables"),
2324
COLUMNS("columns"),
2425
VIEWS("views"),
2526
FUNCTIONS("functions"),

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/snowflake/SnowflakeMetadataConnector.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,18 @@ public final void addTasksTo(
146146
out.add(new FormatTask(FORMAT_NAME));
147147

148148
boolean INJECT_IS_FAULT = arguments.isTestFlag('A');
149-
final String IS = INJECT_IS_FAULT ? "__NONEXISTENT__" : "INFORMATION_SCHEMA";
149+
// INFORMATION_SCHEMA queries must be qualified with a database
150+
// name or that a "USE DATABASE" command has previously been run
151+
// in the same session. Qualify the name to avoid this dependency.
152+
final String databaseName = arguments.getDatabaseSingleName();
153+
final String IS;
154+
if (INJECT_IS_FAULT) {
155+
IS = "__NONEXISTENT__";
156+
} else if (databaseName == null) {
157+
IS = "INFORMATION_SCHEMA";
158+
} else {
159+
IS = sanitizeDatabaseName(databaseName) + ".INFORMATION_SCHEMA";
160+
}
150161
final String AU = "SNOWFLAKE.ACCOUNT_USAGE";
151162
final String AU_WHERE = " WHERE DELETED IS NULL";
152163

@@ -240,15 +251,25 @@ public final void addTasksTo(
240251

241252
if (isAssessment) {
242253
for (AssessmentQuery item : planner.generateAssessmentQueries()) {
243-
String formatString = overrideFormatString(item, arguments);
244-
String query = String.format(formatString, AU, /* an empty WHERE clause */ "");
245-
String zipName = item.zipEntryName;
246-
Task<?> task = new JdbcSelectTask(zipName, query).withHeaderTransformer(item.transformer());
247-
out.add(task);
254+
addAssessmentQuery(item, out, arguments, AU);
248255
}
256+
} else {
257+
addAssessmentQuery(SnowflakePlanner.SHOW_EXTERNAL_TABLES, out, arguments, AU);
249258
}
250259
}
251260

261+
private void addAssessmentQuery(
262+
@Nonnull AssessmentQuery item,
263+
@Nonnull List<? super Task<?>> out,
264+
@Nonnull ConnectorArguments arguments,
265+
@Nonnull String AU) {
266+
String formatString = overrideFormatString(item, arguments);
267+
String query = String.format(formatString, AU, /* an empty WHERE clause */ "");
268+
String zipName = item.zipEntryName;
269+
Task<?> task = new JdbcSelectTask(zipName, query).withHeaderTransformer(item.transformer());
270+
out.add(task);
271+
}
272+
252273
private String overrideFormatString(AssessmentQuery query, ConnectorArguments arguments) {
253274
if (query.needsOverride) {
254275
return getOverrideableQuery(arguments, query.formatString, TABLE_STORAGE_METRICS);

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/snowflake/SnowflakePlanner.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
@ParametersAreNonnullByDefault
4343
final class SnowflakePlanner {
4444

45+
public static final AssessmentQuery SHOW_EXTERNAL_TABLES =
46+
AssessmentQuery.createShow("EXTERNAL TABLES", Format.EXTERNAL_TABLES, LOWER_UNDERSCORE);
47+
4548
private enum Format {
4649
EXTERNAL_TABLES(ExternalTablesFormat.AU_ZIP_ENTRY_NAME),
4750
FUNCTION_INFO(FunctionInfoFormat.AU_ZIP_ENTRY_NAME),
@@ -62,7 +65,7 @@ ImmutableList<AssessmentQuery> generateAssessmentQueries() {
6265
return ImmutableList.of(
6366
AssessmentQuery.createMetricsSelect(Format.TABLE_STORAGE_METRICS, UPPER_UNDERSCORE),
6467
AssessmentQuery.createShow("WAREHOUSES", Format.WAREHOUSES, LOWER_UNDERSCORE),
65-
AssessmentQuery.createShow("EXTERNAL TABLES", Format.EXTERNAL_TABLES, LOWER_UNDERSCORE),
68+
SHOW_EXTERNAL_TABLES,
6669
AssessmentQuery.createShow("FUNCTIONS", Format.FUNCTION_INFO, LOWER_UNDERSCORE));
6770
}
6871

dumper/app/src/test/java/com/google/edwmigration/dumper/application/dumper/connector/snowflake/SnowflakeAccountUsageMetadataConnectorTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ public void testExecution() throws Exception {
5656
validator.withEntryValidator(
5757
SnowflakeMetadataDumpFormat.FunctionsFormat.AU_ZIP_ENTRY_NAME,
5858
SnowflakeMetadataDumpFormat.FunctionsFormat.Header.class);
59+
validator.withEntryValidator(
60+
SnowflakeMetadataDumpFormat.ExternalTablesFormat.AU_ZIP_ENTRY_NAME,
61+
SnowflakeMetadataDumpFormat.ExternalTablesFormat.Header.class);
5962

6063
validator.withExpectedEntries(
6164
SnowflakeMetadataDumpFormat.TableStorageMetricsFormat.AU_ZIP_ENTRY_NAME,
6265
SnowflakeMetadataDumpFormat.FunctionInfoFormat.AU_ZIP_ENTRY_NAME,
63-
SnowflakeMetadataDumpFormat.ExternalTablesFormat.AU_ZIP_ENTRY_NAME,
6466
SnowflakeMetadataDumpFormat.WarehousesFormat.AU_ZIP_ENTRY_NAME);
6567
}
6668
}

dumper/lib-dumper-spi/src/main/java/com/google/edwmigration/dumper/plugin/lib/dumper/spi/SnowflakeMetadataDumpFormat.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,27 @@ interface WarehousesFormat {
139139

140140
interface ExternalTablesFormat {
141141
String AU_ZIP_ENTRY_NAME = "external_tables.csv";
142+
143+
enum Header {
144+
CreatedOn,
145+
Name,
146+
DatabaseName,
147+
SchemaName,
148+
Invalid,
149+
InvalidReason,
150+
Owner,
151+
Comment,
152+
Stage,
153+
Location,
154+
FileFormatName,
155+
FileFormatType,
156+
Cloud,
157+
Region,
158+
NotificationChannel,
159+
LastRefreshedOn,
160+
TableFormat,
161+
LastRefreshDetails,
162+
OwnerRoleType
163+
}
142164
}
143165
}

0 commit comments

Comments
 (0)