Skip to content

feat(workflow): match search and listings against the copy on show - #8576

Merged
aglinxinyuan merged 1 commit into
apache:mainfrom
yangzhang75:pin/4-search
Oct 27, 2026
Merged

aglinxinyuan merged 1 commit into
apache:mainfrom
yangzhang75:pin/4-search

Conversation

@yangzhang75

@yangzhang75 yangzhang75 commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

A listing is where most people meet a workflow, so it has to agree with what opening it shows.
This makes search and the hub match, display and link against the copy on show.

  • Search matches the copy the caller may see. One search returns both the caller's own
    workflows and public ones, so the filter is a disjunction of guarded filters — the working copy
    for rows they were granted, the frozen copy for rows they reach only because those are public.
    Written over bare columns rather than a CASE, so each side stays eligible for its own PGroonga
    index. A pinned workflow no longer turns up on keywords that exist only behind the pin, and the
    author still finds their own work on what they just typed.
  • Listings show the frozen name and description to a viewer without granted access — the same
    copy the detail page serves, so a card cannot advertise a title that opening it does not show.
    Both are NULL while following, which leaves the live values in place.
  • The hub is the public shelf, so everything on it is listed as the public sees it, for the
    author too: they are looking at the shelf, not at their own dashboard.
  • One definition of "the public is behind". WorkflowPublishService.pinDiffersFromWorkingCopy
    is the share dialog's comparison as a SQL condition, and the search projection and the hub
    listing both use it, so a card and the dialog cannot disagree about whether edits are held back.

Any related issues, documentation, discussions?

Closes #7940
Part of #7828. Design discussion: #7128. Builds on #7853 and #8575, both merged.

How was this PR tested?

19 new cases in WorkflowPublishSpec plus WorkflowSearchQueryBuilderSpec and
UnifiedResourceSchemaSpec (567 in the dashboard package):

  • search not matching a public workflow on anything that exists only in unpublished edits, and
    matching it on its published copy — content, name and description, each separately;
  • an unpinned public workflow still matching the author's latest, and the author still matching
    their own workflow on a name only they can see;
  • a listing showing a public viewer the published name and description, a collaborator the live
    ones, and a private workflow's own listing untouched;
  • the drift flag a card carries: true while a pin holds edits back, false for a workflow with
    nothing frozen, and equal to what the share dialog reports for the same workflow — including
    after a rename and after a change of view, the two fields most easily left out of one of the
    three places that answer this.

The shared condition was checked by mutation: dropping the default-view term from it turns the
card-versus-dialog case red.

scalafmtCheckAll clean.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @aglinxinyuan, @tanishqgandhi1908
    You can notify them by mentioning @aglinxinyuan, @tanishqgandhi1908 in a comment.

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 9 worse · ⚪ 6 noise (<±5%) · 0 without baseline

Compared against main 3726dd7 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 673 0.411 14,573/22,470/22,470 us 🔴 +13.6% / 🔴 +59.1%
🔴 bs=100 sw=10 sl=64 1,570 0.958 60,550/92,044/92,044 us 🔴 +37.7% / 🟢 -27.7%
🔴 bs=1000 sw=10 sl=64 1,986 1.212 495,700/593,106/593,106 us 🔴 +6.3% / 🟢 +50.4%
Baseline details

