on master help sign in
fix validation of matching tuple attributes
commit76effd405d1384f7253426ef7b6231207f3e9a79 authorAgentM <agentm@themactionfaction.com> dateSun 16 Aug 2020, 22:28 (6 years ago) parentc29ff0b
2 files changed+31−10
src/lib/ProjectM36/RelationalExpression.hs+21−9 test/TutorialD/Interpreter.hs+10−1
src/lib/ProjectM36/RelationalExpression.hs+21−9
@@ -1155,15 +1155,27 @@ evalGraphRefTupleExprs mAttrs (TupleExprs fixedMarker tupleExprL) = do
11551155 [] -> pure emptyAttributes
11561156 (headTuple:tailTuples) -> do
11571157 --gather up resolved atom types or throw an error if an attribute cannot be made concrete from the inferred types- this could still fail if the type cannot be inferred (e.g. from [Nothing, Nothing])
1158− let mostResolvedTypes =
1159− foldr (\tup acc ->
1160− fmap (\(tupAttr,accAttr) -> --if the attribute is a constructedatomtype, we can recurse into it to potentially resolve type variables
1161− if isResolvedAttribute accAttr then
1162− accAttr
1163− else
1164− case resolveAttributes accAttr tupAttr of
1165− Left _ -> accAttr
1166− Right val -> val) (zip (V.toList $ tupleAttributes tup) acc)) (V.toList $ tupleAttributes headTuple) tailTuples
1158+ let
1159+ processTupleAttrs (tupAttr, accAttr) =
1160+ --if the attribute is a constructedatomtype, we can recurse into it to potentially resolve type variables
1161+ if isResolvedAttribute accAttr && tupAttr == accAttr then
1162+ pure accAttr
1163+ else
1164+ lift $ except $ resolveAttributes accAttr tupAttr
1165+ mostResolvedTypes <-
1166+ foldM (\acc tup -> do
1167+ let zipped = zip (V.toList $ tupleAttributes tup) acc
1168+ accNames = S.fromList $ map A.attributeName acc
1169+ tupNames = A.attributeNameSet (tupleAttributes tup)
1170+ attrNamesDiff = S.union (S.difference accNames tupNames) (S.difference tupNames accNames)
1171+ unless (null attrNamesDiff) (throwError (AttributeNamesMismatchError attrNamesDiff))
1172+ nextTupleAttrs <- mapM processTupleAttrs zipped
1173+ let diff = A.attributesDifference (A.attributesFromList nextTupleAttrs) (A.attributesFromList acc)
1174+ if diff == A.emptyAttributes then
1175+ pure nextTupleAttrs
1176+ else
1177+ throwError (TupleAttributeTypeMismatchError diff)
1178+ ) (V.toList $ tupleAttributes headTuple) tailTuples
11671179 pure (A.attributesFromList mostResolvedTypes)
11681180 --strategy: if all the tuple expr transaction markers refer to one location, then we can pass the type constructor mapping from that location, otherwise, we cannot assume that the types are the same
11691181 tConsMap <- case singularTransactions tupleExprL of
test/TutorialD/Interpreter.hs+10−1
@@ -78,7 +78,8 @@ main = do
7878 testAtomFunctionArgumentMismatch,
7979 testInvalidDataConstructor,
8080 testBasicList,
81− testRelationDeclarationMismatch
81+ testRelationDeclarationMismatch,
82+ testInvalidTuples
8283 ]
8384
8485simpleRelTests :: Test
@@ -691,3 +692,11 @@ testRelationDeclarationMismatch :: Test
691692testRelationDeclarationMismatch = TestCase $ do
692693 (sessionId, dbconn) <- dateExamplesConnection emptyNotificationCallback
693694 expectTutorialDErr sessionId dbconn (T.isPrefixOf "AtomTypeMismatchError") "data A a = A a | B | C; a := relation{a A Integer}{tuple{a A \"1\"}}"
695+
696+--generate errors when the tuples in a new relation don't match
697+testInvalidTuples :: Test
698+testInvalidTuples = TestCase $ do
699+ (sessionId, dbconn) <- dateExamplesConnection emptyNotificationCallback
700+ expectTutorialDErr sessionId dbconn (T.isPrefixOf "AttributeNamesMismatchError") ":showexpr relation{tuple{a 1},tuple{b 2}}"
701+ expectTutorialDErr sessionId dbconn (T.isPrefixOf "AttributeNamesMismatchError") ":showexpr relation{tuple{a 1},tuple{a 2, b 3}}"
702+-- expectTutorialDErr sessionId dbconn (T.isPrefixOf "ParseErrorBundle") ":showexpr relation{tuple{a 2, a 3}}" --parse failure can't be validated with this function