@@ -12,6 +12,7 @@ import qualified Data.HashSet as HS
1212import Control.Monad.State hiding (join)
1313import Data.Maybe
1414import Data.Either
15+import Debug.Trace
1516
1617--relvar state is needed in evaluation of relational expression but only as read-only in order to extract current relvar values
1718evalRelationalExpr :: RelationalExpr -> DatabaseState (Either RelationalError Relation)
@@ -91,11 +92,11 @@ evalRelationalExpr (Equals relExprA relExprB) = do
9192-- extending a relation adds a single attribute with the results of the per-tuple expression evaluated
9293evalRelationalExpr (Extend tupleExpression relExpr) = do
9394 evald <- evalRelationalExpr relExpr
94− funcs <- liftM atomFunctions get
95+ context <- get
9596 case evald of
9697 Left err -> return $ Left err
9798 Right rel -> do
98− case tupleExpressionProcessor rel tupleExpression funcs of
99+ case tupleExpressionProcessor rel tupleExpression context of
99100 Left err -> return $ Left err
100101 Right (newAttrs, tupProc) -> return $ relMogrify tupProc newAttrs rel
101102
@@ -147,7 +148,7 @@ supplierProductsRel = case mkRelationFromList attrs matrix of
147148 where
148149 attrs = A.attributesFromList [Attribute "S#" StringAtomType,
149150 Attribute "P#" StringAtomType,
150− Attribute "QTY" StringAtomType]
151+ Attribute "QTY" IntAtomType]
151152 matrix = [
152153 [StringAtom "S1", StringAtom "P1", IntAtom 300],
153154 [StringAtom "S1", StringAtom "P2", IntAtom 200],
@@ -165,13 +166,13 @@ supplierProductsRel = case mkRelationFromList attrs matrix of
165166
166167productsRel :: Relation
167168productsRel = case mkRelationFromList attrs matrix of
168− Left _ -> undefined
169+ Left err -> traceShow (show err) undefined
169170 Right rel -> rel
170171 where
171172 attrs = A.attributesFromList [Attribute "P#" StringAtomType,
172173 Attribute "PNAME" StringAtomType,
173174 Attribute "COLOR" StringAtomType,
174− Attribute "WEIGHT" StringAtomType,
175+ Attribute "WEIGHT" IntAtomType,
175176 Attribute "CITY" StringAtomType]
176177 matrix = [
177178 [StringAtom "P1", StringAtom "Nut", StringAtom "Red", IntAtom 12, StringAtom "London"],
@@ -352,9 +353,13 @@ predicateRestrictionFilter context (RelationalExprPredicate relExpr) = case runS
352353 else
353354 Left $ PredicateExpressionError "Relational restriction filter must evaluate to 'true' or 'false'"
354355
355−predicateRestrictionFilter _ (AttributeEqualityPredicate attrName atom) = Right $ \tupleIn -> case atomForAttributeName attrName tupleIn of
356+predicateRestrictionFilter context (AttributeEqualityPredicate attrName atomexpr) = Right $ \tupleIn -> case atomForAttributeName attrName tupleIn of
356357 Left _ -> False
357− Right atom2 -> atom2 == atom
358+ Right atomIn ->
359+ case evalAtomExpr tupleIn context atomexpr of
360+ Left _ -> False
361+ Right atomCmp -> atomCmp == atomIn
362+
358363
359364tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
360365tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
@@ -362,15 +367,15 @@ tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName
362367 else
363368 Right rel
364369
365−tupleExpressionProcessor :: Relation -> TupleExpr -> AtomFunctions -> Either RelationalError (Attributes, RelationTuple -> RelationTuple)
370+tupleExpressionProcessor :: Relation -> TupleExpr -> DatabaseContext -> Either RelationalError (Attributes, RelationTuple -> RelationTuple)
366371tupleExpressionProcessor relIn
367− (AttributeTupleExpr newAttrName atomExpr) functions = do
372+ (AttributeTupleExpr newAttrName atomExpr) context = do
368373 _ <- tupleExprCheckNewAttrName newAttrName relIn
369− atomExprType <- typeFromAtomExpr (attributes relIn) functions atomExpr
370− _ <- verifyAtomExprTypes relIn functions atomExpr atomExprType
374+ atomExprType <- typeFromAtomExpr (attributes relIn) context atomExpr
375+ _ <- verifyAtomExprTypes relIn context atomExpr atomExprType
371376 let newAttrs = A.attributesFromList [Attribute newAttrName atomExprType]
372377 newAndOldAttrs = A.addAttributes (attributes relIn) newAttrs
373− return $ (newAndOldAttrs, \tup -> case evalAtomExpr tup functions atomExpr of
378+ return $ (newAndOldAttrs, \tup -> case evalAtomExpr tup context atomExpr of
374379 Left _ -> undefined -- ?!
375380 Right atom -> tupleAtomExtend newAttrName atom tup)
376381
@@ -394,26 +399,40 @@ atomFunctionForName funcName funcSet = if HS.null foundFunc then
394399 where
395400 foundFunc = HS.filter (\(AtomFunction name _ _) -> name == funcName) funcSet
396401
397−typeFromAtomExpr :: Attributes -> AtomFunctions -> AtomExpr -> Either RelationalError AtomType
402+typeFromAtomExpr :: Attributes -> DatabaseContext -> AtomExpr -> Either RelationalError AtomType
398403typeFromAtomExpr attrs _ (AttributeAtomExpr attrName) = A.atomTypeForAttributeName attrName attrs
399404typeFromAtomExpr _ _ (NakedAtomExpr atom) = Right (atomTypeForAtom atom)
400−typeFromAtomExpr _ funcs (FunctionAtomExpr funcName _) = do
405+typeFromAtomExpr _ context (FunctionAtomExpr funcName _) = do
406+ let funcs = atomFunctions context
401407 func <- atomFunctionForName funcName funcs
402408 return $ last (atomFuncType func)
409+typeFromAtomExpr _ context (RelationAtomExpr relExpr) = do
410+ relType <- evalState (typeForRelationalExpr relExpr) context
411+ return $ RelationAtomType (attributes relType)
412+
403413
404−verifyAtomExprTypes :: Relation -> AtomFunctions -> AtomExpr -> AtomType -> Either RelationalError AtomType
414+verifyAtomExprTypes :: Relation -> DatabaseContext -> AtomExpr -> AtomType -> Either RelationalError AtomType
405415verifyAtomExprTypes relIn _ (AttributeAtomExpr attrName) expectedType = do
406416 attrType <- A.atomTypeForAttributeName attrName (attributes relIn)
407417 atomTypeVerify expectedType attrType
408418verifyAtomExprTypes _ _ (NakedAtomExpr atom) expectedType = atomTypeVerify expectedType (atomTypeForAtom atom)
409−verifyAtomExprTypes relIn functions (FunctionAtomExpr funcName funcArgExprs) expectedType = do
419+verifyAtomExprTypes relIn context (FunctionAtomExpr funcName funcArgExprs) expectedType = do
420+ let functions = atomFunctions context
410421 func <- atomFunctionForName funcName functions
411422 let expectedArgTypes = atomFuncType func
412− funcArgTypes <- mapM (\(atomExpr,expectedType) -> verifyAtomExprTypes relIn functions atomExpr expectedType) $ zip funcArgExprs expectedArgTypes
423+ funcArgTypes <- mapM (\(atomExpr,expectedType2,argCount) -> case verifyAtomExprTypes relIn context atomExpr expectedType2 of
424+ Left (AtomTypeMismatchError expSubType actSubType) -> Left $ AtomFunctionTypeError funcName argCount expSubType actSubType
425+ Left err -> Left err
426+ Right x -> Right x
427+ ) $ zip3 funcArgExprs expectedArgTypes [1..]
413428 if length funcArgTypes /= length expectedArgTypes - 1 then
414429 Left $ AtomTypeCountError funcArgTypes expectedArgTypes
415430 else do
416431 atomTypeVerify expectedType (last expectedArgTypes)
432+verifyAtomExprTypes _ context (RelationAtomExpr relationExpr) expectedType = do
433+ case runState (typeForRelationalExpr relationExpr) context of
434+ (Left err, _) -> Left err
435+ (Right relType, _) -> atomTypeVerify expectedType (RelationAtomType (attributes relType))
417436
418437--determine if two types are equal or compatible
419438atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
@@ -424,14 +443,17 @@ atomTypeVerify x y = if x == y then
424443 else
425444 Left $ AtomTypeMismatchError x y
426445
427−evalAtomExpr :: RelationTuple -> AtomFunctions -> AtomExpr -> Either RelationalError Atom
446+evalAtomExpr :: RelationTuple -> DatabaseContext -> AtomExpr -> Either RelationalError Atom
428447evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
429448evalAtomExpr _ _ (NakedAtomExpr atom) = Right atom
430−evalAtomExpr tupIn functions (FunctionAtomExpr funcName arguments) = do
449+evalAtomExpr tupIn context (FunctionAtomExpr funcName arguments) = do
450+ let functions = atomFunctions context
431451 func <- atomFunctionForName funcName functions
432− argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) functions) arguments
452+ argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) context) arguments
433453 _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
434− evaldArgs <- mapM (evalAtomExpr tupIn functions) arguments
454+ evaldArgs <- mapM (evalAtomExpr tupIn context) arguments
435455 return $ (atomFunc func) evaldArgs
436−
456+evalAtomExpr _ context (RelationAtomExpr relExpr) = do
457+ relAtom <- evalState (evalRelationalExpr relExpr) context
458+ return $ RelationAtom relAtom
437459