1
Fork 0

modify basic typenames to support dotted names in the syntax

add syntax for most of the other kinds of typenames
add pretty printing for these
todo: the parsing and the tests
This commit is contained in:
Jake Wheat 2014-04-18 17:55:56 +03:00
parent 438e3383e4
commit fbdcacc604
4 changed files with 120 additions and 22 deletions

View file

@ -121,7 +121,7 @@ which parses as a typed literal
> ((,) <$> identifierBlacklist blacklist > ((,) <$> identifierBlacklist blacklist
> <*> optionMaybe (parens unsignedInteger)) > <*> optionMaybe (parens unsignedInteger))
> where > where
> mkIt val Nothing = TypedLit (TypeName "interval") val > mkIt val Nothing = TypedLit (TypeName [Name "interval"]) val
> mkIt val (Just (a,b)) = IntervalLit val a b > mkIt val (Just (a,b)) = IntervalLit val a b
> characterSetLiteral :: Parser ValueExpr > characterSetLiteral :: Parser ValueExpr
@ -514,12 +514,13 @@ that SQL supports.
> typeName :: Parser TypeName > typeName :: Parser TypeName
> typeName = > typeName =
> (choice [multiWordParsers > (choice [try multiWordParsers
> ,TypeName <$> identifierBlacklist blacklist] > ,mktn <$> identifierBlacklist blacklist]
> >>= optionSuffix precision > >>= optionSuffix precision
> ) <?> "typename" > ) <?> "typename"
> where > where
> multiWordParsers = (TypeName . unwords) <$> makeKeywordTree > mktn = TypeName . (:[]) . Name
> multiWordParsers = mktn . unwords <$> makeKeywordTree
> ["double precision" > ["double precision"
> ,"character varying" > ,"character varying"
> ,"char varying" > ,"char varying"

View file

@ -208,10 +208,53 @@ which have been changed to try to improve the layout of the output.
> names ns = hcat $ punctuate (text ".") $ map name ns > names ns = hcat $ punctuate (text ".") $ map name ns
> typeName :: TypeName -> Doc > typeName :: TypeName -> Doc
> typeName (TypeName t) = text t > typeName (TypeName t) = names t
> typeName (PrecTypeName t a) = text t <+> parens (text $ show a) > typeName (PrecTypeName t a) = names t <+> parens (text $ show a)
> typeName (PrecScaleTypeName t a b) = > typeName (PrecScaleTypeName t a b) =
> text t <+> parens (text (show a) <+> comma <+> text (show b)) > names t <+> parens (text (show a) <+> comma <+> text (show b))
> typeName (LobTypeName t i m u) =
> names t
> <> parens (text (show i)
> <> me (\x -> case x of
> LobK -> text "K"
> LobM -> text "M"
> LobG -> text "G") m)
> <+> me (\x -> case x of
> LobCharacters -> text "CHARACTERS"
> LobCodeUnits -> text "CODE_UNITS"
> LobOctets -> text "OCTETS") u
> typeName (CharTypeName t i cs col) =
> names t
> <> me (\x -> parens (text $ show x)) i
> <+> (if null cs
> then empty
> else text "character set" <+> names cs)
> <+> me (\x -> text "collate" <+> name x) col
> typeName (TimeTypeName t i tz) =
> names t
> <> me (\x -> parens (text $ show x)) i
> <+> text (if tz
> then "with time zone"
> else "without time zone")
> typeName (RowTypeName cs) =
> text "row" <> parens (commaSep $ map f cs)
> where
> f (n,t) = name n <+> typeName t
> typeName (IntervalTypeName f t) =
> text "interval"
> <+> it f
> <+> me (\x -> text "to" <+> it x) t
> where
> it (Itf n p) =
> text n
> <+> me (\(x,x1) -> parens (text (show x)
> <+> me (\y -> (sep [comma,text (show y)])) x1)) p
> typeName (ArrayType tn sz) =
> typeName tn <+> text "array" <+> me (text . show) sz
> typeName (MultisetType tn) =
> typeName tn <+> text "multiset"
= query expressions = query expressions

View file

@ -6,6 +6,9 @@
> ValueExpr(..) > ValueExpr(..)
> ,Name(..) > ,Name(..)
> ,TypeName(..) > ,TypeName(..)
> ,IntervalTypeField(..)
> ,LobMultiplier(..)
> ,LobUnits(..)
> ,SetQuantifier(..) > ,SetQuantifier(..)
> ,SortSpec(..) > ,SortSpec(..)
> ,Direction(..) > ,Direction(..)
@ -151,10 +154,31 @@
> | QName String > | QName String
> deriving (Eq,Show,Read,Data,Typeable) > deriving (Eq,Show,Read,Data,Typeable)
TODO: add ref and scope, any others?
> -- | Represents a type name, used in casts. > -- | Represents a type name, used in casts.
> data TypeName = TypeName String > data TypeName
> | PrecTypeName String Integer > = TypeName [Name]
> | PrecScaleTypeName String Integer Integer > | PrecTypeName [Name] Integer
> | PrecScaleTypeName [Name] Integer Integer
> | LobTypeName [Name] Int (Maybe LobMultiplier) (Maybe LobUnits)
> -- precision, characterset, collate
> | CharTypeName [Name] (Maybe Integer) [Name] (Maybe Name)
> | TimeTypeName [Name] (Maybe Integer) Bool -- true == with time zone
> | RowTypeName [(Name,TypeName)]
> | IntervalTypeName IntervalTypeField (Maybe IntervalTypeField)
> | ArrayType TypeName (Maybe Integer)
> | MultisetType TypeName
> deriving (Eq,Show,Read,Data,Typeable)
> data IntervalTypeField = Itf String (Maybe (Int, Maybe Int))
> deriving (Eq,Show,Read,Data,Typeable)
> data LobMultiplier = LobK | LobM | LobG
> deriving (Eq,Show,Read,Data,Typeable)
> data LobUnits = LobCharacters
> | LobCodeUnits
> | LobOctets
> deriving (Eq,Show,Read,Data,Typeable) > deriving (Eq,Show,Read,Data,Typeable)
> -- | Used for 'expr in (value expression list)', and 'expr in > -- | Used for 'expr in (value expression list)', and 'expr in

View file

@ -21,10 +21,10 @@ large amount of the SQL.
> ,unicodeStringLiterals > ,unicodeStringLiterals
> ,binaryStringLiterals > ,binaryStringLiterals
> ,numericLiterals > ,numericLiterals
> ,dateAndTimeLiterals > --,dateAndTimeLiterals
> ,booleanLiterals > ,booleanLiterals
> --,identifiers > --,identifiers
> --,typeNames > ,typeNameTests
> --,parenthesizedValueExpression > --,parenthesizedValueExpression
> ,targetSpecification > ,targetSpecification
> ,contextuallyTypeValueSpec > ,contextuallyTypeValueSpec
@ -657,11 +657,12 @@ TODO: separator stuff for all the string literals?
<datetime value> ::= <unsigned integer> <datetime value> ::= <unsigned integer>
All these date literals are just like a restricted version of string TODO: interval literals
literals. This parser doesn't check the format inside these literals + consider whether to support date and time literals better
at this time. (e.g. parse the literal string), at the moment they are treated as
normal typed literals
> dateAndTimeLiterals :: TestItem > {-dateAndTimeLiterals :: TestItem
> dateAndTimeLiterals = Group "date and time literals" $ map (uncurry TestValueExpr) > dateAndTimeLiterals = Group "date and time literals" $ map (uncurry TestValueExpr)
> [("date 'date literal'" > [("date 'date literal'"
> ,TypedLit (TypeName "date") "date literal") > ,TypedLit (TypeName "date") "date literal")
@ -669,7 +670,7 @@ at this time.
> ,TypedLit (TypeName "time") "time literal") > ,TypedLit (TypeName "time") "time literal")
> ,("timestamp 'timestamp literal'" > ,("timestamp 'timestamp literal'"
> ,TypedLit (TypeName "timestamp") "timestamp literal") > ,TypedLit (TypeName "timestamp") "timestamp literal")
> ] > ]-}
TODO: intervals + more date and time literals TODO: intervals + more date and time literals
@ -924,9 +925,38 @@ TODO: module stuff
<multiset type> ::= <data type> MULTISET <multiset type> ::= <data type> MULTISET
TODO: review this list better and fill in lots of missing bits: create a list of type name variations:
> typeNames :: TestItem > typeNames :: [(String,TypeName)]
> typeNames =
> [-- example of every standard type name
> ("character", TypeName "character")
> -- 1 single prec + 1 with multiname
> -- 1 scale + with multiname
> -- lob prec + with multiname
> -- 1 with and without tz
> -- chars: (single/multiname) x prec x charset x collate
> -- single row field, two row field
> -- interval each type raw
> -- one type with single suff
> -- one type with double suff
> -- a to b with raw
> -- a to b with single suff
> ]
Now test each variation in both cast expression and typed literal
expression
> typeNameTests :: TestItem
> typeNameTests = Group "type names" $ map (uncurry TestValueExpr)
> $ concatMap makeTests typeNames
> where
> makeTests (ctn, stn) =
> [("cast('test' as " ++ ctn ++ ")", Cast (StringLit "test") stn)
> ,(ctn ++ " 'test'", TypedLit stn "test")
> ]
> {-typeNames :: TestItem
> typeNames = Group "type names" $ map (uncurry TestValueExpr) > typeNames = Group "type names" $ map (uncurry TestValueExpr)
> [("cast('test' as character(5))", undefined) > [("cast('test' as character(5))", undefined)
> ,("cast('test' as character)", undefined) > ,("cast('test' as character)", undefined)
@ -966,7 +996,7 @@ TODO: review this list better and fill in lots of missing bits:
> ,("cast('01-01-99' as timestamp(3))", undefined) > ,("cast('01-01-99' as timestamp(3))", undefined)
> ,("cast('01-01-99' as timestamp with time zone)", undefined) > ,("cast('01-01-99' as timestamp with time zone)", undefined)
> ,("cast('01-01-99' as time(3) with time zone)", undefined) > ,("cast('01-01-99' as time(3) with time zone)", undefined)
> ] > ]-}
@ -975,7 +1005,7 @@ TODO: review this list better and fill in lots of missing bits:
<field definition> ::= <field name> <data type> [ <reference scope check> ] <field definition> ::= <field name> <data type> [ <reference scope check> ]
This is used when e.g. casting to a row type. TODO This is used when e.g. casting to a row type.
@ -1108,7 +1138,7 @@ for or how it works
<default specification> ::= DEFAULT <default specification> ::= DEFAULT
> contextuallyTypeValueSpec :: TestItem > contextuallyTypeValueSpec :: TestItem
> contextuallyTypeValueSpec = Group "ontextually typed value specification" $ map (uncurry TestValueExpr) > contextuallyTypeValueSpec = Group "contextually typed value specification" $ map (uncurry TestValueExpr)
> [("null", Iden "null") > [("null", Iden "null")
> ,("array[]", Array (Iden "array") []) > ,("array[]", Array (Iden "array") [])
> --,("multiset[]", undefined) > --,("multiset[]", undefined)