{-| Module: Squeal.PostgreSQL.Expression.SetOf Description: Set returning functions Copyright: (c) Eitan Chatav, 2019 Maintainer: eitan@morphism.tech Stability: experimental Set returning functions -} {-# LANGUAGE AllowAmbiguousTypes , DataKinds , FlexibleContexts , OverloadedStrings , PolyKinds , RankNTypes , ScopedTypeVariables , TypeApplications , TypeOperators #-} module Squeal.PostgreSQL.Expression.SetOf ( generateSeries , generateSeriesStep , generateSeriesTimestamp , SetOfFunction , unsafeSetOfFunction , SetOfFunctionN , unsafeSetOfFunctionN ) where import GHC.TypeLits import qualified Generics.SOP as SOP import Squeal.PostgreSQL.Alias import Squeal.PostgreSQL.Expression import Squeal.PostgreSQL.List import Squeal.PostgreSQL.Render import Squeal.PostgreSQL.Query import Squeal.PostgreSQL.Schema {- | A @RankNType@ for set returning functions with 1 argument. -} type SetOfFunction fun ty setof = forall outer commons schemas params . Expression outer commons 'Ungrouped schemas params '[] ty -- ^ input -> FromClause outer commons schemas params '[fun ::: setof] -- ^ output -- | Escape hatch for a set returning function with 1 argument. unsafeSetOfFunction :: forall fun ty setof. KnownSymbol fun => SetOfFunction fun ty setof -- ^ set returning function unsafeSetOfFunction x = UnsafeFromClause $ renderSymbol @fun <> parenthesized (renderSQL x) {- | A @RankNType@ for set returning functions with multiple argument. -} type SetOfFunctionN fun tys setof = forall outer commons schemas params . NP (Expression outer commons 'Ungrouped schemas params '[]) tys -- ^ inputs -> FromClause outer commons schemas params '[fun ::: setof] -- ^ output -- | Escape hatch for a set returning function with multiple argument. unsafeSetOfFunctionN :: forall fun tys setof. (SOP.SListI tys, KnownSymbol fun) => SetOfFunctionN fun tys setof -- ^ set returning function unsafeSetOfFunctionN xs = UnsafeFromClause $ renderSymbol @fun <> parenthesized (renderCommaSeparated renderSQL xs) {- | @generateSeries (start *: stop)@ Generate a series of values, from @start@ to @stop@ with a step size of one -} generateSeries :: ty `In` '[ 'PGint4, 'PGint8, 'PGnumeric] => SetOfFunctionN "generate_series" '[ null ty, null ty] '["generate_series" ::: null ty] -- ^ set returning function generateSeries = unsafeSetOfFunctionN {- | @generateSeries (start :* stop *: step)@ Generate a series of values, from @start@ to @stop@ with a step size of @step@ -} generateSeriesStep :: ty `In` '[ 'PGint4, 'PGint8, 'PGnumeric] => SetOfFunctionN "generate_series" '[null ty, null ty, null ty] '["generate_series" ::: null ty] -- ^ set returning function generateSeriesStep = unsafeSetOfFunctionN {- | @generateSeries (start :* stop *: step)@ Generate a series of values, from @start@ to @stop@ with a step size of @step@ -} generateSeriesTimestamp :: ty `In` '[ 'PGtimestamp, 'PGtimestamptz] => SetOfFunctionN "generate_series" '[null ty, null ty, null 'PGinterval] '["generate_series" ::: null ty] -- ^ set returning function generateSeriesTimestamp = unsafeSetOfFunctionN