Skip to content

Commit ef1a4c4

Browse files
committed
create tier specific TableConfig to be used by IndexType.getConfig
1 parent cb8d355 commit ef1a4c4

File tree

23 files changed

+361
-156
lines changed

23 files changed

+361
-156
lines changed

pinot-common/src/main/java/org/apache/pinot/common/utils/config/TableConfigUtils.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@
2020

2121
import com.fasterxml.jackson.core.JsonProcessingException;
2222
import com.fasterxml.jackson.core.type.TypeReference;
23+
import com.fasterxml.jackson.databind.JsonNode;
24+
import com.fasterxml.jackson.databind.node.ObjectNode;
2325
import com.google.common.base.Preconditions;
2426
import java.io.IOException;
2527
import java.util.Collections;
2628
import java.util.HashMap;
29+
import java.util.Iterator;
2730
import java.util.List;
2831
import java.util.Map;
32+
import javax.annotation.Nullable;
2933
import org.apache.commons.collections.MapUtils;
3034
import org.apache.helix.zookeeper.datamodel.ZNRecord;
3135
import org.apache.pinot.spi.config.table.DedupConfig;
@@ -50,9 +54,13 @@
5054
import org.apache.pinot.spi.config.table.ingestion.IngestionConfig;
5155
import org.apache.pinot.spi.config.table.ingestion.StreamIngestionConfig;
5256
import org.apache.pinot.spi.utils.JsonUtils;
57+
import org.slf4j.Logger;
58+
import org.slf4j.LoggerFactory;
5359

5460

