diagnose() in lib.py only counts cancel_query being overridden OR
has_implicit_cancel() returning True (equivalent, statically, to
overriding has_implicit_cancel since the base returns False). The
extractor additionally counted get_cancel_query_id, which could mark
cancellation as supported even when cancel_query wasn't overridden.
Removed get_cancel_query_id from CAP_METHODS and the query_cancelation
check so the generated docs match diagnose().
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cap attrs assigned via expressions (e.g. DruidEngineSpec.allows_joins =
is_feature_enabled("DRUID_JOINS")) can't be statically evaluated, so
they previously silently fell back to the BaseEngineSpec default —
causing generated docs to disagree with runtime behavior.
Now the Python extractor tracks unresolvable assignments per class,
propagates them through the MRO walk, and emits an
_unresolved_cap_fields marker on the database entry. The JS layer
uses that marker to prefer the value from the previously-generated
databases.json (which was produced with Flask context and reflects
real runtime values) and strips the marker before writing output.
Verified against druid.py: extraction correctly emits
"_unresolved_cap_fields": ["joins"], and the existing JSON's
"joins": false is preserved rather than overwritten with the base
default of true.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Python attribute lookup picks the first base that defines the attr; the
previous left-to-right update() order caused later bases to override
earlier ones, contradicting MRO. Reversing the iteration makes the
leftmost base the final writer, which matches Python semantics for the
common single-chain hierarchies in db_engine_specs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Update the database docs generator to extract capability flag values
directly from Python engine spec class attributes (supports_catalog,
supports_dynamic_schema, etc.) and method overrides (cancel_query,
estimate_statement_cost, impersonate_user, has_implicit_cancel, etc.)
using AST parsing in the fallback path.
Previously the generator hardcoded False for all capability flags and
relied on mergeWithExistingDiagnostics to preserve manual edits from
the existing databases.json. This made it impossible to keep flags
in sync with the Python source.
Changes:
- Fallback AST path now extracts cap flags via AST with proper
inheritance resolution (mirrors lib.py has_custom_method logic)
- mergeWithExistingDiagnostics now only preserves score/max_score/
time_grains (Flask-context-only fields), not capability flags
- lib.py generate_yaml_docs now includes supports_dynamic_catalog
in its output, and skips base specs that would overwrite a real
product spec's flags for the same engine_name
- Regenerated databases.json with corrected flag values
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>