Latest main 3726dd7 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 673 tuples/sec 686 tuples/sec 968.33 tuples/sec -1.9% -30.5%
bs=10 sw=10 sl=64 MB/s 0.411 MB/s 0.419 MB/s 0.591 MB/s -1.9% -30.5%
bs=10 sw=10 sl=64 p50 14,573 us 14,404 us 10,646 us +1.2% +36.9%
bs=10 sw=10 sl=64 p95 22,470 us 19,782 us 14,120 us +13.6% +59.1%
bs=10 sw=10 sl=64 p99 22,470 us 19,782 us 16,498 us +13.6% +36.2%
bs=100 sw=10 sl=64 throughput 1,570 tuples/sec 1,783 tuples/sec 1,252 tuples/sec -11.9% +25.4%
bs=100 sw=10 sl=64 MB/s 0.958 MB/s 1.088 MB/s 0.764 MB/s -11.9% +25.4%
bs=100 sw=10 sl=64 p50 60,550 us 55,544 us 83,736 us +9.0% -27.7%
bs=100 sw=10 sl=64 p95 92,044 us 66,842 us 92,464 us +37.7% -0.5%
bs=100 sw=10 sl=64 p99 92,044 us 66,842 us 108,561 us +37.7% -15.2%
bs=1000 sw=10 sl=64 throughput 1,986 tuples/sec 2,014 tuples/sec 1,321 tuples/sec -1.4% +50.4%
bs=1000 sw=10 sl=64 MB/s 1.212 MB/s 1.229 MB/s 0.806 MB/s -1.4% +50.3%
bs=1000 sw=10 sl=64 p50 495,700 us 494,998 us 811,260 us +0.1% -38.9%
bs=1000 sw=10 sl=64 p95 593,106 us 557,847 us 847,636 us +6.3% -30.0%
bs=1000 sw=10 sl=64 p99 593,106 us 557,847 us 879,277 us +6.3% -32.5%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,297.27,200,128000,673,0.411,14573.04,22469.76,22469.76
1,100,10,64,20,1273.57,2000,1280000,1570,0.958,60550.44,92043.97,92043.97
2,1000,10,64,20,10069.33,20000,12800000,1986,1.212,495699.74,593105.64,593105.64

@codecov-commenter

codecov-commenter commented Sep 17, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.78947% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.34%. Comparing base (3726dd7) to head (f44c37f).
⚠️ Report is 34 commits behind head on main.

Files with missing lines Patch % Lines
...shboard/user/workflow/WorkflowPublishService.scala 91.66% 1 Missing and 1 partial ⚠️
...ra/web/resource/dashboard/SearchQueryBuilder.scala 50.00% 1 Missing ⚠️
...esource/dashboard/WorkflowSearchQueryBuilder.scala 97.95% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8576      +/-   ##
============================================
+ Coverage     92.33%   92.34%   +0.01%     
- Complexity     5045     5046       +1     
============================================
  Files          1260     1260              
  Lines         54067    54147      +80     
  Branches       6755     6764       +9     
============================================
+ Hits          49921    50002      +81     
- Misses         2486     2487       +1     
+ Partials       1660     1658       -2     
Flag Coverage Δ *Carryforward flag
access-control-service 77.38% <ø> (ø) Carriedforward from 3726dd7
agent-service 99.16% <ø> (ø) Carriedforward from 3726dd7
amber 87.37% <95.78%> (+0.05%) ⬆️
computing-unit-managing-service 60.48% <ø> (ø) Carriedforward from 3726dd7
config-service 87.37% <ø> (ø) Carriedforward from 3726dd7
file-service 82.00% <ø> (ø) Carriedforward from 3726dd7
frontend 96.55% <ø> (ø) Carriedforward from 3726dd7
notebook-migration-service 83.73% <ø> (ø) Carriedforward from 3726dd7
pyamber 98.57% <ø> (ø) Carriedforward from 3726dd7
workflow-compiling-service 72.43% <ø> (ø) Carriedforward from 3726dd7

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yangzhang75
yangzhang75 force-pushed the pin/4-search branch 3 times, most recently from 3d82740 to 5d4e022 Compare September 28, 2026 21:13
@yangzhang75
yangzhang75 marked this pull request as ready for review October 6, 2026 18:42
@yangzhang75
yangzhang75 marked this pull request as draft October 7, 2026 01:36
@yangzhang75
yangzhang75 force-pushed the pin/4-search branch 3 times, most recently from 7f82065 to 8864b4e Compare October 13, 2026 00:55
Search and the listings it feeds were reading the author's live columns,
which for a pinned workflow is the one copy the public cannot open. A
draft would turn up in a public search under a title nobody has seen, and
the card would advertise a name the detail page does not show.

