@@ -77,6 +77,7 @@ import Data.Word
7777import Generics.SOP hiding (from)
7878import GHC.TypeLits
7979
80+import qualified Data.ByteString as ByteString
8081import qualified GHC.Generics as GHC
8182
8283import Squeal.PostgreSQL.Expression
@@ -618,6 +619,9 @@ data FromClause schema params tables where
618619 Subquery
619620 :: Aliased (Query schema params) table
620621 -> FromClause schema params '[table]
622+ JoinRef
623+ :: JoinRef schema tables
624+ -> FromClause schema params tables
621625 CrossJoin
622626 :: FromClause schema params right
623627 -> FromClause schema params left
@@ -648,6 +652,7 @@ data FromClause schema params tables where
648652renderFromClause :: FromClause schema params tables -> ByteString
649653renderFromClause = \case
650654 Table table -> renderAliasedAs renderTable table
655+ JoinRef joinRef -> renderJoinRef joinRef
651656 Subquery selection -> renderAliasedAs (parenthesized . renderQuery) selection
652657 CrossJoin right left ->
653658 renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
@@ -660,30 +665,35 @@ renderFromClause = \case
660665 renderFromClause left <+> op <+> renderFromClause right
661666 <+> "ON" <+> renderExpression on
662667
663−-- joinRef
664−-- :: ( Has lefttable schema (constraints :=> leftcolumns)
665−-- , leftrel ~ ColumnsToRelation leftcolumns
666−-- , Has righttable schema right
667−-- , rightrel ~ ColumnsToRelation (TableToColumns right)
668−-- , Has ref constraints ('ForeignKey keys reftable refs)
669−-- , SListI keys, All KnownSymbol keys
670−-- , SListI refs, All KnownSymbol refs
671−-- , KnownSymbol leftalias, KnownSymbol rightalias
672−-- )
673−-- => Aliased Alias (rightalias ::: righttable)
674−-- -> Alias ref
675−-- -> Aliased Alias (leftalias ::: lefttable)
676−-- -> FromClause schema params '[leftalias ::: leftrel, rightalias ::: rightrel]
677−-- joinRef
678−-- ((_ :: Alias righttable) `As` rightalias)
679−-- ref
680−-- ((_ :: Alias lefttable) `As` leftalias) =
681−-- InnerJoin
682−-- (Table (fromLabel @righttable `As` rightalias))
683−-- refEq
684−-- (Table (fromLabel @lefttable `As` leftalias))
685−-- where
686−-- refEq = undefined
668+newtype JoinRef (schema :: TablesType) (relations :: RelationsType)
669+ = UnsafeJoinRef { renderJoinRef :: ByteString }
670+ deriving (GHC.Generic,Show,Eq,Ord,NFData)
671+
672+utilizing
673+ :: ( Has left schema (constraints :=> lcols)
674+ , ColumnsToRelation lcols ~ lrel
675+ , Has right (TablesToRelations schema) rrel
676+ , Has ref constraints ('ForeignKey lnames right rnames)
677+ , All KnownSymbol lnames
678+ , All KnownSymbol rnames
679+ )
680+ => (Alias right, NP Alias rnames)
681+ -> Alias ref
682+ -> (Alias left, NP Alias lnames)
683+ -> JoinRef schema '[left ::: lrel,right ::: rrel]
684+utilizing (rtab,rcols) _ref (ltab,lcols) = UnsafeJoinRef $
685+ lname <+> "JOIN" <+> rname <+> "ON" <+> refEq
686+ where
687+ lname = renderAlias ltab
688+ rname = renderAlias rtab
689+ eq1 lcol rcol = lname <> "." <> lcol <> " = " <> rname <> "." <> rcol
690+ renderAliases :: All KnownSymbol names => NP Alias names -> [ByteString]
691+ renderAliases = \case
692+ Nil -> []
693+ alias :* aliases -> renderAlias alias : renderAliases aliases
694+ refEq = ByteString.intercalate " AND " $ zipWith eq1
695+ (renderAliases lcols)
696+ (renderAliases rcols)
687697
688698{-----------------------------------------
689699Grouping