@@ -12,6 +12,7 @@ import qualified Data.HashSet as HS
12import Control.Monad.State hiding (join)
12import Control.Monad.State hiding (join)
13import Data.Maybe
13import Data.Maybe
14import Data.Either
14import Data.Either
16--relvar state is needed in evaluation of relational expression but only as read-only in order to extract current relvar values
17--relvar state is needed in evaluation of relational expression but only as read-only in order to extract current relvar values
17evalRelationalExpr :: RelationalExpr -> DatabaseState (Either RelationalError Relation)
18evalRelationalExpr :: RelationalExpr -> DatabaseState (Either RelationalError Relation)
@@ -91,11 +92,11 @@ evalRelationalExpr (Equals relExprA relExprB) = do
91-- extending a relation adds a single attribute with the results of the per-tuple expression evaluated
92-- extending a relation adds a single attribute with the results of the per-tuple expression evaluated
92evalRelationalExpr (Extend tupleExpression relExpr) = do
93evalRelationalExpr (Extend tupleExpression relExpr) = do
93 evald <- evalRelationalExpr relExpr
94 evald <- evalRelationalExpr relExpr
94− funcs <- liftM atomFunctions get
95+ context <- get
95 case evald of
96 case evald of
96 Left err -> return $ Left err
97 Left err -> return $ Left err
97 Right rel -> do
98 Right rel -> do
98− case tupleExpressionProcessor rel tupleExpression funcs of
99+ case tupleExpressionProcessor rel tupleExpression context of
99 Left err -> return $ Left err
100 Left err -> return $ Left err
100 Right (newAttrs, tupProc) -> return $ relMogrify tupProc newAttrs rel
101 Right (newAttrs, tupProc) -> return $ relMogrify tupProc newAttrs rel
@@ -147,7 +148,7 @@ supplierProductsRel = case mkRelationFromList attrs matrix of
148 attrs = A.attributesFromList [Attribute "S#" StringAtomType,
149 attrs = A.attributesFromList [Attribute "S#" StringAtomType,
149 Attribute "P#" StringAtomType,
150 Attribute "P#" StringAtomType,
150− Attribute "QTY" StringAtomType]
151+ Attribute "QTY" IntAtomType]
151 matrix = [
152 matrix = [
152 [StringAtom "S1", StringAtom "P1", IntAtom 300],
153 [StringAtom "S1", StringAtom "P1", IntAtom 300],
153 [StringAtom "S1", StringAtom "P2", IntAtom 200],
154 [StringAtom "S1", StringAtom "P2", IntAtom 200],
@@ -165,13 +166,13 @@ supplierProductsRel = case mkRelationFromList attrs matrix of
166productsRel :: Relation
167productsRel :: Relation
167productsRel = case mkRelationFromList attrs matrix of
168productsRel = case mkRelationFromList attrs matrix of
168− Left _ -> undefined
169+ Left err -> traceShow (show err) undefined
169 Right rel -> rel
170 Right rel -> rel
171 attrs = A.attributesFromList [Attribute "P#" StringAtomType,
172 attrs = A.attributesFromList [Attribute "P#" StringAtomType,
172 Attribute "PNAME" StringAtomType,
173 Attribute "PNAME" StringAtomType,
173 Attribute "COLOR" StringAtomType,
174 Attribute "COLOR" StringAtomType,
174− Attribute "WEIGHT" StringAtomType,
175+ Attribute "WEIGHT" IntAtomType,
175 Attribute "CITY" StringAtomType]
176 Attribute "CITY" StringAtomType]
176 matrix = [
177 matrix = [
177 [StringAtom "P1", StringAtom "Nut", StringAtom "Red", IntAtom 12, StringAtom "London"],
178 [StringAtom "P1", StringAtom "Nut", StringAtom "Red", IntAtom 12, StringAtom "London"],
@@ -352,9 +353,13 @@ predicateRestrictionFilter context (RelationalExprPredicate relExpr) = case runS
353 Left $ PredicateExpressionError "Relational restriction filter must evaluate to 'true' or 'false'"
354 Left $ PredicateExpressionError "Relational restriction filter must evaluate to 'true' or 'false'"
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
356 Left _ -> False
357 Left _ -> False
357− Right atom2 -> atom2 == atom
358+ Right atomIn ->
359+ case evalAtomExpr tupleIn context atomexpr of
361+ Right atomCmp -> atomCmp == atomIn
359tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
364tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
360tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
365tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
@@ -362,15 +367,15 @@ tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName
363 Right rel
368 Right rel
365−tupleExpressionProcessor :: Relation -> TupleExpr -> AtomFunctions -> Either RelationalError (Attributes, RelationTuple -> RelationTuple)
370+tupleExpressionProcessor :: Relation -> TupleExpr -> DatabaseContext -> Either RelationalError (Attributes, RelationTuple -> RelationTuple)
366tupleExpressionProcessor relIn
371tupleExpressionProcessor relIn
367− (AttributeTupleExpr newAttrName atomExpr) functions = do
372+ (AttributeTupleExpr newAttrName atomExpr) context = do
368 _ <- tupleExprCheckNewAttrName newAttrName relIn
373 _ <- tupleExprCheckNewAttrName newAttrName relIn
369− atomExprType <- typeFromAtomExpr (attributes relIn) functions atomExpr
374+ atomExprType <- typeFromAtomExpr (attributes relIn) context atomExpr
370− _ <- verifyAtomExprTypes relIn functions atomExpr atomExprType
375+ _ <- verifyAtomExprTypes relIn context atomExpr atomExprType
371 let newAttrs = A.attributesFromList [Attribute newAttrName atomExprType]
376 let newAttrs = A.attributesFromList [Attribute newAttrName atomExprType]
372 newAndOldAttrs = A.addAttributes (attributes relIn) newAttrs
377 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
374 Left _ -> undefined -- ?!
379 Left _ -> undefined -- ?!
375 Right atom -> tupleAtomExtend newAttrName atom tup)
380 Right atom -> tupleAtomExtend newAttrName atom tup)
@@ -394,26 +399,40 @@ atomFunctionForName funcName funcSet = if HS.null foundFunc then
395 foundFunc = HS.filter (\(AtomFunction name _ _) -> name == funcName) funcSet
400 foundFunc = HS.filter (\(AtomFunction name _ _) -> name == funcName) funcSet
397−typeFromAtomExpr :: Attributes -> AtomFunctions -> AtomExpr -> Either RelationalError AtomType
402+typeFromAtomExpr :: Attributes -> DatabaseContext -> AtomExpr -> Either RelationalError AtomType
398typeFromAtomExpr attrs _ (AttributeAtomExpr attrName) = A.atomTypeForAttributeName attrName attrs
403typeFromAtomExpr attrs _ (AttributeAtomExpr attrName) = A.atomTypeForAttributeName attrName attrs
399typeFromAtomExpr _ _ (NakedAtomExpr atom) = Right (atomTypeForAtom atom)
404typeFromAtomExpr _ _ (NakedAtomExpr atom) = Right (atomTypeForAtom atom)
400−typeFromAtomExpr _ funcs (FunctionAtomExpr funcName _) = do
405+typeFromAtomExpr _ context (FunctionAtomExpr funcName _) = do
406+ let funcs = atomFunctions context
401 func <- atomFunctionForName funcName funcs
407 func <- atomFunctionForName funcName funcs
402 return $ last (atomFuncType func)
408 return $ last (atomFuncType func)
409+typeFromAtomExpr _ context (RelationAtomExpr relExpr) = do
410+ relType <- evalState (typeForRelationalExpr relExpr) context
411+ return $ RelationAtomType (attributes relType)
404−verifyAtomExprTypes :: Relation -> AtomFunctions -> AtomExpr -> AtomType -> Either RelationalError AtomType
414+verifyAtomExprTypes :: Relation -> DatabaseContext -> AtomExpr -> AtomType -> Either RelationalError AtomType
405verifyAtomExprTypes relIn _ (AttributeAtomExpr attrName) expectedType = do
415verifyAtomExprTypes relIn _ (AttributeAtomExpr attrName) expectedType = do
406 attrType <- A.atomTypeForAttributeName attrName (attributes relIn)
416 attrType <- A.atomTypeForAttributeName attrName (attributes relIn)
407 atomTypeVerify expectedType attrType
417 atomTypeVerify expectedType attrType
408verifyAtomExprTypes _ _ (NakedAtomExpr atom) expectedType = atomTypeVerify expectedType (atomTypeForAtom atom)
418verifyAtomExprTypes _ _ (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
410 func <- atomFunctionForName funcName functions
421 func <- atomFunctionForName funcName functions
411 let expectedArgTypes = atomFuncType func
422 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
427+ ) $ zip3 funcArgExprs expectedArgTypes [1..]
413 if length funcArgTypes /= length expectedArgTypes - 1 then
428 if length funcArgTypes /= length expectedArgTypes - 1 then
414 Left $ AtomTypeCountError funcArgTypes expectedArgTypes
429 Left $ AtomTypeCountError funcArgTypes expectedArgTypes
416 atomTypeVerify expectedType (last expectedArgTypes)
431 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))
418--determine if two types are equal or compatible
437--determine if two types are equal or compatible
419atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
438atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
@@ -424,14 +443,17 @@ atomTypeVerify x y = if x == y then
425 Left $ AtomTypeMismatchError x y
444 Left $ AtomTypeMismatchError x y
427−evalAtomExpr :: RelationTuple -> AtomFunctions -> AtomExpr -> Either RelationalError Atom
446+evalAtomExpr :: RelationTuple -> DatabaseContext -> AtomExpr -> Either RelationalError Atom
428evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
447evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
429evalAtomExpr _ _ (NakedAtomExpr atom) = Right atom
448evalAtomExpr _ _ (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
431 func <- atomFunctionForName funcName functions
451 func <- atomFunctionForName funcName functions
432− argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) functions) arguments
452+ argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) context) arguments
433 _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
453 _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
434− evaldArgs <- mapM (evalAtomExpr tupIn functions) arguments
454+ evaldArgs <- mapM (evalAtomExpr tupIn context) arguments
435 return $ (atomFunc func) evaldArgs
455 return $ (atomFunc func) evaldArgs
436−
456+evalAtomExpr _ context (RelationAtomExpr relExpr) = do
457+ relAtom <- evalState (evalRelationalExpr relExpr) context
458+ return $ RelationAtom relAtom