Each filter is now applied to whichever copy the caller may see:
`onVisibleCopy` builds the same filter twice -- over the live columns for
rows the caller was granted access to, over the frozen ones for rows they
reach only because the workflow is public -- and ORs the two. A
disjunction over bare columns rather than a CASE, so each side stays
eligible for its own fulltext index. Unpinned public rows fall back to
the live columns, so a following workflow searches exactly as it does now.

Listings carry two more things from the same query: the frozen name and
description to show a viewer without granted access, and whether the copy
on show is behind the author's working copy. `constructWhereClause` takes
`includePublic` for this; the other builders accept and ignore it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@yangzhang75
yangzhang75 marked this pull request as ready for review October 18, 2026 22:21
@yangzhang75

Copy link
Copy Markdown
Contributor Author

/request-review: @aglinxinyuan

@github-actions
github-actions Bot requested a review from aglinxinyuan October 18, 2026 23:31

@aglinxinyuan aglinxinyuan left a comment

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.

LGTM!

@aglinxinyuan
aglinxinyuan added this pull request to the merge queue Oct 27, 2026
Merged via the queue into apache:main with commit 9562edb Oct 27, 2026
23 checks passed
renovate-bot pushed a commit to renovate-bot/apache-_-texera that referenced this pull request Oct 28, 2026
… is read (apache#9190)

### What changes were proposed in this PR?

Workflows took the owner's privilege from their `workflow_user_access`
row alone. If that row was missing or downgraded, the owner lost access
to their own workflow, or it was hidden from them. This makes workflows
match datasets, models and computing units (apache#8890): the owner is always
WRITE.

- **Access checks**: `WorkflowAccessResource.getPrivilege` reads the
caller's own owner row and access row in one query (so a workflow with
several owners still yields one row) and returns WRITE for the owner
(via `OwnerAccess.privilege`). `hasReadAccess`, `hasWriteAccess`,
`hasGrantedAccess` and sharing all go through it.
- **Search and the workflow list**: these include owned workflows, not
only ones with an access row, and report the owner as WRITE. For apache#8576's
pinned copies, the owner counts as granted, so they always see their own
live name and description, never the pinned ones.
- **Owned-or-granted ids**: the new
`WorkflowAccessResource.accessibleWids(uid)` is the single source for
the ID and owner filters, the quota page and the admin executions page.
Each of these used to read the access table alone.
- **Hub**: `baseWorkflowSelect(uid)` joins only the viewer's access row,
the same as the dataset/model hub fix in apache#8890. A workflow shared with
several users now gives one card with the viewer's own level, instead of
duplicates or someone else's level.

### Any related issues, documentation, discussions?

Closes apache#9150. Follow-up to apache#8890.

### How was this PR tested?

New tests:
- `WorkflowAccessResourceSpec`: the owner is WRITE with no access row,
and with a READ row. A workflow with several owner rows doesn't fail the
check. `accessibleWids` lists owned and granted workflows once each.
- `WorkflowResourceSpec`: after the owner's access row is deleted, they
still see the workflow as WRITE in the list, search, the ID and owner
filters, and when opening it.
- `HubResourceSpec`: a workflow shared with two other users gives one
entry with the viewer's own level (NONE for an ungranted or anonymous
viewer). The owner without an access row gets WRITE.
- `UserQuotaResourceSpec`, `AdminUserResourceSpec`,
`AdminExecutionResourceSpec`: an owner without an access row still gets
their workflow listed or marked accessible.
- `WorkflowSearchQueryBuilderSpec`: the owner is WRITE whatever their
access row says, and sees their live name rather than the pinned one. An
anonymous viewer of a workflow with no owner row is not mistaken for the
owner.

Three existing tests assumed the old behaviour and were updated. One
asserted NONE for an owner without an access row, which is the bug this
PR fixes. The other two read the privilege as the owner, so they now
read it as a non-owner.

With the main-code changes reverted, the 6 new owner and hub tests fail.
The affected amber specs pass (373), and `scalafmtCheckAll` and
`scalafixAll --check` are clean.

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 5.5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Match search and listings against the copy on show

3 participants