From efd4dea6ff18e60c273d892556e19d4c62781c55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bartosz=20W=C3=B3jcik?= <bartek@sudety.it>
Date: Wed, 1 Dec 2021 21:33:02 +0100
Subject: [PATCH 1/4] minor enhancements for sqlserver dialect

---
 Language/SQL/SimpleSQL/Dialect.lhs |  7 ++++++-
 Language/SQL/SimpleSQL/Parse.lhs   | 13 ++++++++++++-
 Language/SQL/SimpleSQL/Syntax.lhs  |  3 +++
 changelog                          |  2 ++
 simple-sql-parser.cabal            |  2 +-
 stack.yaml.lock                    | 12 ++++++++++++
 6 files changed, 36 insertions(+), 3 deletions(-)
 create mode 100644 stack.yaml.lock

diff --git a/Language/SQL/SimpleSQL/Dialect.lhs b/Language/SQL/SimpleSQL/Dialect.lhs
index 05ab39f..d396022 100644
--- a/Language/SQL/SimpleSQL/Dialect.lhs
+++ b/Language/SQL/SimpleSQL/Dialect.lhs
@@ -88,6 +88,8 @@ Data types to represent different dialect options
 >     ,diPostgresSymbols :: Bool
 >      -- | allow sql server style symbols
 >     ,diSqlServerSymbols :: Bool
+>      -- | allow sql server style forCONVERT function in format @CONVERT(data_type(length), expression, style)@
+>     ,diConvertFunction :: Bool
 >     }
 >                deriving (Eq,Show,Read,Data,Typeable)
 
@@ -109,6 +111,7 @@ Data types to represent different dialect options
 >                    ,diEString = False
 >                    ,diPostgresSymbols = False
 >                    ,diSqlServerSymbols = False
+>                    ,diConvertFunction = False                     
 >                    }
 
 > -- | mysql dialect
@@ -133,7 +136,9 @@ Data types to represent different dialect options
 > sqlserver = ansi2011 {diSquareBracketQuotedIden = True
 >                      ,diAtIdentifier = True
 >                      ,diHashIdentifier = True
->                      ,diSqlServerSymbols = True }
+>                      ,diOdbc = True
+>                      ,diSqlServerSymbols = True
+>                      ,diConvertFunction = True}
 
 > addLimit :: Dialect -> Dialect
 > addLimit d = d {diKeywords = "limit": diKeywords d
diff --git a/Language/SQL/SimpleSQL/Parse.lhs b/Language/SQL/SimpleSQL/Parse.lhs
index 76eefab..284be37 100644
--- a/Language/SQL/SimpleSQL/Parse.lhs
+++ b/Language/SQL/SimpleSQL/Parse.lhs
@@ -597,6 +597,16 @@ cast: cast(expr as type)
 >        parens (Cast <$> scalarExpr
 >                     <*> (keyword_ "as" *> typeName))
 
+=== convert
+
+convertSqlServer: SqlServer dialect CONVERT(data_type(length), expression, style)
+
+> convertSqlServer :: Parser ScalarExpr
+> convertSqlServer = guardDialect diConvertFunction
+>                    *> keyword_ "convert" *>
+>                    parens (Convert <$> typeName <*> (comma *> scalarExpr)
+>                       <*> optionMaybe (comma *> unsignedInteger))
+
 === exists, unique
 
 subquery expression:
@@ -1175,6 +1185,7 @@ documenting/fixing.
 >               ,parensExpr
 >               ,caseExpr
 >               ,cast
+>               ,convertSqlServer
 >               ,arrayCtor
 >               ,multisetCtor
 >               ,nextValueFor
@@ -2027,7 +2038,7 @@ It is only allowed when all the strings are quoted with ' atm.
 >       L.Identifier q p | map toLower p `notElem` blackList -> Just (q,p)
 >       _ -> Nothing)
 
