|
31 | 31 | import com.google.edwmigration.dumper.plugin.ext.jdk.annotation.Description; |
32 | 32 | import com.google.edwmigration.dumper.application.dumper.utils.SqlBuilder; |
33 | 33 | import com.google.edwmigration.dumper.plugin.lib.dumper.spi.TeradataMetadataDumpFormat; |
| 34 | +import java.util.Optional; |
34 | 35 | import org.slf4j.Logger; |
35 | 36 | import org.slf4j.LoggerFactory; |
36 | 37 |
|
|
44 | 45 | @RespectsArgumentAssessment |
45 | 46 | @RespectsInput(order = 450, arg = ConnectorArguments.OPT_TERADATA_MAX_TABLESIZEV_ROWS, |
46 | 47 | description = ConnectorArguments.TERADATA_MAX_TABLE_SIZE_V_ROWS_DESCRIPTION) |
| 48 | +@RespectsInput(order = 450, arg = ConnectorArguments.OPT_TERADATA_MAX_DATABASESV_USER_ROWS, |
| 49 | + description = ConnectorArguments.TERADATA_MAX_DATABASES_V_USER_ROWS_DESCRIPTION) |
| 50 | +@RespectsInput(order = 450, arg = ConnectorArguments.OPT_TERADATA_MAX_DATABASESV_DB_ROWS, |
| 51 | + description = ConnectorArguments.TERADATA_MAX_DATABASES_V_DB_ROWS_DESCRIPTION) |
47 | 52 | public class TeradataMetadataConnector extends AbstractTeradataConnector implements MetadataConnector, TeradataMetadataDumpFormat { |
48 | 53 |
|
49 | 54 | @SuppressWarnings("UnusedVariable") |
@@ -78,9 +83,7 @@ public void addTasksTo(List<? super Task<?>> out, ConnectorArguments arguments) |
78 | 83 | // This is theoretically more reliable than ColumnsV, but if we are bandwidth limited, we should risk taking ColumnsV only. |
79 | 84 | // out.add(new JdbcSelectTask(ColumnsFormat.ZIP_ENTRY_NAME, // Was: teradata.columns.csv |
80 | 85 | // "SELECT \"DatabaseName\", \"TableName\", \"ColumnId\", \"ColumnName\", \"ColumnType\" FROM DBC.Columns" + whereDatabaseNameClause + " ;")); |
81 | | - out.add(new TeradataJdbcSelectTask(DatabasesVFormat.ZIP_ENTRY_NAME, |
82 | | - TaskCategory.REQUIRED, |
83 | | - "SELECT %s FROM DBC.DatabasesV" + whereDatabaseNameClause + " ;")); |
| 86 | + out.add(createTaskForDatabasesV(whereDatabaseNameClause, arguments)); |
84 | 87 | //out.add(new TeradataJdbcSelectTask("td.dbc.Tables.others.csv", "SELECT * FROM DBC.Tables WHERE TableKind <> 'F' ORDER BY 1,2,3,4;")); |
85 | 88 | //out.add(new TeradataJdbcSelectTask("td.dbc.Tables.functions.csv", "SELECT * FROM DBC.Tables WHERE TableKind = 'F' ORDER BY 1,2,3,4;")); |
86 | 89 | // TODO: This contains RequestText for views, which doesn't tell us the "current" database at the point the view was defined. |
@@ -140,25 +143,68 @@ public void addTasksTo(List<? super Task<?>> out, ConnectorArguments arguments) |
140 | 143 | } |
141 | 144 | } |
142 | 145 |
|
| 146 | + private TeradataJdbcSelectTask createTaskForDatabasesV( |
| 147 | + String whereDatabaseNameClause, |
| 148 | + ConnectorArguments arguments) { |
| 149 | + StringBuilder query = new StringBuilder(); |
| 150 | + Optional<Long> userRows = arguments.getTeradataMaxDatabasesVUserRows(); |
| 151 | + Optional<Long> dbRows = arguments.getTeradataMaxDatabasesVDbRows(); |
| 152 | + query.append("SELECT %s FROM "); |
| 153 | + if(!userRows.isPresent() && !dbRows.isPresent()) { |
| 154 | + query.append(" DBC.DatabasesV ").append(whereDatabaseNameClause); |
| 155 | + } else { |
| 156 | + query.append(" (SELECT * FROM ( "); |
| 157 | + appendSelect(query, userRows, |
| 158 | + " * FROM DBC.DatabasesV " |
| 159 | + + concatWhere(whereDatabaseNameClause, " DBKind='U' "), " ORDER BY PermSpace DESC "); |
| 160 | + query.append(" ) AS users UNION SELECT * FROM ("); |
| 161 | + appendSelect(query, dbRows, |
| 162 | + " * FROM DBC.DatabasesV " |
| 163 | + + concatWhere(whereDatabaseNameClause, " DBKind='D' "), " ORDER BY PermSpace DESC "); |
| 164 | + query.append(" ) AS dbs) AS t"); |
| 165 | + } |
| 166 | + query.append(';'); |
| 167 | + return new TeradataJdbcSelectTask(DatabasesVFormat.ZIP_ENTRY_NAME, |
| 168 | + TaskCategory.REQUIRED, formatQuery(query.toString())); |
| 169 | + } |
| 170 | + |
143 | 171 | private TeradataJdbcSelectTask createTaskForTableSizeV( |
144 | 172 | String whereDataBaseNameClause, |
145 | 173 | ConnectorArguments arguments) { |
146 | 174 | StringBuilder query = new StringBuilder(); |
147 | | - query.append("SELECT "); |
148 | | - arguments.getTeradataMaxTableSizeVRows().ifPresent(maxRows -> query.append("TOP ").append(maxRows)); |
149 | 175 | // TableSizeV contains a row per each VProc/AMP, so it can grow significantly for large dbs. |
150 | 176 | // Hence, we aggregate before dumping. |
151 | 177 | // See recommended usage |
152 | 178 | // https://docs.teradata.com/r/Teradata-VantageTM-Data-Dictionary/March-2019/Views-Reference/TableSizeV-X/Examples-Using-TableSizeV |
153 | | - query.append(" DataBaseName, AccountName, TableName, SUM(CurrentPerm) CurrentPerm, SUM(PeakPerm) PeakPerm FROM DBC.TableSizeV ") |
154 | | - .append(whereDataBaseNameClause) |
155 | | - .append(" GROUP BY 1,2,3"); |
156 | | - arguments.getTeradataMaxTableSizeVRows().ifPresent(unused -> query.append(" ORDER BY 4 DESC")); |
| 179 | + appendSelect(query, arguments.getTeradataMaxTableSizeVRows(), |
| 180 | + " DataBaseName, AccountName, TableName, SUM(CurrentPerm) CurrentPerm, SUM(PeakPerm) PeakPerm FROM DBC.TableSizeV " |
| 181 | + + whereDataBaseNameClause + " GROUP BY 1,2,3 ", " ORDER BY 4 DESC "); |
157 | 182 | query.append(';'); |
158 | 183 | return new TeradataJdbcSelectTask( |
159 | 184 | TableSizeVFormat.ZIP_ENTRY_NAME, |
160 | 185 | TaskCategory.OPTIONAL, |
161 | | - query.toString()); |
| 186 | + formatQuery(query.toString())); |
162 | 187 | } |
163 | 188 |
|
| 189 | + private static String concatWhere(String whereClause, String condition) { |
| 190 | + StringBuilder result = new StringBuilder(); |
| 191 | + if(whereClause.isEmpty()) { |
| 192 | + result.append(" WHERE "); |
| 193 | + } else { |
| 194 | + result.append(whereClause); |
| 195 | + } |
| 196 | + result.append(condition); |
| 197 | + return result.toString(); |
| 198 | + } |
| 199 | + |
| 200 | + private static void appendSelect(StringBuilder query, Optional<Long> maxRowCountMaybe, String selectBody, String orderBy) { |
| 201 | + query.append(" SELECT "); |
| 202 | + maxRowCountMaybe.ifPresent(maxRowCount -> query.append(" TOP ").append(maxRowCount).append(' ')); |
| 203 | + query.append(selectBody); |
| 204 | + maxRowCountMaybe.ifPresent(unused -> query.append(orderBy)); |
| 205 | + } |
| 206 | + |
| 207 | + private static String formatQuery(String query) { |
| 208 | + return query.replaceAll("\\s+", " ").replaceAll("\\( ", "(").replaceAll(" \\)", ")").trim(); |
| 209 | + } |
164 | 210 | } |
0 commit comments