You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by sa...@apache.org on 2023/07/04 12:07:40 UTC

[pinot] branch master updated: Startree index build enhancement (#10905)

This is an automated email from the ASF dual-hosted git repository.

saurabhd336 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new f7a076496a Startree index build enhancement (#10905)
f7a076496a is described below

commit f7a076496ae6e07a42207cb2c978dc74562cf0cf
Author: Shounak kulkarni <sh...@gmail.com>
AuthorDate: Tue Jul 4 17:37:34 2023 +0530

    Startree index build enhancement (#10905)
    
    * StarTreeIndexSeparator to split the startrees and reuse them
    
    * Test suite for the StarTreeIndexSeparator
    
    * cleanup the temp dir
    
    * Add license header
    
    * fixed metadata.properties
    
    * license header fix
    
    * handle temp directory cleanup in case of exception
    
    * rename shouldRemoveExistingStarTrees to shouldModifyExistingStarTrees
    
    * pass index dir for deletion instead of segment dir
    
    * Fix conditions so that star-trees are simply deleted if newer config doesn't have star-trees
    
    * rename _indexDirectory to _indexDir
    
    * return null for getExistingStarTrees when no existing tree is present
    
    * minor fixes
    
    * Moved validations to handleExistingStarTreeAddition
    
    handleExistingStarTreeAddition now returns a boolean based on whether the existing star-tree was reused or not.
    
    * checkstyle fix
    
    * change logic to only separate star-trees as required
    
    * style fix
    
    * bug fix
    
    * minor fixes
    
    * handle startree cleanup locally to avoid copying index files
    
    * bug fix
    
    * revert the separator creation
---
 .../segment/index/loader/SegmentPreProcessor.java  |    9 +-
 .../local/startree/StarTreeBuilderUtils.java       |    4 +-
 .../startree/v2/builder/MultipleTreesBuilder.java  |   82 +-
 .../v2/builder/StarTreeIndexSeparator.java         |  154 +++
 .../v2/builder/StarTreeIndexSeparatorTest.java     |  100 ++
 .../test/resources/data/startree/segment/index_map |  363 ++++++
 .../data/startree/segment/metadata.properties      | 1307 ++++++++++++++++++++
 .../data/startree/segment/star_tree_index          |  Bin 0 -> 37111 bytes
 .../data/startree/segment/star_tree_index_map      |   31 +
 .../spi/index/startree/StarTreeV2Constants.java    |    1 +
 10 files changed, 2041 insertions(+), 10 deletions(-)

diff --git a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/SegmentPreProcessor.java b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/SegmentPreProcessor.java
index ba26a41b3a..4913088fc5 100644
--- a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/SegmentPreProcessor.java
+++ b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/SegmentPreProcessor.java
@@ -226,7 +226,7 @@ public class SegmentPreProcessor implements AutoCloseable {
 
     // We need reprocessing if existing configs are to be removed, or new configs have been added
     if (starTreeMetadataList != null) {
-      return StarTreeBuilderUtils.shouldRemoveExistingStarTrees(starTreeBuilderConfigs, starTreeMetadataList);
+      return StarTreeBuilderUtils.shouldModifyExistingStarTrees(starTreeBuilderConfigs, starTreeMetadataList);
     }
     return !starTreeBuilderConfigs.isEmpty();
   }
@@ -242,11 +242,14 @@ public class SegmentPreProcessor implements AutoCloseable {
       List<StarTreeV2Metadata> starTreeMetadataList = _segmentMetadata.getStarTreeV2MetadataList();
       if (starTreeMetadataList != null) {
         // There are existing star-trees
-        if (StarTreeBuilderUtils.shouldRemoveExistingStarTrees(starTreeBuilderConfigs, starTreeMetadataList)) {
-          // Remove the existing star-trees
+        if (!shouldGenerateStarTree) {
+          // Newer config does not have star-trees. Delete all existing star-trees.
           LOGGER.info("Removing star-trees from segment: {}", _segmentMetadata.getName());
           StarTreeBuilderUtils.removeStarTrees(indexDir);
           _segmentMetadata = new SegmentMetadataImpl(indexDir);
+        } else if (StarTreeBuilderUtils.shouldModifyExistingStarTrees(starTreeBuilderConfigs, starTreeMetadataList)) {
+          // Existing and newer both have star-trees, but they don't match. Rebuild the star-trees.
+          LOGGER.info("Change detected in star-trees for segment: {}", _segmentMetadata.getName());
         } else {
           // Existing star-trees match the builder configs, no need to generate the star-trees
           shouldGenerateStarTree = false;
diff --git a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/StarTreeBuilderUtils.java b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/StarTreeBuilderUtils.java
index 3c681c9c5b..f9c66d79ab 100644
--- a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/StarTreeBuilderUtils.java
+++ b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/StarTreeBuilderUtils.java
@@ -226,9 +226,9 @@ public class StarTreeBuilderUtils {
 
   /**
    * Returns {@code true} if the given star-tree builder configs do not match the star-tree metadata, in which case the
-   * existing star-trees need to be removed, {@code false} otherwise.
+   * relevant star-trees need to be added/removed, {@code false} otherwise.
    */
-  public static boolean shouldRemoveExistingStarTrees(List<StarTreeV2BuilderConfig> builderConfigs,
+  public static boolean shouldModifyExistingStarTrees(List<StarTreeV2BuilderConfig> builderConfigs,
       List<StarTreeV2Metadata> metadataList) {
     int numStarTrees = builderConfigs.size();
     if (metadataList.size() != numStarTrees) {
diff --git a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/MultipleTreesBuilder.java b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/MultipleTreesBuilder.java
index ec40df5f97..231825c264 100644
--- a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/MultipleTreesBuilder.java
+++ b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/MultipleTreesBuilder.java
@@ -22,6 +22,7 @@ import com.google.common.base.Preconditions;
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import javax.annotation.Nullable;
@@ -63,6 +64,8 @@ public class MultipleTreesBuilder implements Closeable {
   private final File _segmentDirectory;
   private final PropertiesConfiguration _metadataProperties;
   private final ImmutableSegment _segment;
+  private StarTreeIndexSeparator _separator;
+  private File _separatorTempDir;
 
   public enum BuildMode {
     ON_HEAP, OFF_HEAP
@@ -83,7 +86,7 @@ public class MultipleTreesBuilder implements Closeable {
     _segmentDirectory = SegmentDirectoryPaths.findSegmentDirectory(indexDir);
     _metadataProperties =
         CommonsConfigurationUtils.fromFile(new File(_segmentDirectory, V1Constants.MetadataKeys.METADATA_FILE_NAME));
-    Preconditions.checkState(!_metadataProperties.containsKey(MetadataKey.STAR_TREE_COUNT), "Star-tree already exists");
+    _separator = getSeparator();
     _segment = ImmutableSegmentLoader.load(indexDir, ReadMode.mmap);
   }
 
@@ -115,6 +118,36 @@ public class MultipleTreesBuilder implements Closeable {
     }
   }
 
+  @Nullable
+  private StarTreeIndexSeparator getSeparator()
+      throws Exception {
+    if (!_metadataProperties.containsKey(MetadataKey.STAR_TREE_COUNT)) {
+      return null;
+    }
+    try {
+      _separatorTempDir = new File(_segmentDirectory, StarTreeV2Constants.EXISTING_STAR_TREE_TEMP_DIR);
+      FileUtils.forceMkdir(_separatorTempDir);
+      FileUtils.moveFileToDirectory(
+          new File(_segmentDirectory, StarTreeV2Constants.INDEX_FILE_NAME), _separatorTempDir, false);
+      FileUtils.moveFileToDirectory(
+          new File(_segmentDirectory, StarTreeV2Constants.INDEX_MAP_FILE_NAME), _separatorTempDir, false);
+      StarTreeIndexSeparator separator = new StarTreeIndexSeparator(
+              new File(_separatorTempDir, StarTreeV2Constants.INDEX_MAP_FILE_NAME),
+              new File(_separatorTempDir, StarTreeV2Constants.INDEX_FILE_NAME), _metadataProperties);
+      _metadataProperties.subset(StarTreeV2Constants.MetadataKey.STAR_TREE_SUBSET).clear();
+      SegmentMetadataUtils.savePropertiesConfiguration(_metadataProperties);
+      return separator;
+    } catch (Exception e) {
+      try {
+        FileUtils.forceDelete(_separatorTempDir);
+      } catch (Exception e1) {
+        LOGGER.warn("Caught exception while deleting the separator tmp directory: {}",
+                _separatorTempDir.getAbsolutePath());
+      }
+      throw e;
+    }
+  }
+
   /**
    * Builds the star-trees.
    */
@@ -122,6 +155,7 @@ public class MultipleTreesBuilder implements Closeable {
       throws Exception {
     long startTime = System.currentTimeMillis();
     int numStarTrees = _builderConfigs.size();
+    int reusedStarTrees = 0;
     LOGGER.info("Starting building {} star-trees with configs: {} using {} builder", numStarTrees, _builderConfigs,
         _buildMode);
 
@@ -136,9 +170,15 @@ public class MultipleTreesBuilder implements Closeable {
       for (int i = 0; i < numStarTrees; i++) {
         StarTreeV2BuilderConfig builderConfig = _builderConfigs.get(i);
         Configuration metadataProperties = _metadataProperties.subset(MetadataKey.getStarTreePrefix(i));
-        try (SingleTreeBuilder singleTreeBuilder = getSingleTreeBuilder(builderConfig, starTreeIndexDir, _segment,
-            metadataProperties, _buildMode)) {
-          singleTreeBuilder.build();
+        if (_separator != null && handleExistingStarTreeAddition(starTreeIndexDir, metadataProperties, builderConfig)) {
+          // Used existing tree
+          LOGGER.info("Reused existing star-tree: {}", builderConfig.toString());
+          reusedStarTrees++;
+        } else {
+          try (SingleTreeBuilder singleTreeBuilder = getSingleTreeBuilder(builderConfig, starTreeIndexDir, _segment,
+              metadataProperties, _buildMode)) {
+            singleTreeBuilder.build();
+          }
         }
         indexMaps.add(indexCombiner.combine(builderConfig, starTreeIndexDir));
       }
@@ -150,7 +190,31 @@ public class MultipleTreesBuilder implements Closeable {
       FileUtils.forceDelete(starTreeIndexDir);
     }
 
-    LOGGER.info("Finished building {} star-trees in {}ms", numStarTrees, System.currentTimeMillis() - startTime);
+    LOGGER.info("Finished building {} star-trees ({} reused) in {}ms", numStarTrees, reusedStarTrees,
+        System.currentTimeMillis() - startTime);
+  }
+
+  /**
+   * Helper utility to move the individual star-tree files to the {@param starTreeIndexDir} from where it will be picked
+   * by the combiner to merge them into the single star-tree index file. The method also takes care of updating the
+   * {@param metadataProperties} for the star-tree.
+   * Returns {@code false} if the star-tree is not present in the existing star-trees, otherwise returns {@code true}
+   * upon successful transfer completion
+   */
+  private boolean handleExistingStarTreeAddition(File starTreeIndexDir, Configuration metadataProperties,
+      StarTreeV2BuilderConfig builderConfig)
+      throws IOException {
+    int totalDocs = _separator.separate(starTreeIndexDir, builderConfig);
+    if (totalDocs == -1) {
+      return false;
+    }
+    metadataProperties.setProperty(MetadataKey.TOTAL_DOCS, totalDocs);
+    metadataProperties.setProperty(MetadataKey.DIMENSIONS_SPLIT_ORDER, builderConfig.getDimensionsSplitOrder());
+    metadataProperties.setProperty(MetadataKey.FUNCTION_COLUMN_PAIRS, builderConfig.getFunctionColumnPairs());
+    metadataProperties.setProperty(MetadataKey.MAX_LEAF_RECORDS, builderConfig.getMaxLeafRecords());
+    metadataProperties.setProperty(MetadataKey.SKIP_STAR_NODE_CREATION_FOR_DIMENSIONS,
+        builderConfig.getSkipStarNodeCreationForDimensions());
+    return true;
   }
 
   private static SingleTreeBuilder getSingleTreeBuilder(StarTreeV2BuilderConfig builderConfig, File outputDir,
@@ -165,6 +229,14 @@ public class MultipleTreesBuilder implements Closeable {
 
   @Override
   public void close() {
+    if (_separatorTempDir != null) {
+      try {
+        FileUtils.forceDelete(_separatorTempDir);
+      } catch (Exception e) {
+        LOGGER.warn("Caught exception while deleting the separator tmp directory: {}",
+                _separatorTempDir.getAbsolutePath());
+      }
+    }
     _segment.destroy();
   }
 }
diff --git a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/StarTreeIndexSeparator.java b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/StarTreeIndexSeparator.java
new file mode 100644
index 0000000000..dc475b93fd
--- /dev/null
+++ b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/startree/v2/builder/StarTreeIndexSeparator.java
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.pinot.segment.local.startree.v2.builder;
+
+import com.google.common.collect.Lists;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.io.FileUtils;
+import org.apache.pinot.segment.local.startree.v2.store.StarTreeIndexMapUtils;
+import org.apache.pinot.segment.spi.V1Constants;
+import org.apache.pinot.segment.spi.index.startree.AggregationFunctionColumnPair;
+import org.apache.pinot.segment.spi.index.startree.StarTreeV2Constants;
+import org.apache.pinot.spi.config.table.StarTreeIndexConfig;
+
+
+/**
+ * The {@code StarTreeIndexSeparator} pulls out the individual star-trees from the common star-tree index file
+ */
+public class StarTreeIndexSeparator implements Closeable {
+
+  private final FileChannel _indexFileChannel;
+  private final List<Map<StarTreeIndexMapUtils.IndexKey, StarTreeIndexMapUtils.IndexValue>> _indexMapList;
+  private final List<StarTreeV2BuilderConfig> _builderConfigList;
+  private final List<Integer> _totalDocsList;
+
+  public StarTreeIndexSeparator(File indexMapFile, File indexFile, PropertiesConfiguration metadataProperties)
+      throws IOException {
+    _indexMapList = extractIndexMap(indexMapFile,
+        metadataProperties.getInt(StarTreeV2Constants.MetadataKey.STAR_TREE_COUNT));
+    _indexFileChannel = new RandomAccessFile(indexFile, "r").getChannel();
+    _builderConfigList = extractBuilderConfigs(metadataProperties);
+    _totalDocsList = extractTotalDocsList(metadataProperties);
+  }
+
+  private List<Map<StarTreeIndexMapUtils.IndexKey, StarTreeIndexMapUtils.IndexValue>> extractIndexMap(File indexMapFile,
+      int numStarTrees) {
+    try (InputStream inputStream = new FileInputStream(indexMapFile)) {
+      return StarTreeIndexMapUtils.loadFromInputStream(inputStream, numStarTrees);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public List<Integer> extractTotalDocsList(PropertiesConfiguration metadataProperties) {
+    List<Integer> totalDocsList = new ArrayList<>(_indexMapList.size());
+    for (int i = 0; i < _indexMapList.size(); i++) {
+      Configuration metadata = metadataProperties.subset(StarTreeV2Constants.MetadataKey.getStarTreePrefix(i));
+      totalDocsList.add(i, metadata.getInt(StarTreeV2Constants.MetadataKey.TOTAL_DOCS));
+    }
+    return totalDocsList;
+  }
+
+  /**
+   * Extract the list of {@link StarTreeV2BuilderConfig} for each of the star-tree present in the given metadata
+   * properties.
+   * @param metadataProperties index metadata properties
+   * @return List of {@link StarTreeV2BuilderConfig}
+   */
+  public List<StarTreeV2BuilderConfig> extractBuilderConfigs(PropertiesConfiguration metadataProperties) {
+    List<StarTreeV2BuilderConfig> builderConfigList = new ArrayList<>(_indexMapList.size());
+    for (int i = 0; i < _indexMapList.size(); i++) {
+      Configuration metadata = metadataProperties.subset(StarTreeV2Constants.MetadataKey.getStarTreePrefix(i));
+      builderConfigList.add(i, StarTreeV2BuilderConfig.fromIndexConfig(new StarTreeIndexConfig(
+          Lists.newArrayList(metadata.getStringArray(StarTreeV2Constants.MetadataKey.DIMENSIONS_SPLIT_ORDER)),
+          Lists.newArrayList(
+              metadata.getStringArray(StarTreeV2Constants.MetadataKey.SKIP_STAR_NODE_CREATION_FOR_DIMENSIONS)),
+          Lists.newArrayList(metadata.getStringArray(StarTreeV2Constants.MetadataKey.FUNCTION_COLUMN_PAIRS)),
+          metadata.getInt(StarTreeV2Constants.MetadataKey.MAX_LEAF_RECORDS))));
+    }
+    return builderConfigList;
+  }
+
+  /**
+   * Extract star-tree index files of the star-tree represented by the builderConfig.
+   * The extracted star-tree index files are written to the provided starTreeOutputDir.
+   *
+   * @param starTreeOutputDir output directory for extracted star-trees
+   * @param builderConfig {@link StarTreeV2BuilderConfig} of the star-tree to separate
+   * @return if star-tree exist then total docs in the separated tree, else -1
+   * @throws IOException
+   */
+  public int separate(File starTreeOutputDir, StarTreeV2BuilderConfig builderConfig)
+      throws IOException {
+    int treeIndex = _builderConfigList.indexOf(builderConfig);
+    if (treeIndex == -1) {
+      return -1;
+    }
+    separate(starTreeOutputDir, treeIndex);
+    return _totalDocsList.get(treeIndex);
+  }
+
+  private void separate(File starTreeOutputDir, int treeIndex)
+      throws IOException {
+    Map<StarTreeIndexMapUtils.IndexKey, StarTreeIndexMapUtils.IndexValue> indexMap = _indexMapList.get(treeIndex);
+    FileUtils.forceMkdir(starTreeOutputDir);
+    for (StarTreeIndexMapUtils.IndexKey key : indexMap.keySet()) {
+      File destIndexFile;
+      switch (key._indexType) {
+        case STAR_TREE:
+          destIndexFile = new File(starTreeOutputDir, StarTreeV2Constants.STAR_TREE_INDEX_FILE_NAME);
+          writeIndexToFile(destIndexFile, indexMap.get(key));
+          break;
+        case FORWARD_INDEX:
+          String suffix = key._column.contains(AggregationFunctionColumnPair.DELIMITER)
+              ? V1Constants.Indexes.RAW_SV_FORWARD_INDEX_FILE_EXTENSION
+              : V1Constants.Indexes.UNSORTED_SV_FORWARD_INDEX_FILE_EXTENSION;
+          destIndexFile = new File(starTreeOutputDir, key._column + suffix);
+          writeIndexToFile(destIndexFile, indexMap.get(key));
+          break;
+        default:
+      }
+    }
+  }
+
+  private void writeIndexToFile(File destFile, StarTreeIndexMapUtils.IndexValue value)
+      throws IOException {
+    try (FileChannel dest = new RandomAccessFile(destFile, "rw").getChannel()) {
+      org.apache.pinot.common.utils.FileUtils.transferBytes(_indexFileChannel, value._offset, value._size, dest);
+    }
+  }
+
+  @Override
+  public void close()
+      throws IOException {
+    _indexFileChannel.close();
+  }
+}
diff --git a/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/startree/v2/builder/StarTreeIndexSeparatorTest.java b/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/startree/v2/builder/StarTreeIndexSeparatorTest.java
new file mode 100644
index 0000000000..bc1be710e6
--- /dev/null
+++ b/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/startree/v2/builder/StarTreeIndexSeparatorTest.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.segment.local.startree.v2.builder;
+
+import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.io.FileUtils;
+import org.apache.pinot.segment.spi.V1Constants;
+import org.apache.pinot.segment.spi.index.startree.StarTreeV2Constants;
+import org.apache.pinot.spi.config.table.StarTreeIndexConfig;
+import org.apache.pinot.spi.env.CommonsConfigurationUtils;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.apache.pinot.segment.spi.V1Constants.Indexes.RAW_SV_FORWARD_INDEX_FILE_EXTENSION;
+import static org.apache.pinot.segment.spi.V1Constants.Indexes.UNSORTED_SV_FORWARD_INDEX_FILE_EXTENSION;
+import static org.apache.pinot.segment.spi.index.startree.StarTreeV2Constants.STAR_TREE_INDEX_FILE_NAME;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+
+public class StarTreeIndexSeparatorTest {
+
+  private static final String SEGMENT_PATH = "data/startree/segment";
+  private static final String TOTAL_DOCS_KEY = "startree.v2.0.total.docs";
+
+  private StarTreeIndexSeparator _separator;
+  private PropertiesConfiguration _metadataProperties;
+  private final StarTreeV2BuilderConfig _builderConfig = StarTreeV2BuilderConfig.fromIndexConfig(
+      new StarTreeIndexConfig(
+          Lists.newArrayList("AirlineID", "Origin", "Dest"),
+          Lists.newArrayList(),
+          Lists.newArrayList("count__*", "max__ArrDelay"),
+          10));
+
+  @BeforeClass
+  public void setup()
+      throws IOException {
+    ClassLoader classLoader = getClass().getClassLoader();
+    URL segmentUrl = classLoader.getResource(SEGMENT_PATH);
+    File segmentDir = new File(segmentUrl.getFile());
+    _metadataProperties = CommonsConfigurationUtils.fromFile(
+        new File(segmentDir, V1Constants.MetadataKeys.METADATA_FILE_NAME));
+    _separator = new StarTreeIndexSeparator(
+        new File(segmentDir, StarTreeV2Constants.INDEX_MAP_FILE_NAME),
+        new File(segmentDir, StarTreeV2Constants.INDEX_FILE_NAME),
+        _metadataProperties);
+  }
+
+  @Test
+  public void extractTotalDocsListTest() {
+    assertNotNull(_separator);
+    List<Integer> docsList = _separator.extractTotalDocsList(_metadataProperties);
+    assertNotNull(docsList);
+    assertEquals(docsList, Lists.newArrayList(_metadataProperties.getInt(TOTAL_DOCS_KEY)));
+  }
+
+  @Test
+  public void extractBuilderConfigsTest() {
+    List<StarTreeV2BuilderConfig> builderConfigList = _separator.extractBuilderConfigs(_metadataProperties);
+    assertEquals(builderConfigList, Lists.newArrayList(_builderConfig));
+  }
+
+  @Test
+  public void separateTest()
+      throws IOException {
+    File tempDir = new File(FileUtils.getTempDirectory(), "separateTest");
+    _separator.separate(tempDir, _builderConfig);
+    List<String> files = Arrays.asList(Objects.requireNonNull(tempDir.list()));
+    assertTrue(files.contains(STAR_TREE_INDEX_FILE_NAME));
+    _builderConfig.getDimensionsSplitOrder()
+        .forEach(dimension -> assertTrue(files.contains(dimension + UNSORTED_SV_FORWARD_INDEX_FILE_EXTENSION)));
+    _builderConfig.getFunctionColumnPairs()
+        .forEach(dimension -> assertTrue(files.contains(dimension + RAW_SV_FORWARD_INDEX_FILE_EXTENSION)));
+    FileUtils.forceDelete(tempDir);
+  }
+}
diff --git a/pinot-segment-local/src/test/resources/data/startree/segment/index_map b/pinot-segment-local/src/test/resources/data/startree/segment/index_map
new file mode 100644
index 0000000000..616b3f7a11
--- /dev/null
+++ b/pinot-segment-local/src/test/resources/data/startree/segment/index_map
@@ -0,0 +1,363 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+$ts$DAY.dictionary.startOffset = 0
+$ts$DAY.dictionary.size = 16
+$ts$DAY.forward_index.startOffset = 16
+$ts$DAY.forward_index.size = 16
+$ts$DAY.range_index.startOffset = 32
+$ts$DAY.range_index.size = 38
+$ts$MONTH.dictionary.startOffset = 70
+$ts$MONTH.dictionary.size = 16
+$ts$MONTH.forward_index.startOffset = 86
+$ts$MONTH.forward_index.size = 16
+$ts$MONTH.range_index.startOffset = 102
+$ts$MONTH.range_index.size = 38
+$ts$WEEK.dictionary.startOffset = 140
+$ts$WEEK.dictionary.size = 16
+$ts$WEEK.forward_index.startOffset = 156
+$ts$WEEK.forward_index.size = 16
+$ts$WEEK.range_index.startOffset = 172
+$ts$WEEK.range_index.size = 38
+ActualElapsedTime.dictionary.startOffset = 210
+ActualElapsedTime.dictionary.size = 620
+ActualElapsedTime.forward_index.startOffset = 830
+ActualElapsedTime.forward_index.size = 321
+AirTime.dictionary.startOffset = 1151
+AirTime.dictionary.size = 612
+AirTime.forward_index.startOffset = 1763
+AirTime.forward_index.size = 321
+AirlineID.dictionary.startOffset = 2084
+AirlineID.dictionary.size = 64
+AirlineID.forward_index.startOffset = 2148
+AirlineID.forward_index.size = 165
+ArrDel15.dictionary.startOffset = 2313
+ArrDel15.dictionary.size = 20
+ArrDel15.forward_index.startOffset = 2333
+ArrDel15.forward_index.size = 87
+ArrDelay.dictionary.startOffset = 2420
+ArrDelay.dictionary.size = 320
+ArrDelay.forward_index.startOffset = 2740
+ArrDelay.forward_index.size = 282
+ArrDelayMinutes.dictionary.startOffset = 3022
+ArrDelayMinutes.dictionary.size = 172
+ArrDelayMinutes.forward_index.startOffset = 3194
+ArrDelayMinutes.forward_index.size = 243
+ArrTime.dictionary.startOffset = 3437
+ArrTime.dictionary.size = 1056
+ArrTime.forward_index.startOffset = 4493
+ArrTime.forward_index.size = 361
+ArrTimeBlk.dictionary.startOffset = 4854
+ArrTimeBlk.dictionary.size = 179
+ArrTimeBlk.forward_index.startOffset = 5033
+ArrTimeBlk.forward_index.size = 204
+ArrTimeBlk.inverted_index.startOffset = 5237
+ArrTimeBlk.inverted_index.size = 1018
+ArrivalDelayGroups.dictionary.startOffset = 6255
+ArrivalDelayGroups.dictionary.size = 56
+ArrivalDelayGroups.forward_index.startOffset = 6311
+ArrivalDelayGroups.forward_index.size = 165
+CRSArrTime.dictionary.startOffset = 6476
+CRSArrTime.dictionary.size = 972
+CRSArrTime.forward_index.startOffset = 7448
+CRSArrTime.forward_index.size = 321
+CRSDepTime.dictionary.startOffset = 7769
+CRSDepTime.dictionary.size = 832
+CRSDepTime.forward_index.startOffset = 8601
+CRSDepTime.forward_index.size = 321
+CRSElapsedTime.dictionary.startOffset = 8922
+CRSElapsedTime.dictionary.size = 624
+CRSElapsedTime.forward_index.startOffset = 9546
+CRSElapsedTime.forward_index.size = 321
+CancellationCode.dictionary.startOffset = 9867
+CancellationCode.dictionary.size = 24
+CancellationCode.forward_index.startOffset = 9891
+CancellationCode.forward_index.size = 87
+Cancelled.dictionary.startOffset = 9978
+Cancelled.dictionary.size = 16
+Cancelled.forward_index.startOffset = 9994
+Cancelled.forward_index.size = 48
+Carrier.dictionary.startOffset = 10042
+Carrier.dictionary.size = 36
+Carrier.forward_index.startOffset = 10078
+Carrier.forward_index.size = 165
+CarrierDelay.dictionary.startOffset = 10243
+CarrierDelay.dictionary.size = 84
+CarrierDelay.forward_index.startOffset = 10327
+CarrierDelay.forward_index.size = 204
+DayOfWeek.dictionary.startOffset = 10531
+DayOfWeek.dictionary.size = 12
+DayOfWeek.forward_index.startOffset = 10543
+DayOfWeek.forward_index.size = 16
+DayofMonth.dictionary.startOffset = 10559
+DayofMonth.dictionary.size = 12
+DayofMonth.forward_index.startOffset = 10571
+DayofMonth.forward_index.size = 16
+DaysSinceEpoch.dictionary.startOffset = 10587
+DaysSinceEpoch.dictionary.size = 12
+DaysSinceEpoch.forward_index.startOffset = 10599
+DaysSinceEpoch.forward_index.size = 16
+DepDel15.dictionary.startOffset = 10615
+DepDel15.dictionary.size = 20
+DepDel15.forward_index.startOffset = 10635
+DepDel15.forward_index.size = 87
+DepDelay.dictionary.startOffset = 10722
+DepDelay.dictionary.size = 292
+DepDelay.forward_index.startOffset = 11014
+DepDelay.forward_index.size = 282
+DepDelayMinutes.dictionary.startOffset = 11296
+DepDelayMinutes.dictionary.size = 224
+DepDelayMinutes.forward_index.startOffset = 11520
+DepDelayMinutes.forward_index.size = 243
+DepTime.dictionary.startOffset = 11763
+DepTime.dictionary.size = 1068
+DepTime.forward_index.startOffset = 12831
+DepTime.forward_index.size = 361
+DepTimeBlk.dictionary.startOffset = 13192
+DepTimeBlk.dictionary.size = 170
+DepTimeBlk.forward_index.startOffset = 13362
+DepTimeBlk.forward_index.size = 204
+DepartureDelayGroups.dictionary.startOffset = 13566
+DepartureDelayGroups.dictionary.size = 64
+DepartureDelayGroups.forward_index.startOffset = 13630
+DepartureDelayGroups.forward_index.size = 165
+Dest.dictionary.startOffset = 13795
+Dest.dictionary.size = 320
+Dest.forward_index.startOffset = 14115
+Dest.forward_index.size = 282
+DestAirportID.dictionary.startOffset = 14397
+DestAirportID.dictionary.size = 424
+DestAirportID.forward_index.startOffset = 14821
+DestAirportID.forward_index.size = 282
+DestAirportSeqID.dictionary.startOffset = 15103
+DestAirportSeqID.dictionary.size = 424
+DestAirportSeqID.forward_index.startOffset = 15527
+DestAirportSeqID.forward_index.size = 282
+DestCityMarketID.dictionary.startOffset = 15809
+DestCityMarketID.dictionary.size = 360
+DestCityMarketID.forward_index.startOffset = 16169
+DestCityMarketID.forward_index.size = 282
+DestCityName.dictionary.startOffset = 16451
+DestCityName.dictionary.size = 3008
+DestCityName.forward_index.startOffset = 19459
+DestCityName.forward_index.size = 282
+DestState.dictionary.startOffset = 19741
+DestState.dictionary.size = 92
+DestState.forward_index.startOffset = 19833
+DestState.forward_index.size = 243
+DestStateFips.dictionary.startOffset = 20076
+DestStateFips.dictionary.size = 176
+DestStateFips.forward_index.startOffset = 20252
+DestStateFips.forward_index.size = 243
+DestStateName.dictionary.startOffset = 20495
+DestStateName.dictionary.size = 1940
+DestStateName.forward_index.startOffset = 22435
+DestStateName.forward_index.size = 243
+DestWac.dictionary.startOffset = 22678
+DestWac.dictionary.size = 176
+DestWac.forward_index.startOffset = 22854
+DestWac.forward_index.size = 243
+Distance.dictionary.startOffset = 23097
+Distance.dictionary.size = 1008
+Distance.forward_index.startOffset = 24105
+Distance.forward_index.size = 321
+DistanceGroup.dictionary.startOffset = 24426
+DistanceGroup.dictionary.size = 52
+DistanceGroup.forward_index.startOffset = 24478
+DistanceGroup.forward_index.size = 165
+DivActualElapsedTime.dictionary.startOffset = 24643
+DivActualElapsedTime.dictionary.size = 152
+DivActualElapsedTime.forward_index.startOffset = 24795
+DivActualElapsedTime.forward_index.size = 243
+DivAirportIDs.dictionary.startOffset = 25038
+DivAirportIDs.dictionary.size = 140
+DivAirportIDs.forward_index.startOffset = 25178
+DivAirportIDs.forward_index.size = 287
+DivAirportLandings.dictionary.startOffset = 25465
+DivAirportLandings.dictionary.size = 20
+DivAirportLandings.forward_index.startOffset = 25485
+DivAirportLandings.forward_index.size = 87
+DivAirportSeqIDs.dictionary.startOffset = 25572
+DivAirportSeqIDs.dictionary.size = 140
+DivAirportSeqIDs.forward_index.startOffset = 25712
+DivAirportSeqIDs.forward_index.size = 287
+DivAirports.dictionary.startOffset = 25999
+DivAirports.dictionary.size = 140
+DivAirports.forward_index.startOffset = 26139
+DivAirports.forward_index.size = 287
+DivArrDelay.dictionary.startOffset = 26426
+DivArrDelay.dictionary.size = 132
+DivArrDelay.forward_index.startOffset = 26558
+DivArrDelay.forward_index.size = 204
+DivDistance.dictionary.startOffset = 26762
+DivDistance.dictionary.size = 44
+DivDistance.forward_index.startOffset = 26806
+DivDistance.forward_index.size = 165
+DivLongestGTimes.dictionary.startOffset = 26971
+DivLongestGTimes.dictionary.size = 120
+DivLongestGTimes.forward_index.startOffset = 27091
+DivLongestGTimes.forward_index.size = 248
+DivReachedDest.dictionary.startOffset = 27339
+DivReachedDest.dictionary.size = 20
+DivReachedDest.forward_index.startOffset = 27359
+DivReachedDest.forward_index.size = 87
+DivTailNums.dictionary.startOffset = 27446
+DivTailNums.dictionary.size = 230
+DivTailNums.forward_index.startOffset = 27676
+DivTailNums.forward_index.size = 287
+DivTotalGTimes.dictionary.startOffset = 27963
+DivTotalGTimes.dictionary.size = 140
+DivTotalGTimes.forward_index.startOffset = 28103
+DivTotalGTimes.forward_index.size = 287
+DivWheelsOffs.dictionary.startOffset = 28390
+DivWheelsOffs.dictionary.size = 148
+DivWheelsOffs.forward_index.startOffset = 28538
+DivWheelsOffs.forward_index.size = 287
+DivWheelsOns.dictionary.startOffset = 28825
+DivWheelsOns.dictionary.size = 208
+DivWheelsOns.forward_index.startOffset = 29033
+DivWheelsOns.forward_index.size = 287
+Diverted.dictionary.startOffset = 29320
+Diverted.dictionary.size = 16
+Diverted.forward_index.startOffset = 29336
+Diverted.forward_index.size = 48
+FirstDepTime.dictionary.startOffset = 29384
+FirstDepTime.dictionary.size = 20
+FirstDepTime.forward_index.startOffset = 29404
+FirstDepTime.forward_index.size = 87
+FlightDate.dictionary.startOffset = 29491
+FlightDate.dictionary.size = 18
+FlightDate.forward_index.startOffset = 29509
+FlightDate.forward_index.size = 16
+FlightNum.dictionary.startOffset = 29525
+FlightNum.dictionary.size = 1224
+FlightNum.forward_index.startOffset = 30749
+FlightNum.forward_index.size = 361
+Flights.dictionary.startOffset = 31110
+Flights.dictionary.size = 12
+Flights.forward_index.startOffset = 31122
+Flights.forward_index.size = 16
+LateAircraftDelay.dictionary.startOffset = 31138
+LateAircraftDelay.dictionary.size = 76
+LateAircraftDelay.forward_index.startOffset = 31214
+LateAircraftDelay.forward_index.size = 204
+LongestAddGTime.dictionary.startOffset = 31418
+LongestAddGTime.dictionary.size = 20
+LongestAddGTime.forward_index.startOffset = 31438
+LongestAddGTime.forward_index.size = 87
+Month.dictionary.startOffset = 31525
+Month.dictionary.size = 12
+Month.forward_index.startOffset = 31537
+Month.forward_index.size = 16
+NASDelay.dictionary.startOffset = 31553
+NASDelay.dictionary.size = 84
+NASDelay.forward_index.startOffset = 31637
+NASDelay.forward_index.size = 204
+Origin.dictionary.startOffset = 31841
+Origin.dictionary.size = 299
+Origin.forward_index.startOffset = 32140
+Origin.forward_index.size = 282
+OriginAirportID.dictionary.startOffset = 32422
+OriginAirportID.dictionary.size = 396
+OriginAirportID.forward_index.startOffset = 32818
+OriginAirportID.forward_index.size = 282
+OriginAirportSeqID.dictionary.startOffset = 33100
+OriginAirportSeqID.dictionary.size = 396
+OriginAirportSeqID.forward_index.startOffset = 33496
+OriginAirportSeqID.forward_index.size = 282
+OriginCityMarketID.dictionary.startOffset = 33778
+OriginCityMarketID.dictionary.size = 336
+OriginCityMarketID.forward_index.startOffset = 34114
+OriginCityMarketID.forward_index.size = 282
+OriginCityName.dictionary.startOffset = 34396
+OriginCityName.dictionary.size = 2798
+OriginCityName.forward_index.startOffset = 37194
+OriginCityName.forward_index.size = 282
+OriginState.dictionary.startOffset = 37476
+OriginState.dictionary.size = 94
+OriginState.forward_index.startOffset = 37570
+OriginState.forward_index.size = 243
+OriginStateFips.dictionary.startOffset = 37813
+OriginStateFips.dictionary.size = 180
+OriginStateFips.forward_index.startOffset = 37993
+OriginStateFips.forward_index.size = 243
+OriginStateName.dictionary.startOffset = 38236
+OriginStateName.dictionary.size = 610
+OriginStateName.forward_index.startOffset = 38846
+OriginStateName.forward_index.size = 243
+OriginWac.dictionary.startOffset = 39089
+OriginWac.dictionary.size = 180
+OriginWac.forward_index.startOffset = 39269
+OriginWac.forward_index.size = 243
+Quarter.dictionary.startOffset = 39512
+Quarter.dictionary.size = 12
+Quarter.forward_index.startOffset = 39524
+Quarter.forward_index.size = 16
+RandomAirports.dictionary.startOffset = 39540
+RandomAirports.dictionary.size = 320
+RandomAirports.forward_index.startOffset = 39860
+RandomAirports.forward_index.size = 4436
+SecurityDelay.dictionary.startOffset = 44296
+SecurityDelay.dictionary.size = 16
+SecurityDelay.forward_index.startOffset = 44312
+SecurityDelay.forward_index.size = 48
+TailNum.dictionary.startOffset = 44360
+TailNum.dictionary.size = 1826
+TailNum.forward_index.startOffset = 46186
+TailNum.forward_index.size = 361
+TaxiIn.dictionary.startOffset = 46547
+TaxiIn.dictionary.size = 92
+TaxiIn.forward_index.startOffset = 46639
+TaxiIn.forward_index.size = 204
+TaxiOut.dictionary.startOffset = 46843
+TaxiOut.dictionary.size = 148
+TaxiOut.forward_index.startOffset = 46991
+TaxiOut.forward_index.size = 243
+TotalAddGTime.dictionary.startOffset = 47234
+TotalAddGTime.dictionary.size = 20
+TotalAddGTime.forward_index.startOffset = 47254
+TotalAddGTime.forward_index.size = 87
+UniqueCarrier.dictionary.startOffset = 47341
+UniqueCarrier.dictionary.size = 36
+UniqueCarrier.forward_index.startOffset = 47377
+UniqueCarrier.forward_index.size = 165
+WeatherDelay.dictionary.startOffset = 47542
+WeatherDelay.dictionary.size = 16
+WeatherDelay.forward_index.startOffset = 47558
+WeatherDelay.forward_index.size = 48
+WheelsOff.dictionary.startOffset = 47606
+WheelsOff.dictionary.size = 1084
+WheelsOff.forward_index.startOffset = 48690
+WheelsOff.forward_index.size = 361
+WheelsOn.dictionary.startOffset = 49051
+WheelsOn.dictionary.size = 1044
+WheelsOn.forward_index.startOffset = 50095
+WheelsOn.forward_index.size = 361
+Year.dictionary.startOffset = 50456
+Year.dictionary.size = 12
+Year.forward_index.startOffset = 50468
+Year.forward_index.size = 16
+ts.dictionary.startOffset = 50484
+ts.dictionary.size = 16
+ts.forward_index.startOffset = 50500
+ts.forward_index.size = 16
+tsRaw.dictionary.startOffset = 50516
+tsRaw.dictionary.size = 16
+tsRaw.forward_index.startOffset = 50532
+tsRaw.forward_index.size = 16
diff --git a/pinot-segment-local/src/test/resources/data/startree/segment/metadata.properties b/pinot-segment-local/src/test/resources/data/startree/segment/metadata.properties
new file mode 100644
index 0000000000..96112e136c
--- /dev/null
+++ b/pinot-segment-local/src/test/resources/data/startree/segment/metadata.properties
@@ -0,0 +1,1307 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+segment.padding.character = \u0000
+segment.name = airlineStats_OFFLINE_16085_16085_0
+segment.table.name = airlineStats
+segment.datetime.column.names = $ts$DAY,$ts$MONTH,$ts$WEEK,DaysSinceEpoch,ts,tsRaw
+segment.time.column.name = DaysSinceEpoch
+segment.total.docs = 313
+segment.start.time = 16085
+segment.end.time = 16085
+segment.time.unit = DAYS
+column.$ts$DAY.cardinality = 1
+column.$ts$DAY.totalDocs = 313
+column.$ts$DAY.dataType = TIMESTAMP
+column.$ts$DAY.bitsPerElement = 1
+column.$ts$DAY.lengthOfEachEntry = 0
+column.$ts$DAY.columnType = DATE_TIME
+column.$ts$DAY.isSorted = true
+column.$ts$DAY.hasDictionary = true
+column.$ts$DAY.isSingleValues = true
+column.$ts$DAY.maxNumberOfMultiValues = 0
+column.$ts$DAY.totalNumberOfEntries = 313
+column.$ts$DAY.isAutoGenerated = false
+column.$ts$DAY.datetimeFormat = TIMESTAMP
+column.$ts$DAY.datetimeGranularity = 1:DAYS
+column.$ts$DAY.minValue = 1389744000000
+column.$ts$DAY.maxValue = 1389744000000
+column.$ts$DAY.defaultNullValue = 0
+column.$ts$MONTH.cardinality = 1
+column.$ts$MONTH.totalDocs = 313
+column.$ts$MONTH.dataType = TIMESTAMP
+column.$ts$MONTH.bitsPerElement = 1
+column.$ts$MONTH.lengthOfEachEntry = 0
+column.$ts$MONTH.columnType = DATE_TIME
+column.$ts$MONTH.isSorted = true
+column.$ts$MONTH.hasDictionary = true
+column.$ts$MONTH.isSingleValues = true
+column.$ts$MONTH.maxNumberOfMultiValues = 0
+column.$ts$MONTH.totalNumberOfEntries = 313
+column.$ts$MONTH.isAutoGenerated = false
+column.$ts$MONTH.datetimeFormat = TIMESTAMP
+column.$ts$MONTH.datetimeGranularity = 30:DAYS
+column.$ts$MONTH.minValue = 1388534400000
+column.$ts$MONTH.maxValue = 1388534400000
+column.$ts$MONTH.defaultNullValue = 0
+column.$ts$WEEK.cardinality = 1
+column.$ts$WEEK.totalDocs = 313
+column.$ts$WEEK.dataType = TIMESTAMP
+column.$ts$WEEK.bitsPerElement = 1
+column.$ts$WEEK.lengthOfEachEntry = 0
+column.$ts$WEEK.columnType = DATE_TIME
+column.$ts$WEEK.isSorted = true
+column.$ts$WEEK.hasDictionary = true
+column.$ts$WEEK.isSingleValues = true
+column.$ts$WEEK.maxNumberOfMultiValues = 0
+column.$ts$WEEK.totalNumberOfEntries = 313
+column.$ts$WEEK.isAutoGenerated = false
+column.$ts$WEEK.datetimeFormat = TIMESTAMP
+column.$ts$WEEK.datetimeGranularity = 7:DAYS
+column.$ts$WEEK.minValue = 1389571200000
+column.$ts$WEEK.maxValue = 1389571200000
+column.$ts$WEEK.defaultNullValue = 0
+column.ActualElapsedTime.cardinality = 153
+column.ActualElapsedTime.totalDocs = 313
+column.ActualElapsedTime.dataType = INT
+column.ActualElapsedTime.bitsPerElement = 8
+column.ActualElapsedTime.lengthOfEachEntry = 0
+column.ActualElapsedTime.columnType = DIMENSION
+column.ActualElapsedTime.isSorted = false
+column.ActualElapsedTime.hasDictionary = true
+column.ActualElapsedTime.isSingleValues = true
+column.ActualElapsedTime.maxNumberOfMultiValues = 0
+column.ActualElapsedTime.totalNumberOfEntries = 313
+column.ActualElapsedTime.isAutoGenerated = false
+column.ActualElapsedTime.minValue = -2147483648
+column.ActualElapsedTime.maxValue = 461
+column.ActualElapsedTime.defaultNullValue = -2147483648
+column.AirTime.cardinality = 151
+column.AirTime.totalDocs = 313
+column.AirTime.dataType = INT
+column.AirTime.bitsPerElement = 8
+column.AirTime.lengthOfEachEntry = 0
+column.AirTime.columnType = DIMENSION
+column.AirTime.isSorted = false
+column.AirTime.hasDictionary = true
+column.AirTime.isSingleValues = true
+column.AirTime.maxNumberOfMultiValues = 0
+column.AirTime.totalNumberOfEntries = 313
+column.AirTime.isAutoGenerated = false
+column.AirTime.minValue = -2147483648
+column.AirTime.maxValue = 437
+column.AirTime.defaultNullValue = -2147483648
+column.AirlineID.cardinality = 14
+column.AirlineID.totalDocs = 313
+column.AirlineID.dataType = INT
+column.AirlineID.bitsPerElement = 4
+column.AirlineID.lengthOfEachEntry = 0
+column.AirlineID.columnType = DIMENSION
+column.AirlineID.isSorted = false
+column.AirlineID.hasDictionary = true
+column.AirlineID.isSingleValues = true
+column.AirlineID.maxNumberOfMultiValues = 0
+column.AirlineID.totalNumberOfEntries = 313
+column.AirlineID.isAutoGenerated = false
+column.AirlineID.minValue = 19393
+column.AirlineID.maxValue = 21171
+column.AirlineID.defaultNullValue = -2147483648
+column.ArrDel15.cardinality = 3
+column.ArrDel15.totalDocs = 313
+column.ArrDel15.dataType = INT
+column.ArrDel15.bitsPerElement = 2
+column.ArrDel15.lengthOfEachEntry = 0
+column.ArrDel15.columnType = DIMENSION
+column.ArrDel15.isSorted = false
+column.ArrDel15.hasDictionary = true
+column.ArrDel15.isSingleValues = true
+column.ArrDel15.maxNumberOfMultiValues = 0
+column.ArrDel15.totalNumberOfEntries = 313
+column.ArrDel15.isAutoGenerated = false
+column.ArrDel15.minValue = -2147483648
+column.ArrDel15.maxValue = 1
+column.ArrDel15.defaultNullValue = -2147483648
+column.ArrDelay.cardinality = 78
+column.ArrDelay.totalDocs = 313
+column.ArrDelay.dataType = INT
+column.ArrDelay.bitsPerElement = 7
+column.ArrDelay.lengthOfEachEntry = 0
+column.ArrDelay.columnType = DIMENSION
+column.ArrDelay.isSorted = false
+column.ArrDelay.hasDictionary = true
+column.ArrDelay.isSingleValues = true
+column.ArrDelay.maxNumberOfMultiValues = 0
+column.ArrDelay.totalNumberOfEntries = 313
+column.ArrDelay.isAutoGenerated = false
+column.ArrDelay.minValue = -2147483648
+column.ArrDelay.maxValue = 343
+column.ArrDelay.defaultNullValue = -2147483648
+column.ArrDelayMinutes.cardinality = 41
+column.ArrDelayMinutes.totalDocs = 313
+column.ArrDelayMinutes.dataType = INT
+column.ArrDelayMinutes.bitsPerElement = 6
+column.ArrDelayMinutes.lengthOfEachEntry = 0
+column.ArrDelayMinutes.columnType = DIMENSION
+column.ArrDelayMinutes.isSorted = false
+column.ArrDelayMinutes.hasDictionary = true
+column.ArrDelayMinutes.isSingleValues = true
+column.ArrDelayMinutes.maxNumberOfMultiValues = 0
+column.ArrDelayMinutes.totalNumberOfEntries = 313
+column.ArrDelayMinutes.isAutoGenerated = false
+column.ArrDelayMinutes.minValue = -2147483648
+column.ArrDelayMinutes.maxValue = 343
+column.ArrDelayMinutes.defaultNullValue = -2147483648
+column.ArrTime.cardinality = 262
+column.ArrTime.totalDocs = 313
+column.ArrTime.dataType = INT
+column.ArrTime.bitsPerElement = 9
+column.ArrTime.lengthOfEachEntry = 0
+column.ArrTime.columnType = DIMENSION
+column.ArrTime.isSorted = false
+column.ArrTime.hasDictionary = true
+column.ArrTime.isSingleValues = true
+column.ArrTime.maxNumberOfMultiValues = 0
+column.ArrTime.totalNumberOfEntries = 313
+column.ArrTime.isAutoGenerated = false
+column.ArrTime.minValue = -2147483648
+column.ArrTime.maxValue = 2348
+column.ArrTime.defaultNullValue = -2147483648
+column.ArrTimeBlk.cardinality = 19
+column.ArrTimeBlk.totalDocs = 313
+column.ArrTimeBlk.dataType = STRING
+column.ArrTimeBlk.bitsPerElement = 5
+column.ArrTimeBlk.lengthOfEachEntry = 9
+column.ArrTimeBlk.columnType = DIMENSION
+column.ArrTimeBlk.isSorted = false
+column.ArrTimeBlk.hasDictionary = true
+column.ArrTimeBlk.isSingleValues = true
+column.ArrTimeBlk.maxNumberOfMultiValues = 0
+column.ArrTimeBlk.totalNumberOfEntries = 313
+column.ArrTimeBlk.isAutoGenerated = false
+column.ArrTimeBlk.minValue = 0001-0559
+column.ArrTimeBlk.maxValue = 2300-2359
+column.ArrTimeBlk.defaultNullValue = null
+column.ArrivalDelayGroups.cardinality = 12
+column.ArrivalDelayGroups.totalDocs = 313
+column.ArrivalDelayGroups.dataType = INT
+column.ArrivalDelayGroups.bitsPerElement = 4
+column.ArrivalDelayGroups.lengthOfEachEntry = 0
+column.ArrivalDelayGroups.columnType = DIMENSION
+column.ArrivalDelayGroups.isSorted = false
+column.ArrivalDelayGroups.hasDictionary = true
+column.ArrivalDelayGroups.isSingleValues = true
+column.ArrivalDelayGroups.maxNumberOfMultiValues = 0
+column.ArrivalDelayGroups.totalNumberOfEntries = 313
+column.ArrivalDelayGroups.isAutoGenerated = false
+column.ArrivalDelayGroups.minValue = -2147483648
+column.ArrivalDelayGroups.maxValue = 12
+column.ArrivalDelayGroups.defaultNullValue = -2147483648
+column.CRSArrTime.cardinality = 241
+column.CRSArrTime.totalDocs = 313
+column.CRSArrTime.dataType = INT
+column.CRSArrTime.bitsPerElement = 8
+column.CRSArrTime.lengthOfEachEntry = 0
+column.CRSArrTime.columnType = DIMENSION
+column.CRSArrTime.isSorted = false
+column.CRSArrTime.hasDictionary = true
+column.CRSArrTime.isSingleValues = true
+column.CRSArrTime.maxNumberOfMultiValues = 0
+column.CRSArrTime.totalNumberOfEntries = 313
+column.CRSArrTime.isAutoGenerated = false
+column.CRSArrTime.minValue = 10
+column.CRSArrTime.maxValue = 2359
+column.CRSArrTime.defaultNullValue = -2147483648
+column.CRSDepTime.cardinality = 206
+column.CRSDepTime.totalDocs = 313
+column.CRSDepTime.dataType = INT
+column.CRSDepTime.bitsPerElement = 8
+column.CRSDepTime.lengthOfEachEntry = 0
+column.CRSDepTime.columnType = DIMENSION
+column.CRSDepTime.isSorted = false
+column.CRSDepTime.hasDictionary = true
+column.CRSDepTime.isSingleValues = true
+column.CRSDepTime.maxNumberOfMultiValues = 0
+column.CRSDepTime.totalNumberOfEntries = 313
+column.CRSDepTime.isAutoGenerated = false
+column.CRSDepTime.minValue = 510
+column.CRSDepTime.maxValue = 2209
+column.CRSDepTime.defaultNullValue = -2147483648
+column.CRSElapsedTime.cardinality = 154
+column.CRSElapsedTime.totalDocs = 313
+column.CRSElapsedTime.dataType = INT
+column.CRSElapsedTime.bitsPerElement = 8
+column.CRSElapsedTime.lengthOfEachEntry = 0
+column.CRSElapsedTime.columnType = DIMENSION
+column.CRSElapsedTime.isSorted = false
+column.CRSElapsedTime.hasDictionary = true
+column.CRSElapsedTime.isSingleValues = true
+column.CRSElapsedTime.maxNumberOfMultiValues = 0
+column.CRSElapsedTime.totalNumberOfEntries = 313
+column.CRSElapsedTime.isAutoGenerated = false
+column.CRSElapsedTime.minValue = 33
+column.CRSElapsedTime.maxValue = 470
+column.CRSElapsedTime.defaultNullValue = -2147483648
+column.CancellationCode.cardinality = 4
+column.CancellationCode.totalDocs = 313
+column.CancellationCode.dataType = STRING
+column.CancellationCode.bitsPerElement = 2
+column.CancellationCode.lengthOfEachEntry = 4
+column.CancellationCode.columnType = DIMENSION
+column.CancellationCode.isSorted = false
+column.CancellationCode.hasDictionary = true
+column.CancellationCode.isSingleValues = true
+column.CancellationCode.maxNumberOfMultiValues = 0
+column.CancellationCode.totalNumberOfEntries = 313
+column.CancellationCode.isAutoGenerated = false
+column.CancellationCode.minValue = A
+column.CancellationCode.maxValue = null
+column.CancellationCode.defaultNullValue = null
+column.Cancelled.cardinality = 2
+column.Cancelled.totalDocs = 313
+column.Cancelled.dataType = INT
+column.Cancelled.bitsPerElement = 1
+column.Cancelled.lengthOfEachEntry = 0
+column.Cancelled.columnType = DIMENSION
+column.Cancelled.isSorted = false
+column.Cancelled.hasDictionary = true
+column.Cancelled.isSingleValues = true
+column.Cancelled.maxNumberOfMultiValues = 0
+column.Cancelled.totalNumberOfEntries = 313
+column.Cancelled.isAutoGenerated = false
+column.Cancelled.minValue = 0
+column.Cancelled.maxValue = 1
+column.Cancelled.defaultNullValue = -2147483648
+column.Carrier.cardinality = 14
+column.Carrier.totalDocs = 313
+column.Carrier.dataType = STRING
+column.Carrier.bitsPerElement = 4
+column.Carrier.lengthOfEachEntry = 2
+column.Carrier.columnType = DIMENSION
+column.Carrier.isSorted = false
+column.Carrier.hasDictionary = true
+column.Carrier.isSingleValues = true
+column.Carrier.maxNumberOfMultiValues = 0
+column.Carrier.totalNumberOfEntries = 313
+column.Carrier.isAutoGenerated = false
+column.Carrier.minValue = AA
+column.Carrier.maxValue = WN
+column.Carrier.defaultNullValue = null
+column.CarrierDelay.cardinality = 19
+column.CarrierDelay.totalDocs = 313
+column.CarrierDelay.dataType = INT
+column.CarrierDelay.bitsPerElement = 5
+column.CarrierDelay.lengthOfEachEntry = 0
+column.CarrierDelay.columnType = DIMENSION
+column.CarrierDelay.isSorted = false
+column.CarrierDelay.hasDictionary = true
+column.CarrierDelay.isSingleValues = true
+column.CarrierDelay.maxNumberOfMultiValues = 0
+column.CarrierDelay.totalNumberOfEntries = 313
+column.CarrierDelay.isAutoGenerated = false
+column.CarrierDelay.minValue = -2147483648
+column.CarrierDelay.maxValue = 343
+column.CarrierDelay.defaultNullValue = -2147483648
+column.DayOfWeek.cardinality = 1
+column.DayOfWeek.totalDocs = 313
+column.DayOfWeek.dataType = INT
+column.DayOfWeek.bitsPerElement = 1
+column.DayOfWeek.lengthOfEachEntry = 0
+column.DayOfWeek.columnType = DIMENSION
+column.DayOfWeek.isSorted = true
+column.DayOfWeek.hasDictionary = true
+column.DayOfWeek.isSingleValues = true
+column.DayOfWeek.maxNumberOfMultiValues = 0
+column.DayOfWeek.totalNumberOfEntries = 313
+column.DayOfWeek.isAutoGenerated = false
+column.DayOfWeek.minValue = 3
+column.DayOfWeek.maxValue = 3
+column.DayOfWeek.defaultNullValue = -2147483648
+column.DayofMonth.cardinality = 1
+column.DayofMonth.totalDocs = 313
+column.DayofMonth.dataType = INT
+column.DayofMonth.bitsPerElement = 1
+column.DayofMonth.lengthOfEachEntry = 0
+column.DayofMonth.columnType = DIMENSION
+column.DayofMonth.isSorted = true
+column.DayofMonth.hasDictionary = true
+column.DayofMonth.isSingleValues = true
+column.DayofMonth.maxNumberOfMultiValues = 0
+column.DayofMonth.totalNumberOfEntries = 313
+column.DayofMonth.isAutoGenerated = false
+column.DayofMonth.minValue = 15
+column.DayofMonth.maxValue = 15
+column.DayofMonth.defaultNullValue = -2147483648
+column.DaysSinceEpoch.cardinality = 1
+column.DaysSinceEpoch.totalDocs = 313
+column.DaysSinceEpoch.dataType = INT
+column.DaysSinceEpoch.bitsPerElement = 1
+column.DaysSinceEpoch.lengthOfEachEntry = 0
+column.DaysSinceEpoch.columnType = DATE_TIME
+column.DaysSinceEpoch.isSorted = true
+column.DaysSinceEpoch.hasDictionary = true
+column.DaysSinceEpoch.isSingleValues = true
+column.DaysSinceEpoch.maxNumberOfMultiValues = 0
+column.DaysSinceEpoch.totalNumberOfEntries = 313
+column.DaysSinceEpoch.isAutoGenerated = false
+column.DaysSinceEpoch.datetimeFormat = 1:DAYS:EPOCH
+column.DaysSinceEpoch.datetimeGranularity = 1:DAYS
+column.DaysSinceEpoch.minValue = 16085
+column.DaysSinceEpoch.maxValue = 16085
+column.DaysSinceEpoch.defaultNullValue = -2147483648
+column.DepDel15.cardinality = 3
+column.DepDel15.totalDocs = 313
+column.DepDel15.dataType = INT
+column.DepDel15.bitsPerElement = 2
+column.DepDel15.lengthOfEachEntry = 0
+column.DepDel15.columnType = DIMENSION
+column.DepDel15.isSorted = false
+column.DepDel15.hasDictionary = true
+column.DepDel15.isSingleValues = true
+column.DepDel15.maxNumberOfMultiValues = 0
+column.DepDel15.totalNumberOfEntries = 313
+column.DepDel15.isAutoGenerated = false
+column.DepDel15.minValue = -2147483648
+column.DepDel15.maxValue = 1
+column.DepDel15.defaultNullValue = -2147483648
+column.DepDelay.cardinality = 71
+column.DepDelay.totalDocs = 313
+column.DepDelay.dataType = INT
+column.DepDelay.bitsPerElement = 7
+column.DepDelay.lengthOfEachEntry = 0
+column.DepDelay.columnType = DIMENSION
+column.DepDelay.isSorted = false
+column.DepDelay.hasDictionary = true
+column.DepDelay.isSingleValues = true
+column.DepDelay.maxNumberOfMultiValues = 0
+column.DepDelay.totalNumberOfEntries = 313
+column.DepDelay.isAutoGenerated = false
+column.DepDelay.minValue = -2147483648
+column.DepDelay.maxValue = 356
+column.DepDelay.defaultNullValue = -2147483648
+column.DepDelayMinutes.cardinality = 54
+column.DepDelayMinutes.totalDocs = 313
+column.DepDelayMinutes.dataType = INT
+column.DepDelayMinutes.bitsPerElement = 6
+column.DepDelayMinutes.lengthOfEachEntry = 0
+column.DepDelayMinutes.columnType = DIMENSION
+column.DepDelayMinutes.isSorted = false
+column.DepDelayMinutes.hasDictionary = true
+column.DepDelayMinutes.isSingleValues = true
+column.DepDelayMinutes.maxNumberOfMultiValues = 0
+column.DepDelayMinutes.totalNumberOfEntries = 313
+column.DepDelayMinutes.isAutoGenerated = false
+column.DepDelayMinutes.minValue = -2147483648
+column.DepDelayMinutes.maxValue = 356
+column.DepDelayMinutes.defaultNullValue = -2147483648
+column.DepTime.cardinality = 265
+column.DepTime.totalDocs = 313
+column.DepTime.dataType = INT
+column.DepTime.bitsPerElement = 9
+column.DepTime.lengthOfEachEntry = 0
+column.DepTime.columnType = DIMENSION
+column.DepTime.isSorted = false
+column.DepTime.hasDictionary = true
+column.DepTime.isSingleValues = true
+column.DepTime.maxNumberOfMultiValues = 0
+column.DepTime.totalNumberOfEntries = 313
+column.DepTime.isAutoGenerated = false
+column.DepTime.minValue = -2147483648
+column.DepTime.maxValue = 2216
+column.DepTime.defaultNullValue = -2147483648
+column.DepTimeBlk.cardinality = 18
+column.DepTimeBlk.totalDocs = 313
+column.DepTimeBlk.dataType = STRING
+column.DepTimeBlk.bitsPerElement = 5
+column.DepTimeBlk.lengthOfEachEntry = 9
+column.DepTimeBlk.columnType = DIMENSION
+column.DepTimeBlk.isSorted = false
+column.DepTimeBlk.hasDictionary = true
+column.DepTimeBlk.isSingleValues = true
+column.DepTimeBlk.maxNumberOfMultiValues = 0
+column.DepTimeBlk.totalNumberOfEntries = 313
+column.DepTimeBlk.isAutoGenerated = false
+column.DepTimeBlk.minValue = 0001-0559
+column.DepTimeBlk.maxValue = 2200-2259
+column.DepTimeBlk.defaultNullValue = null
+column.DepartureDelayGroups.cardinality = 14
+column.DepartureDelayGroups.totalDocs = 313
+column.DepartureDelayGroups.dataType = INT
+column.DepartureDelayGroups.bitsPerElement = 4
+column.DepartureDelayGroups.lengthOfEachEntry = 0
+column.DepartureDelayGroups.columnType = DIMENSION
+column.DepartureDelayGroups.isSorted = false
+column.DepartureDelayGroups.hasDictionary = true
+column.DepartureDelayGroups.isSingleValues = true
+column.DepartureDelayGroups.maxNumberOfMultiValues = 0
+column.DepartureDelayGroups.totalNumberOfEntries = 313
+column.DepartureDelayGroups.isAutoGenerated = false
+column.DepartureDelayGroups.minValue = -2147483648
+column.DepartureDelayGroups.maxValue = 12
+column.DepartureDelayGroups.defaultNullValue = -2147483648
+column.Dest.cardinality = 104
+column.Dest.totalDocs = 313
+column.Dest.dataType = STRING
+column.Dest.bitsPerElement = 7
+column.Dest.lengthOfEachEntry = 3
+column.Dest.columnType = DIMENSION
+column.Dest.isSorted = false
+column.Dest.hasDictionary = true
+column.Dest.isSingleValues = true
+column.Dest.maxNumberOfMultiValues = 0
+column.Dest.totalNumberOfEntries = 313
+column.Dest.isAutoGenerated = false
+column.Dest.minValue = ABE
+column.Dest.maxValue = VPS
+column.Dest.defaultNullValue = null
+column.DestAirportID.cardinality = 104
+column.DestAirportID.totalDocs = 313
+column.DestAirportID.dataType = INT
+column.DestAirportID.bitsPerElement = 7
+column.DestAirportID.lengthOfEachEntry = 0
+column.DestAirportID.columnType = DIMENSION
+column.DestAirportID.isSorted = false
+column.DestAirportID.hasDictionary = true
+column.DestAirportID.isSingleValues = true
+column.DestAirportID.maxNumberOfMultiValues = 0
+column.DestAirportID.totalNumberOfEntries = 313
+column.DestAirportID.isAutoGenerated = false
+column.DestAirportID.minValue = 10135
+column.DestAirportID.maxValue = 15624
+column.DestAirportID.defaultNullValue = -2147483648
+column.DestAirportSeqID.cardinality = 104
+column.DestAirportSeqID.totalDocs = 313
+column.DestAirportSeqID.dataType = INT
+column.DestAirportSeqID.bitsPerElement = 7
+column.DestAirportSeqID.lengthOfEachEntry = 0
+column.DestAirportSeqID.columnType = DIMENSION
+column.DestAirportSeqID.isSorted = false
+column.DestAirportSeqID.hasDictionary = true
+column.DestAirportSeqID.isSingleValues = true
+column.DestAirportSeqID.maxNumberOfMultiValues = 0
+column.DestAirportSeqID.totalNumberOfEntries = 313
+column.DestAirportSeqID.isAutoGenerated = false
+column.DestAirportSeqID.minValue = 1013503
+column.DestAirportSeqID.maxValue = 1562401
+column.DestAirportSeqID.defaultNullValue = -2147483648
+column.DestCityMarketID.cardinality = 88
+column.DestCityMarketID.totalDocs = 313
+column.DestCityMarketID.dataType = INT
+column.DestCityMarketID.bitsPerElement = 7
+column.DestCityMarketID.lengthOfEachEntry = 0
+column.DestCityMarketID.columnType = DIMENSION
+column.DestCityMarketID.isSorted = false
+column.DestCityMarketID.hasDictionary = true
+column.DestCityMarketID.isSingleValues = true
+column.DestCityMarketID.maxNumberOfMultiValues = 0
+column.DestCityMarketID.totalNumberOfEntries = 313
+column.DestCityMarketID.isAutoGenerated = false
+column.DestCityMarketID.minValue = 30135
+column.DestCityMarketID.maxValue = 35412
+column.DestCityMarketID.defaultNullValue = -2147483648
+column.DestCityName.cardinality = 100
+column.DestCityName.totalDocs = 313
+column.DestCityName.dataType = STRING
+column.DestCityName.bitsPerElement = 7
+column.DestCityName.lengthOfEachEntry = 30
+column.DestCityName.columnType = DIMENSION
+column.DestCityName.isSorted = false
+column.DestCityName.hasDictionary = true
+column.DestCityName.isSingleValues = true
+column.DestCityName.maxNumberOfMultiValues = 0
+column.DestCityName.totalNumberOfEntries = 313
+column.DestCityName.isAutoGenerated = false
+column.DestCityName.minMaxValueInvalid = true
+column.DestCityName.defaultNullValue = null
+column.DestState.cardinality = 42
+column.DestState.totalDocs = 313
+column.DestState.dataType = STRING
+column.DestState.bitsPerElement = 6
+column.DestState.lengthOfEachEntry = 2
+column.DestState.columnType = DIMENSION
+column.DestState.isSorted = false
+column.DestState.hasDictionary = true
+column.DestState.isSingleValues = true
+column.DestState.maxNumberOfMultiValues = 0
+column.DestState.totalNumberOfEntries = 313
+column.DestState.isAutoGenerated = false
+column.DestState.minValue = AK
+column.DestState.maxValue = WI
+column.DestState.defaultNullValue = null
+column.DestStateFips.cardinality = 42
+column.DestStateFips.totalDocs = 313
+column.DestStateFips.dataType = INT
+column.DestStateFips.bitsPerElement = 6
+column.DestStateFips.lengthOfEachEntry = 0
+column.DestStateFips.columnType = DIMENSION
+column.DestStateFips.isSorted = false
+column.DestStateFips.hasDictionary = true
+column.DestStateFips.isSingleValues = true
+column.DestStateFips.maxNumberOfMultiValues = 0
+column.DestStateFips.totalNumberOfEntries = 313
+column.DestStateFips.isAutoGenerated = false
+column.DestStateFips.minValue = 1
+column.DestStateFips.maxValue = 75
+column.DestStateFips.defaultNullValue = -2147483648
+column.DestStateName.cardinality = 42
+column.DestStateName.totalDocs = 313
+column.DestStateName.dataType = STRING
+column.DestStateName.bitsPerElement = 6
+column.DestStateName.lengthOfEachEntry = 46
+column.DestStateName.columnType = DIMENSION
+column.DestStateName.isSorted = false
+column.DestStateName.hasDictionary = true
+column.DestStateName.isSingleValues = true
+column.DestStateName.maxNumberOfMultiValues = 0
+column.DestStateName.totalNumberOfEntries = 313
+column.DestStateName.isAutoGenerated = false
+column.DestStateName.minValue = Alabama
+column.DestStateName.maxValue = Wisconsin
+column.DestStateName.defaultNullValue = null
+column.DestWac.cardinality = 42
+column.DestWac.totalDocs = 313
+column.DestWac.dataType = INT
+column.DestWac.bitsPerElement = 6
+column.DestWac.lengthOfEachEntry = 0
+column.DestWac.columnType = DIMENSION
+column.DestWac.isSorted = false
+column.DestWac.hasDictionary = true
+column.DestWac.isSingleValues = true
+column.DestWac.maxNumberOfMultiValues = 0
+column.DestWac.totalNumberOfEntries = 313
+column.DestWac.isAutoGenerated = false
+column.DestWac.minValue = 1
+column.DestWac.maxValue = 93
+column.DestWac.defaultNullValue = -2147483648
+column.Distance.cardinality = 250
+column.Distance.totalDocs = 313
+column.Distance.dataType = INT
+column.Distance.bitsPerElement = 8
+column.Distance.lengthOfEachEntry = 0
+column.Distance.columnType = DIMENSION
+column.Distance.isSorted = false
+column.Distance.hasDictionary = true
+column.Distance.isSingleValues = true
+column.Distance.maxNumberOfMultiValues = 0
+column.Distance.totalNumberOfEntries = 313
+column.Distance.isAutoGenerated = false
+column.Distance.minValue = 67
+column.Distance.maxValue = 3801
+column.Distance.defaultNullValue = -2147483648
+column.DistanceGroup.cardinality = 11
+column.DistanceGroup.totalDocs = 313
+column.DistanceGroup.dataType = INT
+column.DistanceGroup.bitsPerElement = 4
+column.DistanceGroup.lengthOfEachEntry = 0
+column.DistanceGroup.columnType = DIMENSION
+column.DistanceGroup.isSorted = false
+column.DistanceGroup.hasDictionary = true
+column.DistanceGroup.isSingleValues = true
+column.DistanceGroup.maxNumberOfMultiValues = 0
+column.DistanceGroup.totalNumberOfEntries = 313
+column.DistanceGroup.isAutoGenerated = false
+column.DistanceGroup.minValue = 1
+column.DistanceGroup.maxValue = 11
+column.DistanceGroup.defaultNullValue = -2147483648
+column.DivActualElapsedTime.cardinality = 36
+column.DivActualElapsedTime.totalDocs = 313
+column.DivActualElapsedTime.dataType = INT
+column.DivActualElapsedTime.bitsPerElement = 6
+column.DivActualElapsedTime.lengthOfEachEntry = 0
+column.DivActualElapsedTime.columnType = DIMENSION
+column.DivActualElapsedTime.isSorted = false
+column.DivActualElapsedTime.hasDictionary = true
+column.DivActualElapsedTime.isSingleValues = true
+column.DivActualElapsedTime.maxNumberOfMultiValues = 0
+column.DivActualElapsedTime.totalNumberOfEntries = 313
+column.DivActualElapsedTime.isAutoGenerated = false
+column.DivActualElapsedTime.minValue = -2147483648
+column.DivActualElapsedTime.maxValue = 1099
+column.DivActualElapsedTime.defaultNullValue = -2147483648
+column.DivAirportIDs.cardinality = 33
+column.DivAirportIDs.totalDocs = 313
+column.DivAirportIDs.dataType = INT
+column.DivAirportIDs.bitsPerElement = 6
+column.DivAirportIDs.lengthOfEachEntry = 0
+column.DivAirportIDs.columnType = DIMENSION
+column.DivAirportIDs.isSorted = false
+column.DivAirportIDs.hasDictionary = true
+column.DivAirportIDs.isSingleValues = false
+column.DivAirportIDs.maxNumberOfMultiValues = 1
+column.DivAirportIDs.totalNumberOfEntries = 313
+column.DivAirportIDs.isAutoGenerated = false
+column.DivAirportIDs.minValue = -2147483648
+column.DivAirportIDs.maxValue = 15096
+column.DivAirportIDs.defaultNullValue = -2147483648
+column.DivAirportLandings.cardinality = 3
+column.DivAirportLandings.totalDocs = 313
+column.DivAirportLandings.dataType = INT
+column.DivAirportLandings.bitsPerElement = 2
+column.DivAirportLandings.lengthOfEachEntry = 0
+column.DivAirportLandings.columnType = DIMENSION
+column.DivAirportLandings.isSorted = false
+column.DivAirportLandings.hasDictionary = true
+column.DivAirportLandings.isSingleValues = true
+column.DivAirportLandings.maxNumberOfMultiValues = 0
+column.DivAirportLandings.totalNumberOfEntries = 313
+column.DivAirportLandings.isAutoGenerated = false
+column.DivAirportLandings.minValue = 0
+column.DivAirportLandings.maxValue = 9
+column.DivAirportLandings.defaultNullValue = -2147483648
+column.DivAirportSeqIDs.cardinality = 33
+column.DivAirportSeqIDs.totalDocs = 313
+column.DivAirportSeqIDs.dataType = INT
+column.DivAirportSeqIDs.bitsPerElement = 6
+column.DivAirportSeqIDs.lengthOfEachEntry = 0
+column.DivAirportSeqIDs.columnType = DIMENSION
+column.DivAirportSeqIDs.isSorted = false
+column.DivAirportSeqIDs.hasDictionary = true
+column.DivAirportSeqIDs.isSingleValues = false
+column.DivAirportSeqIDs.maxNumberOfMultiValues = 1
+column.DivAirportSeqIDs.totalNumberOfEntries = 313
+column.DivAirportSeqIDs.isAutoGenerated = false
+column.DivAirportSeqIDs.minValue = -2147483648
+column.DivAirportSeqIDs.maxValue = 1509602
+column.DivAirportSeqIDs.defaultNullValue = -2147483648
+column.DivAirports.cardinality = 33
+column.DivAirports.totalDocs = 313
+column.DivAirports.dataType = STRING
+column.DivAirports.bitsPerElement = 6
+column.DivAirports.lengthOfEachEntry = 4
+column.DivAirports.columnType = DIMENSION
+column.DivAirports.isSorted = false
+column.DivAirports.hasDictionary = true
+column.DivAirports.isSingleValues = false
+column.DivAirports.maxNumberOfMultiValues = 1
+column.DivAirports.totalNumberOfEntries = 313
+column.DivAirports.isAutoGenerated = false
+column.DivAirports.minValue = ALB
+column.DivAirports.maxValue = null
+column.DivAirports.defaultNullValue = null
+column.DivArrDelay.cardinality = 31
+column.DivArrDelay.totalDocs = 313
+column.DivArrDelay.dataType = INT
+column.DivArrDelay.bitsPerElement = 5
+column.DivArrDelay.lengthOfEachEntry = 0
+column.DivArrDelay.columnType = DIMENSION
+column.DivArrDelay.isSorted = false
+column.DivArrDelay.hasDictionary = true
+column.DivArrDelay.isSingleValues = true
+column.DivArrDelay.maxNumberOfMultiValues = 0
+column.DivArrDelay.totalNumberOfEntries = 313
+column.DivArrDelay.isAutoGenerated = false
+column.DivArrDelay.minValue = -2147483648
+column.DivArrDelay.maxValue = 1024
+column.DivArrDelay.defaultNullValue = -2147483648
+column.DivDistance.cardinality = 9
+column.DivDistance.totalDocs = 313
+column.DivDistance.dataType = INT
+column.DivDistance.bitsPerElement = 4
+column.DivDistance.lengthOfEachEntry = 0
+column.DivDistance.columnType = DIMENSION
+column.DivDistance.isSorted = false
+column.DivDistance.hasDictionary = true
+column.DivDistance.isSingleValues = true
+column.DivDistance.maxNumberOfMultiValues = 0
+column.DivDistance.totalNumberOfEntries = 313
+column.DivDistance.isAutoGenerated = false
+column.DivDistance.minValue = -2147483648
+column.DivDistance.maxValue = 257
+column.DivDistance.defaultNullValue = -2147483648
+column.DivLongestGTimes.cardinality = 28
+column.DivLongestGTimes.totalDocs = 313
+column.DivLongestGTimes.dataType = INT
+column.DivLongestGTimes.bitsPerElement = 5
+column.DivLongestGTimes.lengthOfEachEntry = 0
+column.DivLongestGTimes.columnType = DIMENSION
+column.DivLongestGTimes.isSorted = false
+column.DivLongestGTimes.hasDictionary = true
+column.DivLongestGTimes.isSingleValues = false
+column.DivLongestGTimes.maxNumberOfMultiValues = 1
+column.DivLongestGTimes.totalNumberOfEntries = 313
+column.DivLongestGTimes.isAutoGenerated = false
+column.DivLongestGTimes.minValue = -2147483648
+column.DivLongestGTimes.maxValue = 145
+column.DivLongestGTimes.defaultNullValue = -2147483648
+column.DivReachedDest.cardinality = 3
+column.DivReachedDest.totalDocs = 313
+column.DivReachedDest.dataType = INT
+column.DivReachedDest.bitsPerElement = 2
+column.DivReachedDest.lengthOfEachEntry = 0
+column.DivReachedDest.columnType = DIMENSION
+column.DivReachedDest.isSorted = false
+column.DivReachedDest.hasDictionary = true
+column.DivReachedDest.isSingleValues = true
+column.DivReachedDest.maxNumberOfMultiValues = 0
+column.DivReachedDest.totalNumberOfEntries = 313
+column.DivReachedDest.isAutoGenerated = false
+column.DivReachedDest.minValue = -2147483648
+column.DivReachedDest.maxValue = 1
+column.DivReachedDest.defaultNullValue = -2147483648
+column.DivTailNums.cardinality = 37
+column.DivTailNums.totalDocs = 313
+column.DivTailNums.dataType = STRING
+column.DivTailNums.bitsPerElement = 6
+column.DivTailNums.lengthOfEachEntry = 6
+column.DivTailNums.columnType = DIMENSION
+column.DivTailNums.isSorted = false
+column.DivTailNums.hasDictionary = true
+column.DivTailNums.isSingleValues = false
+column.DivTailNums.maxNumberOfMultiValues = 1
+column.DivTailNums.totalNumberOfEntries = 313
+column.DivTailNums.isAutoGenerated = false
+column.DivTailNums.minValue = N11536
+column.DivTailNums.maxValue = null
+column.DivTailNums.defaultNullValue = null
+column.DivTotalGTimes.cardinality = 33
+column.DivTotalGTimes.totalDocs = 313
+column.DivTotalGTimes.dataType = INT
+column.DivTotalGTimes.bitsPerElement = 6
+column.DivTotalGTimes.lengthOfEachEntry = 0
+column.DivTotalGTimes.columnType = DIMENSION
+column.DivTotalGTimes.isSorted = false
+column.DivTotalGTimes.hasDictionary = true
+column.DivTotalGTimes.isSingleValues = false
+column.DivTotalGTimes.maxNumberOfMultiValues = 1
+column.DivTotalGTimes.totalNumberOfEntries = 313
+column.DivTotalGTimes.isAutoGenerated = false
+column.DivTotalGTimes.minValue = -2147483648
+column.DivTotalGTimes.maxValue = 145
+column.DivTotalGTimes.defaultNullValue = -2147483648
+column.DivWheelsOffs.cardinality = 35
+column.DivWheelsOffs.totalDocs = 313
+column.DivWheelsOffs.dataType = INT
+column.DivWheelsOffs.bitsPerElement = 6
+column.DivWheelsOffs.lengthOfEachEntry = 0
+column.DivWheelsOffs.columnType = DIMENSION
+column.DivWheelsOffs.isSorted = false
+column.DivWheelsOffs.hasDictionary = true
+column.DivWheelsOffs.isSingleValues = false
+column.DivWheelsOffs.maxNumberOfMultiValues = 1
+column.DivWheelsOffs.totalNumberOfEntries = 313
+column.DivWheelsOffs.isAutoGenerated = false
+column.DivWheelsOffs.minValue = -2147483648
+column.DivWheelsOffs.maxValue = 2322
+column.DivWheelsOffs.defaultNullValue = -2147483648
+column.DivWheelsOns.cardinality = 50
+column.DivWheelsOns.totalDocs = 313
+column.DivWheelsOns.dataType = INT
+column.DivWheelsOns.bitsPerElement = 6
+column.DivWheelsOns.lengthOfEachEntry = 0
+column.DivWheelsOns.columnType = DIMENSION
+column.DivWheelsOns.isSorted = false
+column.DivWheelsOns.hasDictionary = true
+column.DivWheelsOns.isSingleValues = false
+column.DivWheelsOns.maxNumberOfMultiValues = 1
+column.DivWheelsOns.totalNumberOfEntries = 313
+column.DivWheelsOns.isAutoGenerated = false
+column.DivWheelsOns.minValue = -2147483648
+column.DivWheelsOns.maxValue = 2347
+column.DivWheelsOns.defaultNullValue = -2147483648
+column.Diverted.cardinality = 2
+column.Diverted.totalDocs = 313
+column.Diverted.dataType = INT
+column.Diverted.bitsPerElement = 1
+column.Diverted.lengthOfEachEntry = 0
+column.Diverted.columnType = DIMENSION
+column.Diverted.isSorted = false
+column.Diverted.hasDictionary = true
+column.Diverted.isSingleValues = true
+column.Diverted.maxNumberOfMultiValues = 0
+column.Diverted.totalNumberOfEntries = 313
+column.Diverted.isAutoGenerated = false
+column.Diverted.minValue = 0
+column.Diverted.maxValue = 1
+column.Diverted.defaultNullValue = -2147483648
+column.FirstDepTime.cardinality = 3
+column.FirstDepTime.totalDocs = 313
+column.FirstDepTime.dataType = INT
+column.FirstDepTime.bitsPerElement = 2
+column.FirstDepTime.lengthOfEachEntry = 0
+column.FirstDepTime.columnType = DIMENSION
+column.FirstDepTime.isSorted = false
+column.FirstDepTime.hasDictionary = true
+column.FirstDepTime.isSingleValues = true
+column.FirstDepTime.maxNumberOfMultiValues = 0
+column.FirstDepTime.totalNumberOfEntries = 313
+column.FirstDepTime.isAutoGenerated = false
+column.FirstDepTime.minValue = -2147483648
+column.FirstDepTime.maxValue = 1301
+column.FirstDepTime.defaultNullValue = -2147483648
+column.FlightDate.cardinality = 1
+column.FlightDate.totalDocs = 313
+column.FlightDate.dataType = STRING
+column.FlightDate.bitsPerElement = 1
+column.FlightDate.lengthOfEachEntry = 10
+column.FlightDate.columnType = DIMENSION
+column.FlightDate.isSorted = true
+column.FlightDate.hasDictionary = true
+column.FlightDate.isSingleValues = true
+column.FlightDate.maxNumberOfMultiValues = 0
+column.FlightDate.totalNumberOfEntries = 313
+column.FlightDate.isAutoGenerated = false
+column.FlightDate.minValue = 2014-01-15
+column.FlightDate.maxValue = 2014-01-15
+column.FlightDate.defaultNullValue = null
+column.FlightNum.cardinality = 304
+column.FlightNum.totalDocs = 313
+column.FlightNum.dataType = INT
+column.FlightNum.bitsPerElement = 9
+column.FlightNum.lengthOfEachEntry = 0
+column.FlightNum.columnType = DIMENSION
+column.FlightNum.isSorted = false
+column.FlightNum.hasDictionary = true
+column.FlightNum.isSingleValues = true
+column.FlightNum.maxNumberOfMultiValues = 0
+column.FlightNum.totalNumberOfEntries = 313
+column.FlightNum.isAutoGenerated = false
+column.FlightNum.minValue = 3
+column.FlightNum.maxValue = 7416
+column.FlightNum.defaultNullValue = -2147483648
+column.Flights.cardinality = 1
+column.Flights.totalDocs = 313
+column.Flights.dataType = INT
+column.Flights.bitsPerElement = 1
+column.Flights.lengthOfEachEntry = 0
+column.Flights.columnType = DIMENSION
+column.Flights.isSorted = true
+column.Flights.hasDictionary = true
+column.Flights.isSingleValues = true
+column.Flights.maxNumberOfMultiValues = 0
+column.Flights.totalNumberOfEntries = 313
+column.Flights.isAutoGenerated = false
+column.Flights.minValue = 1
+column.Flights.maxValue = 1
+column.Flights.defaultNullValue = -2147483648
+column.LateAircraftDelay.cardinality = 17
+column.LateAircraftDelay.totalDocs = 313
+column.LateAircraftDelay.dataType = INT
+column.LateAircraftDelay.bitsPerElement = 5
+column.LateAircraftDelay.lengthOfEachEntry = 0
+column.LateAircraftDelay.columnType = DIMENSION
+column.LateAircraftDelay.isSorted = false
+column.LateAircraftDelay.hasDictionary = true
+column.LateAircraftDelay.isSingleValues = true
+column.LateAircraftDelay.maxNumberOfMultiValues = 0
+column.LateAircraftDelay.totalNumberOfEntries = 313
+column.LateAircraftDelay.isAutoGenerated = false
+column.LateAircraftDelay.minValue = -2147483648
+column.LateAircraftDelay.maxValue = 221
+column.LateAircraftDelay.defaultNullValue = -2147483648
+column.LongestAddGTime.cardinality = 3
+column.LongestAddGTime.totalDocs = 313
+column.LongestAddGTime.dataType = INT
+column.LongestAddGTime.bitsPerElement = 2
+column.LongestAddGTime.lengthOfEachEntry = 0
+column.LongestAddGTime.columnType = DIMENSION
+column.LongestAddGTime.isSorted = false
+column.LongestAddGTime.hasDictionary = true
+column.LongestAddGTime.isSingleValues = true
+column.LongestAddGTime.maxNumberOfMultiValues = 0
+column.LongestAddGTime.totalNumberOfEntries = 313
+column.LongestAddGTime.isAutoGenerated = false
+column.LongestAddGTime.minValue = -2147483648
+column.LongestAddGTime.maxValue = 41
+column.LongestAddGTime.defaultNullValue = -2147483648
+column.Month.cardinality = 1
+column.Month.totalDocs = 313
+column.Month.dataType = INT
+column.Month.bitsPerElement = 1
+column.Month.lengthOfEachEntry = 0
+column.Month.columnType = DIMENSION
+column.Month.isSorted = true
+column.Month.hasDictionary = true
+column.Month.isSingleValues = true
+column.Month.maxNumberOfMultiValues = 0
+column.Month.totalNumberOfEntries = 313
+column.Month.isAutoGenerated = false
+column.Month.minValue = 1
+column.Month.maxValue = 1
+column.Month.defaultNullValue = -2147483648
+column.NASDelay.cardinality = 19
+column.NASDelay.totalDocs = 313
+column.NASDelay.dataType = INT
+column.NASDelay.bitsPerElement = 5
+column.NASDelay.lengthOfEachEntry = 0
+column.NASDelay.columnType = DIMENSION
+column.NASDelay.isSorted = false
+column.NASDelay.hasDictionary = true
+column.NASDelay.isSingleValues = true
+column.NASDelay.maxNumberOfMultiValues = 0
+column.NASDelay.totalNumberOfEntries = 313
+column.NASDelay.isAutoGenerated = false
+column.NASDelay.minValue = -2147483648
+column.NASDelay.maxValue = 66
+column.NASDelay.defaultNullValue = -2147483648
+column.Origin.cardinality = 97
+column.Origin.totalDocs = 313
+column.Origin.dataType = STRING
+column.Origin.bitsPerElement = 7
+column.Origin.lengthOfEachEntry = 3
+column.Origin.columnType = DIMENSION
+column.Origin.isSorted = false
+column.Origin.hasDictionary = true
+column.Origin.isSingleValues = true
+column.Origin.maxNumberOfMultiValues = 0
+column.Origin.totalNumberOfEntries = 313
+column.Origin.isAutoGenerated = false
+column.Origin.minValue = ABR
+column.Origin.maxValue = XNA
+column.Origin.defaultNullValue = null
+column.OriginAirportID.cardinality = 97
+column.OriginAirportID.totalDocs = 313
+column.OriginAirportID.dataType = INT
+column.OriginAirportID.bitsPerElement = 7
+column.OriginAirportID.lengthOfEachEntry = 0
+column.OriginAirportID.columnType = DIMENSION
+column.OriginAirportID.isSorted = false
+column.OriginAirportID.hasDictionary = true
+column.OriginAirportID.isSingleValues = true
+column.OriginAirportID.maxNumberOfMultiValues = 0
+column.OriginAirportID.totalNumberOfEntries = 313
+column.OriginAirportID.isAutoGenerated = false
+column.OriginAirportID.minValue = 10141
+column.OriginAirportID.maxValue = 15919
+column.OriginAirportID.defaultNullValue = -2147483648
+column.OriginAirportSeqID.cardinality = 97
+column.OriginAirportSeqID.totalDocs = 313
+column.OriginAirportSeqID.dataType = INT
+column.OriginAirportSeqID.bitsPerElement = 7
+column.OriginAirportSeqID.lengthOfEachEntry = 0
+column.OriginAirportSeqID.columnType = DIMENSION
+column.OriginAirportSeqID.isSorted = false
+column.OriginAirportSeqID.hasDictionary = true
+column.OriginAirportSeqID.isSingleValues = true
+column.OriginAirportSeqID.maxNumberOfMultiValues = 0
+column.OriginAirportSeqID.totalNumberOfEntries = 313
+column.OriginAirportSeqID.isAutoGenerated = false
+column.OriginAirportSeqID.minValue = 1014102
+column.OriginAirportSeqID.maxValue = 1591902
+column.OriginAirportSeqID.defaultNullValue = -2147483648
+column.OriginCityMarketID.cardinality = 82
+column.OriginCityMarketID.totalDocs = 313
+column.OriginCityMarketID.dataType = INT
+column.OriginCityMarketID.bitsPerElement = 7
+column.OriginCityMarketID.lengthOfEachEntry = 0
+column.OriginCityMarketID.columnType = DIMENSION
+column.OriginCityMarketID.isSorted = false
+column.OriginCityMarketID.hasDictionary = true
+column.OriginCityMarketID.isSingleValues = true
+column.OriginCityMarketID.maxNumberOfMultiValues = 0
+column.OriginCityMarketID.totalNumberOfEntries = 313
+column.OriginCityMarketID.isAutoGenerated = false
+column.OriginCityMarketID.minValue = 30070
+column.OriginCityMarketID.maxValue = 35165
+column.OriginCityMarketID.defaultNullValue = -2147483648
+column.OriginCityName.cardinality = 93
+column.OriginCityName.totalDocs = 313
+column.OriginCityName.dataType = STRING
+column.OriginCityName.bitsPerElement = 7
+column.OriginCityName.lengthOfEachEntry = 30
+column.OriginCityName.columnType = DIMENSION
+column.OriginCityName.isSorted = false
+column.OriginCityName.hasDictionary = true
+column.OriginCityName.isSingleValues = true
+column.OriginCityName.maxNumberOfMultiValues = 0
+column.OriginCityName.totalNumberOfEntries = 313
+column.OriginCityName.isAutoGenerated = false
+column.OriginCityName.minMaxValueInvalid = true
+column.OriginCityName.defaultNullValue = null
+column.OriginState.cardinality = 43
+column.OriginState.totalDocs = 313
+column.OriginState.dataType = STRING
+column.OriginState.bitsPerElement = 6
+column.OriginState.lengthOfEachEntry = 2
+column.OriginState.columnType = DIMENSION
+column.OriginState.isSorted = false
+column.OriginState.hasDictionary = true
+column.OriginState.isSingleValues = true
+column.OriginState.maxNumberOfMultiValues = 0
+column.OriginState.totalNumberOfEntries = 313
+column.OriginState.isAutoGenerated = false
+column.OriginState.minValue = AK
+column.OriginState.maxValue = WI
+column.OriginState.defaultNullValue = null
+column.OriginStateFips.cardinality = 43
+column.OriginStateFips.totalDocs = 313
+column.OriginStateFips.dataType = INT
+column.OriginStateFips.bitsPerElement = 6
+column.OriginStateFips.lengthOfEachEntry = 0
+column.OriginStateFips.columnType = DIMENSION
+column.OriginStateFips.isSorted = false
+column.OriginStateFips.hasDictionary = true
+column.OriginStateFips.isSingleValues = true
+column.OriginStateFips.maxNumberOfMultiValues = 0
+column.OriginStateFips.totalNumberOfEntries = 313
+column.OriginStateFips.isAutoGenerated = false
+column.OriginStateFips.minValue = 1
+column.OriginStateFips.maxValue = 72
+column.OriginStateFips.defaultNullValue = -2147483648
+column.OriginStateName.cardinality = 43
+column.OriginStateName.totalDocs = 313
+column.OriginStateName.dataType = STRING
+column.OriginStateName.bitsPerElement = 6
+column.OriginStateName.lengthOfEachEntry = 14
+column.OriginStateName.columnType = DIMENSION
+column.OriginStateName.isSorted = false
+column.OriginStateName.hasDictionary = true
+column.OriginStateName.isSingleValues = true
+column.OriginStateName.maxNumberOfMultiValues = 0
+column.OriginStateName.totalNumberOfEntries = 313
+column.OriginStateName.isAutoGenerated = false
+column.OriginStateName.minValue = Alabama
+column.OriginStateName.maxValue = Wisconsin
+column.OriginStateName.defaultNullValue = null
+column.OriginWac.cardinality = 43
+column.OriginWac.totalDocs = 313
+column.OriginWac.dataType = INT
+column.OriginWac.bitsPerElement = 6
+column.OriginWac.lengthOfEachEntry = 0
+column.OriginWac.columnType = DIMENSION
+column.OriginWac.isSorted = false
+column.OriginWac.hasDictionary = true
+column.OriginWac.isSingleValues = true
+column.OriginWac.maxNumberOfMultiValues = 0
+column.OriginWac.totalNumberOfEntries = 313
+column.OriginWac.isAutoGenerated = false
+column.OriginWac.minValue = 1
+column.OriginWac.maxValue = 93
+column.OriginWac.defaultNullValue = -2147483648
+column.Quarter.cardinality = 1
+column.Quarter.totalDocs = 313
+column.Quarter.dataType = INT
+column.Quarter.bitsPerElement = 1
+column.Quarter.lengthOfEachEntry = 0
+column.Quarter.columnType = DIMENSION
+column.Quarter.isSorted = true
+column.Quarter.hasDictionary = true
+column.Quarter.isSingleValues = true
+column.Quarter.maxNumberOfMultiValues = 0
+column.Quarter.totalNumberOfEntries = 313
+column.Quarter.isAutoGenerated = false
+column.Quarter.minValue = 1
+column.Quarter.maxValue = 1
+column.Quarter.defaultNullValue = -2147483648
+column.RandomAirports.cardinality = 78
+column.RandomAirports.totalDocs = 313
+column.RandomAirports.dataType = STRING
+column.RandomAirports.bitsPerElement = 7
+column.RandomAirports.lengthOfEachEntry = 4
+column.RandomAirports.columnType = DIMENSION
+column.RandomAirports.isSorted = false
+column.RandomAirports.hasDictionary = true
+column.RandomAirports.isSingleValues = false
+column.RandomAirports.maxNumberOfMultiValues = 77
+column.RandomAirports.totalNumberOfEntries = 4415
+column.RandomAirports.isAutoGenerated = false
+column.RandomAirports.minValue = ABI
+column.RandomAirports.maxValue = null
+column.RandomAirports.defaultNullValue = null
+column.SecurityDelay.cardinality = 2
+column.SecurityDelay.totalDocs = 313
+column.SecurityDelay.dataType = INT
+column.SecurityDelay.bitsPerElement = 1
+column.SecurityDelay.lengthOfEachEntry = 0
+column.SecurityDelay.columnType = DIMENSION
+column.SecurityDelay.isSorted = false
+column.SecurityDelay.hasDictionary = true
+column.SecurityDelay.isSingleValues = true
+column.SecurityDelay.maxNumberOfMultiValues = 0
+column.SecurityDelay.totalNumberOfEntries = 313
+column.SecurityDelay.isAutoGenerated = false
+column.SecurityDelay.minValue = -2147483648
+column.SecurityDelay.maxValue = 0
+column.SecurityDelay.defaultNullValue = -2147483648
+column.TailNum.cardinality = 303
+column.TailNum.totalDocs = 313
+column.TailNum.dataType = STRING
+column.TailNum.bitsPerElement = 9
+column.TailNum.lengthOfEachEntry = 6
+column.TailNum.columnType = DIMENSION
+column.TailNum.isSorted = false
+column.TailNum.hasDictionary = true
+column.TailNum.isSingleValues = true
+column.TailNum.maxNumberOfMultiValues = 0
+column.TailNum.totalNumberOfEntries = 313
+column.TailNum.isAutoGenerated = false
+column.TailNum.minValue = N002AA
+column.TailNum.maxValue = N995DL
+column.TailNum.defaultNullValue = null
+column.TaxiIn.cardinality = 21
+column.TaxiIn.totalDocs = 313
+column.TaxiIn.dataType = INT
+column.TaxiIn.bitsPerElement = 5
+column.TaxiIn.lengthOfEachEntry = 0
+column.TaxiIn.columnType = DIMENSION
+column.TaxiIn.isSorted = false
+column.TaxiIn.hasDictionary = true
+column.TaxiIn.isSingleValues = true
+column.TaxiIn.maxNumberOfMultiValues = 0
+column.TaxiIn.totalNumberOfEntries = 313
+column.TaxiIn.isAutoGenerated = false
+column.TaxiIn.minValue = -2147483648
+column.TaxiIn.maxValue = 36
+column.TaxiIn.defaultNullValue = -2147483648
+column.TaxiOut.cardinality = 35
+column.TaxiOut.totalDocs = 313
+column.TaxiOut.dataType = INT
+column.TaxiOut.bitsPerElement = 6
+column.TaxiOut.lengthOfEachEntry = 0
+column.TaxiOut.columnType = DIMENSION
+column.TaxiOut.isSorted = false
+column.TaxiOut.hasDictionary = true
+column.TaxiOut.isSingleValues = true
+column.TaxiOut.maxNumberOfMultiValues = 0
+column.TaxiOut.totalNumberOfEntries = 313
+column.TaxiOut.isAutoGenerated = false
+column.TaxiOut.minValue = -2147483648
+column.TaxiOut.maxValue = 54
+column.TaxiOut.defaultNullValue = -2147483648
+column.TotalAddGTime.cardinality = 3
+column.TotalAddGTime.totalDocs = 313
+column.TotalAddGTime.dataType = INT
+column.TotalAddGTime.bitsPerElement = 2
+column.TotalAddGTime.lengthOfEachEntry = 0
+column.TotalAddGTime.columnType = DIMENSION
+column.TotalAddGTime.isSorted = false
+column.TotalAddGTime.hasDictionary = true
+column.TotalAddGTime.isSingleValues = true
+column.TotalAddGTime.maxNumberOfMultiValues = 0
+column.TotalAddGTime.totalNumberOfEntries = 313
+column.TotalAddGTime.isAutoGenerated = false
+column.TotalAddGTime.minValue = -2147483648
+column.TotalAddGTime.maxValue = 41
+column.TotalAddGTime.defaultNullValue = -2147483648
+column.UniqueCarrier.cardinality = 14
+column.UniqueCarrier.totalDocs = 313
+column.UniqueCarrier.dataType = STRING
+column.UniqueCarrier.bitsPerElement = 4
+column.UniqueCarrier.lengthOfEachEntry = 2
+column.UniqueCarrier.columnType = DIMENSION
+column.UniqueCarrier.isSorted = false
+column.UniqueCarrier.hasDictionary = true
+column.UniqueCarrier.isSingleValues = true
+column.UniqueCarrier.maxNumberOfMultiValues = 0
+column.UniqueCarrier.totalNumberOfEntries = 313
+column.UniqueCarrier.isAutoGenerated = false
+column.UniqueCarrier.minValue = AA
+column.UniqueCarrier.maxValue = WN
+column.UniqueCarrier.defaultNullValue = null
+column.WeatherDelay.cardinality = 2
+column.WeatherDelay.totalDocs = 313
+column.WeatherDelay.dataType = INT
+column.WeatherDelay.bitsPerElement = 1
+column.WeatherDelay.lengthOfEachEntry = 0
+column.WeatherDelay.columnType = DIMENSION
+column.WeatherDelay.isSorted = false
+column.WeatherDelay.hasDictionary = true
+column.WeatherDelay.isSingleValues = true
+column.WeatherDelay.maxNumberOfMultiValues = 0
+column.WeatherDelay.totalNumberOfEntries = 313
+column.WeatherDelay.isAutoGenerated = false
+column.WeatherDelay.minValue = -2147483648
+column.WeatherDelay.maxValue = 0
+column.WeatherDelay.defaultNullValue = -2147483648
+column.WheelsOff.cardinality = 269
+column.WheelsOff.totalDocs = 313
+column.WheelsOff.dataType = INT
+column.WheelsOff.bitsPerElement = 9
+column.WheelsOff.lengthOfEachEntry = 0
+column.WheelsOff.columnType = DIMENSION
+column.WheelsOff.isSorted = false
+column.WheelsOff.hasDictionary = true
+column.WheelsOff.isSingleValues = true
+column.WheelsOff.maxNumberOfMultiValues = 0
+column.WheelsOff.totalNumberOfEntries = 313
+column.WheelsOff.isAutoGenerated = false
+column.WheelsOff.minValue = -2147483648
+column.WheelsOff.maxValue = 2243
+column.WheelsOff.defaultNullValue = -2147483648
+column.WheelsOn.cardinality = 259
+column.WheelsOn.totalDocs = 313
+column.WheelsOn.dataType = INT
+column.WheelsOn.bitsPerElement = 9
+column.WheelsOn.lengthOfEachEntry = 0
+column.WheelsOn.columnType = DIMENSION
+column.WheelsOn.isSorted = false
+column.WheelsOn.hasDictionary = true
+column.WheelsOn.isSingleValues = true
+column.WheelsOn.maxNumberOfMultiValues = 0
+column.WheelsOn.totalNumberOfEntries = 313
+column.WheelsOn.isAutoGenerated = false
+column.WheelsOn.minValue = -2147483648
+column.WheelsOn.maxValue = 2355
+column.WheelsOn.defaultNullValue = -2147483648
+column.Year.cardinality = 1
+column.Year.totalDocs = 313
+column.Year.dataType = INT
+column.Year.bitsPerElement = 1
+column.Year.lengthOfEachEntry = 0
+column.Year.columnType = DIMENSION
+column.Year.isSorted = true
+column.Year.hasDictionary = true
+column.Year.isSingleValues = true
+column.Year.maxNumberOfMultiValues = 0
+column.Year.totalNumberOfEntries = 313
+column.Year.isAutoGenerated = false
+column.Year.minValue = 2014
+column.Year.maxValue = 2014
+column.Year.defaultNullValue = -2147483648
+column.ts.cardinality = 1
+column.ts.totalDocs = 313
+column.ts.dataType = TIMESTAMP
+column.ts.bitsPerElement = 1
+column.ts.lengthOfEachEntry = 0
+column.ts.columnType = DATE_TIME
+column.ts.isSorted = true
+column.ts.hasDictionary = true
+column.ts.isSingleValues = true
+column.ts.maxNumberOfMultiValues = 0
+column.ts.totalNumberOfEntries = 313
+column.ts.isAutoGenerated = false
+column.ts.datetimeFormat = 1:MILLISECONDS:TIMESTAMP
+column.ts.datetimeGranularity = 1:SECONDS
+column.ts.minValue = 1389744000000
+column.ts.maxValue = 1389744000000
+column.ts.defaultNullValue = 0
+column.tsRaw.cardinality = 1
+column.tsRaw.totalDocs = 313
+column.tsRaw.dataType = TIMESTAMP
+column.tsRaw.bitsPerElement = 1
+column.tsRaw.lengthOfEachEntry = 0
+column.tsRaw.columnType = DATE_TIME
+column.tsRaw.isSorted = true
+column.tsRaw.hasDictionary = true
+column.tsRaw.isSingleValues = true
+column.tsRaw.maxNumberOfMultiValues = 0
+column.tsRaw.totalNumberOfEntries = 313
+column.tsRaw.isAutoGenerated = false
+column.tsRaw.datetimeFormat = 1:MILLISECONDS:TIMESTAMP
+column.tsRaw.datetimeGranularity = 1:SECONDS
+column.tsRaw.minValue = 1389744000000
+column.tsRaw.maxValue = 1389744000000
+column.tsRaw.defaultNullValue = 0
+segment.index.version = v3
+startree.v2.count = 1
+startree.v2.0.total.docs = 1004
+startree.v2.0.split.order = AirlineID
+startree.v2.0.split.order = Origin
+startree.v2.0.split.order = Dest
+startree.v2.0.function.column.pairs = count__*
+startree.v2.0.function.column.pairs = max__ArrDelay
+startree.v2.0.max.leaf.records = 10
diff --git a/pinot-segment-local/src/test/resources/data/startree/segment/star_tree_index b/pinot-segment-local/src/test/resources/data/startree/segment/star_tree_index
new file mode 100644
index 0000000000..c75da7ea81
Binary files /dev/null and b/pinot-segment-local/src/test/resources/data/startree/segment/star_tree_index differ
diff --git a/pinot-segment-local/src/test/resources/data/startree/segment/star_tree_index_map b/pinot-segment-local/src/test/resources/data/startree/segment/star_tree_index_map
new file mode 100644
index 0000000000..0931e9ab53
--- /dev/null
+++ b/pinot-segment-local/src/test/resources/data/startree/segment/star_tree_index_map
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+0.null.STAR_TREE.OFFSET = 0
+0.null.STAR_TREE.SIZE = 18715
+0.AirlineID.FORWARD_INDEX.OFFSET = 18715
+0.AirlineID.FORWARD_INDEX.SIZE = 502
+0.Origin.FORWARD_INDEX.OFFSET = 19217
+0.Origin.FORWARD_INDEX.SIZE = 879
+0.Dest.FORWARD_INDEX.OFFSET = 20096
+0.Dest.FORWARD_INDEX.SIZE = 879
+0.count__*.FORWARD_INDEX.OFFSET = 20975
+0.count__*.FORWARD_INDEX.SIZE = 8068
+0.max__ArrDelay.FORWARD_INDEX.OFFSET = 29043
+0.max__ArrDelay.FORWARD_INDEX.SIZE = 8068
diff --git a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/startree/StarTreeV2Constants.java b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/startree/StarTreeV2Constants.java
index 0d2dba6395..1f5df2ab5e 100644
--- a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/startree/StarTreeV2Constants.java
+++ b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/startree/StarTreeV2Constants.java
@@ -32,6 +32,7 @@ public class StarTreeV2Constants {
   // File names before combining
   public static final String STAR_TREE_TEMP_DIR = "star_tree_tmp";
   public static final String STAR_TREE_INDEX_FILE_NAME = "star_tree.index";
+  public static final String EXISTING_STAR_TREE_TEMP_DIR = "existing_star_tree_tmp";
 
   // NOTE: because of bit compression, we cannot store -1 for star in forward index. Because star value should never be
   // accessed, we can simply put 0 as the place holder


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org