aglinxinyuan opened a new issue, #7874:
URL: https://github.com/apache/texera/issues/7874
### What happened?
`DatasetSearchQueryBuilder.toEntryImpl` builds every entry's owner email out
of the joined owner row:
```scala
val owner = record.into(USER).into(classOf[User])
...
DashboardDataset(dataset, owner.getEmail, ...)
```
and that value is always `null`.
`constructFromClause` does join the owner:
```scala
.leftJoin(USER).on(USER.UID.eq(DATASET.OWNER_UID))
```
But the select list comes entirely from `mappedResourceSchema`, and
`UnifiedResourceSchema.apply` defaults `userEmail` to `DSL.inline("")`
(`UnifiedResourceSchema.scala:74`). The dataset schema never names that slot,
so the rendered SQL projects a literal and never reads the table it joined:
```sql
select distinct 'dataset' as resourceType, ..., '' as email, ...
from texera_db.dataset
left outer join texera_db.dataset_user_access
on (texera_db.dataset_user_access.did = texera_db.dataset.did and ...)
left outer join texera_db.user
on texera_db.user.uid = texera_db.dataset.owner_uid
```
The value reaches the entry as `null` rather than `""` because of a second
step. `UnifiedResourceSchema.translatedFieldSet` dedupes by the *original*
field, and jOOQ compares fields by rendered SQL, so the four `DSL.inline("")`
defaults — `projectsOfWorkflow`, `userName`, `userEmail`, `projectColor` —
collapse into a single entry keyed on the first of them. The translated record
therefore carries no `email` column at all, `record.into(USER)` yields an
all-null `User`, and `getEmail` is `null`.
Every other producer of a `DashboardDataset` fills the field:
| producer | projects the owner email | `ownerEmail` on the result |
|---|---|---|
| `DatasetSearchQueryBuilder` | **no** — `'' as email` | **always `null`** |
| `HubResource:316` | yes — `record.into(USER).getEmail` | correct |
| file-service `/dataset/list` (`DatasetResource:1267`) | yes | correct |
`WorkflowSearchQueryBuilder` is the sibling that shows the missed step: it
opts into the USER column it reads (`userName = USER.NAME`, plus `USER.NAME` in
`getGroupByFields`), and it already filters on `USER.EMAIL` for the `owners`
query param — so the email was reachable through the join all along. Only the
projection was missing.
Consequences today:
- `leftJoin(USER)` is joined and selected from but never read, on every
dataset search.
- `DashboardDataset.ownerEmail` is `null` for every row `/dashboard/search`
returns, and flows into `DashboardEntry.ownerEmail` (`dashboard-entry.ts:132`).
No frontend code reads that field for datasets yet, so no screen is visibly
wrong — this is latent rather than user-facing right now.
- It is a trap all the same, because the field *is* load-bearing for
datasets a few lines away: `dataset-selection-modal.component.ts:127` builds
the storage logical path
`/${ResourceType.Dataset}/${ownerEmail}/${name}/${version}` from a
`DashboardDataset`. That works only because the modal lists via file-service,
which populates the field. Any consumer that switches to sourcing datasets from
search gets `/dataset/null/...`.
### How to reproduce?
The SQL half needs no lakeFS. Render the query and look at the projection:
```scala
getDSLContext.renderInlined(
DatasetSearchQueryBuilder.constructQuery(uid, SearchQueryParams(),
includePublic = true)
)
```
It contains `'' as email` alongside `left outer join texera_db.user on
texera_db.user.uid = texera_db.dataset.owner_uid`.
For the entry, fetch a row and pass it through the trait's public `toEntry`.
`DatasetSearchQueryBuilderSpec` already carries the fixture and the lakeFS
loopback stub needed to reach `toEntryImpl`, so:
```scala
entryFor(ownerUid, sizedDid).dataset.value.ownerEmail // null
```
Through the API, every `dataset.ownerEmail` in the response is `null`:
```
GET /api/dashboard/search?resourceType=dataset
```
Noticed while writing #7855, which documented the defect and deliberately
asserted nothing about the field, so that a fix would not have to fight a test
that had cemented the bug.
### Version/Branch
1.3.0-incubating-SNAPSHOT (main)
--
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]