{-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} -- | This module implements an AST type for SQL92. It allows us to realize -- the call structure of the builders defined in "Database.Beam.Backend.SQL.SQL92" module Database.Beam.Backend.SQL.AST where import Prelude hiding (Ordering) import Database.Beam.Backend.SQL.SQL92 import Database.Beam.Backend.SQL.SQL99 import Database.Beam.Backend.SQL.SQL2003 import Database.Beam.Backend.SQL.Types import Data.Text (Text) import Data.ByteString (ByteString) import Data.Time import Data.Word (Word16, Word32, Word64) import Data.Typeable import Data.Int data Command = SelectCommand Select | InsertCommand Insert | UpdateCommand Update | DeleteCommand Delete deriving (Show, Eq) instance IsSql92Syntax Command where type Sql92SelectSyntax Command = Select type Sql92UpdateSyntax Command = Update type Sql92InsertSyntax Command = Insert type Sql92DeleteSyntax Command = Delete selectCmd = SelectCommand insertCmd = InsertCommand updateCmd = UpdateCommand deleteCmd = DeleteCommand data Select = Select { selectTable :: SelectTable , selectOrdering :: [ Ordering ] , selectLimit, selectOffset :: Maybe Integer } deriving (Show, Eq) instance IsSql92SelectSyntax Select where type Sql92SelectSelectTableSyntax Select = SelectTable type Sql92SelectOrderingSyntax Select = Ordering selectStmt = Select data SelectTable = SelectTable { selectQuantifier :: Maybe SetQuantifier , selectProjection :: Projection , selectFrom :: Maybe From , selectWhere :: Maybe Expression , selectGrouping :: Maybe Grouping , selectHaving :: Maybe Expression } | UnionTables Bool SelectTable SelectTable | IntersectTables Bool SelectTable SelectTable | ExceptTable Bool SelectTable SelectTable deriving (Show, Eq) instance IsSql92SelectTableSyntax SelectTable where type Sql92SelectTableSelectSyntax SelectTable = Select type Sql92SelectTableExpressionSyntax SelectTable = Expression type Sql92SelectTableProjectionSyntax SelectTable = Projection type Sql92SelectTableFromSyntax SelectTable = From type Sql92SelectTableGroupingSyntax SelectTable = Grouping type Sql92SelectTableSetQuantifierSyntax SelectTable = SetQuantifier selectTableStmt = SelectTable unionTables = UnionTables intersectTables = IntersectTables exceptTable = ExceptTable data Insert = Insert { insertTable :: Text , insertFields :: [ Text ] , insertValues :: InsertValues } deriving (Show, Eq) instance IsSql92InsertSyntax Insert where type Sql92InsertValuesSyntax Insert = InsertValues insertStmt = Insert data InsertValues = InsertValues { insertValuesExpressions :: [ [ Expression ] ] } | InsertSelect { insertSelectStmt :: Select } deriving (Show, Eq) instance IsSql92InsertValuesSyntax InsertValues where type Sql92InsertValuesExpressionSyntax InsertValues = Expression type Sql92InsertValuesSelectSyntax InsertValues = Select insertSqlExpressions = InsertValues insertFromSql = InsertSelect data Update = Update { updateTable :: Text , updateFields :: [ (FieldName, Expression) ] , updateWhere :: Maybe Expression } deriving (Show, Eq) instance IsSql92UpdateSyntax Update where type Sql92UpdateFieldNameSyntax Update = FieldName type Sql92UpdateExpressionSyntax Update = Expression updateStmt = Update data Delete = Delete { deleteTable :: Text , deleteWhere :: Maybe Expression } deriving (Show, Eq) instance IsSql92DeleteSyntax Delete where type Sql92DeleteExpressionSyntax Delete = Expression deleteStmt = Delete data FieldName = QualifiedField Text Text | UnqualifiedField Text deriving (Show, Eq) instance IsSql92FieldNameSyntax FieldName where qualifiedField = QualifiedField unqualifiedField = UnqualifiedField data ComparatorQuantifier = ComparatorQuantifierAny | ComparatorQuantifierAll deriving (Show, Eq) instance IsSql92QuantifierSyntax ComparatorQuantifier where quantifyOverAll = ComparatorQuantifierAll quantifyOverAny = ComparatorQuantifierAny data ExtractField = ExtractFieldTimeZoneHour | ExtractFieldTimeZoneMinute | ExtractFieldDateTimeYear | ExtractFieldDateTimeMonth | ExtractFieldDateTimeDay | ExtractFieldDateTimeHour | ExtractFieldDateTimeMinute | ExtractFieldDateTimeSecond deriving (Show, Eq) data CastTarget = CastTargetDataType DataType | CastTargetDomainName Text deriving (Show, Eq) data DataType = DataTypeChar Bool {- Varying -} (Maybe Word) (Maybe Text) | DataTypeNationalChar Bool (Maybe Word) | DataTypeBit Bool (Maybe Word) | DataTypeNumeric (Maybe (Word, Maybe Word)) | DataTypeDecimal (Maybe (Word, Maybe Word)) | DataTypeInteger | DataTypeSmallInt | DataTypeBigInt | DataTypeFloat (Maybe Word) | DataTypeReal | DataTypeDoublePrecision | DataTypeDate | DataTypeTime (Maybe Word) {- time fractional seconds precision -} Bool {- With time zone -} | DataTypeTimeStamp (Maybe Word) Bool | DataTypeInterval ExtractField | DataTypeIntervalFromTo ExtractField ExtractField | DataTypeBoolean | DataTypeBinaryLargeObject | DataTypeCharacterLargeObject | DataTypeArray DataType Int | DataTypeRow [ (Text, DataType) ] | DataTypeDomain Text deriving (Show, Eq) instance IsSql92DataTypeSyntax DataType where domainType = DataTypeDomain charType = DataTypeChar False varCharType = DataTypeChar True nationalCharType = DataTypeNationalChar False nationalVarCharType = DataTypeNationalChar True bitType = DataTypeBit False varBitType = DataTypeBit True numericType = DataTypeNumeric decimalType = DataTypeDecimal intType = DataTypeInteger smallIntType = DataTypeSmallInt floatType = DataTypeFloat doubleType = DataTypeDoublePrecision realType = DataTypeReal dateType = DataTypeDate timeType = DataTypeTime timestampType = DataTypeTimeStamp instance IsSql99DataTypeSyntax DataType where characterLargeObjectType = DataTypeCharacterLargeObject binaryLargeObjectType = DataTypeCharacterLargeObject booleanType = DataTypeBoolean arrayType = DataTypeArray rowType = DataTypeRow instance IsSql2008BigIntDataTypeSyntax DataType where bigIntType = DataTypeBigInt data SetQuantifier = SetQuantifierAll | SetQuantifierDistinct deriving (Show, Eq) instance IsSql92AggregationSetQuantifierSyntax SetQuantifier where setQuantifierDistinct = SetQuantifierDistinct setQuantifierAll = SetQuantifierAll data Expression = ExpressionValue Value | ExpressionDefault | ExpressionRow [ Expression ] | ExpressionIn Expression [ Expression ] | ExpressionIsNull Expression | ExpressionIsNotNull Expression | ExpressionIsTrue Expression | ExpressionIsNotTrue Expression | ExpressionIsFalse Expression | ExpressionIsNotFalse Expression | ExpressionIsUnknown Expression | ExpressionIsNotUnknown Expression | ExpressionCase [(Expression, Expression)] Expression | ExpressionCoalesce [Expression] | ExpressionNullIf Expression Expression | ExpressionFieldName FieldName | ExpressionBetween Expression Expression Expression | ExpressionBinOp Text Expression Expression | ExpressionCompOp Text (Maybe ComparatorQuantifier) Expression Expression | ExpressionUnOp Text Expression | ExpressionPosition Expression Expression | ExpressionCast Expression CastTarget | ExpressionExtract ExtractField Expression | ExpressionCharLength Expression | ExpressionOctetLength Expression | ExpressionBitLength Expression | ExpressionAbs Expression | ExpressionLower Expression | ExpressionUpper Expression | ExpressionTrim Expression | ExpressionFunctionCall Expression [ Expression ] | ExpressionInstanceField Expression Text | ExpressionRefField Expression Text | ExpressionCountAll | ExpressionAgg Text (Maybe SetQuantifier) [ Expression ] | ExpressionBuiltinFunction Text [ Expression ] | ExpressionSubquery Select | ExpressionUnique Select | ExpressionDistinct Select | ExpressionExists Select | ExpressionOver Expression WindowFrame | ExpressionCurrentTimestamp deriving (Show, Eq) instance IsSqlExpressionSyntaxStringType Expression Text instance IsSql92ExpressionSyntax Expression where type Sql92ExpressionQuantifierSyntax Expression = ComparatorQuantifier type Sql92ExpressionValueSyntax Expression = Value type Sql92ExpressionSelectSyntax Expression = Select type Sql92ExpressionFieldNameSyntax Expression = FieldName type Sql92ExpressionCastTargetSyntax Expression = CastTarget type Sql92ExpressionExtractFieldSyntax Expression = ExtractField valueE = ExpressionValue rowE = ExpressionRow isNullE = ExpressionIsNull isNotNullE = ExpressionIsNotNull isTrueE = ExpressionIsTrue isNotTrueE = ExpressionIsNotTrue isFalseE = ExpressionIsFalse isNotFalseE = ExpressionIsNotFalse isUnknownE = ExpressionIsUnknown isNotUnknownE = ExpressionIsNotUnknown caseE = ExpressionCase coalesceE = ExpressionCoalesce nullIfE = ExpressionNullIf positionE = ExpressionPosition extractE = ExpressionExtract castE = ExpressionCast fieldE = ExpressionFieldName betweenE = ExpressionBetween andE = ExpressionBinOp "AND" orE = ExpressionBinOp "OR" eqE = ExpressionCompOp "==" neqE = ExpressionCompOp "<>" ltE = ExpressionCompOp "<" gtE = ExpressionCompOp ">" leE = ExpressionCompOp "<=" geE = ExpressionCompOp ">=" addE = ExpressionBinOp "+" subE = ExpressionBinOp "-" mulE = ExpressionBinOp "*" divE = ExpressionBinOp "/" modE = ExpressionBinOp "%" likeE = ExpressionBinOp "LIKE" overlapsE = ExpressionBinOp "OVERLAPS" notE = ExpressionUnOp "NOT" negateE = ExpressionUnOp "-" charLengthE = ExpressionCharLength octetLengthE = ExpressionOctetLength bitLengthE = ExpressionBitLength absE = ExpressionAbs lowerE = ExpressionLower upperE = ExpressionUpper trimE = ExpressionTrim subqueryE = ExpressionSubquery uniqueE = ExpressionUnique existsE = ExpressionExists currentTimestampE = ExpressionCurrentTimestamp defaultE = ExpressionDefault inE = ExpressionIn instance IsSql99ExpressionSyntax Expression where distinctE = ExpressionDistinct similarToE = ExpressionBinOp "SIMILAR TO" functionCallE = ExpressionFunctionCall instanceFieldE = ExpressionInstanceField refFieldE = ExpressionRefField instance IsSql92AggregationExpressionSyntax Expression where type Sql92AggregationSetQuantifierSyntax Expression = SetQuantifier countAllE = ExpressionCountAll countE q = ExpressionAgg "COUNT" q . pure sumE q = ExpressionAgg "SUM" q . pure minE q = ExpressionAgg "MIN" q . pure maxE q = ExpressionAgg "MAX" q . pure avgE q = ExpressionAgg "AVG" q . pure instance IsSql99AggregationExpressionSyntax Expression where everyE q = ExpressionAgg "EVERY" q . pure someE q = ExpressionAgg "SOME" q . pure anyE q = ExpressionAgg "ANY" q . pure instance IsSql2003EnhancedNumericFunctionsExpressionSyntax Expression where lnE = ExpressionBuiltinFunction "LN" . pure expE = ExpressionBuiltinFunction "EXP" . pure sqrtE = ExpressionBuiltinFunction "SQRT" . pure ceilE = ExpressionBuiltinFunction "CEIL" . pure floorE = ExpressionBuiltinFunction "FLOOR" . pure powerE a b = ExpressionBuiltinFunction "POWER" [a, b] instance IsSql2003EnhancedNumericFunctionsAggregationExpressionSyntax Expression where stddevPopE q = ExpressionAgg "STDDEV_POP" q . pure stddevSampE q = ExpressionAgg "STDDEV_SAMP" q . pure varPopE q = ExpressionAgg "VAR_POP" q . pure varSampE q = ExpressionAgg "VAR_SAMP" q . pure covarPopE q a b = ExpressionAgg "COVAR_POP" q [a, b] covarSampE q a b = ExpressionAgg "COVAR_SAMP" q [a, b] corrE q a b = ExpressionAgg "CORR" q [a, b] regrSlopeE q a b = ExpressionAgg "REGR_SLOPE" q [a, b] regrInterceptE q a b = ExpressionAgg "REGR_INTERCEPT" q [a, b] regrCountE q a b = ExpressionAgg "REGR_COUNT" q [a, b] regrRSquaredE q a b = ExpressionAgg "REGR_R2" q [a, b] regrAvgXE q a b = ExpressionAgg "REGR_AVGX" q [a, b] regrAvgYE q a b = ExpressionAgg "REGR_AVGY" q [a, b] regrSXXE q a b = ExpressionAgg "REGR_SXX" q [a, b] regrSXYE q a b = ExpressionAgg "REGR_SXY" q [a, b] regrSYYE q a b = ExpressionAgg "REGR_SYY" q [a, b] instance IsSql2003NtileExpressionSyntax Expression where ntileE = ExpressionAgg "NTILE" Nothing . pure instance IsSql2003LeadAndLagExpressionSyntax Expression where leadE x Nothing Nothing = ExpressionAgg "LEAD" Nothing [x] leadE x (Just y) Nothing = ExpressionAgg "LEAD" Nothing [x, y] leadE x (Just y) (Just z) = ExpressionAgg "LEAD" Nothing [x, y, z] leadE x Nothing (Just z) = ExpressionAgg "LEAD" Nothing [x, ExpressionValue (Value (1 :: Int)), z] lagE x Nothing Nothing = ExpressionAgg "LAG" Nothing [x] lagE x (Just y) Nothing = ExpressionAgg "LAG" Nothing [x, y] lagE x (Just y) (Just z) = ExpressionAgg "LAG" Nothing [x, y, z] lagE x Nothing (Just z) = ExpressionAgg "LAG" Nothing [x, ExpressionValue (Value (1 :: Int)), z] instance IsSql2003NthValueExpressionSyntax Expression where nthValueE a b = ExpressionAgg "NTH_VALUE" Nothing [a, b] instance IsSql2003ExpressionSyntax Expression where type Sql2003ExpressionWindowFrameSyntax Expression = WindowFrame overE = ExpressionOver newtype Projection = ProjExprs [ (Expression, Maybe Text ) ] deriving (Show, Eq) instance IsSql92ProjectionSyntax Projection where type Sql92ProjectionExpressionSyntax Projection = Expression projExprs = ProjExprs data Ordering = OrderingAsc Expression | OrderingDesc Expression deriving (Show, Eq) instance IsSql92OrderingSyntax Ordering where type Sql92OrderingExpressionSyntax Ordering = Expression ascOrdering = OrderingAsc descOrdering = OrderingDesc newtype Grouping = Grouping [ Expression ] deriving (Show, Eq) instance IsSql92GroupingSyntax Grouping where type Sql92GroupingExpressionSyntax Grouping = Expression groupByExpressions = Grouping data TableSource = TableNamed Text | TableFromSubSelect Select deriving (Show, Eq) instance IsSql92TableSourceSyntax TableSource where type Sql92TableSourceSelectSyntax TableSource = Select tableNamed = TableNamed tableFromSubSelect = TableFromSubSelect data From = FromTable TableSource (Maybe Text) | InnerJoin From From (Maybe Expression) | LeftJoin From From (Maybe Expression) | RightJoin From From (Maybe Expression) | OuterJoin From From (Maybe Expression) deriving (Show, Eq) instance IsSql92FromSyntax From where type Sql92FromTableSourceSyntax From = TableSource type Sql92FromExpressionSyntax From = Expression fromTable = FromTable innerJoin = InnerJoin leftJoin = LeftJoin rightJoin = RightJoin data Value where Value :: (Show a, Eq a, Typeable a) => a -> Value #define VALUE_SYNTAX_INSTANCE(ty) instance HasSqlValueSyntax Value ty where { sqlValueSyntax = Value } VALUE_SYNTAX_INSTANCE(Int) VALUE_SYNTAX_INSTANCE(Int16) VALUE_SYNTAX_INSTANCE(Int32) VALUE_SYNTAX_INSTANCE(Int64) VALUE_SYNTAX_INSTANCE(Word) VALUE_SYNTAX_INSTANCE(Word16) VALUE_SYNTAX_INSTANCE(Word32) VALUE_SYNTAX_INSTANCE(Word64) VALUE_SYNTAX_INSTANCE(Integer) VALUE_SYNTAX_INSTANCE(String) VALUE_SYNTAX_INSTANCE(Text) VALUE_SYNTAX_INSTANCE(ByteString) VALUE_SYNTAX_INSTANCE(LocalTime) VALUE_SYNTAX_INSTANCE(UTCTime) VALUE_SYNTAX_INSTANCE(Day) VALUE_SYNTAX_INSTANCE(TimeOfDay) VALUE_SYNTAX_INSTANCE(SqlNull) VALUE_SYNTAX_INSTANCE(Double) VALUE_SYNTAX_INSTANCE(Bool) instance HasSqlValueSyntax Value x => HasSqlValueSyntax Value (Maybe x) where sqlValueSyntax (Just x) = sqlValueSyntax x sqlValueSyntax Nothing = sqlValueSyntax SqlNull instance Eq Value where Value a == Value b = case cast a of Just a' -> a' == b Nothing -> False instance Show Value where showsPrec prec (Value a) = showParen (prec > app_prec) $ ("Value " ++ ). showsPrec (app_prec + 1) a where app_prec = 10 -- Window functions data WindowFrame = WindowFrame { windowFramePartitions :: Maybe [Expression] , windowFrameOrdering :: Maybe [Ordering] , windowFrameBounds :: Maybe WindowFrameBounds } deriving (Show, Eq) instance IsSql2003WindowFrameSyntax WindowFrame where type Sql2003WindowFrameExpressionSyntax WindowFrame = Expression type Sql2003WindowFrameOrderingSyntax WindowFrame = Ordering type Sql2003WindowFrameBoundsSyntax WindowFrame = WindowFrameBounds frameSyntax = WindowFrame data WindowFrameBounds = WindowFrameBounds { boundsFrom :: WindowFrameBound , boundsTo :: Maybe WindowFrameBound } deriving (Show, Eq) instance IsSql2003WindowFrameBoundsSyntax WindowFrameBounds where type Sql2003WindowFrameBoundsBoundSyntax WindowFrameBounds = WindowFrameBound fromToBoundSyntax = WindowFrameBounds data WindowFrameBound = WindowFrameUnbounded | WindowFrameBoundNRows Int deriving (Show, Eq) instance IsSql2003WindowFrameBoundSyntax WindowFrameBound where unboundedSyntax = WindowFrameUnbounded nrowsBoundSyntax = WindowFrameBoundNRows