From 61e7a89416904d3ccb8beaa1f53155ec3d2528bf Mon Sep 17 00:00:00 2001 From: Jake Wheat Date: Sat, 8 Aug 2015 20:49:23 +0300 Subject: [PATCH] work on website --- .gitignore | 3 +- website/RenderTestCases.lhs | 62 ++++ website/index.txt | 416 +++++++++++++++++++++++++++ website/main.css | 138 +++++++++ website/make_website.sh | 26 ++ website/ocean.css | 546 ++++++++++++++++++++++++++++++++++++ website/supported_sql.txt | 161 +++++++++++ 7 files changed, 1351 insertions(+), 1 deletion(-) create mode 100644 website/RenderTestCases.lhs create mode 100644 website/index.txt create mode 100644 website/main.css create mode 100755 website/make_website.sh create mode 100644 website/ocean.css create mode 100644 website/supported_sql.txt diff --git a/.gitignore b/.gitignore index fc9501b..79a949b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /dist/ /logchanges /cabal.sandbox.config -/.cabal-sandbox/ \ No newline at end of file +/.cabal-sandbox/ +/build/ diff --git a/website/RenderTestCases.lhs b/website/RenderTestCases.lhs new file mode 100644 index 0000000..11a57cc --- /dev/null +++ b/website/RenderTestCases.lhs @@ -0,0 +1,62 @@ + +Converts the test data to markdown + +> import Language.SQL.SimpleSQL.Tests +> import Text.Show.Pretty +> import Control.Monad.State +> import Language.SQL.SimpleSQL.Parser +> import Language.SQL.SimpleSQL.Lexer + +> data TableItem = Heading Int String +> | Row String String + +> doc :: Int -> TestItem -> [TableItem] +> doc n (Group nm is) = +> Heading n nm +> : concatMap (doc (n + 1)) is +> doc _ (TestValueExpr _ str e) = +> [Row str (ppShow e)] +> doc _ (TestQueryExpr _ str e) = +> [Row str (ppShow e)] +> doc _ (TestStatement _ str e) = +> [Row str (ppShow e)] +> doc _ (TestStatements _ str e) = +> [Row str (ppShow e)] +> doc _ (ParseQueryExpr d str) = +> [Row str (ppShow $ parseQueryExpr d "" Nothing str)] +> doc _ (ParseQueryExprFails d str) = +> [Row str (ppShow $ parseQueryExpr d "" Nothing str)] +> doc _ (ParseValueExprFails d str) = +> [Row str (ppShow $ parseValueExpr d "" Nothing str)] + +> doc _ (LexerTest d str t) = +> -- todo: figure out how to handle this: +> -- too many entries, but want to show the lexing +> -- a bit +> -- [Row str (ppShow $ lexSQL d "" Nothing str)] +> [] +> -- should probably think about doing something similar +> -- with other generated combination tests such as the typename +> -- tests + +TODO: should put the dialect in the html output + + +> render :: [TableItem] -> IO () +> render = go False +> where +> go t (Heading level title : is) = do +> when t $ putStrLn "" +> putStrLn $ replicate level '#' ++ " " ++ title +> go False is +> go t (Row sql hask : is) = do +> unless t $ putStrLn "" +> let sql' = "\n~~~~{.sql}\n" ++ sql ++ "\n~~~~\n" +> hask' = "\n~~~~{.haskell}\n" ++ hask ++ "\n~~~~\n" +> putStrLn $ "" +> go True is +> go t [] = when t $ putStrLn "
" ++ sql' +> ++ "" ++ hask' ++ "
" + +> main :: IO () +> main = render $ doc 1 testData diff --git a/website/index.txt b/website/index.txt new file mode 100644 index 0000000..c04cffd --- /dev/null +++ b/website/index.txt @@ -0,0 +1,416 @@ +# simple-sql-parser + +A parser for SQL in Haskell. Also includes a pretty printer which +formats output nicely. Current target is to parse most SQL:2011 +queries, plus a good subset of DDL, non-query DML, transaction +management, access control and session management. + +This is the documentation for version 0.5.0. + +Status: Covers a lot of queries already, but the public API is +probably not very stable, since adding support for all the +not-yet-supported ANSI SQL syntax, then other dialects of SQL is +likely to change the abstract syntax types considerably. + +Tested with GHC 7.10.2, 7.8.4 and 7.6.3. + +# Examples + +Simple expression: + +~~~~{.sql} +select a + b * c +~~~~ + +Parsed AST: + +~~~~{.haskell} +Select{qeSetQuantifier = All, + qeSelectList = + [(BinOp (Iden (Name "a")) (Name "+") + (BinOp (Iden (Name "b")) (Name "*") (Iden (Name "c"))), + Nothing)], + qeFrom = [], qeWhere = Nothing, qeGroupBy = [], qeHaving = Nothing, + qeOrderBy = [], qeOffset = Nothing, qeFetchFirst = Nothing} +~~~~ + +TPC-H query 21: + +~~~~{.sql} +select + s_name, + count(*) as numwait +from + supplier, + lineitem l1, + orders, + nation +where + s_suppkey = l1.l_suppkey + and o_orderkey = l1.l_orderkey + and o_orderstatus = 'F' + and l1.l_receiptdate > l1.l_commitdate + and exists ( + select + * + from + lineitem l2 + where + l2.l_orderkey = l1.l_orderkey + and l2.l_suppkey <> l1.l_suppkey + ) + and not exists ( + select + * + from + lineitem l3 + where + l3.l_orderkey = l1.l_orderkey + and l3.l_suppkey <> l1.l_suppkey + and l3.l_receiptdate > l3.l_commitdate + ) + and s_nationkey = n_nationkey + and n_name = 'INDIA' +group by + s_name +order by + numwait desc, + s_name +fetch first 100 rows only; +~~~~ + +Parsed: + +~~~~{.haskell} +Select{qeSetQuantifier = All, + qeSelectList = + [(Iden (Name "s_name"), Nothing), + (App (Name "count") [Star], Just (Name "numwait"))], + qeFrom = + [TRSimple (Name "supplier"), + TRAlias (TRSimple (Name "lineitem")) (Alias (Name "l1") Nothing), + TRSimple (Name "orders"), TRSimple (Name "nation")], + qeWhere = + Just + (BinOp + (BinOp + (BinOp + (BinOp + (BinOp + (BinOp + (BinOp + (BinOp (Iden (Name "s_suppkey")) (Name "=") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_suppkey")))) + (Name "and") + (BinOp (Iden (Name "o_orderkey")) (Name "=") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_orderkey"))))) + (Name "and") + (BinOp (Iden (Name "o_orderstatus")) (Name "=") (StringLit "F"))) + (Name "and") + (BinOp + (BinOp (Iden (Name "l1")) (Name ".") (Iden (Name "l_receiptdate"))) + (Name ">") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_commitdate"))))) + (Name "and") + (SubQueryExpr SqExists + (Select{qeSetQuantifier = All, qeSelectList = [(Star, Nothing)], + qeFrom = + [TRAlias (TRSimple (Name "lineitem")) + (Alias (Name "l2") Nothing)], + qeWhere = + Just + (BinOp + (BinOp + (BinOp (Iden (Name "l2")) (Name ".") + (Iden (Name "l_orderkey"))) + (Name "=") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_orderkey")))) + (Name "and") + (BinOp + (BinOp (Iden (Name "l2")) (Name ".") + (Iden (Name "l_suppkey"))) + (Name "<>") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_suppkey"))))), + qeGroupBy = [], qeHaving = Nothing, qeOrderBy = [], + qeOffset = Nothing, qeFetchFirst = Nothing}))) + (Name "and") + (PrefixOp (Name "not") + (SubQueryExpr SqExists + (Select{qeSetQuantifier = All, qeSelectList = [(Star, Nothing)], + qeFrom = + [TRAlias (TRSimple (Name "lineitem")) + (Alias (Name "l3") Nothing)], + qeWhere = + Just + (BinOp + (BinOp + (BinOp + (BinOp (Iden (Name "l3")) (Name ".") + (Iden (Name "l_orderkey"))) + (Name "=") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_orderkey")))) + (Name "and") + (BinOp + (BinOp (Iden (Name "l3")) (Name ".") + (Iden (Name "l_suppkey"))) + (Name "<>") + (BinOp (Iden (Name "l1")) (Name ".") + (Iden (Name "l_suppkey"))))) + (Name "and") + (BinOp + (BinOp (Iden (Name "l3")) (Name ".") + (Iden (Name "l_receiptdate"))) + (Name ">") + (BinOp (Iden (Name "l3")) (Name ".") + (Iden (Name "l_commitdate"))))), + qeGroupBy = [], qeHaving = Nothing, qeOrderBy = [], + qeOffset = Nothing, qeFetchFirst = Nothing})))) + (Name "and") + (BinOp (Iden (Name "s_nationkey")) (Name "=") + (Iden (Name "n_nationkey")))) + (Name "and") + (BinOp (Iden (Name "n_name")) (Name "=") (StringLit "INDIA"))), + qeGroupBy = [SimpleGroup (Iden (Name "s_name"))], + qeHaving = Nothing, + qeOrderBy = + [SortSpec (Iden (Name "numwait")) Desc NullsOrderDefault, + SortSpec (Iden (Name "s_name")) Asc NullsOrderDefault], + qeOffset = Nothing, qeFetchFirst = Just (NumLit "100")}) + +~~~~ + +Output from the simple-sql-parser pretty printer: + +~~~~{.sql} +select s_name, count(*) as numwait +from supplier, + lineitem as l1, + orders, + nation +where s_suppkey = l1.l_suppkey + and o_orderkey = l1.l_orderkey + and o_orderstatus = 'F' + and l1.l_receiptdate > l1.l_commitdate + and exists (select * + from lineitem as l2 + where l2.l_orderkey = l1.l_orderkey + and l2.l_suppkey <> l1.l_suppkey) + and not exists (select * + from lineitem as l3 + where l3.l_orderkey = l1.l_orderkey + and l3.l_suppkey <> l1.l_suppkey + and l3.l_receiptdate > l3.l_commitdate) + and s_nationkey = n_nationkey + and n_name = 'INDIA' +group by s_name +order by numwait desc, s_name +fetch first 100 rows only; +~~~~ + +# Feature support + +* query expressions +* * select lists +* * from clause +* * where clause +* * group by clause +* * having clause +* * order by clause +* * offset and fetch +* * set operators +* * common table expressions +* * wide range of value expressions +* DDL +* * TODO +* non-query DML +* * TODO +* Access control +* * TODO +* Transaction management +* * TODO +* Session management +* * TODO + +See the [supported_sql.html](supported_sql.html) page for details on +the supported SQL. + +Here is a document with all the [simple-sql-parser test +cases](test_cases.html) rendered in a webpage so you can get an idea +of what it supports. + +# Installation + +Installing the latest release from Hackage. + +~~~~ +cabal update && cabal install simple-sql-parser +~~~~ + +Working with the latest development version: + +~~~~ +git clone https://github.com/JakeWheat/simple-sql-parser.git +cd simple-sql-parser +cabal sandbox init +cabal install --only-dependencies +cabal build +~~~~ + +## Running the tests + +Get the source using 'cabal unpack' or 'git clone', then change to the +source directory. + +You can run the tests using cabal: + +~~~~ +cabal sandbox init +cabal install --only-dependencies --enable-tests +cabal configure --enable-tests +cabal test +~~~~ + +Or you can run them directly which gives more options. The tests use +tasty, which provides the command line options. + +~~~~ +cabal sandbox init +cabal install --only-dependencies --enable-tests +cabal configure --enable-tests +cabal build +dist/build/Tests/Tests +~~~~ + +--hide-successes is a good option to use: + +~~~~ +dist/build/Tests/Tests --hide-successes +~~~~ + +# Documentation + +* see the [simple-sql-parser test cases](test_cases.html) for + examples. +* [simple-sql-parser haddock](haddock/index.html) (the haddock on + Hackage has source links) + +# Recommended reading + +Here is some recommended reading on understanding SQL in depth. +\ +\ +\ +SQL: The Complete Reference, 3rd Edition, James R. Groff, Paul +N. Weinberg, Andrew J. Oppel + +This is a comprehensive book which covers up to the SQL:1999 standard. +\ +\ +\ +SQL in a Nutshell, Kevin Kline, Brand Hunt, Daniel Kline + +This is another good book which covers some of the SQL:2003 and +SQL:2008 standards. This means it covers a few newer things like +window functions which 'SQL: The Complete Reference' doesn't. It also +compares some main SQL product dialects. +\ +\ +\ +SQL A Comparative Survey, Hugh Darwen +http://bookboon.com/en/sql-a-comparative-survey-ebook + +This is a book about SQL from a relational theory perspective. +\ +\ +\ +SQL and Relational Theory, 2nd Edition, Chris Date + +This also covers SQL from a partly theoretical perspective. +\ +\ +\ +A Guide to the SQL Standard, C. J. Date, Hugh Darwen + +This is a fantastic book for covering all the little details of the +SQL standard in depth. It only covers up to SQL:92. +\ +\ +\ +There are several other good books by Chris Date, some with Hugh +Darwen and others, for instance 'Introduction to Database Systems', +'Temporal Data & the Relational Model, Databases', 'Types and the +Relational Model'. Only the first one (Introduction to +Database Systems) really relates to SQL. +\ +\ +\ +Database Systems: The Complete Book, Hector Garcia-Molina, Jeff Ullman, and Jennifer Widom. + +This book is very comprehensive and has some interesting sections. +\ +\ +\ +Some of the SQL draft standards are available to download for free (follow the +links on the wikipedia page for SQL). They are a little tricky to +read and understand. +\ +\ +\ +TODO: add web links for the pdfs below +\ +\ +\ +IBM DB2 10.5 SQL Reference Volume 1 + + +\ +\ +\ +Oracle SQL Reference 12c release 1 + + +\ +\ +\ +Teradata: + +TODO +\ +\ +\ +Microsoft SQL Server 2012 TSQL reference online. I didn't find a PDF +for this. + + +\ +\ +\ +PostgreSQL 9.3 manual: + + + +No PDF for the Postgres manual either, but the web pages are very +readable. +\ +\ +\ +SQL BNF Grammars + +http://savage.net.au/SQL/index.html + +# Links + +* Homepage: +* Hackage: +* Repository: +* Bug tracker: + +# Contact + +jakewheatmail@gmail.com diff --git a/website/main.css b/website/main.css new file mode 100644 index 0000000..355afea --- /dev/null +++ b/website/main.css @@ -0,0 +1,138 @@ +h1, h2 { + display:block; + background-color: #f0f0f0; + border-top: thin #c0c0c0 solid; + /*position:relative;*/ + padding-left:1ex; + /*z-index: -10;*/ +} +h1 { + font-size: x-large; + /*left: -3ex;*/ + margin-top: 3ex; + /*width: 100%;*/ +} +h2 { + font-size: large; + /*left: -1.5ex;*/ + margin-top: 1.5ex; + /*width: 100%;*/ +} +body { + margin-left: 5em; + margin-right: 5em; + margin-bottom: 5em; + margin-top: 2em; +} +#TOC { + float:right; + z-index:10; + background-color: #f0f0f0; + border: thin #c0c0c0 solid; + padding:2ex; +} +.header { + /*position:relative; + left: -4ex;*/ + border-top: thin #c0c0c0 solid; + border-bottom: thin #c0c0c0 solid; + display:inline; + padding: 1ex; + background-color: #f0f0f0; + font-weight: bold; +} +.footer { + text-align: center; + font-size: small; +} +pre { + padding: 0.5ex; +} + + +pre { + background-color: #f0f0f0; +} + +/* +.SqlPostgresql pre.sourceCode { + padding: 0.5em; + background-color: #f0f6f6; +} +.sql pre.sourceCode { + padding: 0.5em; + background-color: #f0f6f6; +} +.GeneratedSql .SqlPostgresql pre.sourceCode, .SqlPostgresql .GeneratedSql pre.sourceCode { + padding: 0.5em; + background-color: #f0f6e0; +} +.UnusedSql .SqlPostgresql pre.sourceCode, .SqlPostgresql .UnusedSql pre.sourceCode { + padding: 0.5em; + background-color: #e9e9e9; +} +.haskell,.Haskell pre.sourceCode { + background-color: #f5f5d9; +} + +.sh pre.sourceCode { + padding: 0.5em; + background-color: #f0f0f0; +} +*/ +table, tr, td { + border-collapse:collapse; + cell-padding:2px; + cell-spacing:2px; +/* padding:2px + spacing:2px + margin:2px*/ + vertical-align:top; +} +td pre { + width: 98%; + height: 98%; + vertical-align:top; +} +table { + width:100%; + table-layout:fixed; +} +td { + width: 50%; + vertical-align:top; + overflow:auto; +} +hr { + border: 0; + color: black; + background-color: black; + height: 1px; + width: 75%; +} + +.tablediv { + width:100%; +} + +/* higlighting kate */ + +table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre + { /*margin: 2; padding: 2; border: 2; */ vertical-align: baseline; border: none; } +td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; } +td.sourceCode { padding-left: 5px; } +pre.sourceCode { } +pre.sourceCode span.Normal { } +pre.sourceCode span.Keyword { color: #007020; font-weight: bold; } +pre.sourceCode span.DataType { color: #902000; } +pre.sourceCode span.DecVal { color: #40a070; } +pre.sourceCode span.BaseN { color: #40a070; } +pre.sourceCode span.Float { color: #40a070; } +pre.sourceCode span.Char { color: #4070a0; } +pre.sourceCode span.String { color: #4070a0; } +pre.sourceCode span.Comment { color: #60a0b0; font-style: italic; } +pre.sourceCode span.Others { color: #007020; } +pre.sourceCode span.Alert { color: red; font-weight: bold; } +pre.sourceCode span.Function { color: #06287e; } +pre.sourceCode span.RegionMarker { } +pre.sourceCode span.Error { color: red; font-weight: bold; } diff --git a/website/make_website.sh b/website/make_website.sh new file mode 100755 index 0000000..1281791 --- /dev/null +++ b/website/make_website.sh @@ -0,0 +1,26 @@ +#! /bin/sh + +set -x +set -e + +# todo: check this is run from the project root and not the website/ +# dir + +mkdir -p build +cp website/main.css build +cp website/ocean.css build + +# index +pandoc --from=markdown --to=html website/index.txt -o build/index.html -c main.css --title=simple-sql-parser --toc +pandoc --from=markdown --to=html website/supported_sql.txt -o build/supported_sql.html -c main.css '--title=simple-sql-parser supported SQL' --toc +# tpch sql file +# pandoc src/tpch.sql -s --highlight-style kate -o tpch.sql.html +# rendered test cases +runhaskell -package-db=.cabal-sandbox/x86_64-linux-ghc-7.10.2-packages.conf.d -i:tools website/RenderTestCases.lhs > build/test_cases.txt +pandoc --from=markdown --to=html build/test_cases.txt -o build/test_cases.html -c main.css '--title=simple-sql-parser examples/test cases' --toc +rm build/test_cases.txt +# haddock +cabal haddock +rm -Rf build/haddock +mkdir build/haddock/ +cp -R dist/doc/html/simple-sql-parser/* build/haddock/ diff --git a/website/ocean.css b/website/ocean.css new file mode 100644 index 0000000..4223870 --- /dev/null +++ b/website/ocean.css @@ -0,0 +1,546 @@ +/* @group Fundamentals */ + +* { margin: 0; padding: 0 } + +/* Is this portable? */ +html { + background-color: white; + width: 100%; + height: 100%; +} + +body { + background: white; + color: black; + text-align: left; + min-height: 100%; + position: relative; +} + +p { + margin: 0.8em 0; +} + +ul, ol { + margin: 0.8em 0 0.8em 2em; +} + +dl { + margin: 0.8em 0; +} + +dt { + font-weight: bold; +} +dd { + margin-left: 2em; +} + +a { text-decoration: none; } +a[href]:link { color: rgb(196,69,29); } +a[href]:visited { color: rgb(171,105,84); } +a[href]:hover { text-decoration:underline; } + +/* @end */ + +/* @group Fonts & Sizes */ + +/* Basic technique & IE workarounds from YUI 3 + For reasons, see: + http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css + */ + +body { + font:13px/1.4 sans-serif; + *font-size:small; /* for IE */ + *font:x-small; /* for IE in quirks mode */ +} + +h1 { font-size: 146.5%; /* 19pt */ } +h2 { font-size: 131%; /* 17pt */ } +h3 { font-size: 116%; /* 15pt */ } +h4 { font-size: 100%; /* 13pt */ } +h5 { font-size: 100%; /* 13pt */ } + +select, input, button, textarea { + font:99% sans-serif; +} + +table { + font-size:inherit; + font:100%; +} + +pre, code, kbd, samp, tt, .src { + font-family:monospace; + *font-size:108%; + line-height: 124%; +} + +.links, .link { + font-size: 85%; /* 11pt */ +} + +#module-header .caption { + font-size: 182%; /* 24pt */ +} + +.info { + font-size: 85%; /* 11pt */ +} + +#table-of-contents, #synopsis { + /* font-size: 85%; /* 11pt */ +} + + +/* @end */ + +/* @group Common */ + +.caption, h1, h2, h3, h4, h5, h6 { + font-weight: bold; + color: rgb(78,98,114); + margin: 0.8em 0 0.4em; +} + +* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 { + margin-top: 2em; +} + +h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 { + margin-top: inherit; +} + +ul.links { + list-style: none; + text-align: left; + float: right; + display: inline-table; + margin: 0 0 0 1em; +} + +ul.links li { + display: inline; + border-left: 1px solid #d5d5d5; + white-space: nowrap; + padding: 0; +} + +ul.links li a { + padding: 0.2em 0.5em; +} + +.hide { display: none; } +.show { display: inherit; } +.clear { clear: both; } + +.collapser { + background-image: url(minus.gif); + background-repeat: no-repeat; +} +.expander { + background-image: url(plus.gif); + background-repeat: no-repeat; +} +p.caption.collapser, +p.caption.expander { + background-position: 0 0.4em; +} +.collapser, .expander { + padding-left: 14px; + margin-left: -14px; + cursor: pointer; +} + +pre { + padding: 0.25em; + margin: 0.8em 0; + background: rgb(229,237,244); + overflow: auto; + border-bottom: 0.25em solid white; + /* white border adds some space below the box to compensate + for visual extra space that paragraphs have between baseline + and the bounding box */ +} + +.src { + background: #f0f0f0; + padding: 0.2em 0.5em; +} + +.keyword { font-weight: normal; } +.def { font-weight: bold; } + + +/* @end */ + +/* @group Page Structure */ + +#content { + margin: 0 auto; + padding: 0 2em 6em; +} + +#package-header { + background: rgb(41,56,69); + border-top: 5px solid rgb(78,98,114); + color: #ddd; + padding: 0.2em; + position: relative; + text-align: left; +} + +#package-header .caption { + background: url(hslogo-16.png) no-repeat 0em; + color: white; + margin: 0 2em; + font-weight: normal; + font-style: normal; + padding-left: 2em; +} + +#package-header a:link, #package-header a:visited { color: white; } +#package-header a:hover { background: rgb(78,98,114); } + +#module-header .caption { + color: rgb(78,98,114); + font-weight: bold; + border-bottom: 1px solid #ddd; +} + +table.info { + float: right; + padding: 0.5em 1em; + border: 1px solid #ddd; + color: rgb(78,98,114); + background-color: #fff; + max-width: 40%; + border-spacing: 0; + position: relative; + top: -0.5em; + margin: 0 0 0 2em; +} + +.info th { + padding: 0 1em 0 0; +} + +div#style-menu-holder { + position: relative; + z-index: 2; + display: inline; +} + +#style-menu { + position: absolute; + z-index: 1; + overflow: visible; + background: #374c5e; + margin: 0; + text-align: center; + right: 0; + padding: 0; + top: 1.25em; +} + +#style-menu li { + display: list-item; + border-style: none; + margin: 0; + padding: 0; + color: #000; + list-style-type: none; +} + +#style-menu li + li { + border-top: 1px solid #919191; +} + +#style-menu a { + width: 6em; + padding: 3px; + display: block; +} + +#footer { + background: #ddd; + border-top: 1px solid #aaa; + padding: 0.5em 0; + color: #666; + text-align: center; + position: absolute; + bottom: 0; + width: 100%; + height: 3em; +} + +/* @end */ + +/* @group Front Matter */ + +#table-of-contents { + float: right; + clear: right; + background: #faf9dc; + border: 1px solid #d8d7ad; + padding: 0.5em 1em; + max-width: 20em; + margin: 0.5em 0 1em 1em; +} + +#table-of-contents .caption { + text-align: center; + margin: 0; +} + +#table-of-contents ul { + list-style: none; + margin: 0; +} + +#table-of-contents ul ul { + margin-left: 2em; +} + +#description .caption { + display: none; +} + +#synopsis { + display: none; +} + +.no-frame #synopsis { + display: block; + position: fixed; + right: 0; + height: 80%; + top: 10%; + padding: 0; +} + +#synopsis .caption { + float: left; + width: 29px; + color: rgba(255,255,255,0); + height: 110px; + margin: 0; + font-size: 1px; + padding: 0; +} + +#synopsis p.caption.collapser { + background: url(synopsis.png) no-repeat -64px -8px; +} + +#synopsis p.caption.expander { + background: url(synopsis.png) no-repeat 0px -8px; +} + +#synopsis ul { + height: 100%; + overflow: auto; + padding: 0.5em; + margin: 0; +} + +#synopsis ul ul { + overflow: hidden; +} + +#synopsis ul, +#synopsis ul li.src { + background-color: #faf9dc; + white-space: nowrap; + list-style: none; + margin-left: 0; +} + +/* @end */ + +/* @group Main Content */ + +#interface div.top { margin: 2em 0; } +#interface h1 + div.top, +#interface h2 + div.top, +#interface h3 + div.top, +#interface h4 + div.top, +#interface h5 + div.top { + margin-top: 1em; +} +#interface p.src .link { + float: right; + color: #919191; + border-left: 1px solid #919191; + background: #f0f0f0; + padding: 0 0.5em 0.2em; + margin: 0 -0.5em 0 0.5em; +} + +#interface table { border-spacing: 2px; } +#interface td { + vertical-align: top; + padding-left: 0.5em; +} +#interface td.src { + white-space: nowrap; +} +#interface td.doc p { + margin: 0; +} +#interface td.doc p + p { + margin-top: 0.8em; +} + +.subs dl { + margin: 0; +} + +.subs dt { + float: left; + clear: left; + display: block; + margin: 1px 0; +} + +.subs dd { + float: right; + width: 90%; + display: block; + padding-left: 0.5em; + margin-bottom: 0.5em; +} + +.subs dd.empty { + display: none; +} + +.subs dd p { + margin: 0; +} + +.top p.src { + border-top: 1px solid #ccc; +} + +.subs, .doc { + /* use this selector for one level of indent */ + padding-left: 2em; +} + +.warning { + color: red; +} + +.arguments { + margin-top: -0.4em; +} +.arguments .caption { + display: none; +} + +.fields { padding-left: 1em; } + +.fields .caption { display: none; } + +.fields p { margin: 0 0; } + +/* this seems bulky to me +.methods, .constructors { + background: #f8f8f8; + border: 1px solid #eee; +} +*/ + +/* @end */ + +/* @group Auxillary Pages */ + +#mini { + margin: 0 auto; + padding: 0 1em 1em; +} + +#mini > * { + font-size: 93%; /* 12pt */ +} + +#mini #module-list .caption, +#mini #module-header .caption { + font-size: 125%; /* 15pt */ +} + +#mini #interface h1, +#mini #interface h2, +#mini #interface h3, +#mini #interface h4 { + font-size: 109%; /* 13pt */ + margin: 1em 0 0; +} + +#mini #interface .top, +#mini #interface .src { + margin: 0; +} + +#mini #module-list ul { + list-style: none; + margin: 0; +} + +#alphabet ul { + list-style: none; + padding: 0; + margin: 0.5em 0 0; + text-align: center; +} + +#alphabet li { + display: inline; + margin: 0 0.25em; +} + +#alphabet a { + font-weight: bold; +} + +#index .caption, +#module-list .caption { font-size: 131%; /* 17pt */ } + +#index table { + margin-left: 2em; +} + +#index .src { + font-weight: bold; +} +#index .alt { + font-size: 77%; /* 10pt */ + font-style: italic; + padding-left: 2em; +} + +#index td + td { + padding-left: 1em; +} + +#module-list ul { + list-style: none; + margin: 0 0 0 2em; +} + +#module-list li { + clear: right; +} + +#module-list span.collapser, +#module-list span.expander { + background-position: 0 0.3em; +} + +#module-list .package { + float: right; +} + +/* @end */ diff --git a/website/supported_sql.txt b/website/supported_sql.txt new file mode 100644 index 0000000..a175475 --- /dev/null +++ b/website/supported_sql.txt @@ -0,0 +1,161 @@ +# simple-sql-parser supported SQL overview + +[simple-sql-parser home](index.html) + +This page has more details on the supported SQL in simple-sql-parser. + +See the [simple-sql-parser test cases](test_cases.html) page for +examples. + +The target dialect of SQL at this time is ISO/ANSI SQL:2011. The +parser supports queries, DDL, non-query DML, access control, transaction +management and session management syntax. The parser and syntax does +not follow the standard grammar closely - they permit a lot of things +which the grammar in the standard forbids. The intended usage is that +an additional pass over the ast can be made if you want to carefully +prohibit everything that the standard doesn't allow. + +Apart from this permissiveness, some work has been put into trying to +get the best parser error messages possible. + +Although the parser and syntax support some character set constructs, +any source is always parsed in the default system encoding which +Haskell uses, and any encoding/decoding is left to the system. I think +this effectively means that you will usually be using utf-8 character +set for the sql source. + +# Queries + +## Select lists + +Supports value expressions, aliases with optional 'as'. + +Doesn't support 'select * as (a,b,c) from t' yet. + +## Set quantifiers on select + +Supports 'select distinct' and explicit 'select all'. + +## From clause + +* aliases +* subqueries +* functions +* joins + - natural + - inner + - left/right/full outer + - cross + - on expressions + - using lists + - lateral + +## Group by clause + +Supports value expressions, group by (), cube, rollup, grouping +parentheses and grouping sets with nested grouping expressions. + +## Order by clause + +Supports value expressions, asc/desc and nulls first/last. + +## Offset and fetch + +Supports 'offset n rows' and 'fetch first n rows only'. + +## Set operators + +Union, except, intersect + all/distinct and corresponding. + +## Table value constructor + +For example: values (1,2),(3,4). + +## Explicit table + +For example: 'table t', which is shorthand for 'select * from t'. + +## Value expressions + +The value expressions type and parser is used in many contexts, +including: + +* select lists; +* where clause expressions; +* group by clause expressions; +* having clause expressions; +* order by clause expressions; +* offset and fetch clause expressions; +* table value constructors. + +This doesn't exactly follow the ANSI Standards, which have separate +grammars for most of these. + +The supported value expressions include: + +* basic string literals in single quotes (escapes and other string + literal syntaxes coming soon) +* number literals: digits.digitse+-exp +* explicitly typed literal, e.g. int '3' +* binary operators + - comparisons: = != <> <= >= < > + - arithmetic: + - / * % ^ + - logic: and, or + - bitwise: & | (and ^ as above) + - string: ||, like, not like + - other: overlaps, is similar to, is not similar too, is distinct + from, is not distinct from +* prefix unary operators + - +, - + - not + - ~ +* postfix unary + - is null, is not null + - is true, is not true, is false, is not false, is unknown, is not unknown +* other operators + - extract (extract(day from dt)) + - position (position string1 in string2) + - substring (substring(x from 2 for 4)) + - convert (convert(string using conversion)) + - translate (translate(string using translation)) + - overlay (overlay (string placing embedded_string from start for + length)) + - trim (trim(leading '_' from s)) + - between (a between 1 and 5) + - in list (a in (1,2,3,4)) + - cast (cast(a as int)) +* subqueries + - in subquery + - any/some/all + - exists +* case expressions +* parentheses +* quoted and unquoted identifiers +* a.b qualified identifiers +* \*, a.\* +* functions: f(a,b) +* aggregates: agg(distinct a order by b) +* window functions: sum(x) over (partition by y order by z) + plus some explicit frame support (same as in postgres 9.3) +* row constructors, e.g. where (a,b) = any (select a,b from t) +* ? used in parameterized queries + +# DDL + +todo + +# Non-query DML + +todo + +# Access Control + +todo + +# Transaction management + +todo + +# Session management + +todo