Skip to content

[pull] master from cube-js:master#424

Merged
pull[bot] merged 3 commits intocode:masterfrom
cube-js:master
Apr 24, 2026
Merged

[pull] master from cube-js:master#424
pull[bot] merged 3 commits intocode:masterfrom
cube-js:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Apr 24, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

paveltiunov and others added 3 commits April 23, 2026 12:46
…10727)

* fix(tesseract): compile mask.sql against the owning cube for view members

When a cube member with mask.sql is re-exposed through a view (especially
with prefix: true), mask.sql references such as {CUBE.city}, {CUBE}.city
or {users}.city used to fail inside Tesseract with errors like
'Cannot resolve: city', 'Can't find join path to join …' or
'Member references foreign cubes: users'.

The legacy BaseQuery path already compiles mask.sql against the owning
cube by consulting the symbol's aliasMember. Tesseract was compiling
mask.sql against the view's cube name, producing mismatched dependency
resolution.

Propagate aliasMember through DimensionDefinitionStatic /
MeasureDefinitionStatic and use the owning cube name when compiling
mask.sql in the Rust dimension/measure symbol factories.

Also exclude mask.sql from iter_sql_calls so the generic
validate_regular_member_cube_refs check doesn't flag mask references
as foreign cubes.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* fix(schema-compiler): emit 1 = 0 for empty filter arrays in context symbols

SECURITY_CONTEXT array filters (e.g. {groups.filter("…")}) used to
render 'col IN ()' when the array was empty, which is invalid SQL in
most dialects.

Treat an empty array as 'matches nothing' and emit '1 = 0' (or invoke
the callback with an empty list) for both the legacy BaseQuery filter
helper and the Tesseract security_context_filter_fn.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test(rbac): reproduce mask.sql issues with cross-cube refs via prefixed views

Add unit tests (BaseQuery and Tesseract paths) and E2E smoke tests
covering:

* mask.sql authored with {cube.member}, {CUBE.member}, {CUBE}.column
  and {cube}.column references on a cube member re-exposed through a
  prefixed view.
* {groups.filter(...)} with an empty groups array: must not emit
  invalid 'IN ()' SQL.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* test(rbac): shorten fixture names and tighten member_masking scope

The previous fixture names produced Postgres aliases that exceeded the
63-char identifier limit, so the SQL engine's rewrite truncated them
and then failed with 'Member name not found for alias'.

Rename the cube / view / masked dimensions to short forms
(view_mask_base, view_mask_test, pid_full, etc.) and limit the
access_policy.member_masking scope to just the masked dimensions so
non-masked members (id, product_id, count) still resolve to their real
SQL instead of the default NULL mask.

The smoke tests now also select explicit columns instead of SELECT *.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* chore: re-run CI to retry flaky driver tests

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* refactor(tesseract): extract invoke_filter_column_callback helper

security_context_filter_fn had three near-identical blocks calling the
user-provided column callback and converting the result to a string.
Extract them into a single helper method.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

* refactor(tesseract): use sql.resolve_direct_reference for mask.sql cube

Drop the aliasMember plumbing through DimensionDefinitionStatic /
MeasureDefinitionStatic. Tesseract already computes is_sql_direct_ref
for the dimension / measure sql and has SqlCall::resolve_direct_reference
to fetch the referenced MemberSymbol. Use that existing machinery to
find the owning cube for mask.sql, keeping the behavior identical while
avoiding duplicating the owning-cube info across the native bridge.

The semantics match the legacy BaseQuery path: JS sets aliasMember only
when the view member's sql is a pure one-to-one reference to another
cube member, which is exactly the condition SqlCall::is_direct_reference
captures.

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* docs: add upload-asset script and static-assets rule

Bring the upload-asset.sh helper from cubejs-landing into the docs repo so
contributors can publish editorial images (provider logos, screenshots,
diagrams) to the cube-dev-websites-shared S3 bucket without using the AWS
console. Adds a Cursor rule scoped to docs-mintlify/** that documents
usage, first-time AWS setup, path conventions, and the immutability rule.

Made-with: Cursor

* docs: add screenshots cursor rule

Document how to capture, embed, and host UI screenshots for the Mintlify
docs: which demo account to use, viewport / theme / format conventions,
the {/* Screenshot: ... */} placeholder workflow, MDX <Frame> embedding,
and the immutable-key update flow. Also calls out that the cursor-ide-browser
MCP webview is too narrow for production screenshots and tells contributors
to capture in a real desktop browser.

Made-with: Cursor

* docs: remove screenshots cursor rule

Pulling this back for now — embedded creds and the MCP-vs-real-browser
guidance need more thought before we ship a public rule.

Made-with: Cursor
* docs: add Widgets section under Dashboards

Documents the four dashboard widget types (Chart, Text/Markdown,
Control, AI) as dedicated pages under a new Widgets group, mirroring
the structure used by Omni's Tiles section. Also adds a package.json
for the Mintlify docs site so the dev server can be started with
`yarn dev` on port 3002.

Made-with: Cursor

* docs: align dashboard widget docs with product terminology

- Use "dashboard builder" (the actual product term) instead of
  "dashboard editor"
- Split the Control page into separate Filter widget and Time Grain
  widget pages, matching the product's Add Filter / Add Time Grain
  toolbar buttons and the FILTER / TIME_GRAIN widget types
- Document the real way to add chart widgets (the Charts picker in
  the toolbar)
- Reflect the AI Widget label and Add AI Widget button used in the UI
- Update the product taxonomy rule with the Widget hierarchy under
  Dashboard builder so future docs use the same terms

Made-with: Cursor

* docs: rename and consolidate dashboard widget pages

- Use plural, widget-free titles in the sidebar: Charts, Text,
  Controls, AI summary
- Combine the separate Filter widget and Time grain switcher pages
  into a single Controls page with Filter and Time grain switcher
  sections
- Rename the AI page to AI summary and align the docs with the
  product rename of "AI Widget" / "Add AI Widget" to "AI Summary" /
  "Add AI Summary"
- Document filter / time grain switcher Visibility (Visible, Hidden,
  Disabled)
- Document Controls mapping: automatic mapping when dimensions
  match, manual remap or disable per chart from a chart's settings
  menu, time grain switchers restricted to time-typed dimensions,
  and the fact that AI agents configure these mappings when
  building dashboards
- Replace the bullet list of supported Markdown syntax on the Text
  page with a link to the Markdown Guide
- Update the namings rule to match the new widget taxonomy

Made-with: Cursor
@pull pull Bot locked and limited conversation to collaborators Apr 24, 2026
@pull pull Bot added the ⤵️ pull label Apr 24, 2026
@pull pull Bot merged commit b879bea into code:master Apr 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants