Chaemin Lee created KAFKA-20201:
-----------------------------------
Summary: Connect Transforms: SchemaUtil.copySchemaBasics(Schema)
does not preserve keySchema and valueSchema for MAP type
Key: KAFKA-20201
URL: https://issues.apache.org/jira/browse/KAFKA-20201
Project: Kafka
Issue Type: Bug
Components: connect
Affects Versions: 3.1.0
Reporter: Chaemin Lee
Assignee: Chaemin Lee
*Description:*
SchemaUtil.copySchemaBasics(Schema) in the connect/transforms module does not
handle Schema.Type.MAP correctly. When a MAP schema is passed, it falls through
to new SchemaBuilder(source.type()), which leaves both keySchema and
valueSchema as null. Since SchemaBuilder has no public setters for these
fields, the resulting builder is irrecoverably broken.
This was introduced in KAFKA-12305, which added special handling for ARRAY but
overlooked MAP. The same issue applies — MAP requires keySchema and valueSchema
to be set via SchemaBuilder.map(), just as ARRAY requires valueSchema to be set
via SchemaBuilder.array().
Currently no callers pass a MAP schema to this method, so there is no runtime
failure. However, the method is public and accepts any Schema, so it is a
latent bug that will surface if any new transform or external code passes a MAP
schema.
*Steps to Reproduce:*
Call SchemaUtil.copySchemaBasics() with a MAP schema:
{code:java}
Schema mapSchema = SchemaBuilder.map(Schema.STRING_SCHEMA,
Schema.INT32_SCHEMA).build();
SchemaBuilder copied = SchemaUtil.copySchemaBasics(mapSchema);
// copied.keySchema() == null (expected: STRING)
// copied.valueSchema() == null (expected: INT32){code}
*Expected Behavior:*
The returned SchemaBuilder should preserve keySchema and valueSchema from the
source MAP schema.
*Suggested Fix:*
Add a MAP type branch to the existing if statement in copySchemaBasics(Schema):
{code:java}
public static SchemaBuilder copySchemaBasics(Schema source) {
SchemaBuilder builder;
if (source.type() == Schema.Type.ARRAY) {
builder = SchemaBuilder.array(source.valueSchema());
} else if (source.type() == Schema.Type.MAP) {
builder = SchemaBuilder.map(source.keySchema(), source.valueSchema());
} else {
builder = new SchemaBuilder(source.type());
}
return copySchemaBasics(source, builder);
}
{code}
*Comment:*
This issue was self-assigned to me. I'd like to work on this — please let me
know if there are any concerns.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)