diff options
author | Arina Ielchiieva <arina.yelchiyeva@gmail.com> | 2019-01-04 19:30:23 +0200 |
---|---|---|
committer | Arina Ielchiieva <arina.yelchiyeva@gmail.com> | 2019-01-14 11:02:04 +0200 |
commit | 172dc7cb4c3323e9650db2bf7fe1eab76c2fbbe1 (patch) | |
tree | 9a08f6166eff319c065ca4d2c75b634700bb472f | |
parent | 06a210c2d681c3972ca3885840da0559341c1c02 (diff) |
DRILL-6903: SchemaBuilder code improvements
1. ColumnBuilder: setPrecisionAndScale method
2. SchemaContainer: addColumn method parameter AbstractColumnMetadata was changed to ColumnMetadata
3. MapBuilder / RepeatedListBuilder / UnionBuilder: added constructors without parent, made buildColumn method public
4. TupleMetadata: added toMetadataList method
5. Other refactoring
27 files changed, 265 insertions, 175 deletions
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnBuilder.java index aa5d19ab5..33a8eeb8c 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnBuilder.java @@ -36,7 +36,6 @@ import org.apache.drill.exec.physical.rowSet.impl.UnionState.UnionColumnState; import org.apache.drill.exec.physical.rowSet.impl.UnionState.UnionVectorState; import org.apache.drill.exec.physical.rowSet.project.ImpliedTupleRequest; import org.apache.drill.exec.record.MaterializedField; -import org.apache.drill.exec.record.metadata.AbstractColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata; import org.apache.drill.exec.record.metadata.PrimitiveColumnMetadata; import org.apache.drill.exec.record.metadata.ProjectionType; @@ -76,7 +75,6 @@ import org.apache.drill.exec.vector.complex.UnionVector; * the list metadata must contain that one type so the code knows how to build * the nullable array writer for that column. */ - public class ColumnBuilder { private ColumnBuilder() { } @@ -85,16 +83,15 @@ public class ColumnBuilder { * Implementation of the work to add a new column to this tuple given a * schema description of the column. * + * @param parent container * @param columnSchema schema of the column * @return writer for the new column */ - public static ColumnState buildColumn(ContainerState parent, ColumnMetadata columnSchema) { // Indicate projection in the metadata. - ((AbstractColumnMetadata) columnSchema).setProjected( - parent.projectionType(columnSchema.name()) != ProjectionType.UNPROJECTED); + columnSchema.setProjected(parent.projectionType(columnSchema.name()) != ProjectionType.UNPROJECTED); // Build the column @@ -218,8 +215,7 @@ public class ColumnBuilder { vector = null; vectorState = new NullVectorState(); } - final TupleObjectWriter mapWriter = MapWriter.buildMap(columnSchema, - vector, new ArrayList<AbstractObjectWriter>()); + final TupleObjectWriter mapWriter = MapWriter.buildMap(columnSchema, vector, new ArrayList<>()); final SingleMapState mapState = new SingleMapState(parent.loader(), parent.vectorCache().childCache(columnSchema.name()), parent.projectionSet().mapProjection(columnSchema.name())); @@ -256,8 +252,7 @@ public class ColumnBuilder { // Create the writer using the offset vector final AbstractObjectWriter writer = MapWriter.buildMapArray( - columnSchema, mapVector, - new ArrayList<AbstractObjectWriter>()); + columnSchema, mapVector, new ArrayList<>()); // Wrap the offset vector in a vector state @@ -293,11 +288,10 @@ public class ColumnBuilder { * in a join column, say.) Still, Drill supports unions, so the code here * does so. Unions are fully tested in the row set writer mechanism. * - * @param parent - * @param columnSchema - * @return + * @param parent container + * @param columnSchema column schema + * @return column */ - private static ColumnState buildUnion(ContainerState parent, ColumnMetadata columnSchema) { assert columnSchema.isVariant() && ! columnSchema.isArray(); diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnState.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnState.java index 24e270a4f..95f011a23 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnState.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/impl/ColumnState.java @@ -25,7 +25,6 @@ import org.apache.drill.exec.vector.accessor.ScalarWriter; import org.apache.drill.exec.vector.accessor.ScalarWriter.ColumnWriterListener; import org.apache.drill.exec.vector.accessor.impl.HierarchicalFormatter; import org.apache.drill.exec.vector.accessor.writer.AbstractObjectWriter; -import org.apache.drill.exec.vector.accessor.writer.AbstractScalarWriter; /** * Represents the write-time state for a column including the writer and the (optional) @@ -39,7 +38,6 @@ import org.apache.drill.exec.vector.accessor.writer.AbstractScalarWriter; * vector, or even a non-existent vector. The {@link VectorState} class abstracts out * these differences. */ - public abstract class ColumnState { private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ColumnState.class); @@ -61,7 +59,7 @@ public abstract class ColumnState { } else { scalarWriter = writer.scalar(); } - ((AbstractScalarWriter) scalarWriter).bindListener(this); + scalarWriter.bindListener(this); } @Override diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/BaseTupleModel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/BaseTupleModel.java index a8e57f9ef..9320d11a4 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/BaseTupleModel.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/BaseTupleModel.java @@ -20,7 +20,6 @@ package org.apache.drill.exec.physical.rowSet.model; import java.util.ArrayList; import java.util.List; -import org.apache.drill.exec.record.metadata.AbstractColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata; import org.apache.drill.exec.record.metadata.TupleMetadata; import org.apache.drill.exec.record.metadata.TupleSchema; @@ -30,7 +29,6 @@ import org.apache.drill.exec.record.metadata.TupleSchema; * and "hyper" cases. Deals primarily with the structure of the model, * which is common between the two physical implementations. */ - public abstract class BaseTupleModel implements TupleModel { public static abstract class BaseColumnModel implements ColumnModel { @@ -61,10 +59,9 @@ public abstract class BaseTupleModel implements TupleModel { /** * Descriptive schema associated with the columns above. Unlike a - * {@link VectorContainer}, this abstraction keeps the schema in sync + * {@link org.apache.drill.exec.record.VectorContainer}, this abstraction keeps the schema in sync * with vectors as columns are added. */ - protected final TupleSchema schema; public BaseTupleModel() { @@ -107,9 +104,8 @@ public abstract class BaseTupleModel implements TupleModel { * * @param column column implementation to add */ - protected void addBaseColumn(BaseColumnModel column) { - schema.add((AbstractColumnMetadata) column.schema()); + schema.add(column.schema()); columns.add(column); assert columns.size() == schema.size(); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/MetadataProvider.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/MetadataProvider.java index 5212afb08..fea7ecd46 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/MetadataProvider.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/MetadataProvider.java @@ -18,7 +18,6 @@ package org.apache.drill.exec.physical.rowSet.model; import org.apache.drill.exec.record.MaterializedField; -import org.apache.drill.exec.record.metadata.AbstractColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata; import org.apache.drill.exec.record.metadata.MetadataUtils; import org.apache.drill.exec.record.metadata.RepeatedListColumnMetadata; @@ -38,17 +37,16 @@ public interface MetadataProvider { TupleMetadata tuple(); VariantMetadata variant(); - public static class VectorDescrip { + class VectorDescrip { public final MetadataProvider parent; public final ColumnMetadata metadata; public VectorDescrip(MetadataProvider provider, ColumnMetadata metadata) { - parent = provider; + this.parent = provider; this.metadata = metadata; } - public VectorDescrip(MetadataProvider provider, int index, - MaterializedField field) { + public VectorDescrip(MetadataProvider provider, int index, MaterializedField field) { this(provider, provider.metadata(index, field)); } @@ -57,7 +55,7 @@ public interface MetadataProvider { } } - public static class MetadataCreator implements MetadataProvider { + class MetadataCreator implements MetadataProvider { private final TupleSchema tuple; @@ -101,7 +99,7 @@ public interface MetadataProvider { } } - public static class VariantSchemaCreator implements MetadataProvider { + class VariantSchemaCreator implements MetadataProvider { private final VariantSchema variantSchema; @@ -130,7 +128,7 @@ public interface MetadataProvider { } } - public static class ArraySchemaCreator implements MetadataProvider { + class ArraySchemaCreator implements MetadataProvider { private final RepeatedListColumnMetadata arraySchema; @@ -142,7 +140,7 @@ public interface MetadataProvider { public ColumnMetadata metadata(int index, MaterializedField field) { assert index == 0; assert arraySchema.childSchema() == null; - AbstractColumnMetadata childSchema = MetadataUtils.fromField(field.cloneEmpty()); + ColumnMetadata childSchema = MetadataUtils.fromField(field.cloneEmpty()); arraySchema.childSchema(childSchema); return childSchema; } @@ -163,7 +161,7 @@ public interface MetadataProvider { } } - public static class MetadataRetrieval implements MetadataProvider { + class MetadataRetrieval implements MetadataProvider { private final TupleMetadata tuple; @@ -203,7 +201,7 @@ public interface MetadataProvider { } } - public static class VariantSchemaRetrieval implements MetadataProvider { + class VariantSchemaRetrieval implements MetadataProvider { private final VariantSchema variantSchema; @@ -232,7 +230,7 @@ public interface MetadataProvider { } } - public static class ArraySchemaRetrieval implements MetadataProvider { + class ArraySchemaRetrieval implements MetadataProvider { private final ColumnMetadata arraySchema; diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/single/SingleSchemaInference.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/single/SingleSchemaInference.java index ad0c8c045..e6467d616 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/single/SingleSchemaInference.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/rowSet/model/single/SingleSchemaInference.java @@ -24,7 +24,6 @@ import org.apache.drill.common.types.TypeProtos.DataMode; import org.apache.drill.common.types.TypeProtos.MinorType; import org.apache.drill.exec.record.MaterializedField; import org.apache.drill.exec.record.VectorContainer; -import org.apache.drill.exec.record.metadata.AbstractColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata; import org.apache.drill.exec.record.metadata.MetadataUtils; import org.apache.drill.exec.record.metadata.TupleMetadata; @@ -55,7 +54,6 @@ import org.apache.drill.exec.vector.complex.UnionVector; * (repeated), variant (LIST, UNION) and tuple (MAP) columns, the tree grows * quite complex. */ - public class SingleSchemaInference { public TupleMetadata infer(VectorContainer container) { @@ -66,7 +64,7 @@ public class SingleSchemaInference { return MetadataUtils.fromColumns(columns); } - private AbstractColumnMetadata inferVector(ValueVector vector) { + private ColumnMetadata inferVector(ValueVector vector) { final MaterializedField field = vector.getField(); switch (field.getType().getMinorType()) { case MAP: diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/AbstractColumnMetadata.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/AbstractColumnMetadata.java index ab82d650c..595c5c49d 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/AbstractColumnMetadata.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/AbstractColumnMetadata.java @@ -34,7 +34,6 @@ import org.apache.drill.exec.record.MaterializedField; * since maps (and the row itself) will, by definition, differ between * the two views. */ - public abstract class AbstractColumnMetadata implements ColumnMetadata { // Capture the key schema information. We cannot use the MaterializedField @@ -87,7 +86,8 @@ public abstract class AbstractColumnMetadata implements ColumnMetadata { expectedElementCount = from.expectedElementCount; } - protected void bind(TupleSchema parentTuple) { } + @Override + public void bind(TupleMetadata parentTuple) { } @Override public String name() { return name; } @@ -204,6 +204,4 @@ public abstract class AbstractColumnMetadata implements ColumnMetadata { .append("]") .toString(); } - - public abstract AbstractColumnMetadata copy(); }
\ No newline at end of file diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/ColumnBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/ColumnBuilder.java index e60ff9364..d23eeb4c7 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/ColumnBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/ColumnBuilder.java @@ -28,16 +28,16 @@ import org.apache.drill.exec.record.MaterializedField; * some may need a mode other than required, may need a width, may * need scale and precision, and so on. */ - public class ColumnBuilder { + private final String name; private final MajorType.Builder typeBuilder; public ColumnBuilder(String name, MinorType type) { this.name = name; - typeBuilder = MajorType.newBuilder() - .setMinorType(type) - .setMode(DataMode.REQUIRED); + this.typeBuilder = MajorType.newBuilder() + .setMinorType(type) + .setMode(DataMode.REQUIRED); } public ColumnBuilder setMode(DataMode mode) { @@ -54,9 +54,9 @@ public class ColumnBuilder { return this; } - public ColumnBuilder setScale(int scale, int precision) { - typeBuilder.setScale(scale); + public ColumnBuilder setPrecisionAndScale(int precision, int scale) { typeBuilder.setPrecision(precision); + typeBuilder.setScale(scale); return this; } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapBuilder.java index 5ed455737..408dcc4aa 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapBuilder.java @@ -25,14 +25,24 @@ import org.apache.drill.exec.record.MaterializedField; /** * Internal structure for building a map. A map is just a schema, * but one that is part of a parent column. + * <p/> + * Class can be created with and without parent container. + * In the first case, column is added to the parent container during creation + * and all <tt>resumeXXX</tt> methods return qualified parent container. + * In the second case column is created without parent container as standalone entity. + * All <tt>resumeXXX</tt> methods do not produce any action and return null. + * To access built column {@link #buildColumn()} should be used. */ - public class MapBuilder implements SchemaContainer { private final SchemaContainer parent; private final TupleBuilder tupleBuilder = new TupleBuilder(); private final String memberName; private final DataMode mode; + public MapBuilder(String memberName, DataMode mode) { + this(null, memberName, mode); + } + public MapBuilder(SchemaContainer parent, String memberName, DataMode mode) { this.parent = parent; this.memberName = memberName; @@ -40,7 +50,7 @@ public class MapBuilder implements SchemaContainer { } @Override - public void addColumn(AbstractColumnMetadata column) { + public void addColumn(ColumnMetadata column) { tupleBuilder.addColumn(column); } @@ -99,10 +109,9 @@ public class MapBuilder implements SchemaContainer { * map. Building that map, using {@link MapBuilder#resumeSchema()}, * will return the original schema builder. * - * @param pathName the name of the map column + * @param name the name of the map column * @return a builder for the map */ - public MapBuilder addMap(String name) { return tupleBuilder.addMap(this, name); } @@ -123,22 +132,28 @@ public class MapBuilder implements SchemaContainer { return tupleBuilder.addRepeatedList(this, name); } - private MapColumnMetadata buildCol() { + public MapColumnMetadata buildColumn() { return new MapColumnMetadata(memberName, mode, tupleBuilder.schema()); } + public void build() { + if (parent != null) { + parent.addColumn(buildColumn()); + } + } + public SchemaBuilder resumeSchema() { - parent.addColumn(buildCol()); + build(); return (SchemaBuilder) parent; } public MapBuilder resumeMap() { - parent.addColumn(buildCol()); + build(); return (MapBuilder) parent; } public RepeatedListBuilder resumeList() { - parent.addColumn(buildCol()); + build(); return (RepeatedListBuilder) parent; } @@ -146,7 +161,7 @@ public class MapBuilder implements SchemaContainer { // TODO: Use the map schema directly rather than // rebuilding it as is done here. - parent.addColumn(buildCol()); + build(); return (UnionBuilder) parent; } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapColumnMetadata.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapColumnMetadata.java index 795fd7f67..9db2e3e7e 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapColumnMetadata.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MapColumnMetadata.java @@ -26,8 +26,8 @@ import org.apache.drill.exec.record.MaterializedField; * Describes a map and repeated map. Both are tuples that have a tuple * schema as part of the column definition. */ - public class MapColumnMetadata extends AbstractColumnMetadata { + private TupleMetadata parentTuple; private final TupleSchema mapSchema; @@ -36,20 +36,17 @@ public class MapColumnMetadata extends AbstractColumnMetadata { * * @param schema materialized field description of the map */ - public MapColumnMetadata(MaterializedField schema) { this(schema, null); } /** * Build a map column metadata by cloning the type information (but not - * the children) of the materialized field provided. Use the hints - * provided. + * the children) of the materialized field provided. * * @param schema the schema to use - * @param hints metadata hints for this column + * @param mapSchema parent schema */ - MapColumnMetadata(MaterializedField schema, TupleSchema mapSchema) { super(schema); if (mapSchema == null) { @@ -76,12 +73,12 @@ public class MapColumnMetadata extends AbstractColumnMetadata { } @Override - public AbstractColumnMetadata copy() { + public ColumnMetadata copy() { return new MapColumnMetadata(this); } @Override - protected void bind(TupleSchema parentTuple) { + public void bind(TupleMetadata parentTuple) { this.parentTuple = parentTuple; } @@ -99,8 +96,6 @@ public class MapColumnMetadata extends AbstractColumnMetadata { public TupleMetadata parentTuple() { return parentTuple; } - public TupleSchema mapSchemaImpl() { return mapSchema; } - @Override public ColumnMetadata cloneEmpty() { return new MapColumnMetadata(name, mode, new TupleSchema()); @@ -123,4 +118,4 @@ public class MapColumnMetadata extends AbstractColumnMetadata { .setMode(mode) .build()); } -}
\ No newline at end of file +} diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MetadataUtils.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MetadataUtils.java index 8c8dea7b7..469c433d6 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MetadataUtils.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/MetadataUtils.java @@ -44,7 +44,7 @@ public class MetadataUtils { * @return the column metadata that wraps the field */ - public static AbstractColumnMetadata fromField(MaterializedField field) { + public static ColumnMetadata fromField(MaterializedField field) { MinorType type = field.getType().getMinorType(); switch (type) { case MAP: @@ -79,7 +79,7 @@ public class MetadataUtils { } } - public static AbstractColumnMetadata fromView(MaterializedField field) { + public static ColumnMetadata fromView(MaterializedField field) { if (field.getType().getMinorType() == MinorType.MAP) { return new MapColumnMetadata(field, null); } else { @@ -98,7 +98,7 @@ public class MetadataUtils { public static TupleSchema fromColumns(List<ColumnMetadata> columns) { TupleSchema tuple = new TupleSchema(); for (ColumnMetadata column : columns) { - tuple.add((AbstractColumnMetadata) column); + tuple.add(column); } return tuple; } @@ -149,11 +149,11 @@ public class MetadataUtils { } } - public static RepeatedListColumnMetadata newRepeatedList(String name, AbstractColumnMetadata child) { + public static RepeatedListColumnMetadata newRepeatedList(String name, ColumnMetadata child) { return new RepeatedListColumnMetadata(name, child); } - public static AbstractColumnMetadata newMapArray(String name, TupleMetadata schema) { + public static ColumnMetadata newMapArray(String name, TupleMetadata schema) { return new MapColumnMetadata(name, DataMode.REPEATED, (TupleSchema) schema); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/PrimitiveColumnMetadata.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/PrimitiveColumnMetadata.java index f0c25eb2f..dfbd4a9ee 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/PrimitiveColumnMetadata.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/PrimitiveColumnMetadata.java @@ -31,7 +31,7 @@ import org.apache.drill.exec.record.MaterializedField; public class PrimitiveColumnMetadata extends AbstractColumnMetadata { - protected int expectedWidth; + private int expectedWidth; public PrimitiveColumnMetadata(MaterializedField schema) { super(schema); @@ -71,7 +71,7 @@ public class PrimitiveColumnMetadata extends AbstractColumnMetadata { } @Override - public AbstractColumnMetadata copy() { + public ColumnMetadata copy() { return new PrimitiveColumnMetadata(this); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListBuilder.java index 233b4c20e..9bb6b8d5a 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListBuilder.java @@ -25,13 +25,23 @@ import org.apache.drill.common.types.TypeProtos.MinorType; * list as a chain of materialized fields and that is the pattern used * here. It would certainly be cleaner to have a single field, with the * number of dimensions as a property, but that is not how Drill evolved. + * <p/> + * Class can be created with and without parent container. + * In the first case, column is added to the parent container during creation + * and all <tt>resumeXXX</tt> methods return qualified parent container. + * In the second case column is created without parent container as standalone entity. + * All <tt>resumeXXX</tt> methods do not produce any action and return null. + * To access built column {@link #buildColumn()} should be used. */ - public class RepeatedListBuilder implements SchemaContainer { private final SchemaContainer parent; private final String name; - private AbstractColumnMetadata child; + private ColumnMetadata child; + + public RepeatedListBuilder(String name) { + this(null, name); + } public RepeatedListBuilder(SchemaContainer parent, String name) { this.parent = parent; @@ -57,12 +67,14 @@ public class RepeatedListBuilder implements SchemaContainer { return this; } - private RepeatedListColumnMetadata buildCol() { + public RepeatedListColumnMetadata buildColumn() { return MetadataUtils.newRepeatedList(name, child); } public void build() { - parent.addColumn(buildCol()); + if (parent != null) { + parent.addColumn(buildColumn()); + } } public RepeatedListBuilder resumeList() { @@ -86,7 +98,7 @@ public class RepeatedListBuilder implements SchemaContainer { } @Override - public void addColumn(AbstractColumnMetadata column) { + public void addColumn(ColumnMetadata column) { assert child == null; child = column; } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListColumnMetadata.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListColumnMetadata.java index 0f8ae763f..e677a0a23 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListColumnMetadata.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/RepeatedListColumnMetadata.java @@ -28,10 +28,9 @@ public class RepeatedListColumnMetadata extends AbstractColumnMetadata { /** * Indicates we don't know the number of dimensions. */ - public static final int UNKNOWN_DIMENSIONS = -1; - private AbstractColumnMetadata childSchema; + private ColumnMetadata childSchema; public RepeatedListColumnMetadata(MaterializedField field) { super(field); @@ -44,7 +43,7 @@ public class RepeatedListColumnMetadata extends AbstractColumnMetadata { } } - public RepeatedListColumnMetadata(String name, AbstractColumnMetadata childSchema) { + public RepeatedListColumnMetadata(String name, ColumnMetadata childSchema) { super(name, MinorType.LIST, DataMode.REPEATED); if (childSchema != null) { Preconditions.checkArgument(childSchema.isArray()); @@ -55,7 +54,7 @@ public class RepeatedListColumnMetadata extends AbstractColumnMetadata { public void childSchema(ColumnMetadata childMetadata) { Preconditions.checkState(childSchema == null); Preconditions.checkArgument(childMetadata.mode() == DataMode.REPEATED); - childSchema = (AbstractColumnMetadata) childMetadata; + childSchema = childMetadata; } @Override @@ -84,7 +83,7 @@ public class RepeatedListColumnMetadata extends AbstractColumnMetadata { } @Override - public AbstractColumnMetadata copy() { + public ColumnMetadata copy() { return new RepeatedListColumnMetadata(name, childSchema); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaBuilder.java index 4d326ea12..0c7c5243c 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaBuilder.java @@ -23,7 +23,6 @@ import org.apache.drill.common.types.TypeProtos.MinorType; import org.apache.drill.exec.record.BatchSchema; import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode; import org.apache.drill.exec.record.MaterializedField; -import org.apache.drill.exec.record.metadata.TupleMetadata; /** * Builder of a row set schema expressed as a list of materialized @@ -106,7 +105,7 @@ public class SchemaBuilder implements SchemaContainer { } @Override - public void addColumn(AbstractColumnMetadata column) { + public void addColumn(ColumnMetadata column) { tupleBuilder.addColumn(column); } @@ -174,10 +173,9 @@ public class SchemaBuilder implements SchemaContainer { * map. Building that map, using {@link MapBuilder#resumeSchema()}, * will return the original schema builder. * - * @param pathName the name of the map column + * @param name the name of the map column * @return a builder for the map */ - public MapBuilder addMap(String name) { return tupleBuilder.addMap(this, name); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaContainer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaContainer.java index ef93d1528..873da4c21 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaContainer.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/SchemaContainer.java @@ -21,7 +21,7 @@ package org.apache.drill.exec.record.metadata; * Magic that allows one schema builder to nest inside another * without needing to know the type of the parent. */ - interface SchemaContainer { - void addColumn(AbstractColumnMetadata column); + + void addColumn(ColumnMetadata column); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleBuilder.java index d4f51c090..d5ffebb8e 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleBuilder.java @@ -30,13 +30,12 @@ import org.apache.drill.exec.record.MaterializedField; * versions of the "add" methods return themselves to allow fluent * construction. */ +public class TupleBuilder implements SchemaContainer { -class TupleBuilder implements SchemaContainer { - - protected TupleSchema schema = new TupleSchema(); + private final TupleSchema schema = new TupleSchema(); @Override - public void addColumn(AbstractColumnMetadata column) { + public void addColumn(ColumnMetadata column) { schema.add(column); } @@ -80,11 +79,10 @@ class TupleBuilder implements SchemaContainer { add(name, type, DataMode.REPEATED); } - public void addDecimal(String name, MinorType type, DataMode mode, - int precision, int scale) { + public void addDecimal(String name, MinorType type, DataMode mode, int precision, int scale) { MaterializedField field = new ColumnBuilder(name, type) .setMode(mode) - .setScale(scale, precision) + .setPrecisionAndScale(precision, scale) .build(); add(field); } @@ -96,9 +94,7 @@ class TupleBuilder implements SchemaContainer { * @param name column name * @param type base data type * @param dims number of dimensions, 1 or more - * @return this builder */ - public void addArray(String name, MinorType type, int dims) { assert dims >= 1; if (dims == 1) { @@ -126,10 +122,10 @@ class TupleBuilder implements SchemaContainer { * map. Building that map, using {@link MapBuilder#resumeSchema()}, * will return the original schema builder. * - * @param pathName the name of the map column + * @param parent schema container + * @param name the name of the map column * @return a builder for the map */ - public MapBuilder addMap(SchemaContainer parent, String name) { return new MapBuilder(parent, name, DataMode.REQUIRED); } @@ -139,21 +135,17 @@ class TupleBuilder implements SchemaContainer { } public UnionBuilder addUnion(SchemaContainer parent, String name) { - return new UnionBuilder(parent, name, MinorType.UNION, DataMode.OPTIONAL); + return new UnionBuilder(parent, name, MinorType.UNION); } public UnionBuilder addList(SchemaContainer parent, String name) { - return new UnionBuilder(parent, name, MinorType.LIST, DataMode.REPEATED); + return new UnionBuilder(parent, name, MinorType.LIST); } public RepeatedListBuilder addRepeatedList(SchemaContainer parent, String name) { return new RepeatedListBuilder(parent, name); } - void finish(AbstractColumnMetadata col) { - schema.add(col); - } - public BatchSchema batchSchema(SelectionVectorMode svMode) { return schema.toBatchSchema(svMode); } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleSchema.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleSchema.java index 0c69dbc49..1196143a9 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleSchema.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/TupleSchema.java @@ -20,6 +20,7 @@ package org.apache.drill.exec.record.metadata; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; import org.apache.drill.exec.record.BatchSchema; import org.apache.drill.exec.record.MaterializedField; @@ -45,20 +46,20 @@ public class TupleSchema implements TupleMetadata { public TupleMetadata copy() { TupleMetadata tuple = new TupleSchema(); for (ColumnMetadata md : this) { - tuple.addColumn(((AbstractColumnMetadata) md).copy()); + tuple.addColumn(md.copy()); } return tuple; } @Override public ColumnMetadata add(MaterializedField field) { - AbstractColumnMetadata md = MetadataUtils.fromField(field); + ColumnMetadata md = MetadataUtils.fromField(field); add(md); return md; } public ColumnMetadata addView(MaterializedField field) { - AbstractColumnMetadata md = MetadataUtils.fromView(field); + ColumnMetadata md = MetadataUtils.fromView(field); add(md); return md; } @@ -70,15 +71,14 @@ public class TupleSchema implements TupleMetadata { * @param md the custom column metadata which must have the correct * index set (from {@link #size()} */ - - public void add(AbstractColumnMetadata md) { + public void add(ColumnMetadata md) { md.bind(this); nameSpace.add(md.name(), md); } @Override public int addColumn(ColumnMetadata column) { - add((AbstractColumnMetadata) column); + add(column); return size() - 1; } @@ -145,6 +145,11 @@ public class TupleSchema implements TupleMetadata { return cols; } + @Override + public List<ColumnMetadata> toMetadataList() { + return new ArrayList<>(nameSpace.entries()); + } + public BatchSchema toBatchSchema(SelectionVectorMode svMode) { return new BatchSchema(svMode, toFieldList()); } @@ -179,18 +184,16 @@ public class TupleSchema implements TupleMetadata { @Override public String toString() { - StringBuilder buf = new StringBuilder() + StringBuilder builder = new StringBuilder() .append("[") .append(getClass().getSimpleName()) .append(" "); - boolean first = true; - for (ColumnMetadata md : nameSpace) { - if (! first) { - buf.append(", "); - } - buf.append(md.toString()); - } - buf.append("]"); - return buf.toString(); + + builder.append(nameSpace.entries().stream() + .map(ColumnMetadata::toString) + .collect(Collectors.joining(", "))); + + builder.append("]"); + return builder.toString(); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/UnionBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/UnionBuilder.java index 98e30e152..eee9b3ad3 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/UnionBuilder.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/UnionBuilder.java @@ -24,20 +24,30 @@ import org.apache.drill.common.types.Types; /** * Builds unions or (non-repeated) lists (which implicitly contain * unions.) + * <p/> + * Class can be created with and without parent container. + * In the first case, column is added to the parent container during creation + * and all <tt>resumeXXX</tt> methods return qualified parent container. + * In the second case column is created without parent container as standalone entity. + * All <tt>resumeXXX</tt> methods do not produce any action and return null. + * To access built column {@link #buildColumn()} should be used. */ - public class UnionBuilder implements SchemaContainer { + private final SchemaContainer parent; private final String name; private final MinorType type; private final VariantSchema union; - public UnionBuilder(SchemaContainer parent, String name, - MinorType type, DataMode mode) { + public UnionBuilder(String name, MinorType type) { + this(null, name, type); + } + + public UnionBuilder(SchemaContainer parent, String name, MinorType type) { this.parent = parent; this.name = name; this.type = type; - union = new VariantSchema(); + this.union = new VariantSchema(); } private void checkType(MinorType type) { @@ -47,7 +57,7 @@ public class UnionBuilder implements SchemaContainer { } @Override - public void addColumn(AbstractColumnMetadata column) { + public void addColumn(ColumnMetadata column) { assert column.name().equals(Types.typeKey(column.type())); union.addType(column); } @@ -65,8 +75,7 @@ public class UnionBuilder implements SchemaContainer { public UnionBuilder addList() { checkType(MinorType.LIST); - return new UnionBuilder(this, Types.typeKey(MinorType.LIST), - MinorType.LIST, DataMode.OPTIONAL); + return new UnionBuilder(this, Types.typeKey(MinorType.LIST), MinorType.LIST); } public RepeatedListBuilder addRepeatedList() { @@ -74,27 +83,28 @@ public class UnionBuilder implements SchemaContainer { return new RepeatedListBuilder(this, Types.typeKey(MinorType.LIST)); } - private VariantColumnMetadata buildCol() { + public VariantColumnMetadata buildColumn() { return new VariantColumnMetadata(name, type, union); } - public SchemaBuilder resumeSchema() { - parent.addColumn(buildCol()); - return (SchemaBuilder) parent; + public void build() { + if (parent != null) { + parent.addColumn(buildColumn()); + } } - public UnionBuilder buildNested() { - parent.addColumn(buildCol()); - return (UnionBuilder) parent; + public SchemaBuilder resumeSchema() { + build(); + return (SchemaBuilder) parent; } public MapBuilder resumeMap() { - parent.addColumn(buildCol()); + build(); return (MapBuilder) parent; } public UnionBuilder resumeUnion() { - parent.addColumn(buildCol()); + build(); return (UnionBuilder) parent; } }
\ No newline at end of file diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantColumnMetadata.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantColumnMetadata.java index b41710791..c87e25b36 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantColumnMetadata.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantColumnMetadata.java @@ -32,7 +32,7 @@ public class VariantColumnMetadata extends AbstractColumnMetadata { super(schema); variantSchema = new VariantSchema(); variantSchema.bind(this); - List<MinorType> types = null; + List<MinorType> types; if (type() == MinorType.UNION) { types = schema.getType().getSubTypeList(); } else { @@ -104,7 +104,7 @@ public class VariantColumnMetadata extends AbstractColumnMetadata { } @Override - public AbstractColumnMetadata copy() { + public ColumnMetadata copy() { // TODO Auto-generated method stub assert false; return null; diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantSchema.java b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantSchema.java index 5c43bfc86..179ff12e5 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantSchema.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/record/metadata/VariantSchema.java @@ -38,7 +38,7 @@ public class VariantSchema implements VariantMetadata { this.parent = parent; } - public static AbstractColumnMetadata memberMetadata(MinorType type) { + public static ColumnMetadata memberMetadata(MinorType type) { String name = Types.typeKey(type); switch (type) { case LIST: @@ -64,7 +64,7 @@ public class VariantSchema implements VariantMetadata { @Override public ColumnMetadata addType(MinorType type) { checkType(type); - AbstractColumnMetadata dummyCol = memberMetadata(type); + ColumnMetadata dummyCol = memberMetadata(type); types.put(type, dummyCol); return dummyCol; } @@ -140,7 +140,7 @@ public class VariantSchema implements VariantMetadata { Preconditions.checkState(! isSimple); MinorType type = field.getType().getMinorType(); checkType(type); - AbstractColumnMetadata col; + ColumnMetadata col; switch (type) { case LIST: col = new VariantColumnMetadata(field); diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/rowSet/impl/TestResultSetLoaderUnions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/rowSet/impl/TestResultSetLoaderUnions.java index 175b81890..09c7eb096 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/rowSet/impl/TestResultSetLoaderUnions.java +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/rowSet/impl/TestResultSetLoaderUnions.java @@ -74,7 +74,6 @@ import org.apache.drill.shaded.guava.com.google.common.base.Charsets; * Most operators do not support them. But, JSON uses them, so they must * be made to work in the result set loader layer. */ - public class TestResultSetLoaderUnions extends SubOperatorTest { @Test @@ -219,7 +218,7 @@ public class TestResultSetLoaderUnions extends SubOperatorTest { // Make a bit bigger to overflow early. final int strLength = 600; - final byte value[] = new byte[strLength - 6]; + final byte[] value = new byte[strLength - 6]; Arrays.fill(value, (byte) 'X'); final String strValue = new String(value, Charsets.UTF_8); int count = 0; @@ -633,7 +632,7 @@ public class TestResultSetLoaderUnions extends SubOperatorTest { .addList("a") .addList() .addType(MinorType.INT) - .buildNested() + .resumeUnion() .resumeSchema() .buildSchema(); final RowSet expected = new RowSetBuilder(fixture.allocator(), expectedSchema) diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/record/TestTupleSchema.java b/exec/java-exec/src/test/java/org/apache/drill/exec/record/TestTupleSchema.java index 5e4bbe879..a59a6c1e4 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/exec/record/TestTupleSchema.java +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/record/TestTupleSchema.java @@ -51,7 +51,6 @@ import org.junit.Test; /** * Test the tuple and column metadata, including extended attributes. */ - public class TestTupleSchema extends SubOperatorTest { /** @@ -452,7 +451,7 @@ public class TestTupleSchema extends SubOperatorTest { @Test public void testNonEmptyRootTuple() { - TupleMetadata root = new TupleSchema(); + TupleSchema root = new TupleSchema(); MaterializedField fieldA = SchemaBuilder.columnSchema("a", MinorType.INT, DataMode.REQUIRED ); ColumnMetadata colA = root.add(fieldA); @@ -529,11 +528,11 @@ public class TestTupleSchema extends SubOperatorTest { // A tuple is equivalent to its copy. - assertTrue(root.isEquivalent(((TupleSchema) root).copy())); + assertTrue(root.isEquivalent(root.copy())); // And it is equivalent to the round trip to a batch schema. - BatchSchema batchSchema = ((TupleSchema) root).toBatchSchema(SelectionVectorMode.NONE); + BatchSchema batchSchema = root.toBatchSchema(SelectionVectorMode.NONE); assertTrue(root.isEquivalent(MetadataUtils.fromFields(batchSchema))); } @@ -549,7 +548,7 @@ public class TestTupleSchema extends SubOperatorTest { @Test public void testMapTupleFromMetadata() { - TupleMetadata root = new TupleSchema(); + TupleSchema root = new TupleSchema(); MaterializedField fieldA = SchemaBuilder.columnSchema("a", MinorType.MAP, DataMode.REQUIRED); ColumnMetadata colA = root.add(fieldA); @@ -606,7 +605,7 @@ public class TestTupleSchema extends SubOperatorTest { // Copying should be deep. - TupleMetadata root2 = ((TupleSchema) root).copy(); + TupleMetadata root2 = root.copy(); assertEquals(2, root2.metadata(0).mapSchema().metadata(0).mapSchema().metadata(0).mapSchema().size()); assert(root.isEquivalent(root2)); @@ -791,7 +790,7 @@ public class TestTupleSchema extends SubOperatorTest { .addList() .addType(MinorType.FLOAT8) .addType(MinorType.DECIMAL18) - .buildNested() + .resumeUnion() .resumeSchema() .buildSchema(); diff --git a/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/DummyWriterTest.java b/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/DummyWriterTest.java index 3b64c3f81..e353e6d86 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/DummyWriterTest.java +++ b/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/DummyWriterTest.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.List; import org.apache.drill.common.types.TypeProtos.MinorType; -import org.apache.drill.exec.record.metadata.AbstractColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata; import org.apache.drill.exec.record.metadata.SchemaBuilder; import org.apache.drill.exec.record.metadata.TupleMetadata; @@ -133,8 +132,8 @@ public class DummyWriterTest extends SubOperatorTest { // Mark schema as non-projected - ((AbstractColumnMetadata) schema.metadata("m1")).setProjected(false); - ((AbstractColumnMetadata) schema.metadata("m2")).setProjected(false); + schema.metadata("m1").setProjected(false); + schema.metadata("m2").setProjected(false); // Create the writers diff --git a/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestSchemaBuilder.java b/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestSchemaBuilder.java index a26ef4364..358330d2f 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestSchemaBuilder.java +++ b/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestSchemaBuilder.java @@ -26,12 +26,14 @@ import org.apache.drill.common.types.TypeProtos.DataMode; import org.apache.drill.common.types.TypeProtos.MinorType; import org.apache.drill.common.types.Types; import org.apache.drill.exec.record.MaterializedField; -import org.apache.drill.exec.record.metadata.AbstractColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata; import org.apache.drill.exec.record.metadata.ColumnMetadata.StructureType; +import org.apache.drill.exec.record.metadata.MapBuilder; import org.apache.drill.exec.record.metadata.MetadataUtils; +import org.apache.drill.exec.record.metadata.RepeatedListBuilder; import org.apache.drill.exec.record.metadata.SchemaBuilder; import org.apache.drill.exec.record.metadata.TupleMetadata; +import org.apache.drill.exec.record.metadata.UnionBuilder; import org.apache.drill.exec.record.metadata.VariantMetadata; import org.apache.drill.test.DrillTest; import org.junit.Test; @@ -41,7 +43,6 @@ import org.junit.Test; * lists and repeated lists. This test verifies that it assembles the various * pieces correctly for the various nesting combinations. */ - public class TestSchemaBuilder extends DrillTest { @Test @@ -81,7 +82,7 @@ public class TestSchemaBuilder extends DrillTest { MaterializedField aField = MaterializedField.create("a", Types.optional(MinorType.VARCHAR)); - AbstractColumnMetadata bCol = MetadataUtils.newScalar("b", + ColumnMetadata bCol = MetadataUtils.newScalar("b", MinorType.INT, DataMode.REQUIRED); SchemaBuilder builder = new SchemaBuilder() @@ -596,4 +597,82 @@ public class TestSchemaBuilder extends DrillTest { assertEquals(MinorType.VARCHAR, child.type()); assertEquals(DataMode.REPEATED, child.mode()); } + + @Test + public void testStandaloneMapBuilder() { + ColumnMetadata columnMetadata= new MapBuilder("m1", DataMode.OPTIONAL) + .addNullable("b", MinorType.BIGINT) + .addMap("m2") + .addNullable("v", MinorType.VARCHAR) + .resumeMap() + .buildColumn(); + + assertTrue(columnMetadata.isMap()); + assertTrue(columnMetadata.isNullable()); + assertEquals("m1", columnMetadata.name()); + + TupleMetadata schema = columnMetadata.mapSchema(); + + ColumnMetadata col0 = schema.metadata(0); + assertEquals("b", col0.name()); + assertEquals(MinorType.BIGINT, col0.type()); + assertTrue(col0.isNullable()); + + ColumnMetadata col1 = schema.metadata(1); + assertEquals("m2", col1.name()); + assertTrue(col1.isMap()); + assertFalse(col1.isNullable()); + + ColumnMetadata child = col1.mapSchema().metadata(0); + assertEquals("v", child.name()); + assertEquals(MinorType.VARCHAR, child.type()); + assertTrue(child.isNullable()); + } + + @Test + public void testStandaloneRepeatedListBuilder() { + ColumnMetadata columnMetadata = new RepeatedListBuilder("l") + .addMapArray() + .addNullable("v", MinorType.VARCHAR) + .add("i", MinorType.INT) + .resumeList() + .buildColumn(); + + assertTrue(columnMetadata.isArray()); + assertEquals("l", columnMetadata.name()); + assertEquals(MinorType.LIST, columnMetadata.type()); + + ColumnMetadata child = columnMetadata.childSchema(); + assertEquals("l", child.name()); + assertTrue(child.isArray()); + assertTrue(child.isMap()); + + TupleMetadata mapSchema = child.mapSchema(); + + ColumnMetadata col0 = mapSchema.metadata(0); + assertEquals("v", col0.name()); + assertEquals(MinorType.VARCHAR, col0.type()); + assertTrue(col0.isNullable()); + + ColumnMetadata col1 = mapSchema.metadata(1); + assertEquals("i", col1.name()); + assertEquals(MinorType.INT, col1.type()); + assertFalse(col1.isNullable()); + } + + @Test + public void testStandaloneUnionBuilder() { + ColumnMetadata columnMetadata = new UnionBuilder("u", MinorType.VARCHAR) + .addType(MinorType.INT) + .addType(MinorType.VARCHAR) + .buildColumn(); + + assertEquals("u", columnMetadata.name()); + assertTrue(columnMetadata.isVariant()); + + VariantMetadata variantMetadata = columnMetadata.variantSchema(); + assertTrue(variantMetadata.hasType(MinorType.INT)); + assertTrue(variantMetadata.hasType(MinorType.VARCHAR)); + } + } diff --git a/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestVariantAccessors.java b/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestVariantAccessors.java index 10c9bd7a5..3d017c31f 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestVariantAccessors.java +++ b/exec/java-exec/src/test/java/org/apache/drill/test/rowSet/test/TestVariantAccessors.java @@ -67,7 +67,6 @@ import org.junit.Test; * result set builder. It does not, however, work in the Project * and other operators. Some assembly required for future use.) */ - public class TestVariantAccessors extends SubOperatorTest { @Test @@ -84,7 +83,7 @@ public class TestVariantAccessors extends SubOperatorTest { .resumeUnion() .addList() .addType(MinorType.VARCHAR) - .buildNested() + .resumeUnion() .resumeSchema() .buildSchema(); @@ -216,7 +215,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.INT); + assertSame(vr.dataType(), MinorType.INT); assertSame(intReader, vr.scalar()); assertNotNull(vr.member()); assertSame(vr.scalar(), vr.member().scalar()); @@ -229,7 +228,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.VARCHAR); + assertSame(vr.dataType(), MinorType.VARCHAR); assertSame(strReader, vr.scalar()); assertFalse(strReader.isNull()); assertEquals("fred", strReader.getString()); @@ -250,7 +249,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.FLOAT8); + assertSame(vr.dataType(), MinorType.FLOAT8); assertSame(floatReader, vr.scalar()); assertFalse(floatReader.isNull()); assertEquals(123.45, vr.scalar().getDouble(), 0.001); @@ -261,7 +260,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.INT); + assertSame(vr.dataType(), MinorType.INT); assertTrue(intReader.isNull()); // Int 20 @@ -321,7 +320,7 @@ public class TestVariantAccessors extends SubOperatorTest { .addList() .addType(MinorType.FLOAT8) - .buildNested() + .resumeUnion() .resumeSchema() .buildSchema(); @@ -1054,7 +1053,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.INT); + assertSame(vr.dataType(), MinorType.INT); assertSame(vr.scalar(MinorType.INT), vr.scalar()); assertNotNull(vr.member()); assertSame(vr.scalar(), vr.member().scalar()); @@ -1062,7 +1061,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.VARCHAR); + assertSame(vr.dataType(), MinorType.VARCHAR); assertSame(vr.scalar(MinorType.VARCHAR), vr.scalar()); assertEquals("fred", vr.scalar().getString()); @@ -1073,7 +1072,7 @@ public class TestVariantAccessors extends SubOperatorTest { assertTrue(reader.next()); assertFalse(vr.isNull()); - assertTrue(vr.dataType() == MinorType.FLOAT8); + assertSame(vr.dataType(), MinorType.FLOAT8); assertSame(vr.scalar(MinorType.FLOAT8), vr.scalar()); assertEquals(123.45, vr.scalar().getDouble(), 0.001); @@ -1093,7 +1092,7 @@ public class TestVariantAccessors extends SubOperatorTest { .addType(MinorType.INT) .addList() .addType(MinorType.VARCHAR) - .buildNested() + .resumeUnion() .resumeSchema() .buildSchema(); diff --git a/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/ColumnMetadata.java b/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/ColumnMetadata.java index f3aa877b7..0e0fb4920 100644 --- a/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/ColumnMetadata.java +++ b/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/ColumnMetadata.java @@ -26,7 +26,6 @@ import org.apache.drill.exec.record.MaterializedField; * Metadata description of a column including names, types and structure * information. */ - public interface ColumnMetadata { /** @@ -203,4 +202,8 @@ public interface ColumnMetadata { int precision(); int scale(); + + void bind(TupleMetadata parentTuple); + + ColumnMetadata copy(); } diff --git a/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/TupleMetadata.java b/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/TupleMetadata.java index a65c9f2e5..cd21fa78b 100644 --- a/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/TupleMetadata.java +++ b/exec/vector/src/main/java/org/apache/drill/exec/record/metadata/TupleMetadata.java @@ -43,13 +43,12 @@ import org.apache.drill.exec.record.MaterializedField; * In the future, this structure will also gather metadata useful * for vector processing such as expected widths and so on. */ - public interface TupleMetadata extends Iterable<ColumnMetadata> { /** * Add a new column to the schema. * - * @param columnSchema + * @param field materialized field * @return the index of the new column */ ColumnMetadata add(MaterializedField field); @@ -73,10 +72,17 @@ public interface TupleMetadata extends Iterable<ColumnMetadata> { * @return a list of the top-level fields. Maps contain their child * fields */ - List<MaterializedField> toFieldList(); /** + * Returns schema as list of <tt>ColumnMetadata</tt> objects + * which can be used to create JSON schema object. + * + * @return a list of metadata for each column + */ + List<ColumnMetadata> toMetadataList(); + + /** * Full name of the column. Note: this name cannot be used to look up * the column because of ambiguity. The name "a.b.c" may mean a single * column with that name, or may mean maps "a", and "b" with column "c", |