5561
public class TableConfigUtils {
62+
private static final Logger LOGGER = LoggerFactory.getLogger(TableConfigUtils.class);
63+
5664
private TableConfigUtils() {
5765
}
5866

@@ -331,6 +339,96 @@ public static void convertFromLegacyTableConfig(TableConfig tableConfig) {
331339
validationConfig.setSegmentPushType(null);
332340
}
333341

342+
/**
343+
* Helper method to create a new TableConfig by overwriting the original TableConfig with tier specific configs, so
344+
* that the consumers of TableConfig don't have to handle tier overwrites themselves. To begin with, we only
345+
* consider to overwrite the index configs in `tableIndexConfig` and `fieldConfigList`, e.g.
346+
*
347+
* {
348+
* "tableIndexConfig": {
349+
* ... // configs allowed in IndexingConfig, for default tier
350+
* "tierOverwrites": {
351+
* "hotTier": {...}, // configs allowed in IndexingConfig, for hot tier
352+
* "coldTier": {...} // configs allowed in IndexingConfig, for cold tier
353+
* }
354+
* }
355+
* "fieldConfigList": [
356+
* {
357+
* ... // configs allowed in FieldConfig, for default tier
358+
* "tierOverwrites": {
359+
* "hotTier": {...}, // configs allowed in FieldConfig, for hot tier
360+
* "coldTier": {...} // configs allowed in FieldConfig, for cold tier
361+
* }
362+
* },
363+
* ...
364+
* ]
365+
* }
366+
*
367+
* Overwriting is to extract tier specific configs from those `tierOverwrites` sections and replace the
368+
* corresponding configs set for default tier.
369+
*
370+
* TODO: Other tier specific configs like segment assignment policy may be handled in this helper method too, to
371+
* keep tier overwrites transparent to consumers of TableConfig.
372+
*
373+
* @param tableConfig the input table config which is kept intact
374+
* @param tier the target tier to overwrite the table config
375+
* @return a new table config overwritten for the tier, or the original table if overwriting doesn't happen.
376+
*/
377+
public static TableConfig overwriteTableConfigForTier(TableConfig tableConfig, @Nullable String tier) {
378+
if (tier == null) {
379+
return tableConfig;
380+
}
381+
try {
382+
boolean updated = false;
383+
JsonNode tblCfgJson = tableConfig.toJsonNode();
384+
// Apply tier specific overwrites for `tableIndexConfig`
385+
JsonNode tblIdxCfgJson = tblCfgJson.get(TableConfig.INDEXING_CONFIG_KEY);
386+
if (tblIdxCfgJson != null && tblIdxCfgJson.has(TableConfig.TIER_OVERWRITES_KEY)) {
387+
JsonNode tierCfgJson = tblIdxCfgJson.get(TableConfig.TIER_OVERWRITES_KEY).get(tier);
388+
if (tierCfgJson != null) {
389+
LOGGER.debug("Got table index config overwrites: {} for tier: {}", tierCfgJson, tier);
390+
overwriteConfig(tblIdxCfgJson, tierCfgJson);
391+
updated = true;
392+
}
393+
}
394+
// Apply tier specific overwrites for `fieldConfigList`
395+
JsonNode fieldCfgListJson = tblCfgJson.get(TableConfig.FIELD_CONFIG_LIST_KEY);
396+
if (fieldCfgListJson != null && fieldCfgListJson.isArray()) {
397+
Iterator<JsonNode> fieldCfgListItr = fieldCfgListJson.elements();
398+
while (fieldCfgListItr.hasNext()) {
399+
JsonNode fieldCfgJson = fieldCfgListItr.next();
400+
if (!fieldCfgJson.has(TableConfig.TIER_OVERWRITES_KEY)) {
401+
continue;
402+
}
403+
JsonNode tierCfgJson = fieldCfgJson.get(TableConfig.TIER_OVERWRITES_KEY).get(tier);
404+
if (tierCfgJson != null) {
405+
LOGGER.debug("Got field index config overwrites: {} for tier: {}", tierCfgJson, tier);
406+
overwriteConfig(fieldCfgJson, tierCfgJson);
407+
updated = true;
408+
}
409+
}
410+
}
411+
if (updated) {
412+
LOGGER.debug("Got overwritten table config: {} for tier: {}", tblCfgJson, tier);
413+
return JsonUtils.jsonNodeToObject(tblCfgJson, TableConfig.class);
414+
} else {
415+
LOGGER.debug("No table config overwrites for tier: {}", tier);
416+
return tableConfig;
417+
}
418+
} catch (IOException e) {
419+
LOGGER.warn("Failed to overwrite table config for tier: {} for table: {}", tier, tableConfig.getTableName(), e);
420+
return tableConfig;
421+
}
422+
}
423+
424+
private static void overwriteConfig(JsonNode oldCfg, JsonNode newCfg) {
425+
Iterator<Map.Entry<String, JsonNode>> cfgItr = newCfg.fields();
426+
while (cfgItr.hasNext()) {
427+
Map.Entry<String, JsonNode> cfgEntry = cfgItr.next();
428+
((ObjectNode) oldCfg).set(cfgEntry.getKey(), cfgEntry.getValue());
429+
}
430+
}
431+
334432
/**
335433
* Returns true if the table has pre-configured instance partitions for any type (OFFLINE/CONSUMING/COMPLETED).
336434
*/

pinot-common/src/test/java/org/apache/pinot/common/utils/config/TableConfigUtilsTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
*/
1919
package org.apache.pinot.common.utils.config;
2020

21+
import java.util.Collections;
2122
import java.util.HashMap;
2223
import java.util.Map;
2324
import java.util.Set;
25+
import org.apache.pinot.spi.config.table.FieldConfig;
2426
import org.apache.pinot.spi.config.table.SegmentsValidationAndRetentionConfig;
27+
import org.apache.pinot.spi.config.table.StarTreeIndexConfig;
2528
import org.apache.pinot.spi.config.table.TableConfig;
2629
import org.apache.pinot.spi.config.table.TableType;
2730
import org.apache.pinot.spi.config.table.ingestion.BatchIngestionConfig;
@@ -33,6 +36,7 @@
3336
import org.apache.pinot.spi.stream.StreamLevelConsumer;
3437
import org.apache.pinot.spi.stream.StreamMessageDecoder;
3538
import org.apache.pinot.spi.stream.StreamMetadataProvider;
39+
import org.apache.pinot.spi.utils.JsonUtils;
3640
import org.apache.pinot.spi.utils.builder.TableConfigBuilder;
3741
import org.testng.Assert;
3842
import org.testng.annotations.Test;
@@ -85,6 +89,57 @@ public void testConvertFromLegacyTableConfig() {
8589
Assert.assertNull(validationConfig.getSegmentPushType());
8690
}
8791

92+
@Test
93+
public void testOverwriteTableConfigForTier()
94+
throws Exception {
95+
String col1CfgStr = "{"
96+
+ " \"name\": \"col1\","
97+
+ " \"encodingType\": \"DICTIONARY\","
98+
+ " \"indexes\": {"
99+
+ " \"bloom\": {\"enabled\": \"true\"}"
100+
+ " },"
101+
+ " \"tierOverwrites\": {"
102+
+ " \"coldTier\": {"
103+
+ " \"encodingType\": \"RAW\","
104+
+ " \"indexes\": {}"
105+
+ " }"
106+
+ " }"
107+
+ "}";
108+
FieldConfig col2Cfg = JsonUtils.stringToObject(col1CfgStr, FieldConfig.class);
109+
String stIdxCfgStr = "{"
110+
+ " \"dimensionsSplitOrder\": [\"col1\"],"
111+
+ " \"functionColumnPairs\": [\"MAX__col1\"],"
112+
+ " \"maxLeafRecords\": 10"
113+
+ "}";
114+
StarTreeIndexConfig stIdxCfg = JsonUtils.stringToObject(stIdxCfgStr, StarTreeIndexConfig.class);
115+
TableConfig tableConfig = new TableConfigBuilder(TableType.OFFLINE).setTableName(TABLE_NAME)
116+
.setStarTreeIndexConfigs(Collections.singletonList(stIdxCfg))
117+
.setTierOverwrites(JsonUtils.stringToJsonNode("{\"coldTier\": {\"starTreeIndexConfigs\": []}}"))
118+
.setFieldConfigList(Collections.singletonList(col2Cfg)).build();
119+
120+
TableConfig tierTblCfg = TableConfigUtils.overwriteTableConfigForTier(tableConfig, "unknownTier");
121+
Assert.assertEquals(tierTblCfg, tableConfig);
122+
tierTblCfg = TableConfigUtils.overwriteTableConfigForTier(tableConfig, null);
123+
Assert.assertEquals(tierTblCfg, tableConfig);
124+
// Check original TableConfig and tier specific TableConfig
125+
Assert.assertEquals(tierTblCfg.getFieldConfigList().get(0).getEncodingType(), FieldConfig.EncodingType.DICTIONARY);
126+
Assert.assertEquals(tierTblCfg.getFieldConfigList().get(0).getIndexes().size(), 1);
127+
Assert.assertEquals(tierTblCfg.getIndexingConfig().getStarTreeIndexConfigs().size(), 1);
128+
tierTblCfg = TableConfigUtils.overwriteTableConfigForTier(tableConfig, "coldTier");
129+
Assert.assertEquals(tierTblCfg.getFieldConfigList().get(0).getEncodingType(), FieldConfig.EncodingType.RAW);
130+
Assert.assertEquals(tierTblCfg.getFieldConfigList().get(0).getIndexes().size(), 0);
131+
Assert.assertEquals(tierTblCfg.getIndexingConfig().getStarTreeIndexConfigs().size(), 0);
132+
}
133+
134+
@Test
135+
public void testOverwriteTableConfigForTierWithError()
136+
throws Exception {
137+
TableConfig tableConfig = new TableConfigBuilder(TableType.OFFLINE).setTableName(TABLE_NAME)
138+
.setTierOverwrites(JsonUtils.stringToJsonNode("{\"coldTier\": {\"starTreeIndexConfigs\": {}}}")).build();
139+
TableConfig tierTblCfg = TableConfigUtils.overwriteTableConfigForTier(tableConfig, "coldTier");
140+
Assert.assertEquals(tierTblCfg, tableConfig);
141+
}
142+
88143
/**
89144
* Helper method to create a test StreamConfigs map.
90145
* @return Map containing Stream Configs

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/bloom/BloomIndexType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ public BloomFilterConfig getDefaultConfig() {
7171
}
7272

7373
@Override
74-
public ColumnConfigDeserializer<BloomFilterConfig> createDeserializer(@Nullable String tier) {
75-
return IndexConfigDeserializer.fromIndexes("bloom", tier, getIndexConfigClass())
74+
public ColumnConfigDeserializer<BloomFilterConfig> createDeserializer() {
75+
return IndexConfigDeserializer.fromIndexes("bloom", getIndexConfigClass())
7676
.withExclusiveAlternative(
7777
IndexConfigDeserializer.ifIndexingConfig(// reads tableConfig.indexingConfig.bloomFilterConfigs
7878
IndexConfigDeserializer.fromMap(tableConfig -> tableConfig.getIndexingConfig().getBloomFilterConfigs())

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/dictionary/DictionaryIndexType.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public DictionaryIndexConfig getDefaultConfig() {
110110
}
111111

112112
@Override
113-
public ColumnConfigDeserializer<DictionaryIndexConfig> createDeserializer(@Nullable String tier) {
113+
public ColumnConfigDeserializer<DictionaryIndexConfig> createDeserializer() {
114114
// reads tableConfig.indexingConfig.noDictionaryConfig
115115
ColumnConfigDeserializer<DictionaryIndexConfig> fromNoDictConf = IndexConfigDeserializer.fromMap(
116116
tableConfig -> tableConfig.getIndexingConfig() == null ? Collections.emptyMap()
@@ -127,7 +127,6 @@ public ColumnConfigDeserializer<DictionaryIndexConfig> createDeserializer(@Nulla
127127
ColumnConfigDeserializer<DictionaryIndexConfig> fromFieldConfigList = IndexConfigDeserializer.fromCollection(
128128
TableConfig::getFieldConfigList,
129129
(accum, fieldConfig) -> {
130-
fieldConfig = fieldConfig.withTierOverwrites(tier);
131130
if (fieldConfig.getEncodingType() == FieldConfig.EncodingType.RAW) {
132131
accum.put(fieldConfig.getName(), DictionaryIndexConfig.disabled());
133132
}
@@ -155,7 +154,7 @@ public ColumnConfigDeserializer<DictionaryIndexConfig> createDeserializer(@Nulla
155154
.withFallbackAlternative(fromNoDictCol)
156155
.withFallbackAlternative(fromFieldConfigList)
157156
.withFallbackAlternative(fromIndexingConfig)
158-
.withExclusiveAlternative(IndexConfigDeserializer.fromIndexes(getId(), tier, getIndexConfigClass()));
157+
.withExclusiveAlternative(IndexConfigDeserializer.fromIndexes(getId(), getIndexConfigClass()));
159158
}
160159

161160
@Override

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/forward/ForwardIndexType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public ForwardIndexConfig getDefaultConfig() {
126126
}
127127

128128
@Override
129-
public ColumnConfigDeserializer<ForwardIndexConfig> createDeserializer(@Nullable String tier) {
129+
public ColumnConfigDeserializer<ForwardIndexConfig> createDeserializer() {
130130
// reads tableConfig.fieldConfigList and decides what to create using the FieldConfig properties and encoding
131131
ColumnConfigDeserializer<ForwardIndexConfig> fromFieldConfig = IndexConfigDeserializer.fromCollection(
132132
TableConfig::getFieldConfigList,
@@ -144,7 +144,7 @@ public ColumnConfigDeserializer<ForwardIndexConfig> createDeserializer(@Nullable
144144
// the default `fromIndexes` deserializer.
145145
}
146146
);
147-
return IndexConfigDeserializer.fromIndexes("forward", tier, getIndexConfigClass())
147+
return IndexConfigDeserializer.fromIndexes("forward", getIndexConfigClass())
148148
.withExclusiveAlternative(fromFieldConfig);
149149
}
150150

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/fst/FstIndexType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ public FstIndexConfig getDefaultConfig() {
9191
}
9292

9393
@Override
94-
public ColumnConfigDeserializer<FstIndexConfig> createDeserializer(@Nullable String tier) {
95-
return IndexConfigDeserializer.fromIndexes("fst", tier, getIndexConfigClass())
94+
public ColumnConfigDeserializer<FstIndexConfig> createDeserializer() {
95+
return IndexConfigDeserializer.fromIndexes("fst", getIndexConfigClass())
9696
.withExclusiveAlternative(IndexConfigDeserializer.fromIndexTypes(
9797
FieldConfig.IndexType.FST,
9898
(tableConfig, fieldConfig) -> {

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/h3/H3IndexType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ public H3IndexConfig getDefaultConfig() {
7676
}
7777

7878
@Override
79-
public ColumnConfigDeserializer<H3IndexConfig> createDeserializer(@Nullable String tier) {
80-
return IndexConfigDeserializer.fromIndexes("h3", tier, getIndexConfigClass())
79+
public ColumnConfigDeserializer<H3IndexConfig> createDeserializer() {
80+
return IndexConfigDeserializer.fromIndexes("h3", getIndexConfigClass())
8181
.withExclusiveAlternative(IndexConfigDeserializer.fromIndexTypes(
8282
FieldConfig.IndexType.H3,
8383
((tableConfig, fieldConfig) -> new H3IndexConfig(fieldConfig.getProperties()))));

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/inverted/InvertedIndexType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ public IndexConfig getDefaultConfig() {
7979
}
8080

8181
@Override
82-
public ColumnConfigDeserializer<IndexConfig> createDeserializer(@Nullable String tier) {
82+
public ColumnConfigDeserializer<IndexConfig> createDeserializer() {
8383
ColumnConfigDeserializer<IndexConfig> fromInvertedCols = IndexConfigDeserializer.fromCollection(
8484
tableConfig -> tableConfig.getIndexingConfig().getInvertedIndexColumns(),
8585
(acum, column) -> acum.put(column, IndexConfig.ENABLED));
86-
return IndexConfigDeserializer.fromIndexes("inverted", tier, getIndexConfigClass())
86+
return IndexConfigDeserializer.fromIndexes("inverted", getIndexConfigClass())
8787
.withExclusiveAlternative(IndexConfigDeserializer.ifIndexingConfig(fromInvertedCols));
8888
}
8989

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/json/JsonIndexType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public JsonIndexConfig getDefaultConfig() {
7474
}
7575

7676
@Override
77-
public ColumnConfigDeserializer<JsonIndexConfig> createDeserializer(@Nullable String tier) {
77+
public ColumnConfigDeserializer<JsonIndexConfig> createDeserializer() {
7878
// reads tableConfig.indexingConfig.jsonIndexConfigs
7979
ColumnConfigDeserializer<JsonIndexConfig> fromJsonIndexConf =
8080
IndexConfigDeserializer.fromMap(tableConfig -> tableConfig.getIndexingConfig().getJsonIndexConfigs());
@@ -83,7 +83,7 @@ public ColumnConfigDeserializer<JsonIndexConfig> createDeserializer(@Nullable St
8383
IndexConfigDeserializer.fromCollection(
8484
tableConfig -> tableConfig.getIndexingConfig().getJsonIndexColumns(),
8585
(accum, column) -> accum.put(column, new JsonIndexConfig()));
86-
return IndexConfigDeserializer.fromIndexes("json", tier, getIndexConfigClass())
86+
return IndexConfigDeserializer.fromIndexes("json", getIndexConfigClass())
8787
.withExclusiveAlternative(
8888
IndexConfigDeserializer.ifIndexingConfig(fromJsonIndexCols.withExclusiveAlternative(fromJsonIndexConf)));
8989
}

pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/ForwardIndexHandler.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ Map<String, List<Operation>> computeOperations(SegmentDirectory.Reader segmentRe
226226

227227
if (existingForwardIndexColumns.contains(column) && !newIsFwd) {
228228
// Existing column has a forward index. New column config disables the forward index
229-
LOGGER.debug("Existing column: {} has forward index but new column config disables it", column);
229+
230230
ColumnMetadata columnMetadata = _segmentDirectory.getSegmentMetadata().getColumnMetadataFor(column);
231231
if (columnMetadata.isSorted()) {
232232
// Check if the column is sorted. If sorted, disabling forward index should be a no-op. Do not return an
@@ -260,7 +260,7 @@ Map<String, List<Operation>> computeOperations(SegmentDirectory.Reader segmentRe
260260
}
261261
} else if (existingForwardIndexDisabledColumns.contains(column) && newIsFwd) {
262262
// Existing column does not have a forward index. New column config enables the forward index
263-
LOGGER.debug("Existing column: {} does not have a forward index but new column config enables it", column);
263+
264264
ColumnMetadata columnMetadata = _segmentDirectory.getSegmentMetadata().getColumnMetadataFor(column);
265265
if (columnMetadata != null && columnMetadata.isSorted()) {
266266
// Check if the column is sorted. If sorted, disabling forward index should be a no-op and forward index
@@ -286,7 +286,7 @@ Map<String, List<Operation>> computeOperations(SegmentDirectory.Reader segmentRe
286286
} else if (existingForwardIndexDisabledColumns.contains(column) && !newIsFwd) {
287287
// Forward index is disabled for the existing column and should remain disabled based on the latest config
288288
// Need some checks to see whether the dictionary is being enabled or disabled here and take appropriate actions
289-
LOGGER.debug("Existing column: {} does not have a forward index and new column config keeps so", column);
289+
290290
// If the dictionary is not enabled on the existing column it must be on the new noDictionary column list.
291291
// Cannot enable the dictionary for a column with forward index disabled.
292292
Preconditions.checkState(existingDictColumns.contains(column) || !newIsDict,
@@ -304,7 +304,6 @@ Map<String, List<Operation>> computeOperations(SegmentDirectory.Reader segmentRe
304304
}
305305
} else if (existingNoDictColumns.contains(column) && newIsDict) {
306306
// Existing column is RAW. New column is dictionary enabled.
307-
LOGGER.debug("Existing column: {} has RAW forward index but new column config requires dict-encoded", column);
308307
if (_schema == null || _tableConfig == null) {
309308
// This can only happen in tests.
310309
LOGGER.warn("Cannot enable dictionary for column={} as schema or tableConfig is null.", column);
@@ -314,19 +313,17 @@ Map<String, List<Operation>> computeOperations(SegmentDirectory.Reader segmentRe
314313
columnOperationsMap.put(column, Collections.singletonList(Operation.ENABLE_DICTIONARY));
315314
} else if (existingDictColumns.contains(column) && !newIsDict) {
316315
// Existing column has dictionary. New config for the column is RAW.
317-
LOGGER.debug("Existing column: {} has dict-encoded forward index but new column config requires RAW", column);
318316
if (shouldDisableDictionary(column, _segmentDirectory.getSegmentMetadata().getColumnMetadataFor(column))) {
319317
columnOperationsMap.put(column, Collections.singletonList(Operation.DISABLE_DICTIONARY));
320318
}
321319
} else if (existingNoDictColumns.contains(column) && !newIsDict) {
322320
// Both existing and new column is RAW forward index encoded. Check if compression needs to be changed.
323-
LOGGER.debug("Existing column: {} has RAW forward index and new column config keeps so", column);
324321
if (shouldChangeCompressionType(column, segmentReader)) {
325322
columnOperationsMap.put(column, Collections.singletonList(Operation.CHANGE_RAW_INDEX_COMPRESSION_TYPE));
326323
}
327324
}
328325
}
329-
LOGGER.debug("Got column operations: {}", columnOperationsMap);
326+
330327
return columnOperationsMap;
331328
}
332329

0 commit comments

Comments
 (0)