Data types to represent different dialect options
> {-# LANGUAGE DeriveDataTypeable #-}
> module Language.SQL.SimpleSQL.Dialect
> (Dialect(..)
> ,ansi2011
> ,mysql
> ,postgres
> ,oracle
> ,sqlserver
> ) where
> import Data.Data
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> data Dialect = Dialect
> {
> Dialect -> [String]
diKeywords :: [String]
>
> ,Dialect -> [String]
diIdentifierKeywords :: [String]
>
> ,Dialect -> [String]
diAppKeywords :: [String]
>
>
> ,Dialect -> [String]
diSpecialTypeNames :: [String]
>
> ,Dialect -> Bool
diFetchFirst :: Bool
>
>
> ,Dialect -> Bool
diLimit :: Bool
>
> ,Dialect -> Bool
diOdbc :: Bool
>
> ,Dialect -> Bool
diBackquotedIden :: Bool
>
> ,Dialect -> Bool
diSquareBracketQuotedIden :: Bool
>
> ,Dialect -> Bool
diAtIdentifier :: Bool
>
> ,Dialect -> Bool
diHashIdentifier :: Bool
>
> ,Dialect -> Bool
diPositionalArg :: Bool
>
> ,Dialect -> Bool
diDollarString :: Bool
>
> ,Dialect -> Bool
diEString :: Bool
>
> ,Dialect -> Bool
diPostgresSymbols :: Bool
>
> ,Dialect -> Bool
diSqlServerSymbols :: Bool
> }
> deriving (Dialect -> Dialect -> Bool
(Dialect -> Dialect -> Bool)
-> (Dialect -> Dialect -> Bool) -> Eq Dialect
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Dialect -> Dialect -> Bool
$c/= :: Dialect -> Dialect -> Bool
== :: Dialect -> Dialect -> Bool
$c== :: Dialect -> Dialect -> Bool
Eq,Int -> Dialect -> ShowS
[Dialect] -> ShowS
Dialect -> String
(Int -> Dialect -> ShowS)
-> (Dialect -> String) -> ([Dialect] -> ShowS) -> Show Dialect
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Dialect] -> ShowS
$cshowList :: [Dialect] -> ShowS
show :: Dialect -> String
$cshow :: Dialect -> String
showsPrec :: Int -> Dialect -> ShowS
$cshowsPrec :: Int -> Dialect -> ShowS
Show,ReadPrec [Dialect]
ReadPrec Dialect
Int -> ReadS Dialect
ReadS [Dialect]
(Int -> ReadS Dialect)
-> ReadS [Dialect]
-> ReadPrec Dialect
-> ReadPrec [Dialect]
-> Read Dialect
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Dialect]
$creadListPrec :: ReadPrec [Dialect]
readPrec :: ReadPrec Dialect
$creadPrec :: ReadPrec Dialect
readList :: ReadS [Dialect]
$creadList :: ReadS [Dialect]
readsPrec :: Int -> ReadS Dialect
$creadsPrec :: Int -> ReadS Dialect
Read,Typeable Dialect
DataType
Constr
Typeable Dialect =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Dialect -> c Dialect)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Dialect)
-> (Dialect -> Constr)
-> (Dialect -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Dialect))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Dialect))
-> ((forall b. Data b => b -> b) -> Dialect -> Dialect)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r)
-> (forall u. (forall d. Data d => d -> u) -> Dialect -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Dialect -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect)
-> Data Dialect
Dialect -> DataType
Dialect -> Constr
(forall b. Data b => b -> b) -> Dialect -> Dialect
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Dialect -> c Dialect
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Dialect
forall a.
Typeable a =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Dialect -> u
forall u. (forall d. Data d => d -> u) -> Dialect -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Dialect
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Dialect -> c Dialect
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Dialect)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Dialect)
$cDialect :: Constr
$tDialect :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Dialect -> m Dialect
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect
gmapMp :: (forall d. Data d => d -> m d) -> Dialect -> m Dialect
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect
gmapM :: (forall d. Data d => d -> m d) -> Dialect -> m Dialect
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Dialect -> m Dialect
gmapQi :: Int -> (forall d. Data d => d -> u) -> Dialect -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Dialect -> u
gmapQ :: (forall d. Data d => d -> u) -> Dialect -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Dialect -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Dialect -> r
gmapT :: (forall b. Data b => b -> b) -> Dialect -> Dialect
$cgmapT :: (forall b. Data b => b -> b) -> Dialect -> Dialect
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Dialect)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Dialect)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Dialect)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Dialect)
dataTypeOf :: Dialect -> DataType
$cdataTypeOf :: Dialect -> DataType
toConstr :: Dialect -> Constr
$ctoConstr :: Dialect -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Dialect
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Dialect
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Dialect -> c Dialect
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Dialect -> c Dialect
$cp1Data :: Typeable Dialect
Data,Typeable)
>
> ansi2011 :: Dialect
> ansi2011 :: Dialect
ansi2011 = Dialect :: [String]
-> [String]
-> [String]
-> [String]
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Dialect
Dialect {diKeywords :: [String]
diKeywords = [String]
ansi2011ReservedKeywords
> ,diIdentifierKeywords :: [String]
diIdentifierKeywords = []
> ,diAppKeywords :: [String]
diAppKeywords = ["set"]
> ,diSpecialTypeNames :: [String]
diSpecialTypeNames = [String]
ansi2011TypeNames
> ,diFetchFirst :: Bool
diFetchFirst = Bool
True
> ,diLimit :: Bool
diLimit = Bool
False
> ,diOdbc :: Bool
diOdbc = Bool
False
> ,diBackquotedIden :: Bool
diBackquotedIden = Bool
False
> ,diSquareBracketQuotedIden :: Bool
diSquareBracketQuotedIden = Bool
False
> ,diAtIdentifier :: Bool
diAtIdentifier = Bool
False
> ,diHashIdentifier :: Bool
diHashIdentifier = Bool
False
> ,diPositionalArg :: Bool
diPositionalArg = Bool
False
> ,diDollarString :: Bool
diDollarString = Bool
False
> ,diEString :: Bool
diEString = Bool
False
> ,diPostgresSymbols :: Bool
diPostgresSymbols = Bool
False
> ,diSqlServerSymbols :: Bool
diSqlServerSymbols = Bool
False
> }
>
> mysql :: Dialect
> mysql :: Dialect
mysql = Dialect -> Dialect
addLimit Dialect
ansi2011 {diFetchFirst :: Bool
diFetchFirst = Bool
False
> ,diBackquotedIden :: Bool
diBackquotedIden = Bool
True
> }
>
> postgres :: Dialect
> postgres :: Dialect
postgres = Dialect -> Dialect
addLimit Dialect
ansi2011 {diPositionalArg :: Bool
diPositionalArg = Bool
True
> ,diDollarString :: Bool
diDollarString = Bool
True
> ,diEString :: Bool
diEString = Bool
True
> ,diPostgresSymbols :: Bool
diPostgresSymbols = Bool
True}
>
> oracle :: Dialect
> oracle :: Dialect
oracle = Dialect
ansi2011
>
> sqlserver :: Dialect
> sqlserver :: Dialect
sqlserver = Dialect
ansi2011 {diSquareBracketQuotedIden :: Bool
diSquareBracketQuotedIden = Bool
True
> ,diAtIdentifier :: Bool
diAtIdentifier = Bool
True
> ,diHashIdentifier :: Bool
diHashIdentifier = Bool
True
> ,diSqlServerSymbols :: Bool
diSqlServerSymbols = Bool
True }
> addLimit :: Dialect -> Dialect
> addLimit :: Dialect -> Dialect
addLimit d :: Dialect
d = Dialect
d {diKeywords :: [String]
diKeywords = "limit"String -> [String] -> [String]
forall a. a -> [a] -> [a]
: Dialect -> [String]
diKeywords Dialect
d
> ,diLimit :: Bool
diLimit = Bool
True}
The keyword handling is quite strong - an alternative way to do it
would be to have as few keywords as possible, and only require them
to be quoted when this is needed to resolve a parsing ambiguity.
I don't think this is a good idea for genuine keywords (it probably is
for all the 'fake' keywords in the standard - things which are
essentially function names, or predefined variable names, or type
names, eetc.).
1. working out exactly when each keyword would need to be quoted is
quite error prone, and might change as the parser implementation is
maintained - which would be terrible for users
2. it's not user friendly for the user to deal with a whole load of
special cases - either something is a keyword, then you know you must
always quote it, or it isn't, then you know you never need to quote
it
3. I think not having exceptions makes for better error messages for
the user, and a better sql code maintenance experience.
This might not match actual existing SQL products that well, some of
which I think have idiosyncratic rules about when a keyword must be
quoted. If you want to match one of these dialects exactly with this
parser, I think it will be a lot of work.
> ansi2011ReservedKeywords :: [String]
> ansi2011ReservedKeywords :: [String]
ansi2011ReservedKeywords =
> [
> "all"
> ,"allocate"
> ,"alter"
> ,"and"
>
> ,"are"
> ,"array"
>
>
> ,"as"
> ,"asensitive"
> ,"asymmetric"
> ,"at"
> ,"atomic"
> ,"authorization"
>
> ,"begin"
>
>
> ,"between"
> ,"bigint"
> ,"binary"
> ,"blob"
> ,"boolean"
> ,"both"
> ,"by"
> ,"call"
> ,"called"
>
> ,"cascaded"
> ,"case"
> ,"cast"
>
>
> ,"char"
>
> ,"character"
>
> ,"check"
> ,"clob"
> ,"close"
>
> ,"collate"
>
> ,"column"
> ,"commit"
> ,"condition"
> ,"connect"
> ,"constraint"
>
>
>
> ,"corresponding"
>
>
>
> ,"create"
> ,"cross"
> ,"cube"
>
> ,"current"
>
>
>
>
>
>
>
>
>
>
>
> ,"cursor"
> ,"cycle"
> ,"date"
>
> ,"deallocate"
> ,"dec"
> ,"decimal"
> ,"declare"
>
> ,"delete"
>
> ,"deref"
> ,"describe"
> ,"deterministic"
> ,"disconnect"
> ,"distinct"
> ,"double"
> ,"drop"
> ,"dynamic"
> ,"each"
>
> ,"else"
> ,"end"
>
>
> ,"end-exec"
> ,"equals"
> ,"escape"
>
> ,"except"
> ,"exec"
> ,"execute"
> ,"exists"
> ,"exp"
> ,"external"
> ,"extract"
>
> ,"fetch"
> ,"filter"
>
> ,"float"
>
> ,"for"
> ,"foreign"
>
> ,"free"
> ,"from"
> ,"full"
> ,"function"
>
> ,"get"
> ,"global"
> ,"grant"
> ,"group"
>
> ,"groups"
> ,"having"
> ,"hold"
>
> ,"identity"
> ,"in"
> ,"indicator"
> ,"inner"
> ,"inout"
> ,"insensitive"
> ,"insert"
> ,"int"
> ,"integer"
> ,"intersect"
>
> ,"interval"
> ,"into"
> ,"is"
> ,"join"
>
> ,"language"
> ,"large"
>
> ,"lateral"
>
> ,"leading"
> ,"left"
> ,"like"
> ,"like_regex"
>
> ,"local"
> ,"localtime"
> ,"localtimestamp"
>
> ,"match"
>
> ,"member"
> ,"merge"
> ,"method"
>
>
>
> ,"modifies"
>
>
> ,"multiset"
> ,"national"
> ,"natural"
> ,"nchar"
> ,"nclob"
> ,"new"
> ,"no"
> ,"none"
> ,"normalize"
> ,"not"
>
> ,"ntile"
>
>
> ,"numeric"
> ,"octet_length"
> ,"occurrences_regex"
> ,"of"
> ,"offset"
> ,"old"
> ,"on"
> ,"only"
> ,"open"
> ,"or"
> ,"order"
> ,"out"
> ,"outer"
> ,"over"
> ,"overlaps"
> ,"overlay"
> ,"parameter"
> ,"partition"
> ,"percent"
>
>
>
> ,"period"
> ,"portion"
> ,"position"
> ,"position_regex"
>
> ,"precedes"
> ,"precision"
> ,"prepare"
> ,"primary"
> ,"procedure"
> ,"range"
>
> ,"reads"
> ,"real"
> ,"recursive"
> ,"ref"
> ,"references"
> ,"referencing"
>
>
>
>
>
>
>
>
>
> ,"release"
> ,"result"
> ,"return"
> ,"returns"
> ,"revoke"
> ,"right"
> ,"rollback"
> ,"rollup"
>
>
> ,"rows"
> ,"savepoint"
> ,"scope"
> ,"scroll"
> ,"search"
>
> ,"select"
> ,"sensitive"
>
> ,"set"
> ,"similar"
> ,"smallint"
>
> ,"specific"
> ,"specifictype"
> ,"sql"
> ,"sqlexception"
> ,"sqlstate"
> ,"sqlwarning"
>
>
> ,"static"
>
>
> ,"submultiset"
>
> ,"substring_regex"
> ,"succeeds"
>
> ,"symmetric"
> ,"system"
>
>
> ,"table"
> ,"tablesample"
> ,"then"
> ,"time"
> ,"timestamp"
> ,"timezone_hour"
> ,"timezone_minute"
> ,"to"
> ,"trailing"
> ,"translate"
> ,"translate_regex"
> ,"translation"
> ,"treat"
> ,"trigger"
> ,"truncate"
>
>
>
> ,"uescape"
> ,"union"
> ,"unique"
>
> ,"unnest"
> ,"update"
> ,"upper"
>
> ,"using"
>
> ,"values"
> ,"value_of"
>
>
> ,"varbinary"
> ,"varchar"
> ,"varying"
> ,"versioning"
> ,"when"
> ,"whenever"
> ,"where"
>
> ,"window"
> ,"with"
> ,"within"
> ,"without"
>
> ]
> ansi2011TypeNames :: [String]
> ansi2011TypeNames :: [String]
ansi2011TypeNames =
> ["double precision"
> ,"character varying"
> ,"char varying"
> ,"character large object"
> ,"char large object"
> ,"national character"
> ,"national char"
> ,"national character varying"
> ,"national char varying"
> ,"national character large object"
> ,"nchar large object"
> ,"nchar varying"
> ,"bit varying"
> ,"binary large object"
> ,"binary varying"
>
> ,"array"
> ,"bigint"
> ,"binary"
> ,"blob"
> ,"boolean"
> ,"char"
> ,"character"
> ,"clob"
> ,"date"
> ,"dec"
> ,"decimal"
> ,"double"
> ,"float"
> ,"int"
> ,"integer"
> ,"nchar"
> ,"nclob"
> ,"numeric"
> ,"real"
> ,"smallint"
> ,"time"
> ,"timestamp"
> ,"varchar"
> ,"varbinary"
> ]