Skip to content

[Enh]: Allow tables with unsupported data type columns. #3181

@JerryNixon

Description

@JerryNixon

What?

Support entities (tables and views) that have columns with unsupported data types.

Configuration

{
  "entities": {
    "SpatialData": {
      "source": "dbo.SpatialData",
      "exclude-unsupported-types": true // new!
    }
  }
}
  • false (default) : Current behavior. Unsupported column types cause the entity to fail at startup.
  • true : DAB silently drops unsupported columns from the schema and proceeds.

Behavior When true

Concern What Happens
Startup Introspect all columns. Unsupported types are dropped from the internal model. Warning logged per column.
GraphQL / REST schema Excluded columns don't exist.
SELECT Excluded columns omitted from projection. Never fetched.
INSERT / UPDATE Excluded columns omitted. DB default or NULL fills them.
fields.include Excluded or unsupported columns are ignored.
fields.exclude Excluded or unsupported columns are ignored.
policy @item.field This is the one hard failure. Column reference causes startup exception. Policies are security boundaries, silent exclusion is not safe.
Client sends excluded column 400 — field not recognized (same as any unknown field today).
Filter/OrderBy on excluded column 400 — field not recognized.
NOT NULL, no default Database will return standard error. Developer is responsible for defaults.

Design Principles

Principle How
Transparent Startup warnings list every dropped column and its native type.
Deterministic Same schema + true = same columns dropped, every time.
Predictable No coercion. No casting. No partial data. Columns are fully in or fully out.
Safe Policies fail loud. DB errors surface honestly. DAB never touches data it can't represent.
Optional false by default. Zero impact on existing users.

Behavior When false (default, unchanged)

Unsupported column in entity fails to load with startup error. No regression, same as today.

Why?

Reduce blockers. Enable DAB adoption in real, messy databases, where "one unsupported column" is otherwise a dealbreaker. Teams can migrate services to DAB even if a few columns are currently unsupported. No need to wait for full support; just flip a switch.

Considerations

  1. What happens if an unsupported column is part of a primary key or foreign key? Fail to start.
  2. If a GraphQL relationship uses an excluded column as a join key? Fail to start.
  3. For entities backed by stored procedures? This feature does and can only apply to tables/views.
  4. Excluded columns don't appear in OpenAPI request/response schemas.
  5. When included in an entity Fields array? Fail to start.
  6. The proposal focuses on SQL databases only. JSON Schema constraint should enforce mssql.

How?

How?

1. Config Model

Add exclude-unsupported-types to EntitySource:

[JsonPropertyName("exclude-unsupported-types")]
public bool ExcludeUnsupportedTypes { get; init; } = false;

Update schemas/dab.draft.schema.json. Constrain to mssql only via JSON Schema.

2. Metadata Provider: Skip unsupported columns

The crash today is in SqlMetadataProvider.GetTableWithSchemaFromDataSetAsync() when DataReader.GetFieldType() returns null or the type is false in SupportedSqlDbTypes. When ExcludeUnsupportedTypes is true, log a warning and skip the column instead of throwing. The column never enters SourceDefinition.Columns.

if (columnTypeIsUnsupported)
{
    if (entityConfig.Source.ExcludeUnsupportedTypes)
    {
        _logger.LogWarning(
            "Entity '{EntityName}': column '{ColumnName}' of type '{NativeType}' "
            + "is unsupported and will be excluded.",
            entityName, columnName, nativeTypeName);
        continue;
    }

    throw new DataApiBuilderException(...);
}

Because the column never enters the model, every downstream consumer (GraphQL schema builder, REST/OpenAPI, query builders, authorization) naturally ignores it. No column in the model means no field in the schema means no column in SQL projection. This is why a single toggle works.

Key files:

  • src/Core/Services/MetadataProviders/SqlMetadataProvider.cs
  • src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs
  • src/Core/Models/SqlTypeConstants.cs

3. Startup Validation: Hard failures

After metadata is populated and unsupported columns are excluded, validate that no excluded column is referenced where silent exclusion is unsafe. Fail to start if any of these are true:

Condition Behavior
Excluded column is part of a primary key Startup exception
Excluded column is a foreign key or relationship join key Startup exception
Policy @item.field references an excluded column Startup exception
fields.include or fields.exclude explicitly names an excluded column Startup exception
Entity source type is stored procedure Startup exception (feature applies to tables/views only)
Excluded column is NOT NULL with no default Log warning (not a failure, DB will error on INSERT)

Policy validation reuses the existing @item.* extraction pattern from AuthorizationResolver.cs. Add these checks to RuntimeConfigValidator.cs.

4. Fields.include / Fields.exclude

When the excluded column is NOT explicitly listed in fields.include or fields.exclude, it is silently ignored since it never enters SourceDefinition.Columns. No code change needed for this path.

When the excluded column IS explicitly listed, fail at startup per the table above.

5. CLI

Add --exclude-unsupported-types to dab add and dab update in src/Cli/. Wire to the config serializer.

dab add SpatialData --source dbo.SpatialData --exclude-unsupported-types true

6. Tests

Add a column with type xml (already false in SupportedSqlDbTypes) to an existing MSSQL test table. Use TestCategory=MsSql.

Test Validates
Startup succeeds with flag true Entity loads, column absent from SourceDefinition.Columns
Startup fails with flag false Current behavior preserved
GraphQL schema excludes column Introspection shows no field
REST GET omits column JSON response has no key
REST POST with excluded column returns 400 Field not recognized
Filter on excluded column returns 400 Field not recognized
Policy referencing excluded column fails startup DataApiBuilderException thrown
fields.include naming excluded column fails startup DataApiBuilderException thrown
Excluded column in primary key fails startup DataApiBuilderException thrown
INSERT without excluded NOT NULL column surfaces DB error DAB passes through the database error
Excluded column NOT NULL with no default logs warning Warning logged at startup
Flag on stored procedure entity fails startup Feature only applies to tables/views

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions