@@ -6,6 +6,7 @@ import ProjectM36.TupleSet
6import ProjectM36.Base
6import ProjectM36.Base
7import ProjectM36.Error
7import ProjectM36.Error
8import ProjectM36.Atom
8import ProjectM36.Atom
9+import ProjectM36.AtomFunction
9import qualified ProjectM36.Attribute as A
10import qualified ProjectM36.Attribute as A
10import qualified Data.Map as M
11import qualified Data.Map as M
11import qualified Data.HashSet as HS
12import qualified Data.HashSet as HS
@@ -99,7 +100,7 @@ evalRelationalExpr (Extend tupleExpression relExpr) = do
99 case tupleExpressionProcessor rel tupleExpression context of
100 case tupleExpressionProcessor rel tupleExpression context of
100 Left err -> return $ Left err
101 Left err -> return $ Left err
101 Right (newAttrs, tupProc) -> return $ relMogrify tupProc newAttrs rel
102 Right (newAttrs, tupProc) -> return $ relMogrify tupProc newAttrs rel
103emptyDatabaseContext :: DatabaseContext
104emptyDatabaseContext :: DatabaseContext
104emptyDatabaseContext = DatabaseContext { inclusionDependencies = HS.empty,
105emptyDatabaseContext = DatabaseContext { inclusionDependencies = HS.empty,
105 relationVariables = M.empty,
106 relationVariables = M.empty,
@@ -359,7 +360,6 @@ predicateRestrictionFilter context (AttributeEqualityPredicate attrName atomexpr
359 case evalAtomExpr tupleIn context atomexpr of
360 case evalAtomExpr tupleIn context atomexpr of
360 Left _ -> False
361 Left _ -> False
361 Right atomCmp -> atomCmp == atomIn
362 Right atomCmp -> atomCmp == atomIn
364tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
364tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
365tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
365tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
@@ -379,25 +379,19 @@ tupleExpressionProcessor relIn
379 Left _ -> undefined -- ?!
379 Left _ -> undefined -- ?!
380 Right atom -> tupleAtomExtend newAttrName atom tup)
380 Right atom -> tupleAtomExtend newAttrName atom tup)
382−basicAtomFunctions :: AtomFunctions
382+evalAtomExpr :: RelationTuple -> DatabaseContext -> AtomExpr -> Either RelationalError Atom
383−basicAtomFunctions = HS.fromList [
383+evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
384− --match on any relation type
384+evalAtomExpr _ _ (NakedAtomExpr atom) = Right atom
385− AtomFunction "add" [IntAtomType, IntAtomType, IntAtomType] (\(i1:i2:_) -> (\(IntAtom a) (IntAtom b) -> IntAtom (a + b)) i1 i2),
385+evalAtomExpr tupIn context (FunctionAtomExpr funcName arguments) = do
386− AtomFunction { atomFuncName = "id",
386+ let functions = atomFunctions context
387− atomFuncType = [AnyAtomType],
387+ func <- atomFunctionForName funcName functions
388− atomFunc = (\(x:_) -> x)}
388+ argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) context) arguments
389−
389+ _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
390−-- AtomFunction "count" [RelationAtomType , IntAtom],
390+ evaldArgs <- mapM (evalAtomExpr tupIn context) arguments
391−-- AtomFunction "sum" [RelationAtomType IntAtomType
391+ return $ (atomFunc func) evaldArgs
392− ]
392+evalAtomExpr _ context (RelationAtomExpr relExpr) = do
393−
393+ relAtom <- evalState (evalRelationalExpr relExpr) context
394−atomFunctionForName :: AtomFunctionName -> AtomFunctions -> Either RelationalError AtomFunction
394+ return $ RelationAtom relAtom
395−atomFunctionForName funcName funcSet = if HS.null foundFunc then
396− Left $ NoSuchTupleExprFunctionError funcName
398− Right $ head $ HS.toList foundFunc
400− foundFunc = HS.filter (\(AtomFunction name _ _) -> name == funcName) funcSet
402typeFromAtomExpr :: Attributes -> DatabaseContext -> AtomExpr -> Either RelationalError AtomType
396typeFromAtomExpr :: Attributes -> DatabaseContext -> AtomExpr -> Either RelationalError AtomType
403typeFromAtomExpr attrs _ (AttributeAtomExpr attrName) = A.atomTypeForAttributeName attrName attrs
397typeFromAtomExpr attrs _ (AttributeAtomExpr attrName) = A.atomTypeForAttributeName attrName attrs
@@ -409,7 +403,6 @@ typeFromAtomExpr _ context (FunctionAtomExpr funcName _) = do
409typeFromAtomExpr _ context (RelationAtomExpr relExpr) = do
403typeFromAtomExpr _ context (RelationAtomExpr relExpr) = do
410 relType <- evalState (typeForRelationalExpr relExpr) context
404 relType <- evalState (typeForRelationalExpr relExpr) context
411 return $ RelationAtomType (attributes relType)
405 return $ RelationAtomType (attributes relType)
414verifyAtomExprTypes :: Relation -> DatabaseContext -> AtomExpr -> AtomType -> Either RelationalError AtomType
407verifyAtomExprTypes :: Relation -> DatabaseContext -> AtomExpr -> AtomType -> Either RelationalError AtomType
415verifyAtomExprTypes relIn _ (AttributeAtomExpr attrName) expectedType = do
408verifyAtomExprTypes relIn _ (AttributeAtomExpr attrName) expectedType = do
@@ -433,27 +426,25 @@ verifyAtomExprTypes _ context (RelationAtomExpr relationExpr) expectedType = do
433 case runState (typeForRelationalExpr relationExpr) context of
426 case runState (typeForRelationalExpr relationExpr) context of
434 (Left err, _) -> Left err
427 (Left err, _) -> Left err
435 (Right relType, _) -> atomTypeVerify expectedType (RelationAtomType (attributes relType))
428 (Right relType, _) -> atomTypeVerify expectedType (RelationAtomType (attributes relType))
437−--determine if two types are equal or compatible
430+basicAtomFunctions :: AtomFunctions
438−atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
431+basicAtomFunctions = HS.fromList [
439−atomTypeVerify AnyAtomType x = Right x
432+ --match on any relation type
440−atomTypeVerify x AnyAtomType = Right x
433+ AtomFunction "add" [IntAtomType, IntAtomType, IntAtomType] (\(i1:i2:_) -> (\(IntAtom a) (IntAtom b) -> IntAtom (a + b)) i1 i2),
441−atomTypeVerify x y = if x == y then
434+ AtomFunction { atomFuncName = "id",
442− Right x
435+ atomFuncType = [AnyAtomType, AnyAtomType],
443− else
436+ atomFunc = (\(x:_) -> x)},
444− Left $ AtomTypeMismatchError x y
437+ AtomFunction { atomFuncName = "sum",
445−
438+ atomFuncType = foldAtomFuncType IntAtomType IntAtomType,
446−evalAtomExpr :: RelationTuple -> DatabaseContext -> AtomExpr -> Either RelationalError Atom
439+ atomFunc = (\((RelationAtom relIn):_) -> relationSum relIn)},
447−evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
440+ AtomFunction { atomFuncName = "count",
448−evalAtomExpr _ _ (NakedAtomExpr atom) = Right atom
441+ atomFuncType = foldAtomFuncType AnyAtomType IntAtomType,
449−evalAtomExpr tupIn context (FunctionAtomExpr funcName arguments) = do
442+ atomFunc = (\((RelationAtom relIn):_) -> relationCount relIn)},
450− let functions = atomFunctions context
443+ AtomFunction { atomFuncName = "max",
451− func <- atomFunctionForName funcName functions
444+ atomFuncType = foldAtomFuncType IntAtomType IntAtomType,
452− argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) context) arguments
445+ atomFunc = (\((RelationAtom relIn):_) -> relationMax relIn)},
453− _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
446+ AtomFunction { atomFuncName = "min",
454− evaldArgs <- mapM (evalAtomExpr tupIn context) arguments
447+ atomFuncType = foldAtomFuncType IntAtomType IntAtomType,
455− return $ (atomFunc func) evaldArgs
448+ atomFunc = (\((RelationAtom relIn):_) -> relationMin relIn)}
456−evalAtomExpr _ context (RelationAtomExpr relExpr) = do
449+
457− relAtom <- evalState (evalRelationalExpr relExpr) context
450+ ]
458− return $ RelationAtom relAtom