hasktorch-gradually-typed-0.2.0.0: experimental project for hasktorch
Safe HaskellSafe-Inferred
LanguageHaskell2010

Torch.Language.SpiderSQL

Description

This module contains bits and pieces to work with the Spider SQL language.

TODO: * don't accept reserved keywords in names without quoting * aliases have to be defined in scope, otherwise fall back to table id * don't define an alias twice in the same scope * optionally (?) use the schema to constrain column and table names * test the parser(s) on more examples * pretty printing * random generation of SpiderSQL values

Synopsis

Documentation

data Select Source #

Constructors

Select [Agg] 
SelectDistinct [Agg] 

Instances

Instances details
Show Select Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq Select Source # 
Instance details

Defined in Torch.Language.SpiderSQL

data From Source #

Constructors

From 

Instances

Instances details
Show From Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq From Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Methods

(==) :: From -> From -> Bool Source #

(/=) :: From -> From -> Bool Source #

data Cond Source #

Instances

Instances details
Show Cond Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq Cond Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Methods

(==) :: Cond -> Cond -> Bool Source #

(/=) :: Cond -> Cond -> Bool Source #

data OrderBy Source #

Constructors

OrderBy OrderByOrder [ValUnit] 

Instances

Instances details
Show OrderBy Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq OrderBy Source # 
Instance details

Defined in Torch.Language.SpiderSQL

data Agg Source #

Constructors

Agg AggType ValUnit 

Instances

Instances details
Show Agg Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq Agg Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Methods

(==) :: Agg -> Agg -> Bool Source #

(/=) :: Agg -> Agg -> Bool Source #

data Val Source #

Instances

Instances details
Show Val Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq Val Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Methods

(==) :: Val -> Val -> Bool Source #

(/=) :: Val -> Val -> Bool Source #

data AggType Source #

Constructors

NoneAggOp 
Max 
Min 
Count 
Sum 
Avg 

Instances

Instances details
Show AggType Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq AggType Source # 
Instance details

Defined in Torch.Language.SpiderSQL

data ColumnId Source #

Constructors

Star 
ColumnId String 

Instances

Instances details
Show ColumnId Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq ColumnId Source # 
Instance details

Defined in Torch.Language.SpiderSQL

newtype TableId Source #

Constructors

TableId String 

Instances

Instances details
Show TableId Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq TableId Source # 
Instance details

Defined in Torch.Language.SpiderSQL

newtype Alias Source #

Constructors

Alias String 

Instances

Instances details
Show Alias Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Eq Alias Source # 
Instance details

Defined in Torch.Language.SpiderSQL

Methods

(==) :: Alias -> Alias -> Bool Source #

(/=) :: Alias -> Alias -> Bool Source #

isKeyword :: CharParsing m => String -> m String Source #

keyword k is a parser that consumes Char tokens and yields them if and only if they assemble the String s. The parser is not sensitive to letter casing.

>>> head $ parseString @[] (isKeyword "mykeyword") "MYKEYWORD"
("MYKEYWORD","")

select :: (TokenParsing m, Monad m) => m Select Source #

Select parser

>>> head $ parseString @[] select "select count table.*"
(Select [Agg Count (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "table")), colUnitColId = Star}))],"")
>>> head $ parseString @[] select "SELECT COUNT (DISTINCT t5.title)"
(Select [Agg Count (Column (DistinctColUnit {distinctColUnitAggId = NoneAggOp, distinctColUnitTable = Just (Left (Alias "t5")), distinctColUnitColdId = ColumnId "title"}))],"")

agg :: (TokenParsing m, Monad m) => m Agg Source #

Agg parser.

>>> head $ parseString @[] agg "count table.id"
(Agg Count (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "table")), colUnitColId = ColumnId "id"})),"")

aggType :: CharParsing m => m AggType Source #

AggType parser.

>>> head $ parseString @[] aggType ""
(NoneAggOp,"")

valUnit :: (TokenParsing m, Monad m) => m ValUnit Source #

ValUnit parser.

>>> head $ parseString @[] valUnit "t1.stadium_id"
(Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_id"}),"")
>>> head . filter (null . snd) $ parseString @[] valUnit "t1.stadium_length * t1.stadium_width"
(Times (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_length"}) (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_width"}),"")

colUnit :: (TokenParsing m, Monad m) => m ColUnit Source #

ColUnit parser.

>>> head $ parseString @[] colUnit "count ( distinct my_table.* )"
(DistinctColUnit {distinctColUnitAggId = Count, distinctColUnitTable = Just (Left (Alias "my_table")), distinctColUnitColdId = Star},"")

alias :: CharParsing m => m Alias Source #

Alias parser.

columnId :: CharParsing m => m ColumnId Source #

ColumnId parser.

>>> parseString @[] columnId "*"
[(Star,"")]
>>> parseString @[] columnId "c"
[(ColumnId "c","")]

from :: forall m. (TokenParsing m, Monad m) => m From Source #

From parser.

>>> head $ parseString @[] from "FROM people AS t1 JOIN pets AS t2 ON t1.pet_id = t2.pet_id"
(From {fromTableUnits = [Table (TableId "people") (Just (Alias "t1")),Table (TableId "pets") (Just (Alias "t2"))], fromCond = Just (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "pet_id"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "pet_id"})))},"")
>>> head $ parseString @[] from "FROM organization AS t3 JOIN author AS t1 ON t3.oid = t1.oid JOIN writes AS t4 ON t4.aid = t1.aid JOIN publication AS t5 ON t4.pid = t5.pid JOIN conference AS t2 ON t5.cid = t2.cid"
(From {fromTableUnits = [Table (TableId "organization") (Just (Alias "t3")),Table (TableId "author") (Just (Alias "t1")),Table (TableId "writes") (Just (Alias "t4")),Table (TableId "publication") (Just (Alias "t5")),Table (TableId "conference") (Just (Alias "t2"))], fromCond = Just (And (And (And (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t3")), colUnitColId = ColumnId "oid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "oid"}))) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t4")), colUnitColId = ColumnId "aid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "aid"})))) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t4")), colUnitColId = ColumnId "pid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t5")), colUnitColId = ColumnId "pid"})))) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t5")), colUnitColId = ColumnId "cid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "cid"}))))},"")

tableUnit :: (TokenParsing m, Monad m) => m TableUnit Source #

TableUnit parser.

>>> head $ parseString @[] tableUnit "people as t1"
(Table (TableId "people") (Just (Alias "t1")),"")

cond :: (TokenParsing m, Monad m) => m Cond Source #

Cond parser.

>>> head $ parseString @[] cond "t1.stadium_id = t2.stadium_id"
(Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_id"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "stadium_id"})),"")
>>> head $ parseString @[] (cond <* isToken ';') "t2.name = \"VLDB\" AND t3.name = \"University of Michigan\";"
(And (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "name"})) (ValString "VLDB")) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t3")), colUnitColId = ColumnId "name"})) (ValString "University of Michigan")),"")

val :: (TokenParsing m, Monad m) => m Val Source #

Val parser.

>>> head $ parseString @[] val "count t1.stadium_id"
(ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Nothing, colUnitColId = ColumnId "count"})," t1.stadium_id")
>>> head $ parseString @[] val "(select *)"
(ValSQL (SpiderSQL {spiderSQLSelect = Select [Agg NoneAggOp (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Nothing, colUnitColId = Star}))], spiderSQLFrom = From {fromTableUnits = [], fromCond = Nothing}, spiderSQLWhere = Nothing, spiderSQLGroupBy = [], spiderSQLOrderBy = Nothing, spiderSQLHaving = Nothing, spiderSQLLimit = Nothing, spiderSQLIntersect = Nothing, spiderSQLExcept = Nothing, spiderSQLUnion = Nothing}),"")

quotedString :: CharParsing m => m String Source #

Parser for quoted strings.

>>> head $ parseString @[] quotedString "\"hello world\""
("hello world","")

whereCond :: (TokenParsing m, Monad m) => m Cond Source #

Parser for where clauses.

>>> head $ parseString @[] whereCond "where t1.id = t2.id"
(Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "id"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "id"})),"")

groupBy :: (TokenParsing m, Monad m) => m [ColUnit] Source #

Parser for group-by clauses.

>>> head $ parseString @[] groupBy "group by count t1.id, t2.id"
([ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Nothing, colUnitColId = ColumnId "count"}]," t1.id, t2.id")

orderBy :: (TokenParsing m, Monad m) => m OrderBy Source #

OrderBy Parser.

