|
53 | 53 | import java.util.Objects; |
54 | 54 | import java.util.Set; |
55 | 55 | import java.util.TreeMap; |
| 56 | +import java.util.function.Function; |
56 | 57 | import java.util.stream.Collectors; |
57 | 58 | import org.slf4j.Logger; |
58 | 59 | import org.slf4j.LoggerFactory; |
@@ -126,12 +127,23 @@ public List<String> generateDifferenceStatements(Map<String, Boolean> options) |
126 | 127 |
|
127 | 128 | if (!indexDifferences.entriesDiffering().isEmpty() |
128 | 129 | && !options.get(ALLOW_RECREATE_INDEXES_OPT)) { |
129 | | - throw new DdlDiffException( |
130 | | - "At least one Index differs, and " |
131 | | - + ALLOW_RECREATE_INDEXES_OPT |
132 | | - + " is not set.\n" |
133 | | - + "Indexes: " |
134 | | - + Joiner.on(", ").join(indexDifferences.entriesDiffering().keySet())); |
| 130 | + |
| 131 | + long numChangedIndexes = |
| 132 | + indexDifferences.entriesDiffering().values().stream() |
| 133 | + // Check if the indexes only difference is the STORING clause |
| 134 | + .map((diff) -> DdlDiff.checkIndexDiffOnlyStoring(diff)) |
| 135 | + // Filter out those who have only changed Storing clauses |
| 136 | + .filter((v) -> !v) |
| 137 | + .count(); |
| 138 | + |
| 139 | + if (numChangedIndexes > 0) { |
| 140 | + throw new DdlDiffException( |
| 141 | + "At least one Index differs, and " |
| 142 | + + ALLOW_RECREATE_INDEXES_OPT |
| 143 | + + " is not set.\n" |
| 144 | + + "Indexes: " |
| 145 | + + Joiner.on(", ").join(indexDifferences.entriesDiffering().keySet())); |
| 146 | + } |
135 | 147 | } |
136 | 148 |
|
137 | 149 | if (!constraintDifferences.entriesDiffering().isEmpty() |
@@ -171,9 +183,13 @@ public List<String> generateDifferenceStatements(Map<String, Boolean> options) |
171 | 183 | } |
172 | 184 |
|
173 | 185 | // Drop modified indexes that need to be re-created... |
174 | | - for (String indexName : indexDifferences.entriesDiffering().keySet()) { |
175 | | - LOG.info("Dropping changed index for re-creation: {}", indexName); |
176 | | - output.add("DROP INDEX " + indexName); |
| 186 | + for (ValueDifference<ASTcreate_index_statement> difference : |
| 187 | + indexDifferences.entriesDiffering().values()) { |
| 188 | + if (!checkIndexDiffOnlyStoring(difference)) { |
| 189 | + LOG.info( |
| 190 | + "Dropping changed index for re-creation: {}", difference.leftValue().getIndexName()); |
| 191 | + output.add("DROP INDEX " + difference.leftValue().getIndexName()); |
| 192 | + } |
177 | 193 | } |
178 | 194 |
|
179 | 195 | // Drop deleted constraints |
@@ -256,8 +272,36 @@ public List<String> generateDifferenceStatements(Map<String, Boolean> options) |
256 | 272 | // Re-create modified indexes... |
257 | 273 | for (ValueDifference<ASTcreate_index_statement> difference : |
258 | 274 | indexDifferences.entriesDiffering().values()) { |
259 | | - LOG.info("Re-creating changed index: {}", difference.leftValue().getIndexName()); |
260 | | - output.add(difference.rightValue().toStringOptionalExistClause(false)); |
| 275 | + |
| 276 | + if (checkIndexDiffOnlyStoring(difference)) { |
| 277 | + LOG.info("Updating STORING clause on index: {}", difference.leftValue().getIndexName()); |
| 278 | + Map<String, String> originalStoredCols = |
| 279 | + difference.leftValue().getStoredColumnNames().stream() |
| 280 | + .collect(Collectors.toMap(Function.identity(), Function.identity())); |
| 281 | + Map<String, String> newStoredCols = |
| 282 | + difference.rightValue().getStoredColumnNames().stream() |
| 283 | + .collect(Collectors.toMap(Function.identity(), Function.identity())); |
| 284 | + |
| 285 | + MapDifference<String, String> colDiff = Maps.difference(originalStoredCols, newStoredCols); |
| 286 | + |
| 287 | + for (String deletedCol : colDiff.entriesOnlyOnLeft().values()) { |
| 288 | + output.add( |
| 289 | + "ALTER INDEX " |
| 290 | + + difference.leftValue().getIndexName() |
| 291 | + + " DROP STORED COLUMN " |
| 292 | + + deletedCol); |
| 293 | + } |
| 294 | + for (String deletedCol : colDiff.entriesOnlyOnRight().values()) { |
| 295 | + output.add( |
| 296 | + "ALTER INDEX " |
| 297 | + + difference.leftValue().getIndexName() |
| 298 | + + " ADD STORED COLUMN " |
| 299 | + + deletedCol); |
| 300 | + } |
| 301 | + } else { |
| 302 | + LOG.info("Re-creating changed index: {}", difference.leftValue().getIndexName()); |
| 303 | + output.add(difference.rightValue().toStringOptionalExistClause(false)); |
| 304 | + } |
261 | 305 | } |
262 | 306 |
|
263 | 307 | // Create new constraints. |
@@ -329,6 +373,16 @@ public List<String> generateDifferenceStatements(Map<String, Boolean> options) |
329 | 373 | return output.build(); |
330 | 374 | } |
331 | 375 |
|
| 376 | + /** Verify that different indexes are only different in STORING clause. */ |
| 377 | + private static boolean checkIndexDiffOnlyStoring( |
| 378 | + ValueDifference<ASTcreate_index_statement> indexDifference) { |
| 379 | + |
| 380 | + return indexDifference |
| 381 | + .leftValue() |
| 382 | + .getDefinitionWithoutStoring() |
| 383 | + .equals(indexDifference.rightValue().getDefinitionWithoutStoring()); |
| 384 | + } |
| 385 | + |
332 | 386 | @VisibleForTesting |
333 | 387 | static List<String> generateAlterTableStatements( |
334 | 388 | ASTcreate_table_statement left, ASTcreate_table_statement right, Map<String, Boolean> options) |
|
0 commit comments