on master help sign in
refactoring to add more expression types
commit2e1e4d2627d0676bb774d3fc1f7230ca9de255e0 authorAgentM <agentm@themactionfaction.com> dateSun 23 Nov 2014, 16:24 (12 years ago) parent5ab3a11
8 files changed+243−164
DatabaseContext.hs Relation.hs+1−1 RelationExpr.hs+88−108 RelationType.hs+47 RelationalError.hs+3−5 RelationalInclusionDependency.hs+10 TutorialDInterpreter.hs+81−39 TutorialDInterpreterTest.hs+13−11
DatabaseContext.hsnew file

No changes to the content.

Relation.hs+1−1
@@ -243,7 +243,7 @@ imageRelationFor matchTuple rel@(Relation attrs _) = do
243243imageRelationTest = imageRelationFor tup s
244244 where
245245 tup = mkRelationTuple (S.fromList ["SNAME", "CITY", "S#"]) (M.fromList [("SNAME", StringAtom "Smith"), ("S#", StringAtom "S1"), ("CITY", StringAtom "London")])
246−
246+
247247--returns a relation-valued attribute image relation for each tuple in rel1
248248--algorithm:
249249 {-
RelationExpr.hs+88−108
@@ -1,154 +1,80 @@
1−{-# LANGUAGE GADTs #-}
21module RelationExpr where
32import Relation
43import RelationTuple
4+import RelationTupleSet
55import RelationType
66import RelationalError
7−import qualified Data.Set as S
87import qualified Data.Map as M
98import qualified Data.HashSet as HS
109import Control.Monad.State hiding (join)
1110
12−type RelVarContext = M.Map String Relation
13−
14−type AtomName = String
15−
16−data RelationalExpr where
17− MakeStaticRelation :: Attributes -> RelationTupleSet -> RelationalExpr
18− --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
19− --in Tutorial D, relational variables pick up the type of the first relation assigned to them
20− --relational variables should also be able to be explicitly-typed like in Haskell
21− RelationVariable :: String -> RelationalExpr
22− Project :: S.Set AttributeName -> RelationalExpr -> RelationalExpr
23− Union :: RelationalExpr -> RelationalExpr -> RelationalExpr
24− Join :: RelationalExpr -> RelationalExpr -> RelationalExpr
25− MultipleExpr :: [RelationalExpr] -> RelationalExpr
26− Rename :: AttributeName -> AttributeName -> RelationalExpr -> RelationalExpr
27− Group :: S.Set AttributeName -> AttributeName -> RelationalExpr -> RelationalExpr
28− Ungroup :: AttributeName -> RelationalExpr -> RelationalExpr
29− --Restrict :: RExpr.RestrictionExpr -> RelationalExpr -> RelationalExpr
30−
31− --nominal relational expressions- the following operations could also be deemed non-relational, but I allow them to return relational expressions regardless- maybe this doesn't make sense since they should only be allowed as top-level commands
32− Define :: String -> Attributes -> RelationalExpr
33− Assign :: String -> RelationalExpr -> RelationalExpr
34− Insert :: String -> RelationalExpr -> RelationalExpr
35− Delete :: String -> RelationalExpr -- needs restriction support
36− Update :: String -> M.Map String Atom -> RelationalExpr -- needs restriction support
37−
38−{- maybe break this into multiple steps:
39−1. check relational types for match (attribute counts) (typechecking step
40−2. create an execution plan (another system of nodes, another GADT)
41−3. execute the plan
42−-}
43− deriving (Show)
44−
45−type RelVarState a = State RelVarContext a
46−
47−--helper function to process relation variable creation/assignment
48−setRelVar :: String -> Relation -> RelVarState (Either RelationalError Relation)
49−setRelVar relVarName rel = do
50− relVars <- get
51− put $ M.insert relVarName rel relVars
52− return $ Right rel
53−
54−eval :: RelationalExpr -> RelVarState (Either RelationalError Relation)
55−
56−--define a relvar by creating an empty-tupled relation
57−eval (Define relVarName attributes) = do
58− relvars <- get
59− case M.member relVarName relvars of
60− True -> return (Left (RelvarAlreadyDefined relVarName))
61− False -> setRelVar relVarName emptyRelation
62− where
63− emptyRelation = Relation attributes HS.empty
64−
65−eval (Assign relVarName expr) = do
66− relVarTable <- get
67− -- in the future, it would be nice to get types from the RelationalExpr instead of needing to evaluate it
68− let existingRelVar = M.lookup relVarName relVarTable
69− value <- eval expr
70− case value of
71− Left err -> return $ Left err
72− Right rel -> case existingRelVar of
73− Nothing -> setRelVar relVarName rel
74− Just existingRel -> if attributes existingRel == attributes rel then
75− setRelVar relVarName rel
76− else
77− return $ Left RelvarAssignmentTypeMismatch
78−
79−
80−eval (RelationVariable name) = do
81− relvarTable <- get
11+--relvar state is needed in evaluation of relational expression but only as read-only in order to extract current relvar values
12+evalRelationalExpr :: RelationalExpr -> DatabaseState (Either RelationalError Relation)
13+evalRelationalExpr (RelationVariable name) = do
14+ relvarTable <- liftM relationVariables get
8215 return $ case M.lookup name relvarTable of
8316 Just res -> Right res
84− Nothing -> Left $ RelvarNotDefinedError name
17+ Nothing -> Left $ RelVarNotDefinedError name
8518
86−eval (Project attrNameSet expr) = do
87− rel <- eval expr
19+evalRelationalExpr (Project attrNameSet expr) = do
20+ rel <- evalRelationalExpr expr
8821 case rel of
8922 Right rel -> return $ project attrNameSet rel
9023 Left err -> return $ Left err
9124
92−eval (Union exprA exprB) = do
93− relA <- eval exprA
94− relB <- eval exprB
25+evalRelationalExpr (Union exprA exprB) = do
26+ relA <- evalRelationalExpr exprA
27+ relB <- evalRelationalExpr exprB
9528 case relA of
9629 Left err -> return $ Left err
9730 Right relA -> case relB of
9831 Left err -> return $ Left err
9932 Right relB -> return $ union relA relB
10033
101−eval (Join exprA exprB) = do
102− relA <- eval exprA
103− relB <- eval exprB
34+evalRelationalExpr (Join exprA exprB) = do
35+ relA <- evalRelationalExpr exprA
36+ relB <- evalRelationalExpr exprB
10437 case relA of
10538 Left err -> return $ Left err
10639 Right relA -> case relB of
10740 Left err -> return $ Left err
10841 Right relB -> return $ join relA relB
10942
110−eval (MultipleExpr exprs) = do
111− evald <- mapM eval exprs
112− return $ last evald
113−
114−eval (MakeStaticRelation attributes tupleSet) = do
43+evalRelationalExpr (MakeStaticRelation attributes tupleSet) = do
11544 case mkRelation attributes tupleSet of
11645 Right rel -> return $ Right rel
11746 Left err -> return $ Left err
11847
119−eval (Rename oldAttrName newAttrName relExpr) = do
120− evald <- eval relExpr
48+evalRelationalExpr (Rename oldAttrName newAttrName relExpr) = do
49+ evald <- evalRelationalExpr relExpr
12150 case evald of
12251 Right rel -> return $ rename oldAttrName newAttrName rel
12352 Left err -> return $ Left err
12453
125−eval (Group oldAttrNameSet newAttrName relExpr) = do
126− evald <- eval relExpr
54+evalRelationalExpr (Group oldAttrNameSet newAttrName relExpr) = do
55+ evald <- evalRelationalExpr relExpr
12756 case evald of
12857 Right rel -> return $ group oldAttrNameSet newAttrName rel
12958 Left err -> return $ Left err
13059
131−eval (Ungroup attrName relExpr) = do
132− evald <- eval relExpr
60+evalRelationalExpr (Ungroup attrName relExpr) = do
61+ evald <- evalRelationalExpr relExpr
13362 case evald of
13463 Right rel -> return $ ungroup attrName rel
13564 Left err -> return $ Left err
136−
137−eval (Insert relVarName relExpr) = do
138− evald <- eval $ Assign relVarName (Union relExpr (RelationVariable relVarName))
139− case evald of
140− Right rel -> return $ evald
141− Left err -> return $ Left err
142−
143−emptyRelVarContext :: RelVarContext
144−emptyRelVarContext = M.empty
145−
146−basicRelVarContext :: RelVarContext
147−basicRelVarContext = M.fromList [("true", relationTrue),
148− ("false", relationFalse)]
149−
150−dateExamples :: RelVarContext
151−dateExamples = M.union basicRelVarContext dateRelVars
65+
66+emptyDatabaseContext :: DatabaseContext
67+emptyDatabaseContext = DatabaseContext { inclusionDependencies = HS.empty,
68+ relationVariables = M.empty}
69+
70+basicDatabaseContext :: DatabaseContext
71+basicDatabaseContext = DatabaseContext { inclusionDependencies = HS.empty,
72+ relationVariables = M.fromList [("true", relationTrue),
73+ ("false", relationFalse)]}
74+
75+dateExamples :: DatabaseContext
76+dateExamples = DatabaseContext { inclusionDependencies = HS.empty, -- add foreign key relationships
77+ relationVariables = M.union (relationVariables basicDatabaseContext) dateRelVars }
15278 where
15379 dateRelVars = M.fromList [("S", suppliers),
15480 ("P", products),
@@ -212,3 +138,57 @@ supplierProductsRel = case mkRelation attributes tupleSet of
212138 M.fromList [("S#", StringAtom "S4"), ("P#", StringAtom "P4"), ("QTY", IntAtom 300)],
213139 M.fromList [("S#", StringAtom "S4"), ("P#", StringAtom "P5"), ("QTY", IntAtom 400)]
214140 ]
141+
142+--helper function to process relation variable creation/assignment
143+setRelVar :: String -> Relation -> DatabaseState (Maybe RelationalError)
144+setRelVar relVarName rel = do
145+ state <- get
146+ let newRelVars = M.insert relVarName rel $ relationVariables state
147+ put $ DatabaseContext (inclusionDependencies state) newRelVars
148+ return Nothing
149+
150+evalContextExpr :: DatabaseExpr -> DatabaseState (Maybe RelationalError)
151+evalContextExpr (Define relVarName attrs) = do
152+ relvars <- liftM relationVariables get
153+ case M.member relVarName relvars of
154+ True -> return (Just (RelVarAlreadyDefinedError relVarName))
155+ False -> setRelVar relVarName emptyRelation
156+ where
157+ emptyRelation = Relation attrs HS.empty
158+
159+evalContextExpr (Assign relVarName expr) = do
160+ -- in the future, it would be nice to get types from the RelationalExpr instead of needing to evaluate it
161+ relVarTable <- liftM relationVariables get
162+ let existingRelVar = M.lookup relVarName relVarTable
163+ value <- evalRelationalExpr expr
164+ case value of
165+ Left err -> return $ Just err
166+ Right rel -> case existingRelVar of
167+ Nothing -> setRelVar relVarName rel
168+ Just existingRel -> if attributes existingRel == attributes rel then
169+ setRelVar relVarName rel
170+ else
171+ return $ Just RelVarAssignmentTypeMismatchError
172+
173+evalContextExpr (Insert relVarName relExpr) = evalContextExpr $ Assign relVarName (Union relExpr (RelationVariable relVarName))
174+
175+--assign empty rel until restriction is implemented
176+evalContextExpr (Delete relVarName) = do
177+ relVarTable <- liftM relationVariables get
178+ case M.lookup relVarName relVarTable of
179+ Nothing -> return $ Just (RelVarNotDefinedError relVarName)
180+ Just rel -> setRelVar relVarName (Relation (attributes rel) emptyTupleSet)
181+
182+evalContextExpr (Update relVarName attrAssignments) = undefined
183+
184+evalContextExpr (AddInclusionDependency dep) = undefined
185+
186+evalContextExpr (MultipleExpr exprs) = do
187+ evald <- mapM evalContextExpr exprs
188+ return $ last evald
189+
190+-- restrict relvar to get affected tuples, update tuples, delete restriction from relvar, relvar = relvar union updated tuples
191+--evalRelVarExpr (Update relVarName updateMap) = do
192+
193+
194+
RelationType.hs+47
@@ -1,7 +1,10 @@
1+{-# LANGUAGE GADTs #-}
12module RelationType where
23import qualified Data.Map as M
34import qualified Data.HashSet as HS
45import qualified Data.Hashable as Hash
6+import qualified Data.Set as S
7+import Control.Monad.State hiding (join)
58
69data Atom = StringAtom String |
710 IntAtom Int |
@@ -12,6 +15,8 @@ data AtomType = StringAtomType |
1215 RelationAtomType Attributes deriving (Eq, Show)
1316
1417type AttributeName = String
18+type AtomName = String
19+
1520data Attribute = Attribute AttributeName AtomType deriving (Eq, Show)
1621
1722type Attributes = M.Map AttributeName Attribute --attributes keys by attribute name for ease of access
@@ -27,4 +32,46 @@ data Relation = Relation Attributes RelationTupleSet deriving (Show, Eq)
2732data RelationCardinality = Uncountable | Countable Int deriving (Eq, Show)
2833data RelationSizeInfinite = RelationSizeInfinite
2934
35+data RelationalExpr where
36+ MakeStaticRelation :: Attributes -> RelationTupleSet -> RelationalExpr
37+ --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
38+ --in Tutorial D, relational variables pick up the type of the first relation assigned to them
39+ --relational variables should also be able to be explicitly-typed like in Haskell
40+ RelationVariable :: String -> RelationalExpr
41+ Project :: S.Set AttributeName -> RelationalExpr -> RelationalExpr
42+ Union :: RelationalExpr -> RelationalExpr -> RelationalExpr
43+ Join :: RelationalExpr -> RelationalExpr -> RelationalExpr
44+ Rename :: AttributeName -> AttributeName -> RelationalExpr -> RelationalExpr
45+ Group :: S.Set AttributeName -> AttributeName -> RelationalExpr -> RelationalExpr
46+ Ungroup :: AttributeName -> RelationalExpr -> RelationalExpr
47+ --Restrict :: RExpr.RestrictionExpr -> RelationalExpr -> RelationalExpr
48+
49+{- maybe break this into multiple steps:
50+1. check relational types for match (attribute counts) (typechecking step
51+2. create an execution plan (another system of nodes, another GADT)
52+3. execute the plan
53+-}
54+ deriving (Show)
55+
56+data DatabaseContext = DatabaseContext {
57+ inclusionDependencies :: HS.HashSet InclusionDependency,
58+ relationVariables :: M.Map String Relation
59+ } deriving (Show)
60+
61+data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show)
62+
63+instance Hash.Hashable InclusionDependency where
64+ hashWithSalt salt dep = Hash.hashWithSalt salt (show dep)
65+
66+--Database context expressions modify the database context while relational expressions do not
67+data DatabaseExpr where
68+ Define :: String -> Attributes -> DatabaseExpr
69+ Assign :: String -> RelationalExpr -> DatabaseExpr
70+ Insert :: String -> RelationalExpr -> DatabaseExpr
71+ Delete :: String -> DatabaseExpr -- needs restriction support
72+ Update :: String -> M.Map String RelationalExpr -> DatabaseExpr -- needs restriction support
73+ AddInclusionDependency :: InclusionDependency -> DatabaseExpr
74+ MultipleExpr :: [DatabaseExpr] -> DatabaseExpr
75+ deriving (Show)
3076
77+type DatabaseState a = State DatabaseContext a
RelationalError.hs+3−5
@@ -1,5 +1,4 @@
11module RelationalError where
2−import qualified Control.Monad.Error as Err
32import RelationType
43
54data RelationalError = NoSuchAttributeNameError String
@@ -9,11 +8,10 @@ data RelationalError = NoSuchAttributeNameError String
98 | AttributeNameMismatchError String
109 | AttributeNameInUseError AttributeName
1110 | AttributeIsNotRelationValuedError AttributeName
12− | RelvarNotDefinedError String
13− | RelvarAlreadyDefined String
14− | RelvarAssignmentTypeMismatch
11+ | RelVarNotDefinedError String
12+ | RelVarAlreadyDefinedError String
13+ | RelVarAssignmentTypeMismatchError
1514 | ParseError String
1615 deriving (Show,Eq)
1716
18−instance Err.Error RelationalError where
1917
RelationalInclusionDependency.hsnew file+10
@@ -0,0 +1,10 @@
1+module RelationalInclusionDependency where
2+import RelationalError
3+
4+--run verification on all constraints
5+checkConstraints :: DatabaseContext -> Maybe RelationalError
6+checkConstraints context = undefined
7+
8+checkConstraint :: DatabaseContext -> Constraint -> Maybe RelationalError
9+checkConstraint context constraint = undefined
10+
TutorialDInterpreter.hs+81−39
@@ -14,7 +14,7 @@ import qualified Data.Set as S
1414import qualified Data.HashSet as HS
1515import qualified Data.Map as M
1616import qualified Data.List as L
17−import Control.Applicative (liftA)
17+import Control.Applicative (liftA, (<*))
1818import Control.Monad.State
1919import System.Console.Readline
2020
@@ -80,17 +80,18 @@ relVarP = liftA RelationVariable identifier
8080
8181relTerm = parens relExpr
8282 <|> makeRelation
83− <|> (try defineP)
8483 <|> relVarP
8584
8685projectOp = do
8786 attrs <- braces attributeList
8887 return $ Project (S.fromList attrs)
8988
89+assignP :: Parser DatabaseExpr
9090assignP = do
9191 relVarName <- identifier
9292 reservedOp ":="
93− return $ Assign relVarName
93+ expr <- relExpr
94+ return $ Assign relVarName expr
9495
9596renameClause = do
9697 oldAttr <- identifier
@@ -123,52 +124,90 @@ ungroupP = do
123124 rvaAttrName <- identifier
124125 return $ Ungroup rvaAttrName
125126
126−insertP :: Parser (RelationalExpr -> RelationalExpr)
127−insertP = do
128− reservedOp "insert"
129− relvar <- identifier
130− return $ Insert relvar
131−
132−defineP :: Parser RelationalExpr
133−defineP = do
134− relVarName <- identifier
135− reservedOp "::"
136− attributes <- makeAttributes
137− return $ Define relVarName attributes
138−
139127relOperators = [
140128 [Postfix projectOp],
141129 [Postfix renameP],
142130 [Postfix groupP],
143131 [Postfix ungroupP],
144132 [Infix (reservedOp "join" >> return Join) AssocLeft],
145− [Infix (reservedOp "union" >> return Union) AssocLeft],
146− [Prefix insertP],
147−
148− [Prefix (try assignP)]
133+ [Infix (reservedOp "union" >> return Union) AssocLeft]
149134 ]
150135
151136relExpr :: Parser RelationalExpr
152137relExpr = buildExpressionParser relOperators relTerm
153138
154−multipleRelExpr :: Parser RelationalExpr
155−multipleRelExpr = do
156− exprs <- sepBy1 relExpr semi
157− return $ MultipleExpr exprs
139+databaseExpr :: Parser DatabaseExpr
140+databaseExpr = insertP
141+ <|> deleteP
142+ <|> updateP
143+ <|> try defineP
144+ <|> try assignP
145+
146+multipleDatabaseExpr :: Parser DatabaseExpr
147+multipleDatabaseExpr = do
148+ exprs <- sepBy1 databaseExpr semi
149+ return $ MultipleExpr exprs
150+
151+insertP :: Parser DatabaseExpr
152+insertP = do
153+ reservedOp "insert"
154+ relvar <- identifier
155+ expr <- relExpr
156+ return $ Insert relvar expr
157+
158+defineP :: Parser DatabaseExpr
159+defineP = do
160+ relVarName <- identifier
161+ reservedOp "::"
162+ attributes <- makeAttributes
163+ return $ Define relVarName attributes
164+
165+deleteP :: Parser DatabaseExpr
166+deleteP = do
167+ reservedOp "delete"
168+ relVarName <- identifier
169+ return $ Delete relVarName
170+
171+updateP :: Parser DatabaseExpr
172+updateP = do
173+ reservedOp "update"
174+ relVarName <- identifier
175+ -- where clause
176+ attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignment comma)
177+ return $ Update relVarName attributeAssignments
158178
159−parseString :: String -> Either RelationalError RelationalExpr
160−parseString str = case parse multipleRelExpr "" str of
179+attributeAssignment :: Parser (String, RelationalExpr)
180+attributeAssignment = do
181+ attrName <- identifier
182+ reservedOp ":="
183+ relExpr <- relExpr
184+ return $ (attrName, relExpr)
185+
186+parseString :: String -> Either RelationalError DatabaseExpr
187+parseString str = case parse multipleDatabaseExpr "" str of
161188 Left err -> Left $ ParseError (show err)
162189 Right r -> Right r
163190
164191data TutorialDOperator where
192+ ShowRelation :: RelationalExpr -> TutorialDOperator
165193 ShowRelationVariableType :: String -> TutorialDOperator
194+ deriving (Show)
166195
167−interpreterOps :: Parser TutorialDOperator
168−interpreterOps = do
196+typeP :: Parser TutorialDOperator
197+typeP = do
169198 reservedOp ":t"
170199 relVarName <- identifier
171200 return $ ShowRelationVariableType relVarName
201+
202+showP :: Parser TutorialDOperator
203+showP = do
204+ reservedOp ":s"
205+ expr <- relExpr
206+ return $ ShowRelation expr
207+
208+interpreterOps :: Parser TutorialDOperator
209+interpreterOps = typeP
210+ <|> showP
172211
173212showRelationAttributes :: Relation -> String
174213showRelationAttributes rel = "{" ++ concat (L.intersperse ", " $ map showAttribute attrs) ++ "}"
@@ -179,11 +218,16 @@ showRelationAttributes rel = "{" ++ concat (L.intersperse ", " $ map showAttribu
179218 attrs = values (attributes rel)
180219 values m = map snd (M.toAscList m)
181220
182−evalTutorialDOp :: RelVarContext -> TutorialDOperator -> String
183−evalTutorialDOp context (ShowRelationVariableType relVarName) = case M.lookup relVarName context of
221+evalTutorialDOp :: DatabaseContext -> TutorialDOperator -> String
222+evalTutorialDOp context (ShowRelationVariableType relVarName) = case M.lookup relVarName (relationVariables context) of
184223 Just rel -> showRelationAttributes rel
185224 Nothing -> relVarName ++ " not defined"
186225
226+evalTutorialDOp context (ShowRelation expr) = do
227+ case runState (evalRelationalExpr expr) context of
228+ (Left err, _) -> show err
229+ (Right rel, _) -> showRelation rel
230+
187231example1 = "relA {a,b, c}"
188232example2 = "relA join relB"
189233example3 = "relA join relB {x,y,z}"
@@ -194,18 +238,18 @@ example7 = "rv1 := relA union relB"
194238example8 = "relA := true; relB := false"
195239example9 = "relA := relation { SNO CHAR }"
196240
197−interpret :: RelVarContext -> String -> (Either RelationalError Relation, RelVarContext)
241+interpret :: DatabaseContext -> String -> (Maybe RelationalError, DatabaseContext)
198242interpret context tutdstring = case parseString tutdstring of
199− Left err -> (Left err, context)
200− Right parsed -> runState (eval parsed) context
243+ Left err -> (Just err, context)
244+ Right parsed -> runState (evalContextExpr parsed) context
201245
202246-- for interpreter-specific operations
203−interpretOps :: RelVarContext -> String -> Maybe String
247+interpretOps :: DatabaseContext -> String -> Maybe String
204248interpretOps context instring = case parse interpreterOps "" instring of
205249 Left err -> Nothing
206250 Right ops -> Just $ evalTutorialDOp context ops
207251
208−reprLoop :: RelVarContext -> IO ()
252+reprLoop :: DatabaseContext -> IO ()
209253reprLoop context = do
210254 maybeLine <- readline "TutorialD: "
211255 case maybeLine of
@@ -221,10 +265,8 @@ reprLoop context = do
221265
222266 let (value, contextup) = interpret context line
223267 case value of
224− (Right rel) -> do
225− putStrLn $ showRelation rel
226− reprLoop contextup
227− (Left err) -> do
268+ Nothing -> reprLoop contextup
269+ (Just err) -> do
228270 putStrLn $ show err
229271 reprLoop context
230272
TutorialDInterpreterTest.hs+13−11
@@ -11,22 +11,24 @@ main = do
1111 counts <- runTestTT (TestList tests)
1212 if errors counts + failures counts > 0 then exitFailure else exitSuccess
1313 where
14− tests = map (\(tutd, expected) -> TestCase $ assertTutdEqual basicRelVarContext tutd expected) simpleRelTests
15− simpleRelTests = [("true", Right relationTrue),
16− ("false", Right relationFalse),
17− ("true union false", Right relationTrue),
18− ("true; false", Right relationFalse),
19− ("a:=relation{a int}", mkRelation simpleAAttributes HS.empty),
20− ("b:=relation{c int} rename {c as d}", mkRelation simpleBAttributes HS.empty),
21− ("a:=relation{b int, c int}; a{c}", mkRelation simpleProjectionAttributes HS.empty)
14+ tests = map (\(tutd, expected) -> TestCase $ assertTutdEqual basicDatabaseContext tutd expected) simpleRelTests
15+ simpleRelTests = [("x:=true", Right relationTrue),
16+ ("x:=false", Right relationFalse),
17+ ("x:=true union false", Right relationTrue),
18+ ("x:=true; x:=false", Right relationFalse),
19+ ("x:=relation{a int}", mkRelation simpleAAttributes HS.empty),
20+ ("x:=relation{c int} rename {c as d}", mkRelation simpleBAttributes HS.empty),
21+ ("y:=relation{b int, c int}; x:=y{c}", mkRelation simpleProjectionAttributes HS.empty)
2222 ]
2323 simpleAAttributes = M.fromList [("a", Attribute "a" IntAtomType)]
2424 simpleBAttributes = M.fromList [("d", Attribute "d" IntAtomType)]
2525 simpleProjectionAttributes = M.fromList [("c", Attribute "c" IntAtomType)]
2626
2727
28−testSimple1 = TestCase $ assertTutdEqual basicRelVarContext "true" (Right relationTrue)
28+testSimple1 = TestCase $ assertTutdEqual basicDatabaseContext "true" (Right relationTrue)
2929
30−assertTutdEqual relVarContext tutd expected = assertEqual tutd interpreted expected
30+assertTutdEqual databaseContext tutd expected = assertEqual tutd interpreted expected
3131 where
32− interpreted = fst (interpret relVarContext tutd)
32+ interpreted = case interpret databaseContext tutd of
33+ (Just err, _) -> Left err
34+ (Nothing, context) -> Right $ (relationVariables context) M.! "x"