-> unquotedIdentifierTok :: [String] -> Maybe String -> Parser String
+> unquotedIdentifierTok :: [String] -> Maybe String -> Parser String 
 > unquotedIdentifierTok blackList kw = mytoken (\tok ->
 >     case (kw,tok) of
 >       (Nothing, L.Identifier Nothing p) | map toLower p `notElem` blackList -> Just p
diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs
index 5c669da..6c90cdc 100644
--- a/Language/SQL/SimpleSQL/Syntax.lhs
+++ b/Language/SQL/SimpleSQL/Syntax.lhs
@@ -167,6 +167,9 @@
 >       -- | cast(a as typename)
 >     | Cast ScalarExpr TypeName
 
+>       -- | convert expression to given datatype @CONVERT(data_type(length), expression, style)@
+>     | Convert TypeName ScalarExpr (Maybe Integer)
+
 >       -- | case expression. both flavours supported
 >     | Case
 >       {caseTest :: Maybe ScalarExpr -- ^ test value
diff --git a/changelog b/changelog
index 060028d..645c4ba 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,5 @@
+0.6.1   added odbc handling to sqlsqerver dialect	
+		added sqlserver dialect case for convert function
 0.6.0
         tested with ghc 8.8.1 also
         change the dialect handling - now a dialect is a bunch of flags
diff --git a/simple-sql-parser.cabal b/simple-sql-parser.cabal
index afe4a4f..5f2e7c1 100644
--- a/simple-sql-parser.cabal
+++ b/simple-sql-parser.cabal
@@ -1,7 +1,7 @@
 cabal-version:       2.2
 
 name:                simple-sql-parser
-version:             0.6.0
+version:             0.6.1
 synopsis:            A parser for SQL.
 
 description:
diff --git a/stack.yaml.lock b/stack.yaml.lock
new file mode 100644
index 0000000..7fb2c31
--- /dev/null
+++ b/stack.yaml.lock
@@ -0,0 +1,12 @@
+# This file was autogenerated by Stack.
+# You should not edit this file by hand.
+# For more information, please see the documentation at:
+#   https://docs.haskellstack.org/en/stable/lock_files
+
+packages: []
+snapshots:
+- completed:
+    size: 500539
+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/13/27.yaml
+    sha256: 690db832392afe55733b4c7023fd29b1b1c660ee42f1fb505b86b07394ca994e
+  original: lts-13.27

From 61275461b5a3b8010de7ccc01485fb7c5cc16a36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bartosz=20W=C3=B3jcik?= <bartek@sudety.it>
Date: Thu, 2 Dec 2021 16:50:35 +0100
Subject: [PATCH 2/4] Added tests for new added sqlserver dialect syntax.

---
 Language/SQL/SimpleSQL/Pretty.lhs            |  5 +++++
 tools/Language/SQL/SimpleSQL/LexerTests.lhs  |  4 ++--
 tools/Language/SQL/SimpleSQL/ScalarExprs.lhs | 13 ++++++++++++-
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs
index b085e83..272e63e 100644
--- a/Language/SQL/SimpleSQL/Pretty.lhs
+++ b/Language/SQL/SimpleSQL/Pretty.lhs
@@ -254,6 +254,11 @@ Try to do this when this code is ported to a modern pretty printing lib.
 > scalarExpr d (OdbcFunc e) =
 >     text "{fn" <+> scalarExpr d e <> text "}"
 
+> scalarExpr d (Convert t e Nothing) =
+>     text "convert(" <> typeName t <> text "," <+> scalarExpr d e <> text ")"
+> scalarExpr d (Convert t e (Just i)) =
+>     text "convert(" <> typeName t <> text "," <+> scalarExpr d e <> text "," <+> text (show i) <> text ")"
+
 > unname :: Name -> String
 > unname (Name Nothing n) = n
 > unname (Name (Just (s,e)) n) =
diff --git a/tools/Language/SQL/SimpleSQL/LexerTests.lhs b/tools/Language/SQL/SimpleSQL/LexerTests.lhs
index fc0a46b..14246f5 100644
--- a/tools/Language/SQL/SimpleSQL/LexerTests.lhs
+++ b/tools/Language/SQL/SimpleSQL/LexerTests.lhs
@@ -318,8 +318,8 @@ the + or -.
 >     [ LexTest sqlserver {diOdbc = True} s t | (s,t) <-
 >     [("{}", [Symbol "{", Symbol "}"])
 >     ]]
->     ++ [LexFails sqlserver "{"
->        ,LexFails sqlserver "}"]
+>     ++ [LexFails sqlserver {diOdbc = False} "{"
+>        ,LexFails sqlserver {diOdbc = False} "}"]
 
 > combos :: [a] -> Int -> [[a]]
 > combos _ 0 = [[]]
diff --git a/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs b/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs
index f2397d3..80dad53 100644
--- a/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs
+++ b/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs
@@ -5,7 +5,7 @@ Tests for parsing scalar expressions
 
 > import Language.SQL.SimpleSQL.TestTypes
 > import Language.SQL.SimpleSQL.Syntax
-
+  
 > scalarExprTests :: TestItem
 > scalarExprTests = Group "scalarExprTests"
 >     [literals
@@ -15,6 +15,7 @@ Tests for parsing scalar expressions
 >     ,dots
 >     ,app
 >     ,caseexp
+>     ,convertfun     
 >     ,operators
 >     ,parens
 >     ,subqueries
@@ -110,6 +111,16 @@ Tests for parsing scalar expressions
 
 >     ]
 
+> convertfun :: TestItem 
+> convertfun = Group "convert" $ map (uncurry (TestScalarExpr sqlserver))
+>     [("CONVERT(varchar, 25.65)"
+>      ,Convert (TypeName [Name Nothing "varchar"]) (NumLit "25.65") Nothing)
+>     ,("CONVERT(datetime, '2017-08-25')"
+>      ,Convert (TypeName [Name Nothing "datetime"]) (StringLit "'" "'" "2017-08-25") Nothing)
+>     ,("CONVERT(varchar, '2017-08-25', 101)"
+>      ,Convert (TypeName [Name Nothing "varchar"]) (StringLit "'" "'" "2017-08-25") (Just 101))
+>     ]
+
 > operators :: TestItem
 > operators = Group "operators"
 >     [binaryOperators

From b74bbefd2b108d448f1f7eebe922be9d9171fea7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bartosz=20W=C3=B3jcik?= <bartek@sudety.it>
Date: Thu, 2 Dec 2021 17:03:27 +0100
Subject: [PATCH 3/4] Delete stack.yaml.lock

---
 stack.yaml.lock | 12 ------------
 1 file changed, 12 deletions(-)
 delete mode 100644 stack.yaml.lock

diff --git a/stack.yaml.lock b/stack.yaml.lock
deleted file mode 100644
index 7fb2c31..0000000
--- a/stack.yaml.lock
+++ /dev/null
@@ -1,12 +0,0 @@
-# This file was autogenerated by Stack.
-# You should not edit this file by hand.
-# For more information, please see the documentation at:
-#   https://docs.haskellstack.org/en/stable/lock_files
-
-packages: []
-snapshots:
-- completed:
-    size: 500539
-    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/13/27.yaml
-    sha256: 690db832392afe55733b4c7023fd29b1b1c660ee42f1fb505b86b07394ca994e
-  original: lts-13.27

From 80e79ced2eb64206c26aa14a73a40d012e222bca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bartosz=20W=C3=B3jcik?= <bartek@sudety.it>
Date: Thu, 2 Dec 2021 17:04:01 +0100
Subject: [PATCH 4/4] Small editorial

---
 Language/SQL/SimpleSQL/Dialect.lhs           | 2 +-
 Language/SQL/SimpleSQL/Parse.lhs             | 2 +-
 tools/Language/SQL/SimpleSQL/ScalarExprs.lhs | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Language/SQL/SimpleSQL/Dialect.lhs b/Language/SQL/SimpleSQL/Dialect.lhs
index d396022..c6bcfb3 100644
--- a/Language/SQL/SimpleSQL/Dialect.lhs
+++ b/Language/SQL/SimpleSQL/Dialect.lhs
@@ -88,7 +88,7 @@ Data types to represent different dialect options
 >     ,diPostgresSymbols :: Bool
 >      -- | allow sql server style symbols
 >     ,diSqlServerSymbols :: Bool
->      -- | allow sql server style forCONVERT function in format @CONVERT(data_type(length), expression, style)@
+>      -- | allow sql server style for CONVERT function in format CONVERT(data_type(length), expression, style)
 >     ,diConvertFunction :: Bool
 >     }
 >                deriving (Eq,Show,Read,Data,Typeable)
diff --git a/Language/SQL/SimpleSQL/Parse.lhs b/Language/SQL/SimpleSQL/Parse.lhs
index 284be37..89a1e37 100644
--- a/Language/SQL/SimpleSQL/Parse.lhs
+++ b/Language/SQL/SimpleSQL/Parse.lhs
@@ -2038,7 +2038,7 @@ It is only allowed when all the strings are quoted with ' atm.
 >       L.Identifier q p | map toLower p `notElem` blackList -> Just (q,p)
 >       _ -> Nothing)
 
-> unquotedIdentifierTok :: [String] -> Maybe String -> Parser String 
+> unquotedIdentifierTok :: [String] -> Maybe String -> Parser String
 > unquotedIdentifierTok blackList kw = mytoken (\tok ->
 >     case (kw,tok) of
 >       (Nothing, L.Identifier Nothing p) | map toLower p `notElem` blackList -> Just p
diff --git a/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs b/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs
index 80dad53..f587e1c 100644
--- a/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs
+++ b/tools/Language/SQL/SimpleSQL/ScalarExprs.lhs
@@ -5,7 +5,7 @@ Tests for parsing scalar expressions
 
 > import Language.SQL.SimpleSQL.TestTypes
 > import Language.SQL.SimpleSQL.Syntax
-  
+
 > scalarExprTests :: TestItem
 > scalarExprTests = Group "scalarExprTests"
 >     [literals