Data types to represent different dialect options

> {-# LANGUAGE DeriveDataTypeable #-}
> module Language.SQL.SimpleSQL.Dialect
>     (Dialect(..)
>     ,ansi2011
>     ,mysql
>     ,postgres
>     ,oracle
>     ,sqlserver
>     ) where

> import Data.Data

> -- | Used to set the dialect used for parsing and pretty printing,
> -- very unfinished at the moment.
> --
> -- The keyword handling works as follows:
> --
> -- There is a list of reserved keywords. These will never parse as
> -- anything other than as a keyword, unless they are in one of the
> -- other lists.
> --
> -- There is a list of \'identifier\' keywords. These are reserved
> -- keywords, with an exception that they will parse as an
> -- identifier in a scalar expression. They won't parse as
> -- identifiers in other places, e.g. column names or aliases.
> --
> -- There is a list of \'app\' keywords. These are reserved keywords,
> -- with an exception that they will also parse in an \'app-like\'
> -- construct - a regular function call, or any of the aggregate and
> -- window variations.
> --
> -- There is a list of special type names. This list serves two
> -- purposes - it is a list of the reserved keywords which are also
> -- type names, and it is a list of all the multi word type names.
> --
> -- Every keyword should appear in the keywords lists, and then you can
> -- add them to the other lists if you want exceptions. Most things
> -- that refer to functions, types or variables that are keywords in
> -- the ansi standard, can be removed from the keywords lists
> -- completely with little effect. With most of the actual SQL
> -- keywords, removing them from the keyword list will result in
> -- lots of valid syntax no longer parsing (and probably bad parse
> -- error messages too).
> --
> -- In the code, all special syntax which looks identical to regular
> -- identifiers or function calls (apart from the name), is treated
> -- like a regular identifier or function call.
> --
> -- It's easy to break the parser by removing the wrong words from
> -- the keywords list or adding the wrong words to the other lists.
>
> data Dialect = Dialect
>     { -- | reserved keywords
>      Dialect -> [String]
diKeywords :: [String]
>       -- | keywords with identifier exception
>     ,Dialect -> [String]
diIdentifierKeywords :: [String]
>       -- | keywords with app exception
>     ,Dialect -> [String]
diAppKeywords :: [String]
>      -- | keywords with type exception plus all the type names which
>      -- are multiple words
>     ,Dialect -> [String]
diSpecialTypeNames :: [String]
>      -- | allow ansi fetch first syntax
>     ,Dialect -> Bool
diFetchFirst :: Bool
>      -- | allow limit keyword (mysql, postgres,
>      -- ...)
>     ,Dialect -> Bool
diLimit :: Bool
>      -- | allow parsing ODBC syntax
>     ,Dialect -> Bool
diOdbc :: Bool
>      -- | allow quoting identifiers with \`backquotes\`
>     ,Dialect -> Bool
diBackquotedIden :: Bool
>      -- | allow quoting identifiers with [square brackets]
>     ,Dialect -> Bool
diSquareBracketQuotedIden :: Bool
>      -- | allow identifiers with a leading at @example
>     ,Dialect -> Bool
diAtIdentifier :: Bool
>      -- | allow identifiers with a leading \# \#example
>     ,Dialect -> Bool
diHashIdentifier :: Bool
>      -- | allow positional identifiers like this: $1 
>     ,Dialect -> Bool
diPositionalArg :: Bool
>      -- | allow postgres style dollar strings
>     ,Dialect -> Bool
diDollarString :: Bool
>      -- | allow strings with an e - e"example"
>     ,Dialect -> Bool
diEString :: Bool
>      -- | allow postgres style symbols
>     ,Dialect -> Bool
diPostgresSymbols :: Bool
>      -- | allow sql server style symbols
>     ,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)

> -- | ansi sql 2011 dialect
> 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
mysql = Dialect -> Dialect
addLimit Dialect
ansi2011 {diFetchFirst :: Bool
diFetchFirst = Bool
False
>                           ,diBackquotedIden :: Bool
diBackquotedIden = Bool
True
>                           }

> -- | postgresql dialect
> 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
oracle = Dialect
ansi2011 -- {}

> -- | microsoft sql server dialect
> 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 =
>     [--"abs" -- function
>      "all" -- keyword only?
>     ,"allocate" -- keyword
>     ,"alter" -- keyword
>     ,"and" -- keyword
>     --,"any" -- keyword? and function
>     ,"are" -- keyword
>     ,"array" -- keyword, and used in some special places, like array[...], and array(subquery)
>     --,"array_agg" -- function
>     -- ,"array_max_cardinality" -- function
>     ,"as" -- keyword
>     ,"asensitive" -- keyword
>     ,"asymmetric" -- keyword
>     ,"at" -- keyword
>     ,"atomic" -- keyword
>     ,"authorization" -- keyword
>     --,"avg" -- function
>     ,"begin" -- keyword
>     --,"begin_frame" -- identifier
>     --,"begin_partition" -- identifier
>     ,"between" -- keyword
>     ,"bigint" -- type
>     ,"binary" -- type
>     ,"blob" -- type
>     ,"boolean" -- type
>     ,"both" -- keyword
>     ,"by" -- keyword
>     ,"call" -- keyword
>     ,"called" -- keyword
>     -- ,"cardinality" -- function + identifier?
>     ,"cascaded" -- keyword
>     ,"case" -- keyword
>     ,"cast" -- special function
>     -- ,"ceil" -- function
>     -- ,"ceiling" -- function
>     ,"char"  -- type (+ keyword?)
>     --,"char_length" -- function
>     ,"character" -- type
>     --,"character_length" -- function
>     ,"check" -- keyword
>     ,"clob" -- type
>     ,"close" -- keyword
>     -- ,"coalesce" -- function
>     ,"collate" -- keyword
>     --,"collect" -- function
>     ,"column" -- keyword
>     ,"commit" -- keyword
>     ,"condition" -- keyword
>     ,"connect" -- keyword
>     ,"constraint" --keyword
>     --,"contains" -- keyword?
>     --,"convert" -- function?
>     --,"corr" -- function
>     ,"corresponding" --keyword
>     --,"count" --function
>     --,"covar_pop" -- function
>     --,"covar_samp" --function
>     ,"create" -- keyword
>     ,"cross" -- keyword
>     ,"cube" -- keyword
>     --,"cume_dist" -- function
>     ,"current" -- keyword
>     -- ,"current_catalog" --identifier?
>     --,"current_date" -- identifier
>     --,"current_default_transform_group"  -- identifier
>     --,"current_path"  -- identifier
>     --,"current_role"  -- identifier
>     -- ,"current_row"  -- identifier
>     -- ,"current_schema"  -- identifier
>     -- ,"current_time"  -- identifier
>     --,"current_timestamp"  -- identifier
>     --,"current_transform_group_for_type"  -- identifier, or keyword?
>     --,"current_user" -- identifier
>     ,"cursor" -- keyword
>     ,"cycle" --keyword
>     ,"date" -- type
>     --,"day" -- keyword? - the parser needs it to not be a keyword to parse extract at the moment
>     ,"deallocate" -- keyword
>     ,"dec" -- type
>     ,"decimal" -- type
>     ,"declare" -- keyword
>     --,"default" -- identifier + keyword
>     ,"delete" -- keyword
>     --,"dense_rank" -- functino
>     ,"deref" -- keyword
>     ,"describe"  -- keyword
>     ,"deterministic"
>     ,"disconnect"
>     ,"distinct"
>     ,"double"
>     ,"drop"
>     ,"dynamic"
>     ,"each"
>     --,"element"
>     ,"else"
>     ,"end"
>     -- ,"end_frame"  -- identifier
>     -- ,"end_partition"  -- identifier
>     ,"end-exec" -- no idea what this is
>     ,"equals"
>     ,"escape"
>     --,"every"
>     ,"except"
>     ,"exec"
>     ,"execute"
>     ,"exists"
>     ,"exp"
>     ,"external"
>     ,"extract"
>     --,"false"
>     ,"fetch"
>     ,"filter"
>     -- ,"first_value"
>     ,"float"
>     --,"floor"
>     ,"for"
>     ,"foreign"
>     -- ,"frame_row"  -- identifier
>     ,"free"
>     ,"from"
>     ,"full"
>     ,"function"
>     --,"fusion"
>     ,"get"
>     ,"global"
>     ,"grant"
>     ,"group"
>     --,"grouping"
>     ,"groups"
>     ,"having"
>     ,"hold"
>     --,"hour"
>     ,"identity"
>     ,"in"
>     ,"indicator"
>     ,"inner"
>     ,"inout"
>     ,"insensitive"
>     ,"insert"
>     ,"int"
>     ,"integer"
>     ,"intersect"
>     --,"intersection"
>     ,"interval"
>     ,"into"
>     ,"is"
>     ,"join"
>     --,"lag"
>     ,"language"
>     ,"large"
>     --,"last_value"
>     ,"lateral"
>     --,"lead"
>     ,"leading"
>     ,"left"
>     ,"like"
>     ,"like_regex"
>     --,"ln"
>     ,"local"
>     ,"localtime"
>     ,"localtimestamp"
>     --,"lower"
>     ,"match"
>     --,"max"
>     ,"member"
>     ,"merge"
>     ,"method"
>     --,"min"
>     --,"minute"
>     --,"mod"
>     ,"modifies"
>     --,"module"
>     --,"month"
>     ,"multiset"
>     ,"national"
>     ,"natural"
>     ,"nchar"
>     ,"nclob"
>     ,"new"
>     ,"no"
>     ,"none"
>     ,"normalize"
>     ,"not"
>     --,"nth_value"
>     ,"ntile"
>     --,"null"
>     --,"nullif"
>     ,"numeric"
>     ,"octet_length"
>     ,"occurrences_regex"
>     ,"of"
>     ,"offset"
>     ,"old"
>     ,"on"
>     ,"only"
>     ,"open"
>     ,"or"
>     ,"order"
>     ,"out"
>     ,"outer"
>     ,"over"
>     ,"overlaps"
>     ,"overlay"
>     ,"parameter"
>     ,"partition"
>     ,"percent"
>     --,"percent_rank"
>     --,"percentile_cont"
>     --,"percentile_disc"
>     ,"period"
>     ,"portion"
>     ,"position"
>     ,"position_regex"
>     --,"power"
>     ,"precedes"
>     ,"precision"
>     ,"prepare"
>     ,"primary"
>     ,"procedure"
>     ,"range"
>     --,"rank"
>     ,"reads"
>     ,"real"
>     ,"recursive"
>     ,"ref"
>     ,"references"
>     ,"referencing"
>     --,"regr_avgx"
>     --,"regr_avgy"
>     --,"regr_count"
>     --,"regr_intercept"
>     --,"regr_r2"
>     --,"regr_slope"
>     --,"regr_sxx"
>     --,"regr_sxy"
>     --,"regr_syy"
>     ,"release"
>     ,"result"
>     ,"return"
>     ,"returns"
>     ,"revoke"
>     ,"right"
>     ,"rollback"
>     ,"rollup"
>     --,"row"
>     --,"row_number"
>     ,"rows"
>     ,"savepoint"
>     ,"scope"
>     ,"scroll"
>     ,"search"
>     --,"second"
>     ,"select"
>     ,"sensitive"
>     --,"session_user"
>     ,"set"
>     ,"similar"
>     ,"smallint"
>     --,"some"
>     ,"specific"
>     ,"specifictype"
>     ,"sql"
>     ,"sqlexception"
>     ,"sqlstate"
>     ,"sqlwarning"
>     --,"sqrt"
>     --,"start"
>     ,"static"
>     --,"stddev_pop"
>     --,"stddev_samp"
>     ,"submultiset"
>     --,"substring"
>     ,"substring_regex"
>     ,"succeeds"
>     --,"sum"
>     ,"symmetric"
>     ,"system"
>     --,"system_time"
>     --,"system_user"
>     ,"table"
>     ,"tablesample"
>     ,"then"
>     ,"time"
>     ,"timestamp"
>     ,"timezone_hour"
>     ,"timezone_minute"
>     ,"to"
>     ,"trailing"
>     ,"translate"
>     ,"translate_regex"
>     ,"translation"
>     ,"treat"
>     ,"trigger"
>     ,"truncate"
>     --,"trim"
>     --,"trim_array"
>     --,"true"
>     ,"uescape"
>     ,"union"
>     ,"unique"
>     --,"unknown"
>     ,"unnest"
>     ,"update"
>     ,"upper"
>     --,"user"
>     ,"using"
>     --,"value"
>     ,"values"
>     ,"value_of"
>     --,"var_pop"
>     --,"var_samp"
>     ,"varbinary"
>     ,"varchar"
>     ,"varying"
>     ,"versioning"
>     ,"when"
>     ,"whenever"
>     ,"where"
>     --,"width_bucket"
>     ,"window"
>     ,"with"
>     ,"within"
>     ,"without"
>     --,"year"
>     ]


> 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"
>         -- reserved keyword typenames:
>     ,"array"
>     ,"bigint"
>     ,"binary"
>     ,"blob"
>     ,"boolean"
>     ,"char"
>     ,"character"
>     ,"clob"
>     ,"date"
>     ,"dec"
>     ,"decimal"
>     ,"double"
>     ,"float"
>     ,"int"
>     ,"integer"
>     ,"nchar"
>     ,"nclob"
>     ,"numeric"
>     ,"real"
>     ,"smallint"
>     ,"time"
>     ,"timestamp"
>     ,"varchar"
>     ,"varbinary"
>     ]