Skip to content

Commit db4a5ee

Browse files
committed
address comments
1 parent 5a0689a commit db4a5ee

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

coral-schema/src/main/java/com/linkedin/coral/schema/avro/ToLowercaseSchemaVisitor.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -89,29 +89,30 @@ private Schema.Field lowercaseField(Schema.Field field, Schema schema) {
8989
* Recursively lowercases field names within default values based on the schema structure.
9090
* This handles complex types like records, maps, and arrays where field names appear in default values.
9191
*
92-
* @param defaultValue The original default value (can be null, primitive, Map, List, etc.)
93-
* @param schema The schema that describes the structure of this default value
92+
* @param fieldDefaultValue The original default value for a field (can be null, primitive, Map, List, etc.)
93+
* @param fieldSchema The schema that describes the structure of this field's default value
9494
* @return The default value with all field names lowercased
9595
*/
9696
@SuppressWarnings("unchecked")
97-
private Object lowercaseDefaultValue(Object defaultValue, Schema schema) {
98-
if (defaultValue == null) {
97+
private Object lowercaseDefaultValue(Object fieldDefaultValue, Schema fieldSchema) {
98+
if (fieldDefaultValue == null) {
9999
return null;
100100
}
101101

102-
Schema actualSchema = schema;
103-
104-
// Handle union types - get the actual schema based on the default value type
105-
if (schema.getType() == Schema.Type.UNION) {
106-
// For unions, the default value corresponds to the first type in the union
107-
actualSchema = schema.getTypes().get(0);
102+
// Handle union types to get the actual schema for processing the default value
103+
// For nullable unions, extract the non-null type since we know defaultValue is non-null
104+
Schema actualSchema = SchemaUtilities.extractIfOption(fieldSchema);
105+
// If still a union after extracting nullable option (i.e., multi-type non-nullable union),
106+
// the default value corresponds to the first type per Avro specification
107+
if (actualSchema.getType() == Schema.Type.UNION) {
108+
actualSchema = actualSchema.getTypes().get(0);
108109
}
109110

110111
switch (actualSchema.getType()) {
111112
case RECORD:
112113
// For records, the default value can be either a Map or GenericData.Record
113-
if (defaultValue instanceof GenericData.Record) {
114-
GenericData.Record record = (GenericData.Record) defaultValue;
114+
if (fieldDefaultValue instanceof GenericData.Record) {
115+
GenericData.Record record = (GenericData.Record) fieldDefaultValue;
115116
return lowercaseRecordDefaultValue(actualSchema, lowercasedFieldName -> {
116117
// Find the matching field in the original record's schema (case-insensitive)
117118
Schema.Field originalField = record.getSchema().getField(lowercasedFieldName);
@@ -125,21 +126,21 @@ private Object lowercaseDefaultValue(Object defaultValue, Schema schema) {
125126
}
126127
return originalField != null ? record.get(originalField.pos()) : null;
127128
});
128-
} else if (defaultValue instanceof Map) {
129-
Map<?, ?> recordMap = (Map<?, ?>) defaultValue;
129+
} else if (fieldDefaultValue instanceof Map) {
130+
Map<?, ?> recordMap = (Map<?, ?>) fieldDefaultValue;
130131
return lowercaseRecordDefaultValue(actualSchema, lowercasedFieldName -> {
131132
// Find the matching key in the original map (case-insensitive)
132133
String matchingKey = findMatchingKeyForLowercased(recordMap, lowercasedFieldName);
133134
return matchingKey != null ? recordMap.get(matchingKey) : null;
134135
});
135136
}
136137
// If neither Map nor GenericData.Record, return as-is
137-
return defaultValue;
138+
return fieldDefaultValue;
138139

139140
case MAP:
140141
// For maps, lowercase the keys and recursively process values
141-
if (defaultValue instanceof Map) {
142-
Map<?, ?> mapValue = (Map<?, ?>) defaultValue; // Use wildcards to handle Utf8 keys
142+
if (fieldDefaultValue instanceof Map) {
143+
Map<?, ?> mapValue = (Map<?, ?>) fieldDefaultValue; // Use wildcards to handle Utf8 keys
143144
Map<String, Object> lowercasedMap = new LinkedHashMap<>();
144145
Schema valueSchema = actualSchema.getValueType();
145146

@@ -151,19 +152,19 @@ private Object lowercaseDefaultValue(Object defaultValue, Schema schema) {
151152
}
152153
return lowercasedMap;
153154
}
154-
return defaultValue;
155+
return fieldDefaultValue;
155156

156157
case ARRAY:
157158
// For arrays, recursively process each element
158-
if (defaultValue instanceof List) {
159-
List<Object> arrayValue = (List<Object>) defaultValue;
159+
if (fieldDefaultValue instanceof List) {
160+
List<Object> arrayValue = (List<Object>) fieldDefaultValue;
160161
Schema elementSchema = actualSchema.getElementType();
161162

162163
return arrayValue.stream()
163164
.map(element -> lowercaseDefaultValue(element, elementSchema))
164165
.collect(Collectors.toList());
165166
}
166-
return defaultValue;
167+
return fieldDefaultValue;
167168

168169
case NULL:
169170
case BOOLEAN:
@@ -177,7 +178,7 @@ private Object lowercaseDefaultValue(Object defaultValue, Schema schema) {
177178
case FIXED:
178179
default:
179180
// Primitive types and others: return as-is
180-
return defaultValue;
181+
return fieldDefaultValue;
181182
}
182183
}
183184

0 commit comments

Comments
 (0)