on master help sign in
implement undefine Tutorial D operator
44ec3cdAgentM
RelationExpr.hs+11−1
@@ -170,7 +170,14 @@ setRelVar relVarName rel = do
170 Nothing -> do
170 Nothing -> do
171 put $ DatabaseContext (inclusionDependencies state) newRelVars
171 put $ DatabaseContext (inclusionDependencies state) newRelVars
172 return Nothing
172 return Nothing
173−
173+
174+-- it is not an error to delete a relvar which does not exist, just like it is not an error to insert a pre-existing tuple into a relation
175+deleteRelVar :: String -> DatabaseState (Maybe RelationalError)
176+deleteRelVar relVarName = do
177+ state <- get
178+ let newRelVars = M.delete relVarName (relationVariables state)
179+ put $ DatabaseContext (inclusionDependencies state) newRelVars
180+ return Nothing
174
181
175evalContextExpr :: DatabaseExpr -> DatabaseState (Maybe RelationalError)
182evalContextExpr :: DatabaseExpr -> DatabaseState (Maybe RelationalError)
176evalContextExpr (Define relVarName attrs) = do
183evalContextExpr (Define relVarName attrs) = do
@@ -180,6 +187,9 @@ evalContextExpr (Define relVarName attrs) = do
180 False -> setRelVar relVarName emptyRelation
187 False -> setRelVar relVarName emptyRelation
181 where
188 where
182 emptyRelation = Relation attrs HS.empty
189 emptyRelation = Relation attrs HS.empty
190+
191+evalContextExpr (Undefine relVarName) = do
192+ deleteRelVar relVarName
183
193
184evalContextExpr (Assign relVarName expr) = do
194evalContextExpr (Assign relVarName expr) = do
185 -- in the future, it would be nice to get types from the RelationalExpr instead of needing to evaluate it
195 -- in the future, it would be nice to get types from the RelationalExpr instead of needing to evaluate it
TutorialDInterpreter.hs+7
@@ -177,6 +177,7 @@ databaseExpr = insertP
177 <|> updateP
177 <|> updateP
178 <|> constraintP
178 <|> constraintP
179 <|> defineP
179 <|> defineP
180+ <|> undefineP
180 <|> assignP
181 <|> assignP
181
182
182multipleDatabaseExpr :: Parser DatabaseExpr
183multipleDatabaseExpr :: Parser DatabaseExpr
@@ -200,6 +201,12 @@ defineP = do
200 attributes <- makeAttributes
201 attributes <- makeAttributes
201 return $ Define relVarName attributes
202 return $ Define relVarName attributes
202
203
204+undefineP :: Parser DatabaseExpr
205+undefineP = do
206+ reservedOp "undefine"
207+ relVarName <- identifier
208+ return $ Undefine relVarName
209+
203deleteP :: Parser DatabaseExpr
210deleteP :: Parser DatabaseExpr
204deleteP = do
211deleteP = do
205 reservedOp "delete"
212 reservedOp "delete"
TutorialDInterpreterTest.hs+4−1
@@ -30,6 +30,7 @@ main = do
30 ("x:=true where true and true", Right relationTrue),
30 ("x:=true where true and true", Right relationTrue),
31 ("x:=true=true", Right relationTrue),
31 ("x:=true=true", Right relationTrue),
32 ("x:=true=false", Right relationFalse),
32 ("x:=true=false", Right relationFalse),
33+ ("x:=true; undefine x", Right relationTrue),
33 ("x:=relation {b int, a char}; insert x relation{tuple{b int(5), a char(\"spam\")}}", mkRelation simpleCAttributes (HS.fromList [RelationTuple $ M.fromList [("a", StringAtom "spam"), ("b", IntAtom 5)]])),
34 ("x:=relation {b int, a char}; insert x relation{tuple{b int(5), a char(\"spam\")}}", mkRelation simpleCAttributes (HS.fromList [RelationTuple $ M.fromList [("a", StringAtom "spam"), ("b", IntAtom 5)]])),
34 ("x:=relation{tuple{b int(5),a char(\"spam\")},tuple{b int(6),a char(\"sam\")}}; delete x where b=6", mkRelation simpleCAttributes $ HS.fromList [RelationTuple $ M.fromList [("a", StringAtom "spam"), ("b", IntAtom 5)]])
35 ("x:=relation{tuple{b int(5),a char(\"spam\")},tuple{b int(6),a char(\"sam\")}}; delete x where b=6", mkRelation simpleCAttributes $ HS.fromList [RelationTuple $ M.fromList [("a", StringAtom "spam"), ("b", IntAtom 5)]])
35 ]
36 ]
@@ -50,4 +51,6 @@ assertTutdEqual databaseContext tutd expected = assertEqual tutd interpreted exp
50 where
51 where
51 interpreted = case interpret databaseContext tutd of
52 interpreted = case interpret databaseContext tutd of
52 (Just err, _) -> Left err
53 (Just err, _) -> Left err
53− (Nothing, context) -> Right $ (relationVariables context) M.! "x"
54+ (Nothing, context) -> case M.lookup "x" (relationVariables context) of
55+ Nothing -> Left $ RelVarNotDefinedError "x"
56+ Just rel -> Right rel