aglinxinyuan opened a new pull request, #7116:
URL: https://github.com/apache/texera/pull/7116

   ### What changes were proposed in this PR?
   
   `FulltextSearchQueryUtilsSpec` was the only spec in the dashboard package. 
It also proves the approach: a **dialect-only** 
`DSL.using(SQLDialect.POSTGRES)` context renders jOOQ parts with no connection, 
and `ctx.newRecord(...)` builds records purely in memory. These three specs 
extend that to the rest of the connection-free tier.
   
   | New spec | Target | Why it isn't DB-bound |
   |---|---|---|
   | `DashboardResourceSpec` | `getOrderFields`, unknown-`resourceType` guard | 
both public and pure; the guard throws *before* any query is built |
   | `WorkflowSearchQueryBuilderSpec` | `toEntryImpl`, `mappedResourceSchema` | 
this object drops the trait's `protected`, widening access to public |
   | `UnifiedResourceSchemaSpec` | `apply`, the `translatedFieldSet` de-dup | 
24 default-arg `Field`s, all `DSL.inline`/`cast`/`castNull` |
   
   **`getOrderFields`** — existing coverage was only incidental (via 
`WorkflowResourceSpec`) and reached `NameAsc`/`Desc`, 
`ExecutionTimeAsc`/`Desc`, and `EditTime` through the default. This adds 
`CreateTime` both ways and the non-matching fall-through. It also pins the 
asc/desc asymmetry:
   
   ```
   Asc  -> "resourceCreationTime" asc
   Desc -> "resourceCreationTime" desc nulls last
   ```
   
   That asymmetry is the point: Postgres defaults to NULLS LAST for ASC and 
NULLS FIRST for DESC, so the explicit `nullsLast()` on the descending branch is 
what makes the *observable* ordering symmetric. Dropping it looks like a 
harmless simplification and silently moves NULLs to the top of every descending 
page.
   
   **`toEntryImpl`** — covers the projects-aggregate lookup, both comma-split 
branches, the NULL-privilege fallback to `NONE`, and the ownership flag both 
ways. The first test deliberately pins the aggregate lookup itself: 
`toEntryImpl` builds a *fresh* `groupConcatDistinct(WORKFLOW_OF_PROJECT.PID)` 
rather than reusing the one in `mappedResourceSchema`, so the whole projects 
feature rides on jOOQ comparing two structurally identical aggregates as equal.
   
   **`UnifiedResourceSchema`** — the counts were measured, not assumed: 24 
aliases, collapsing to 6 entries for the all-defaults schema and 17 for the 
workflow schema.
   
   Assertion strength was checked by **mutating production and confirming 
red**, then reverting (`git diff -- amber/src/main` is empty):
   
   | Mutation | Caught by |
   |---|---|
   | `desc().nullsLast()` → `desc()` | 2 tests |
   | `EditTime` → `resourceCreationTimeField` | 2 tests |
   | `into(WORKFLOW_OF_USER).getUid == uid` → `into(USER).getUid != uid` | 2 
tests |
   | privilege fallback `NONE` → `READ` | 1 test |
   | de-dup guard → `if (true)` | 3 tests |
   
   Out of scope, and noted in-file: `translateRecord`, `resultsOwnersInfo`, 
`searchAllPublicResourceCall`, `constructQuery` and every fetch path go through 
`SqlServer.getInstance().createDSLContext()`. `DatasetSearchQueryBuilder` is 
untouched — all five of its members are `override protected`, and Scala 
`protected` grants no same-package access.
   
   Two things deliberately **not** asserted, with the reasoning left in the 
files: `case None => List()` in `getOrderFields` and `case _ => null` in the 
private `getColumnField` are unreachable (the regex yields only four column 
names, all mapping non-null); and the projects parser's `NumberFormatException` 
on a padded separator is real but unproducible in production, so pinning it 
would only punish someone hardening the parser.
   
   None of these specs reads or writes `FulltextSearchQueryUtils.usePgroonga`, 
so they neither depend on it nor mutate it — worth stating because two existing 
specs set that JVM-global and never restore it while amber's suites run 
concurrently.
   
   Fragilities found in passing, reported rather than changed: 
`DashboardWorkflow.ownerId` is read as `record.into(USER).getUid` although the 
projection never selects `USER.UID` — it works only because jOOQ matches the 
unqualified name `uid` against `workflow_of_user.uid`; and 
`searchAllResources`'s per-record `resourceType` match has no default arm, so 
changing the inline `'workflow'` literal becomes a runtime `MatchError`.
   
   ### Any related issues, documentation, discussions?
   
   Closes #7115
   
   ### How was this PR tested?
   
   Three new specs, 27 tests. Run together with the existing sibling spec to 
confirm nothing in the package regressed — 41 tests, Java 17:
   
   ```
   sbt "WorkflowExecutionService/testOnly 
org.apache.texera.web.resource.dashboard.DashboardResourceSpec 
org.apache.texera.web.resource.dashboard.WorkflowSearchQueryBuilderSpec 
org.apache.texera.web.resource.dashboard.UnifiedResourceSchemaSpec 
org.apache.texera.web.resource.dashboard.FulltextSearchQueryUtilsSpec"
   ```
   
   ```
   [info] Suites: completed 4, aborted 0
   [info] Tests: succeeded 41, failed 0, canceled 0, ignored 0, pending 0
   [info] All tests passed.
   ```
   
   Verified with no Postgres provisioned locally, which is the point. 
`Test/scalafmtCheck` and `Test/scalafix --check` both `[success]`.
   
   One brittleness to be aware of: the expected strings (`desc nulls last`, 
`cast(null as timestamp)`, `'workflow' as "resourceType"`) and the de-dup 
counts are jOOQ **3.19.36** rendering artifacts, so a jOOQ bump could require 
updating them together.
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Opus 5)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to