@@ -735,13 +735,13 @@ update
735735 -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
736736 -> Expression params '[table ::: columns] ('Required ('NotNull 'PGBool))
737737 -> Statement params '[] schema schema
738−update (Alias table) columns where' = UnsafeStatement $ mconcat
738+update (Alias table) columns wh = UnsafeStatement $ mconcat
739739 [ "UPDATE "
740740 , fromString $ symbolVal' table
741741 , " SET "
742742 , ByteString.intercalate ", " . catMaybes . hcollapse $
743743 hmap (K . renderSet) columns
744− , " WHERE ", renderExpression where', ";"
744+ , " WHERE ", renderExpression wh, ";"
745745 ] where
746746 renderSet
747747 :: Aliased (Maybe :.: Expression params tables) column
@@ -753,3 +753,40 @@ update (Alias table) columns where' = UnsafeStatement $ mconcat
753753 , renderExpression expression
754754 ]
755755 Comp Nothing `As` _ -> Nothing
756+
757+upsertInto
758+ :: (SListI columns, HasTable table schema columns)
759+ => Alias table
760+ -> NP (Aliased (Expression params '[])) columns
761+ -> NP (Aliased (Maybe :.: Expression params '[table ::: columns])) columns
762+ -> Expression params '[table ::: columns] ('Required ('NotNull 'PGBool))
763+ -> Statement params '[] schema schema
764+upsertInto (Alias table) inserts updates wh = UnsafeStatement . mconcat $
765+ [ "INSERT INTO "
766+ , fromString (symbolVal' table)
767+ , " (" <> ByteString.intercalate ", " aliases
768+ , ") VALUES ("
769+ , ByteString.intercalate ", " values
770+ , ") ON CONFLICT UPDATE "
771+ , fromString $ symbolVal' table
772+ , " SET "
773+ , ByteString.intercalate ", " . catMaybes . hcollapse $
774+ hmap (K . renderSet) updates
775+ , " WHERE ", renderExpression wh, ";"
776+ ] where
777+ renderSet
778+ :: Aliased (Maybe :.: Expression params '[table ::: columns]) column
779+ -> Maybe ByteString
780+ renderSet = \case
781+ Comp (Just expression) `As` Alias column -> Just $ mconcat
782+ [ fromString $ symbolVal' column
783+ , " = "
784+ , renderExpression expression
785+ ]
786+ Comp Nothing `As` _ -> Nothing
787+ aliases = hcollapse $ hmap
788+ (\ (_ `As` Alias name) -> K (fromString (symbolVal' name)))
789+ inserts
790+ values = hcollapse $ hmap
791+ (\ (expression `As` _) -> K (renderExpression expression))
792+ inserts