edgedb-js
edgedb-js copied to clipboard
Polymorphic shapes that share property names are being shadowed
In the case that a query has polymorphic shapes where multiple subtypes return a shape that share the same property name, only the last subtype actually gets built into the final query.
Example:
e.select(e.Content, content => ({
title: true,
...e.is(e.Movie, { link: true }),
...e.is(e.TVShow, { link: true }),
}));
In the above example, only the e.TVShow polymorphic shape is built into the final expression object that is transformed into EdgeQL.
As an aside, renaming the field using computed doesn't work due to how we look up the type:
https://github.com/edgedb/edgedb-js/blob/464b0988121e7183a8304b37014a096ff0d01895/packages/generate/src/syntax/typesystem.ts#L374-L383
We do not save the source key into the expression, so we match the key to the pointer's key.
So this does not work:
e.select(e.Content, content => ({
title: true,
movie_link: e.is(e.Movie, { link: true }).link,
tv_show_link: e.is(e.TVShow, { link: true }).link,
}));
Since infer will look for e.Movie.movie_link instead of e.Movie.link in this case.
Quick workaround to mimic union types and solve the above problem using the coalescing operator. In EdgeQL
Select Content {
release_year := [is Movie].release_year ?? [is TVShow].release_year
}
In query Builder (TS)
const q = e.select(e.Content, content => ({
...e.Content['*'],
release_year: e.op(
content.is(e.Movie).release_year,
'??',
content.is(e.TVShow).release_year,
),
},
}))
Other related issue : https://github.com/edgedb/edgedb/issues/1577