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 $ "" ++ sql'
+> ++ " | " ++ hask' ++ " |
"
+> go True is
+> go t [] = when t $ putStrLn "
"
+
+> 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