Skip to content

fix: clustered segment catalog spec complex handling - #19842

Open
clintropolis wants to merge 2 commits into
apache:masterfrom
clintropolis:fix-catalog-clustered-segments-complex-types
Open

fix: clustered segment catalog spec complex handling#19842
clintropolis wants to merge 2 commits into
apache:masterfrom
clintropolis:fix-catalog-clustered-segments-complex-types

Conversation

@clintropolis

Copy link
Copy Markdown
Member

Description

ClusteredValueGroupsBaseTableMetadata now checks for a complex DimensionHandler from a new method DimensionHandlerUtils#getComplexDimensionSchema which checks DIMENSION_HANDLER_PROVIDERS directly (instead of using the existing DimensionHandlerUtils#getHandlerFromCapabilities which now shares the underlying logic with this new method). DimensionSchemaUtils has also been updated to use this new method as it was already only calling getHandlerFromCapabilities for COMPLEX types.

@github-actions github-actions Bot added Area - Batch Ingestion Area - Segment Format and Ser/De Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 labels Jul 31, 2026

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity Findings
P0 0
P1 0
P2 1
P3 0
Total 1

Reviewed 5 of 5 changed files.


This is an automated review by Codex GPT-5.6-Sol

// Other complex types cannot be ingested into a clustered base table: there is no dimension handler for them,
// and clustered base tables have no aggregators to produce them.
if (druidType.is(ValueType.COMPLEX)) {
return complexDimensionSchema(column.name(), druidType);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Reject handler schemas that change the declared type

This path accepts the provider's DimensionSchema without checking that schema.getColumnType() equals the catalog's declared complex type. The new test demonstrates the problem by declaring COMPLEX but producing a DoubleDimensionSchema. During ingestion, DimensionSchema.getDimensionHandler() then selects the double handler from that returned schema, so complex values fail conversion or are stored as a type that contradicts the sealed catalog schema. Apply the same type-consistency check used for custom schemas before accepting the provider result.

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity Findings
P0 0
P1 0
P2 1
P3 0
Total 1

Reviewed 5 of 5 changed files.


This is an automated review by Codex GPT-5.6-Sol

druidType
);
}
if (!druidType.equals(schema.getColumnType())) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Reject handler schemas that rename the column

The new guard validates only the returned schema's type. A provider can still return the correct complex type under a different column name, which createSpec accepts verbatim. Downstream clustered ingestion then reads row.getRaw(schema.getName()), silently storing nulls for the declared catalog column and exposing the provider-chosen name instead. Validate name.equals(schema.getName()) alongside the type.

}
// Other complex types cannot be ingested into a clustered base table: there is no dimension handler for them,
// and clustered base tables have no aggregators to produce them.
if (druidType.is(ValueType.COMPLEX)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the special case for NESTED_DATA? That would help prove this system works and potentially get some extra test coverage.

public static DimensionSchema getComplexDimensionSchema(String dimensionName, ColumnType type)
{
if (!type.is(ValueType.COMPLEX) || type.getComplexTypeName() == null) {
throw new IAE("Type [%s] is not a named complex type", type);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using InvalidInput. Please include dimensionName in the error message.

{
final DimensionHandlerProvider provider = DIMENSION_HANDLER_PROVIDERS.get(complexTypeName);
if (provider == null) {
throw new ISE("Can't find DimensionHandlerProvider for typeName [%s]", complexTypeName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this error was pre-existing, but still, it's a funny error for someone to get if they provide an invalid complex type. Consider rewording it to include dimensionName, to be an InvalidInput, and to say something more user friendly like Complex type[%s] for dimension[%s] is not a valid type.

);
}
if (!druidType.equals(schema.getColumnType())) {
throw InvalidInput.exception(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Push this check up to DimensionHandlerUtils?

catch (ISE e) {
// No handler is registered for this complex type, which usually means the extension that defines it is not
// loaded on whichever service is validating the spec.
throw InvalidInput.exception(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the errors in DimensionHandlerUtils are made more friendly then this catch + rethrow won't be needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area - Batch Ingestion Area - MSQ For multi stage queries - https://github.com/apache/druid/issues/12262 Area - Segment Format and Ser/De Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants