From 7a847045163feb2339ab40ebe93afe2f1c9ad813 Mon Sep 17 00:00:00 2001
From: Jake Wheat <jakewheatmail@gmail.com>
Date: Fri, 18 Apr 2014 21:48:14 +0300
Subject: [PATCH] implement reference type name (I think - cannot find any
 examples or   explanation of what it means, didn't try reading the standard  
 itself, just the grammar)

---
 Language/SQL/SimpleSQL/Parser.lhs        | 7 ++++++-
 Language/SQL/SimpleSQL/Pretty.lhs        | 5 +++++
 Language/SQL/SimpleSQL/Syntax.lhs        | 1 +
 tools/Language/SQL/SimpleSQL/SQL2003.lhs | 5 +++--
 4 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs
index 3c7c04d..1517acc 100644
--- a/Language/SQL/SimpleSQL/Parser.lhs
+++ b/Language/SQL/SimpleSQL/Parser.lhs
@@ -530,7 +530,7 @@ TODO: this need heavy refactoring
 
 > typeName :: Parser TypeName
 > typeName =
->     (rowTypeName <|> intervalTypeName <|> otherTypeName)
+>     (rowTypeName <|> intervalTypeName <|> ref <|> otherTypeName)
 >     >>= tnSuffix
 >     <?> "typename"
 >   where
@@ -542,6 +542,11 @@ TODO: this need heavy refactoring
 >     intervalTypeName =
 >         keyword_ "interval" >>
 >         uncurry IntervalTypeName <$> intervalQualifier
+>     ref =
+>         keyword_ "ref" >>
+>         RefTypeName
+>         <$> parens (names)
+>         <*> optionMaybe (keyword_ "scope" *> names)
 >     -- other type names, which includes:
 >     -- precision, scale, lob scale and units, timezone, character
 >     -- set and collations
diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs
index 50e9744..48002ab 100644
--- a/Language/SQL/SimpleSQL/Pretty.lhs
+++ b/Language/SQL/SimpleSQL/Pretty.lhs
@@ -284,6 +284,11 @@ which have been changed to try to improve the layout of the output.
 > typeName (MultisetTypeName tn) =
 >     typeName tn <+> text "multiset"
 
+> typeName (RefTypeName rt sc) =
+>     text "ref"
+>     <> parens (names rt)
+>     <+> me (\x -> text "scope" <+> names x) sc
+
 > intervalTypeField :: IntervalTypeField -> Doc
 > intervalTypeField (Itf n p) =
 >     text n
diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs
index a1b3742..e2aeef1 100644
--- a/Language/SQL/SimpleSQL/Syntax.lhs
+++ b/Language/SQL/SimpleSQL/Syntax.lhs
@@ -174,6 +174,7 @@ TODO: add ref and scope, any others?
 >     | IntervalTypeName IntervalTypeField (Maybe IntervalTypeField)
 >     | ArrayTypeName TypeName (Maybe Integer)
 >     | MultisetTypeName TypeName
+>     | RefTypeName [Name] (Maybe [Name])
 >       deriving (Eq,Show,Read,Data,Typeable)
 
 > data IntervalTypeField = Itf String (Maybe (Integer, Maybe Integer))
diff --git a/tools/Language/SQL/SimpleSQL/SQL2003.lhs b/tools/Language/SQL/SimpleSQL/SQL2003.lhs
index 320e66b..63aa6ca 100644
--- a/tools/Language/SQL/SimpleSQL/SQL2003.lhs
+++ b/tools/Language/SQL/SimpleSQL/SQL2003.lhs
@@ -987,8 +987,7 @@ create a list of type name variations:
 >         ,"timestamp"]
 >         --interval -- not allowed without interval qualifier
 >         --row -- not allowed without row type body
->         --ref -- todo
->         --scope -- todo
+>         --ref -- not allowed without reference type
 >         -- array -- not allowed on own
 >         -- multiset -- not allowed on own
 
@@ -1092,6 +1091,8 @@ create a list of type name variations:
 >          ,("interval year(4) to second(2,3)"
 >           ,IntervalTypeName (Itf "year" $ Just (4,Nothing))
 >                             (Just $ Itf "second" $ Just (2, Just 3)))
+>          ,("ref (t)", RefTypeName [Name "t"] Nothing)
+>          ,("ref (t) scope q", RefTypeName [Name "t"] (Just [Name "q"]))
 >          ]
 
 Now test each variation in both cast expression and typed literal