@@ -14,7 +14,7 @@ import qualified Data.Set as S
14import qualified Data.HashSet as HS
14import qualified Data.HashSet as HS
15import qualified Data.Map as M
15import qualified Data.Map as M
16import qualified Data.List as L
16import qualified Data.List as L
17−import Control.Applicative (liftA)
17+import Control.Applicative (liftA, (<*), (*>))
18import Control.Monad.State
18import Control.Monad.State
19import System.Console.Readline
19import System.Console.Readline
@@ -108,6 +108,11 @@ renameP = do
108 (oldAttr, newAttr) <- braces renameClause
108 (oldAttr, newAttr) <- braces renameClause
109 return $ Rename oldAttr newAttr
109 return $ Rename oldAttr newAttr
113+ boolExpr <- restrictionPredicateP
114+ return $ Restrict boolExpr
111groupClause = do
116groupClause = do
112 attrs <- braces attributeList
117 attrs <- braces attributeList
113 reservedOp "as"
118 reservedOp "as"
@@ -130,6 +135,7 @@ ungroupP = do
130relOperators = [
135relOperators = [
131 [Postfix projectOp],
136 [Postfix projectOp],
132 [Postfix renameP],
137 [Postfix renameP],
138+ [Postfix whereClauseP],
133 [Postfix groupP],
139 [Postfix groupP],
134 [Postfix ungroupP],
140 [Postfix ungroupP],
135 [Infix (reservedOp "join" >> return Join) AssocLeft],
141 [Infix (reservedOp "join" >> return Join) AssocLeft],
@@ -182,14 +188,6 @@ updateP = do
182 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignment comma)
188 attributeAssignments <- liftM M.fromList $ parens (sepBy attributeAssignment comma)
183 return $ Update relVarName attributeAssignments
189 return $ Update relVarName attributeAssignments
186−restrictionPredicateP :: Parser RestrictionPredicateExpr
187−restrictionPredicateP = do
190− subexpr = try attributeEqP <|>
193constraintP :: Parser DatabaseExpr
191constraintP :: Parser DatabaseExpr
194constraintP = do
192constraintP = do
195 reservedOp "constraint"
193 reservedOp "constraint"
@@ -213,15 +211,15 @@ parseString str = case parse multipleDatabaseExpr "" str of
214data TutorialDOperator where
212data TutorialDOperator where
215 ShowRelation :: RelationalExpr -> TutorialDOperator
213 ShowRelation :: RelationalExpr -> TutorialDOperator
216− ShowRelationVariableType :: String -> TutorialDOperator
214+ ShowRelationType :: RelationalExpr -> TutorialDOperator
217 ShowConstraint :: String -> TutorialDOperator
215 ShowConstraint :: String -> TutorialDOperator
218 deriving (Show)
216 deriving (Show)
220typeP :: Parser TutorialDOperator
218typeP :: Parser TutorialDOperator
221typeP = do
219typeP = do
222 reservedOp ":t"
220 reservedOp ":t"
223− relVarName <- identifier
221+ expr <- relExpr
224− return $ ShowRelationVariableType relVarName
222+ return $ ShowRelationType expr
226showRelP :: Parser TutorialDOperator
224showRelP :: Parser TutorialDOperator
227showRelP = do
225showRelP = do
@@ -250,9 +248,9 @@ showRelationAttributes rel = "{" ++ concat (L.intersperse ", " $ map showAttribu
250 values m = map snd (M.toAscList m)
248 values m = map snd (M.toAscList m)
252evalTutorialDOp :: DatabaseContext -> TutorialDOperator -> String
250evalTutorialDOp :: DatabaseContext -> TutorialDOperator -> String
253−evalTutorialDOp context (ShowRelationVariableType relVarName) = case M.lookup relVarName (relationVariables context) of
251+evalTutorialDOp context (ShowRelationType expr) = case runState (typeForRelationalExpr expr) context of
254− Just rel -> showRelationAttributes rel
252+ (Right rel, _) -> showRelationAttributes rel
255− Nothing -> relVarName ++ " not defined"
253+ (Left err, _) -> show err
257evalTutorialDOp context (ShowRelation expr) = do
255evalTutorialDOp context (ShowRelation expr) = do
258 case runState (evalRelationalExpr expr) context of
256 case runState (evalRelationalExpr expr) context of
@@ -309,3 +307,35 @@ reprLoop context = do
309 putStrLn $ show err
307 putStrLn $ show err
310 reprLoop context
308 reprLoop context
310+restrictionPredicateP :: Parser RestrictionPredicateExpr
311+restrictionPredicateP = buildExpressionParser predicateOperators predicateTerm
313+ predicateOperators = [
314+ [Infix (reservedOp "and" >> return AndPredicate) AssocLeft],
315+ [Infix (reservedOp "or" >> return OrPredicate) AssocLeft]
317+ predicateTerm = parens restrictionPredicateP
318+ <|> try restrictionAttributeEqualityP
319+ <|> relationalBooleanExpr
321+relationalBooleanExpr :: Parser RestrictionPredicateExpr
322+relationalBooleanExpr = do
324+ return $ RelationalExprPredicate relexpr
326+restrictionAttributeEqualityP :: Parser RestrictionPredicateExpr
327+restrictionAttributeEqualityP = do
328+ attributeName <- identifier
330+ atom <- stringAtomP <|> intAtomP
331+ return $ AttributeEqualityPredicate attributeName atom
333+quotedChar = noneOf "\""
334+ <|> try (string "\"\"" >> return '"')
336+stringAtomP = liftA StringAtom (string "\"" *> many quotedChar <* string "\"")
339+ intstr <- many digit
340+ return $ IntAtom (read intstr)