@@ -108,9 +108,8 @@ coalesce
108108 -> Expression params tables grouping ('Required ('NotNull x))
109109 -> Expression params tables grouping ('Required ('NotNull x))
110110coalesce nulls isn'tNull = UnsafeExpression $
111− "COALESCE"
112− <> parenthesized (commaSeparated (renderExpression <$> nulls))
113− <> ", " <> renderExpression isn'tNull
111+ "COALESCE" <> parenthesized (commaSeparated
112+ ((renderExpression <$> nulls) <> [renderExpression isn'tNull]))
114113
115114unsafeBinaryOp
116115 :: ByteString
@@ -384,12 +383,18 @@ data By
384383 (tables :: [(Symbol,[(Symbol,ColumnType)])])
385384 (tabcol :: (Symbol,Symbol)) where
386385 By
386+ :: (tables ~ '[table ::: columns], HasColumn column columns ty)
387+ => Alias column
388+ -> By tables '(table, column)
389+ By2
387390 :: (HasTable table tables columns, HasColumn column columns ty)
388391 => (Alias table, Alias column)
389392 -> By tables '(table, column)
390393
391394renderBy :: By tables tabcolty -> ByteString
392−renderBy (By (table, column)) = renderAlias table <> "." <> renderAlias column
395+renderBy = \case
396+ By column -> renderAlias column
397+ By2 (table, column) -> renderAlias table <> "." <> renderAlias column
393398
394399data GroupByClause tables grouping where
395400 NoGroups :: GroupByClause tables 'Ungrouped
@@ -866,14 +871,84 @@ createTable
866871 :: (KnownSymbol table, SListI columns)
867872 => Alias table
868873 -> NP (Aliased TypeExpression) columns
874+ -> [TableConstraint schema columns]
869875 -> Definition schema (Create table columns schema)
870−createTable table columns = UnsafeDefinition $
876+createTable table columns constraints = UnsafeDefinition $
871877 "CREATE TABLE" <+> renderAlias table
872− <+> parenthesized (renderCommaSeparated renderColumn columns) <> ";"
878+ <+> parenthesized
879+ ( renderCommaSeparated renderColumnDef columns
880+ <> renderConstraints constraints )
881+ <> ";"
873882 where
874− renderColumn :: Aliased TypeExpression x -> ByteString
875− renderColumn (ty `As` column) =
883+ renderColumnDef :: Aliased TypeExpression x -> ByteString
884+ renderColumnDef (ty `As` column) =
876885 renderAlias column <+> renderTypeExpression ty
886+ renderConstraints :: [TableConstraint schema columns] -> ByteString
887+ renderConstraints = \case
888+ [] -> ""
889+ _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
890+
891+data TableConstraint
892+ (schema :: [(Symbol,[(Symbol,ColumnType)])])
893+ (columns :: [(Symbol,ColumnType)])
894+ = UnsafeTableConstraint { renderTableConstraint :: ByteString }
895+
896+check
897+ :: Condition '[] '[table ::: columns] 'Ungrouped
898+ -> TableConstraint schema columns
899+check condition = UnsafeTableConstraint $
900+ "CHECK" <+> parenthesized (renderExpression condition)
901+
902+data Column
903+ (columns :: [(Symbol,ColumnType)])
904+ (columnty :: (Symbol,ColumnType))
905+ where
906+ Column
907+ :: HasColumn column columns ty
908+ => Alias column
909+ -> Column columns (column ::: ty)
910+
911+renderColumn :: Column columns columnty -> ByteString
912+renderColumn (Column column) = renderAlias column
913+
914+unique
915+ :: SListI subcolumns
916+ => NP (Column columns) subcolumns
917+ -> TableConstraint schema columns
918+unique columns = UnsafeTableConstraint $
919+ "UNIQUE" <+> parenthesized (renderCommaSeparated renderColumn columns)
920+
921+primaryKey
922+ :: (SListI subcolumns, NotNullTypes subcolumns)
923+ => NP (Column columns) subcolumns
924+ -> TableConstraint schema columns
925+primaryKey columns = UnsafeTableConstraint $
926+ "PRIMARY KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
927+
928+type family SameTypes columns0 columns1 :: Constraint where
929+ SameTypes '[] '[] = ()
930+ SameTypes ((column0 ::: ty0) ': columns0) ((column1 ::: ty1) ': columns1)
931+ = (ty0 ~ ty1, SameTypes columns0 columns1)
932+
933+type family NotNullTypes columns :: Constraint where
934+ NotNullTypes '[] = ()
935+ NotNullTypes ((column ::: (optionality ('NotNull ty))) ': columns)
936+ = NotNullTypes columns
937+
938+foreignKey
939+ :: ( HasTable reftable schema refcolumns
940+ , SameTypes subcolumns refsubcolumns
941+ , NotNullTypes subcolumns
942+ , SListI subcolumns
943+ , SListI refsubcolumns)
944+ => NP (Column columns) subcolumns
945+ -> Alias reftable
946+ -> NP (Column refcolumns) refsubcolumns
947+ -> TableConstraint schema columns
948+foreignKey columns reftable refcolumns = UnsafeTableConstraint $
949+ "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
950+ <+> "REFERENCES" <+> renderAlias reftable
951+ <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
877952
878953{-----------------------------------------
879954DROP statements