Skip to content

Default LookML view table to the view name when unspecified#244

Open
nicosuave wants to merge 1 commit into
fix/lookml-export-aggregationsfrom
fix/lookml-default-view-table
Open

Default LookML view table to the view name when unspecified#244
nicosuave wants to merge 1 commit into
fix/lookml-export-aggregationsfrom
fix/lookml-default-view-table

Conversation

@nicosuave

Copy link
Copy Markdown
Member

Summary

Part of the LookML adapter correctness series. Stacked on #243 (base = fix/lookml-export-aggregations).

In Looker, a view with no sql_table_name and no derived_table implicitly queries a table named after the view. The adapter left table unset, so importing such a (perfectly valid) view crashed with ModelValidationError: Model must have a table.

Changes

  • Default table to the view name when there is no sql_table_name, no derived_table, no extends, it is not a refinement (+view), and not extension: required.
  • Regression test (parse + compile).

These exclusions preserve correct behavior for abstract/extended/refinement views, which legitimately have no table of their own.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 84410ae8a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
# via extends or are abstract (extension: required).
if (
table is None
and sql is None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require no derived_table before applying the default table

For views that do have a derived_table block but not a sql or explore_source variant the adapter understands (for example derived_table: { sql_create: ... } or create_process), sql stays None, so this fallback now assigns table = name. That imports a derived table as a physical table named after the view and generated queries target the wrong relation instead of preserving or flagging the unsupported derived table; the fallback should also require derived_table is None.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 84410ae to 92c08af Compare June 26, 2026 18:16
@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from adf80bc to e4e46ef Compare June 26, 2026 19:43
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 92c08af to d2cb276 Compare June 26, 2026 19:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2cb276882

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
table is None
and sql is None
and not view_def.get("derived_table")
and not extends

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve child defaults when extending tableless views

When a view extends a parent that also omitted sql_table_name, this guard prevents the child from ever getting its own default while the parent has already been assigned table = name; for view: base { ... } plus view: child { extends: [base] ... }, Sidemantic now compiles child against base instead of child. Looker applies defaults only after the merged view is interpreted, so an extended view with no explicit sql_table_name assumes the extending view name (see https://docs.cloud.google.com/looker/docs/reusing-code-with-extends#implementation_details_for_extends); this needs to distinguish explicit parent tables from synthetic defaults or apply the default after inheritance.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from e4e46ef to 5efe508 Compare June 26, 2026 20:02
@nicosuave nicosuave closed this Jun 26, 2026
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from d2cb276 to 5efe508 Compare June 26, 2026 20:02
@nicosuave nicosuave reopened this Jun 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5af0072a7d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
Comment on lines +597 to +599
and not name.startswith("+")
and view_def.get("extension") != "required"
and (dimensions or measures)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply default tables after merging refinements

When the base view is fieldless and a +view refinement supplies the dimensions/measures, neither parsed model gets the implicit table: the base fails the (dimensions or measures) guard while the refinement is excluded by name.startswith("+"). After merge_model the final view has queryable fields but still no table, so adding or compiling that valid LookML pattern (view: orders {} plus view: +orders { dimension: id ... }) still fails validation even though Looker would default it to orders; the default needs to run on the merged view or otherwise account for fields added by refinements.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 8dad963 to 4815fce Compare June 29, 2026 15:02
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 5af0072 to 50ef09e Compare June 29, 2026 15:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50ef09e59d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
model.table is None
and model.sql is None
and not model.extends
and not meta.get("extension_required")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve concrete children of abstract views

When a tableless view extends an extension: required base, resolve_model_inheritance() copies the parent's meta onto the child, so this check treats the concrete child as abstract and never assigns the implicit table. A valid pattern like view: base { extension: required ... } plus view: orders { extends: [base] ... } still imports orders with table=None, causing SemanticLayer.add_model()/queries to fail even though the table should default to orders; the skip needs to apply only to the original extension-required view, not inherited metadata.

Useful? React with 👍 / 👎.

Comment thread sidemantic/adapters/lookml.py Outdated
and model.sql is None
and not model.extends
and not meta.get("extension_required")
and not meta.get("unsupported_derived_table")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve unsupported derived-table markers through refinements

The direct unsupported-derived-table case is now marked, but this pass runs after refinements are merged, and merge_model() replaces the parent's meta when a refinement has any metadata such as label, hidden, or tags. In that scenario the base view's unsupported_derived_table marker is lost, so a view with an unsupported derived_table can still be defaulted to a physical table named after the view instead of remaining unsupported; the marker needs to survive refinement merges or be tracked outside ordinary metadata.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 4815fce to 7e3fe2e Compare June 29, 2026 15:29
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 50ef09e to 1dfe950 Compare June 29, 2026 15:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1dfe950fda

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
and model.sql is None
and not model.extends
and model_name not in abstract_views
and model_name not in unsupported_dt_views

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip children inheriting unsupported derived tables

When a view extends a parent whose derived_table is unsupported and does not override the source, resolve_model_inheritance() copies the parent's unsupported_derived_table marker onto the child, but this check only skips names captured before inheritance. In that scenario the child has table is None, sql is None, no remaining extends, and inherited fields, so it is defaulted to a physical table named after the child even though it should remain unsupported like its parent; generated queries will target the wrong relation.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch 2 times, most recently from 4380274 to 8346ee9 Compare June 29, 2026 16:00
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 1dfe950 to 0a99120 Compare June 29, 2026 16:04
@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 8346ee9 to e7c09f7 Compare June 29, 2026 16:28
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 0a99120 to 276e8e2 Compare June 29, 2026 16:28

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 276e8e29e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
model.table is None
and model.sql is None
and not model.extends
and model_name not in abstract_views

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep abstract refinements tableless

When a +view refinement is what adds extension: required, abstract_views was captured before refinements, and this guard never re-checks extension_required on the merged base model. A model like view: base { dimension: id ... } with view: +base { extension: required } therefore gets table='base' even though the merged view is abstract; track refinement-added abstractness for the refined view while still allowing concrete children to default.

Useful? React with 👍 / 👎.

Comment thread sidemantic/adapters/lookml.py Outdated
and not model.extends
and model_name not in abstract_views
and model_name not in unsupported_dt_views
and not (model.meta or {}).get("unsupported_derived_table")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep unsupported derived-table descendants tableless

When a child extends an unsupported derived table and also has its own model metadata (label, hidden, or tags) without overriding the source, merge_model() replaces the inherited meta, so this post-merge check no longer sees unsupported_derived_table and the child is not in unsupported_dt_views. For example view: base { derived_table: { sql_trigger_value: ... } ... } plus view: child { extends: [base] label: "Child" } is defaulted to table='child', causing generated queries to hit a fabricated physical table instead of leaving the unsupported derived table unqueryable.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from e7c09f7 to ca47e68 Compare June 29, 2026 16:46
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 276e8e2 to 0966fe7 Compare June 29, 2026 16:50

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0966fe71be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
# child that only INHERITS abstractness is not treated as abstract. Record
# extends parents too, so descendants of an unsupported derived table can be
# detected after resolution clears `extends`.
abstract_views = abstract_pre | {n for n, m in graph.models.items() if (m.meta or {}).get("extension_required")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve abstract flags across multiple refinements

The remaining gap is when one +view refinement adds extension: required and a later refinement only sets metadata such as label: merge_model() replaces meta, and this set is computed only from the pre-refinement models plus the final post-merge state, so the transient extension_required marker is missed. That leaves the refined base eligible for the defaulting block and assigns table = "base", making an abstract LookML view queryable; record the flag during each refinement merge or merge these meta flags instead.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 0966fe7 to ec74f18 Compare June 29, 2026 17:04

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec74f18f38

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
and not (model.meta or {}).get("unsupported_derived_table")
and (model.dimensions or model.metrics)
):
model.table = model_name

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply the default before auto-registration

When LookMLAdapter.parse() is called after constructing a default SemanticLayer() or inside with SemanticLayer(), the current-layer auto-registration path runs from Model.__init__ during _parse_view, before this post-parse assignment executes. For a valid tableless LookML view such as view: just_fields { ... }, layer.add_model validates immediately and raises ModelValidationError because table is still None, so this new default does not work in the default Python API ordering; the table needs to be set before model construction or auto-registration suppressed while parsing.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from ec74f18 to e72acbd Compare June 29, 2026 17:23
@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from ca47e68 to d029bab Compare June 29, 2026 19:15

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c5a0536389

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/loaders.py Outdated
# unsupported derived tables) BEFORE inference + registration, so FK inference never
# targets a model that won't be registered (which would leave a dangling relationship)
# and add_model never rejects a template that was never meant to be queried.
all_models = {name: model for name, model in all_models.items() if _is_registerable_model(model)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Strip relationships to skipped templates

When a LookML explore has already added a relationship to a model that this filter removes (for example an extension: required template or an unsupported derived-table view used as an explicit join target), the relationship remains on the surviving model while the target model is dropped. I checked the CLI validation path in validation_runner.validate_directory, which reports an error whenever rel.name is absent from layer.graph.models, so sidemantic validate can still fail with a dangling relationship after this intended skip; remove or suppress relationships whose targets are filtered here.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from b01a0e7 to 83a40fa Compare June 29, 2026 23:01
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from c5a0536 to 417f230 Compare June 29, 2026 23:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 417f2305c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
Comment on lines +65 to +66
if model.name not in prev_layer.graph.models and (model.table or model.sql):
prev_layer.add_model(model)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove skipped-template relationships before registering

When parsing inside an active with SemanticLayer() context, this deferred registration skips tableless templates but registers the surviving models with their original relationships intact. In the same scenario the loader path now fixes—e.g. an orders explore joining an extension: required customer template—the customer model is skipped here while orders.relationships still contains customer, leaving the active layer with a dangling relationship that validation reports as missing; strip relationships to models this loop will skip before calling add_model().

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 83a40fa to d226311 Compare June 29, 2026 23:19
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 417f230 to f051bbf Compare June 29, 2026 23:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f051bbf593

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
# relationships pointing at a skipped template (e.g. an explore join to it) so the
# active layer is not left with a dangling relationship that validation flags.
if prev_layer is not None:
skipped = {name for name, m in graph.models.items() if not (m.table or m.sql)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not skip unresolved tableless views during deferred registration

When parse() runs with an active SemanticLayer, this marks every model without table/sql as skipped, but tableless models are not always intentional templates. For example, view: child { extends: [missing] ... } remains tableless with extends='missing' after _chain_resolvable leaves it unresolved; this loop then silently omits child from the layer instead of surfacing the validation error that the model has no source. Limit the skip to the abstract/unsupported-derived-table markers so broken LookML is still reported.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from d226311 to 8fee1ca Compare June 30, 2026 00:14
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from f051bbf to d1a7eb4 Compare June 30, 2026 00:14

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1a7eb4ce1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/adapters/lookml.py Outdated
and model_name not in abstract_views
and not _extends_chain_has(model_name, unsupported_dt_views)
and not (model.meta or {}).get("unsupported_derived_table")
and (model.dimensions or model.metrics or model.segments)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Default ordinary fieldless LookML views too

When a valid LookML view omits sql_table_name and currently has no parsed dimensions, measures, or segments (for example view: orders {} or a view that only contains adapter-ignored LookML fields), this guard leaves table unset even though Looker still defaults the table name to the view name. In the CLI load path the model is not marked abstract/unsupported, so load_from_directory() still registers it and raises the no-table ModelValidationError; the default should not depend on parsed fields for non-template views.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 8fee1ca to 8f9d121 Compare June 30, 2026 00:39
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from d1a7eb4 to e093d18 Compare June 30, 2026 00:39
@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 8f9d121 to 2ec0bbe Compare June 30, 2026 00:55
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from e093d18 to 8110430 Compare June 30, 2026 00:55
@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 2ec0bbe to 9c8ddd7 Compare June 30, 2026 01:13
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 8110430 to 9202c25 Compare June 30, 2026 01:13

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9202c250ff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/loaders.py Outdated
# unsupported derived tables) BEFORE inference + registration, so FK inference never
# targets a model that won't be registered (which would leave a dangling relationship)
# and add_model never rejects a template that was never meant to be queried.
all_models = _drop_non_registerable_models(all_models)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop graph metrics from skipped templates

When this removes a LookML template, graph-level metrics already copied from the adapter remain in all_metrics: all_metrics.update(graph.metrics) runs before this point, and SemanticGraph.add_model() auto-registers model metrics with type time_comparison/conversion. For an extension: required view with a period_over_period measure and no surviving concrete child, CLI loading now drops the only model but still registers the graph metric, so sidemantic info/queries expose a metric whose base model is missing and compile(metrics=[...]) fails with no models found. Filter the metrics associated with dropped templates, or avoid carrying graph metrics from skipped LookML templates.

Useful? React with 👍 / 👎.

Comment thread sidemantic/loaders.py Outdated
Comment on lines +28 to +29
meta = model.meta or {}
return not (meta.get("extension_required") or meta.get("unsupported_derived_table"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope template skipping to LookML models

This helper is called on the combined output from every adapter, but the skip decision uses unscoped arbitrary model.meta keys. A native Sidemantic or other-format model with no source and user metadata like extension_required: true is now removed before add_model() instead of producing the missing table/sql validation error, so CLI validation can silently pass while dropping user-defined models. Please also require the LookML source format, or a parser-owned marker, before treating these keys as non-queryable-template signals.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 9c8ddd7 to 8b92870 Compare June 30, 2026 01:40
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 9202c25 to 33ee7f7 Compare June 30, 2026 01:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33ee7f716c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/loaders.py Outdated
Comment on lines +57 to +58
surviving = {m.name for model in kept.values() for m in (getattr(model, "metrics", None) or [])}
orphaned = {m.name for name in dropped for m in (getattr(all_models[name], "metrics", None) or [])} - surviving

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop graph metrics by source, not by metric name

Fresh evidence beyond the prior orphaned-metric issue is that this name-only survivor check keeps a dropped template's graph metric whenever any surviving model has a same-named ordinary measure. For example, a skipped extension: required view with a period_over_period measure pop and a real orders view with a simple measure: pop leaves all_metrics['pop'] pointing at the skipped template metric; after CLI loading, sidemantic info/compile(metrics=['pop']) exposes a graph metric whose base model was removed and fails with no models found. The filter needs to distinguish actual graph-level metrics contributed by surviving models from same-named model-local measures.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 8b92870 to 39f0919 Compare June 30, 2026 02:01
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 33ee7f7 to 64fefb4 Compare June 30, 2026 02:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64fefb4aa6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/loaders.py Outdated
surviving = {n for model in kept.values() for n in _graph_metric_names(model)}
orphaned = {n for name in dropped for n in _graph_metric_names(all_models[name])} - surviving
for mn in orphaned:
all_metrics.pop(mn, None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve same-named standalone metrics

When a dropped LookML template has a time_comparison/conversion measure with the same name as a valid graph-level metric from another file, all_metrics may currently contain that surviving metric after the directory-wide all_metrics.update(...) calls. This name-only removal still pops it because surviving is computed only from model-local special metrics, so CLI loads silently lose the valid standalone metric; the filter needs to verify the metric being removed was contributed by the dropped model rather than matching only by name.

Useful? React with 👍 / 👎.

@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from 39f0919 to bf0b444 Compare June 30, 2026 02:20
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from 64fefb4 to c57bdda Compare June 30, 2026 02:20

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c57bddabf3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/loaders.py Outdated
Comment on lines +65 to +66
if m.type in ("time_comparison", "conversion") and all_metrics.get(m.name) is m:
all_metrics.pop(m.name, None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop graph metrics from refined skipped templates

Fresh evidence beyond the prior orphaned-metric comments is that a label-only +view refinement (or any merge that reconstructs the model) creates new Metric objects for the skipped template, while all_metrics still holds the original object registered by graph.add_model() before refinement. Because this check only pops when the object identity still matches, a skipped extension: required view with a period_over_period measure and a later refinement leaves layer.graph.metrics['pop'] behind with no models loaded, so sidemantic info/compile(metrics=['pop']) exposes an orphan and fails with “No models found for query.”

Useful? React with 👍 / 👎.

A LookML view with no sql_table_name and no derived_table implicitly uses a
table named after the view (Looker's default behavior), but the adapter left
table unset, so importing such a view crashed layer validation with
"Model must have a table". Default table to the view name in that case,
while leaving refinements, extends-based views, and abstract
(extension: required) views untouched.
@nicosuave nicosuave force-pushed the fix/lookml-export-aggregations branch from bf0b444 to 6416688 Compare June 30, 2026 02:34
@nicosuave nicosuave force-pushed the fix/lookml-default-view-table branch from c57bdda to 589cca7 Compare June 30, 2026 02:34

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 589cca7e79

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sidemantic/loaders.py
Comment on lines +76 to +77
elif ref in _surviving_measures: # unqualified ref a surviving model provides
return True

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop template metrics even when bases share names

Fresh evidence beyond the earlier same-name metric comments is that this unqualified-base check keeps a graph metric from a skipped LookML template whenever any surviving model has a same-named base measure. In the CLI load path, an extension: required base view with total and pop based_on: total, plus a real orders.total, leaves pop in layer.graph.metrics even though no loaded model defines pop; compiling it then fails with the unresolved base (Measure total not found). The filter needs to prove the graph metric itself came from a surviving model or standalone metric source, not just that its unqualified base name exists somewhere.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant