This note is in Hasura.GraphQL.Schema.Select.
T
and U
are tables.
r
is a relationship on T
to table U
with the join condition, T.c =
U.d
where c
and d
are columns on tables T
and U
respectively.
s
is a relationship on U
to table T
with the join condition, U.d =
T.c
.
p(T)
and p(U)
denote the permission filters on table T
and U
respectively for some role R
.
Consider the SQL that we generate for this query:
query {
T {
c
r {
d
}
}
}
It would be along these lines:
SELECT
*
FROM
(
SELECT * FROM T WHERE p(T)
) AS T
LEFT OUTER JOIN LATERAL
(
SELECT * FROM U WHERE T.c = U.d AND p(U)
) AS U
ON TRUE
The expression T.c = U.d
is the join condition for relationship r
. Note
that we use lateral joins, so the join condition is not expressed using ON
but on the where clause of U
.
Now, let’s say p(U)
is of the form { s : p(T) }
.
SELECT
*
FROM
(
SELECT * FROM T WHERE p(T)
) AS T
LEFT OUTER JOIN LATERAL
(
SELECT * FROM U WHERE T.c = U.d
AND EXISTS (
SELECT 1 FROM T WHERE U.d = T.c AND p(T)
)
) AS U
ON TRUE
p(U)
, i.e, { s : p(T) }
got expanded to
EXISTS (
SELECT 1 FROM T WHERE U.d = T.c AND p(T)
)
Now, assuming, in the WHERE
clause for U
, that T.c = U.d
holds, then the
EXISTS
clause must evaluate to true. The EXISTS
clause must evaluate to true
because the row from T
we are joining against is exactly such a row satisfying
p(T)
. In other words, the row obtained from T
(as the left-hand side of the
join) satisfies p(T)
.