>>> head . filter (null . snd) $ parseString @[] orderBy "order by t1.stadium_id, t2.pet_id desc"
(OrderBy Desc [Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_id"}),Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "pet_id"})],"")

havingCond :: (TokenParsing m, Monad m) => m Cond Source #

Parser for having clauses.

>>> head $ parseString @[] havingCond "having count(t1.customer_id) = 10"
(Eq (Column (ColUnit {colUnitAggId = Count, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "customer_id"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Nothing, colUnitColId = ColumnId "10"})),"")

limit :: (TokenParsing m, Monad m) => m Int Source #

Parser for limit clauses.

>>> head $ parseString @[] limit "limit 10"
(10,"")

spiderSQL :: (TokenParsing m, Monad m) => m SpiderSQL Source #

SpiderSQL parser.

>>> head $ parseString @[] (spiderSQL <* spaces <* isSemicolon) "select * ;"
(SpiderSQL {spiderSQLSelect = Select [Agg NoneAggOp (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Nothing, colUnitColId = Star}))], spiderSQLFrom = From {fromTableUnits = [], fromCond = Nothing}, spiderSQLWhere = Nothing, spiderSQLGroupBy = [], spiderSQLOrderBy = Nothing, spiderSQLHaving = Nothing, spiderSQLLimit = Nothing, spiderSQLIntersect = Nothing, spiderSQLExcept = Nothing, spiderSQLUnion = Nothing},"")
>>> head $ parseString @[] (spiderSQL <* spaces <* isSemicolon) "select * from concert;"
(SpiderSQL {spiderSQLSelect = Select [Agg NoneAggOp (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Nothing, colUnitColId = Star}))], spiderSQLFrom = From {fromTableUnits = [Table (TableId "concert") Nothing], fromCond = Nothing}, spiderSQLWhere = Nothing, spiderSQLGroupBy = [], spiderSQLOrderBy = Nothing, spiderSQLHaving = Nothing, spiderSQLLimit = Nothing, spiderSQLIntersect = Nothing, spiderSQLExcept = Nothing, spiderSQLUnion = Nothing},"")
>>> head $ parseString @[] (spiderSQL <* spaces <* isSemicolon) "select T2.name, count(*) from concert as t1 join stadium as t2 on t1.stadium_id = t2.stadium_id group by t1.stadium_id;"
(SpiderSQL {spiderSQLSelect = Select [Agg NoneAggOp (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "T2")), colUnitColId = ColumnId "name"})),Agg NoneAggOp (Column (ColUnit {colUnitAggId = Count, colUnitTable = Nothing, colUnitColId = Star}))], spiderSQLFrom = From {fromTableUnits = [Table (TableId "concert") (Just (Alias "t1")),Table (TableId "stadium") (Just (Alias "t2"))], fromCond = Just (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_id"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "stadium_id"})))}, spiderSQLWhere = Nothing, spiderSQLGroupBy = [ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "stadium_id"}], spiderSQLOrderBy = Nothing, spiderSQLHaving = Nothing, spiderSQLLimit = Nothing, spiderSQLIntersect = Nothing, spiderSQLExcept = Nothing, spiderSQLUnion = Nothing},"")
>>> head $ parseString @[] (spiderSQL <* spaces <* isSemicolon) "SELECT COUNT ( DISTINCT t5.title ) FROM organization AS t3 JOIN author AS t1 ON t3.oid = t1.oid JOIN writes AS t4 ON t4.aid = t1.aid JOIN publication AS t5 ON t4.pid = t5.pid JOIN conference AS t2 ON t5.cid = t2.cid WHERE t2.name = \"VLDB\" AND t3.name = \"University of Michigan\";"
(SpiderSQL {spiderSQLSelect = Select [Agg Count (Column (DistinctColUnit {distinctColUnitAggId = NoneAggOp, distinctColUnitTable = Just (Left (Alias "t5")), distinctColUnitColdId = ColumnId "title"}))], spiderSQLFrom = From {fromTableUnits = [Table (TableId "organization") (Just (Alias "t3")),Table (TableId "author") (Just (Alias "t1")),Table (TableId "writes") (Just (Alias "t4")),Table (TableId "publication") (Just (Alias "t5")),Table (TableId "conference") (Just (Alias "t2"))], fromCond = Just (And (And (And (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t3")), colUnitColId = ColumnId "oid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "oid"}))) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t4")), colUnitColId = ColumnId "aid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t1")), colUnitColId = ColumnId "aid"})))) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t4")), colUnitColId = ColumnId "pid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t5")), colUnitColId = ColumnId "pid"})))) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t5")), colUnitColId = ColumnId "cid"})) (ValColUnit (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "cid"}))))}, spiderSQLWhere = Just (And (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t2")), colUnitColId = ColumnId "name"})) (ValString "VLDB")) (Eq (Column (ColUnit {colUnitAggId = NoneAggOp, colUnitTable = Just (Left (Alias "t3")), colUnitColId = ColumnId "name"})) (ValString "University of Michigan"))), spiderSQLGroupBy = [], spiderSQLOrderBy = Nothing, spiderSQLHaving = Nothing, spiderSQLLimit = Nothing, spiderSQLIntersect = Nothing, spiderSQLExcept = Nothing, spiderSQLUnion = Nothing},"")

name :: CharParsing m => m String Source #

Auxiliary parser for table names, column names, and aliases.