@Test public void testFixedType() { // Build a required uint field definition MajorType.Builder typeBuilder = MajorType.newBuilder(); FieldDef.Builder defBuilder = FieldDef.newBuilder(); typeBuilder.setMinorType(MinorType.UINT4).setMode(DataMode.REQUIRED).setWidth(4); defBuilder.setMajorType(typeBuilder.build()); MaterializedField field = MaterializedField.create(defBuilder.build()); // Create a new value vector for 1024 integers UInt4Vector v = new UInt4Vector(field, allocator); UInt4Vector.Mutator m = v.getMutator(); v.allocateNew(1024); // Put and set a few values m.set(0, 100); m.set(1, 101); m.set(100, 102); m.set(1022, 103); m.set(1023, 104); assertEquals(100, v.getAccessor().get(0)); assertEquals(101, v.getAccessor().get(1)); assertEquals(102, v.getAccessor().get(100)); assertEquals(103, v.getAccessor().get(1022)); assertEquals(104, v.getAccessor().get(1023)); // Ensure unallocated space returns 0 assertEquals(0, v.getAccessor().get(3)); }
// The output table's column names always follow the left table, // where the output type is chosen based on DRILL's implicit casting rules private void inferOutputFields() { outputFields = Lists.newArrayList(); leftSchema = leftSide.getRecordBatch().getSchema(); rightSchema = rightSide.getRecordBatch().getSchema(); Iterator<MaterializedField> leftIter = leftSchema.iterator(); Iterator<MaterializedField> rightIter = rightSchema.iterator(); int index = 1; while (leftIter.hasNext() && rightIter.hasNext()) { MaterializedField leftField = leftIter.next(); MaterializedField rightField = rightIter.next(); if (hasSameTypeAndMode(leftField, rightField)) { outputFields.add(MaterializedField.create(leftField.getPath(), leftField.getType())); } else { // If the output type is not the same, // cast the column of one of the table to a data type which is the Least Restrictive MinorType outputMinorType; if (leftField.getType().getMinorType() == rightField.getType().getMinorType()) { outputMinorType = leftField.getType().getMinorType(); } else { List<MinorType> types = Lists.newLinkedList(); types.add(leftField.getType().getMinorType()); types.add(rightField.getType().getMinorType()); outputMinorType = TypeCastRules.getLeastRestrictiveType(types); if (outputMinorType == null) { throw new DrillRuntimeException( "Type mismatch between " + leftField.getType().getMinorType().toString() + " on the left side and " + rightField.getType().getMinorType().toString() + " on the right side in column " + index + " of UNION ALL"); } } // The output data mode should be as flexible as the more flexible one from the two input // tables List<DataMode> dataModes = Lists.newLinkedList(); dataModes.add(leftField.getType().getMode()); dataModes.add(rightField.getType().getMode()); DataMode dataMode = TypeCastRules.getLeastRestrictiveDataMode(dataModes); MajorType.Builder builder = MajorType.newBuilder(); builder.setMinorType(outputMinorType); builder.setMode(dataMode); outputFields.add(MaterializedField.create(leftField.getPath(), builder.build())); } ++index; } assert !leftIter.hasNext() && !rightIter.hasNext() : "Mis-match of column count should have been detected when validating sqlNode at planning"; }
@Test public void testNullableFloat() { // Build an optional float field definition MajorType.Builder typeBuilder = MajorType.newBuilder(); FieldDef.Builder defBuilder = FieldDef.newBuilder(); typeBuilder.setMinorType(MinorType.FLOAT4).setMode(DataMode.OPTIONAL).setWidth(4); defBuilder.setMajorType(typeBuilder.build()); MaterializedField field = MaterializedField.create(defBuilder.build()); // Create a new value vector for 1024 integers NullableFloat4Vector v = (NullableFloat4Vector) TypeHelper.getNewVector(field, allocator); NullableFloat4Vector.Mutator m = v.getMutator(); v.allocateNew(1024); // Put and set a few values m.set(0, 100.1f); m.set(1, 101.2f); m.set(100, 102.3f); m.set(1022, 103.4f); m.set(1023, 104.5f); assertEquals(100.1f, v.getAccessor().get(0), 0); assertEquals(101.2f, v.getAccessor().get(1), 0); assertEquals(102.3f, v.getAccessor().get(100), 0); assertEquals(103.4f, v.getAccessor().get(1022), 0); assertEquals(104.5f, v.getAccessor().get(1023), 0); // Ensure null values throw { boolean b = false; try { v.getAccessor().get(3); } catch (AssertionError e) { b = true; } finally { if (!b) { assert false; } } } v.allocateNew(2048); { boolean b = false; try { v.getAccessor().get(0); } catch (AssertionError e) { b = true; } finally { if (!b) { assert false; } } } }
/** * Returns the merger of schemas. The merged schema will include the union all columns. If there * is a type conflict between columns with the same schemapath but different types, the merged * schema will contain a Union type. * * @param schemas * @return */ public static BatchSchema mergeSchemas(BatchSchema... schemas) { Map<SchemaPath, Set<MinorType>> typeSetMap = Maps.newLinkedHashMap(); for (BatchSchema s : schemas) { for (MaterializedField field : s) { SchemaPath path = field.getPath(); Set<MinorType> currentTypes = typeSetMap.get(path); if (currentTypes == null) { currentTypes = Sets.newHashSet(); typeSetMap.put(path, currentTypes); } MinorType newType = field.getType().getMinorType(); if (newType == MinorType.MAP || newType == MinorType.LIST) { throw new RuntimeException( "Schema change not currently supported for schemas with complex types"); } if (newType == MinorType.UNION) { for (MinorType subType : field.getType().getSubTypeList()) { currentTypes.add(subType); } } else { currentTypes.add(newType); } } } List<MaterializedField> fields = Lists.newArrayList(); for (SchemaPath path : typeSetMap.keySet()) { Set<MinorType> types = typeSetMap.get(path); if (types.size() > 1) { MajorType.Builder builder = MajorType.newBuilder().setMinorType(MinorType.UNION).setMode(DataMode.OPTIONAL); for (MinorType t : types) { builder.addSubType(t); } MaterializedField field = MaterializedField.create(path, builder.build()); fields.add(field); } else { MaterializedField field = MaterializedField.create(path, Types.optional(types.iterator().next())); fields.add(field); } } SchemaBuilder schemaBuilder = new SchemaBuilder(); BatchSchema s = schemaBuilder .addFields(fields) .setSelectionVectorMode(schemas[0].getSelectionVectorMode()) .build(); return s; }
@Test public void testBitVector() { // Build a required boolean field definition MajorType.Builder typeBuilder = MajorType.newBuilder(); FieldDef.Builder defBuilder = FieldDef.newBuilder(); typeBuilder.setMinorType(MinorType.BIT).setMode(DataMode.REQUIRED).setWidth(4); defBuilder.setMajorType(typeBuilder.build()); MaterializedField field = MaterializedField.create(defBuilder.build()); // Create a new value vector for 1024 integers BitVector v = new BitVector(field, allocator); BitVector.Mutator m = v.getMutator(); v.allocateNew(1024); // Put and set a few values m.set(0, 1); m.set(1, 0); m.set(100, 0); m.set(1022, 1); assertEquals(1, v.getAccessor().get(0)); assertEquals(0, v.getAccessor().get(1)); assertEquals(0, v.getAccessor().get(100)); assertEquals(1, v.getAccessor().get(1022)); // test setting the same value twice m.set(0, 1); m.set(0, 1); m.set(1, 0); m.set(1, 0); assertEquals(1, v.getAccessor().get(0)); assertEquals(0, v.getAccessor().get(1)); // test toggling the values m.set(0, 0); m.set(1, 1); assertEquals(0, v.getAccessor().get(0)); assertEquals(1, v.getAccessor().get(1)); // Ensure unallocated space returns 0 assertEquals(0, v.getAccessor().get(3)); }
@JsonIgnore public MajorType getMajorType() { MajorType.Builder b = MajorType.newBuilder(); b.setMode(mode); b.setMinorType(minorType); if (precision != null) b.setPrecision(precision); if (width != null) b.setWidth(width); if (scale != null) b.setScale(scale); return b.build(); }
@Test public void testNullableVarLen2() { // Build an optional varchar field definition MajorType.Builder typeBuilder = MajorType.newBuilder(); FieldDef.Builder defBuilder = FieldDef.newBuilder(); typeBuilder.setMinorType(MinorType.VARCHAR).setMode(DataMode.OPTIONAL).setWidth(2); defBuilder.setMajorType(typeBuilder.build()); MaterializedField field = MaterializedField.create(defBuilder.build()); // Create a new value vector for 1024 integers NullableVarCharVector v = new NullableVarCharVector(field, allocator); NullableVarCharVector.Mutator m = v.getMutator(); v.allocateNew(1024 * 10, 1024); // Create and set 3 sample strings String str1 = new String("AAAAA1"); String str2 = new String("BBBBBBBBB2"); String str3 = new String("CCCC3"); m.set(0, str1.getBytes(Charset.forName("UTF-8"))); m.set(1, str2.getBytes(Charset.forName("UTF-8"))); m.set(2, str3.getBytes(Charset.forName("UTF-8"))); // Check the sample strings assertEquals(str1, new String(v.getAccessor().get(0), Charset.forName("UTF-8"))); assertEquals(str2, new String(v.getAccessor().get(1), Charset.forName("UTF-8"))); assertEquals(str3, new String(v.getAccessor().get(2), Charset.forName("UTF-8"))); // Ensure null value throws boolean b = false; try { v.getAccessor().get(3); } catch (AssertionError e) { b = true; } finally { if (!b) { assert false; } } }
@Test public void testNullableFixedType() { // Build an optional uint field definition MajorType.Builder typeBuilder = MajorType.newBuilder(); FieldDef.Builder defBuilder = FieldDef.newBuilder(); typeBuilder.setMinorType(MinorType.UINT4).setMode(DataMode.OPTIONAL).setWidth(4); defBuilder.setMajorType(typeBuilder.build()); MaterializedField field = MaterializedField.create(defBuilder.build()); // Create a new value vector for 1024 integers NullableUInt4Vector v = new NullableUInt4Vector(field, allocator); NullableUInt4Vector.Mutator m = v.getMutator(); v.allocateNew(1024); // Put and set a few values m.set(0, 100); m.set(1, 101); m.set(100, 102); m.set(1022, 103); m.set(1023, 104); assertEquals(100, v.getAccessor().get(0)); assertEquals(101, v.getAccessor().get(1)); assertEquals(102, v.getAccessor().get(100)); assertEquals(103, v.getAccessor().get(1022)); assertEquals(104, v.getAccessor().get(1023)); // Ensure null values throw { boolean b = false; try { v.getAccessor().get(3); } catch (AssertionError e) { b = true; } finally { if (!b) { assert false; } } } v.allocateNew(2048); { boolean b = false; try { v.getAccessor().get(0); } catch (AssertionError e) { b = true; } finally { if (!b) { assert false; } } } m.set(0, 100); m.set(1, 101); m.set(100, 102); m.set(1022, 103); m.set(1023, 104); assertEquals(100, v.getAccessor().get(0)); assertEquals(101, v.getAccessor().get(1)); assertEquals(102, v.getAccessor().get(100)); assertEquals(103, v.getAccessor().get(1022)); assertEquals(104, v.getAccessor().get(1023)); // Ensure null values throw { boolean b = false; try { v.getAccessor().get(3); } catch (AssertionError e) { b = true; } finally { if (!b) { assert false; } } } }