static void toJson(Types.MapType map, JsonGenerator generator) throws IOException { generator.writeStartObject(); generator.writeStringField(TYPE, MAP); generator.writeNumberField(KEY_ID, map.keyId()); generator.writeFieldName(KEY); toJson(map.keyType(), generator); generator.writeNumberField(VALUE_ID, map.valueId()); generator.writeFieldName(VALUE); toJson(map.valueType(), generator); generator.writeBooleanField(VALUE_REQUIRED, !map.isValueOptional()); generator.writeEndObject(); }
@Override public Type map(Types.MapType map, Type kResult, Type vResult) { // if any updates are intended for the key, throw an exception int keyId = map.fields().get(0).fieldId(); if (deletes.contains(keyId)) { throw new IllegalArgumentException("Cannot delete map keys: " + map); } else if (updates.containsKey(keyId)) { throw new IllegalArgumentException("Cannot update map keys: " + map); } else if (adds.containsKey(keyId)) { throw new IllegalArgumentException("Cannot add fields to map keys: " + map); } else if (!map.keyType().equals(kResult)) { throw new IllegalArgumentException("Cannot alter map keys: " + map); } // use field to apply updates to the value Type valueResult = field(map.fields().get(1), vResult); if (valueResult == null) { throw new IllegalArgumentException("Cannot delete value type from map: " + map); } if (map.valueType() == valueResult) { return map; } if (map.isValueOptional()) { return Types.MapType.ofOptional(map.keyId(), map.valueId(), map.keyType(), valueResult); } else { return Types.MapType.ofRequired(map.keyId(), map.valueId(), map.keyType(), valueResult); } }
@Override public Type map(Types.MapType map, Supplier<Type> keyTypeFuture, Supplier<Type> valueTypeFuture) { Preconditions.checkArgument(sourceType.isMapType(), "Not a map: " + sourceType); Types.MapType sourceMap = sourceType.asMapType(); int sourceKeyId = sourceMap.keyId(); int sourceValueId = sourceMap.valueId(); try { this.sourceType = sourceMap.keyType(); Type keyType = keyTypeFuture.get(); this.sourceType = sourceMap.valueType(); Type valueType = valueTypeFuture.get(); if (map.isValueOptional()) { return Types.MapType.ofOptional(sourceKeyId, sourceValueId, keyType, valueType); } else { return Types.MapType.ofRequired(sourceKeyId, sourceValueId, keyType, valueType); } } finally { this.sourceType = sourceMap; } }
TypeDescription key = toOrc(map.keyId(),map.keyType(), columnIds); result = TypeDescription.createMap(key, toOrc(map.valueId(), map.valueType(), columnIds));
T valueResult; visitor.fieldIds.push(map.keyId()); try { keyResult = visit(map.keyType(), visitor);
@Override public Type map(Types.MapType map, Supplier<Type> keyResult, Supplier<Type> valueResult) { Preconditions.checkArgument(current instanceof MapType, "Not a map: %s", current); MapType m = (MapType) current; Preconditions.checkArgument(m.valueContainsNull() || !map.isValueOptional(), "Cannot project a map of optional values as required values: %s", map); Preconditions.checkArgument(StringType.class.isInstance(m.keyType()), "Invalid map key type (not string): %s", m.keyType()); this.current = m.valueType(); try { Type valueType = valueResult.get(); if (map.valueType() == valueType) { return map; } if (map.isValueOptional()) { return Types.MapType.ofOptional(map.keyId(), map.valueId(), map.keyType(), valueType); } else { return Types.MapType.ofRequired(map.keyId(), map.valueId(), map.keyType(), valueType); } } finally { this.current = m; } }
@Override public Type map(Types.MapType map, Supplier<Type> keyResult, Supplier<Type> valueResult) { Preconditions.checkArgument(current instanceof MapType, "Not a map: %s", current); MapType m = (MapType) current; Preconditions.checkArgument(m.valueContainsNull() || !map.isValueOptional(), "Cannot project a map of optional values as required values: %s", map); this.current = m.valueType(); try { Type valueType = valueResult.get(); if (map.valueType() == valueType) { return map; } if (map.isValueOptional()) { return Types.MapType.ofOptional(map.keyId(), map.valueId(), map.keyType(), valueType); } else { return Types.MapType.ofRequired(map.keyId(), map.valueId(), map.keyType(), valueType); } } finally { this.current = m; } }
@Override public Type map(Types.MapType map, Supplier<Type> keyTypeFuture, Supplier<Type> valueTypeFuture) { Preconditions.checkArgument(sourceType.isMapType(), "Not a map: " + sourceType); Types.MapType sourceMap = sourceType.asMapType(); try { this.sourceType = sourceMap.keyType(); Type keyType = keyTypeFuture.get(); this.sourceType = sourceMap.valueType(); Type valueType = valueTypeFuture.get(); if (map.keyType() == keyType && map.valueType() == valueType) { return map; } if (map.isValueOptional()) { return Types.MapType.ofOptional(map.keyId(), map.valueId(), keyType, valueType); } else { return Types.MapType.ofRequired(map.keyId(), map.valueId(), keyType, valueType); } } finally { this.sourceType = sourceMap; } }
@Override public Schema map(Types.MapType map, Schema keySchema, Schema valueSchema) { Schema mapSchema = results.get(map); if (mapSchema != null) { return mapSchema; } if (keySchema.getType() == Schema.Type.STRING) { // if the map has string keys, use Avro's map type mapSchema = Schema.createMap( map.isValueOptional() ? toOption(valueSchema) : valueSchema); mapSchema.addProp(AvroSchemaUtil.KEY_ID_PROP, map.keyId()); mapSchema.addProp(AvroSchemaUtil.VALUE_ID_PROP, map.valueId()); } else { mapSchema = AvroSchemaUtil.createMap(map.keyId(), keySchema, map.valueId(), map.isValueOptional() ? toOption(valueSchema) : valueSchema); } results.put(map, mapSchema); return mapSchema; }
@Override public Type map(Types.MapType map, Type ignored, Type valueResult) { if (selected.contains(map.valueId())) { return map; } else if (valueResult != null) { if (map.valueType() == valueResult) { return map; } else if (map.isValueOptional()) { return Types.MapType.ofOptional(map.keyId(), map.valueId(), map.keyType(), valueResult); } else { return Types.MapType.ofRequired(map.keyId(), map.valueId(), map.keyType(), valueResult); } } else if (selected.contains(map.keyId())) { // right now, maps can't be selected without values return map; } return null; }