aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bsfs/graph/schema.nt3
-rw-r--r--bsfs/query/validator.py6
-rw-r--r--bsfs/triple_store/sparql/parse_filter.py1
-rw-r--r--bsfs/triple_store/sparql/sparql.py4
-rw-r--r--test/apps/schema-2.nt3
-rw-r--r--test/graph/ac/test_null.py3
-rw-r--r--test/graph/test_graph.py12
-rw-r--r--test/graph/test_nodes.py6
-rw-r--r--test/graph/test_resolve.py3
-rw-r--r--test/query/test_validator.py6
-rw-r--r--test/schema/test_schema.py17
-rw-r--r--test/schema/test_serialize.py10
-rw-r--r--test/triple_store/sparql/test_parse_filter.py3
-rw-r--r--test/triple_store/sparql/test_sparql.py12
14 files changed, 57 insertions, 32 deletions
diff --git a/bsfs/graph/schema.nt b/bsfs/graph/schema.nt
index 8612681..f619746 100644
--- a/bsfs/graph/schema.nt
+++ b/bsfs/graph/schema.nt
@@ -8,7 +8,8 @@ prefix bsfs: <http://bsfs.ai/schema/>
prefix bsm: <http://bsfs.ai/schema/Meta#>
# literals
-xsd:integer rdfs:subClassOf bsfs:Literal .
+bsfs:Number rdfs:subClassOf bsfs:Literal .
+xsd:integer rdfs:subClassOf bsfs:Number .
# predicates
bsm:t_created rdfs:subClassOf bsfs:Predicate ;
diff --git a/bsfs/query/validator.py b/bsfs/query/validator.py
index b04a9bf..75b51ca 100644
--- a/bsfs/query/validator.py
+++ b/bsfs/query/validator.py
@@ -182,8 +182,7 @@ class Filter():
if not type_ <= dom:
raise errors.ConsistencyError(f'expected type {dom}, found {type_}')
# node.count is a numerical expression
- # FIXME: We have to ensure that ns.xsd.integer is always known in the schema!
- self._parse_filter_expression(self.schema.literal(ns.xsd.integer), node.count)
+ self._parse_filter_expression(self.schema.literal(ns.bsfs.Number), node.count)
## conditions
@@ -211,6 +210,9 @@ class Filter():
# type exists in the schema
if type_ not in self.schema.literals():
raise errors.ConsistencyError(f'literal {type_} is not in the schema')
+ # type must be a numerical
+ if not type_ <= self.schema.literal(ns.bsfs.Number):
+ raise errors.ConsistencyError(f'expected a number type, found {type_}')
# FIXME: Check if node.value corresponds to type_
diff --git a/bsfs/triple_store/sparql/parse_filter.py b/bsfs/triple_store/sparql/parse_filter.py
index 0297cbc..18a3288 100644
--- a/bsfs/triple_store/sparql/parse_filter.py
+++ b/bsfs/triple_store/sparql/parse_filter.py
@@ -242,7 +242,6 @@ class Filter():
# predicate count expression (fetch number of predicates at *head*)
num_preds = f'{{ SELECT (COUNT(distinct {inner}) as {outer}) WHERE {{ {head} {pred} {inner} }} }}'
# count expression
- # FIXME: We have to ensure that ns.xsd.integer is always known in the schema!
count_bounds = self._parse_filter_expression(self.schema.literal(ns.xsd.integer), node.count, outer)
# combine
return num_preds + ' . ' + count_bounds
diff --git a/bsfs/triple_store/sparql/sparql.py b/bsfs/triple_store/sparql/sparql.py
index ddace35..87467ff 100644
--- a/bsfs/triple_store/sparql/sparql.py
+++ b/bsfs/triple_store/sparql/sparql.py
@@ -11,6 +11,7 @@ import rdflib
# bsfs imports
from bsfs import schema as bsc
+from bsfs.namespace import ns
from bsfs.query import ast
from bsfs.utils import errors, URI
@@ -94,7 +95,8 @@ class SparqlStore(base.TripleStoreBase):
super().__init__(None)
self._graph = rdflib.Graph()
self._transaction = _Transaction(self._graph)
- self._schema = bsc.Schema()
+ # NOTE: parsing bsfs.query.ast.filter.Has requires xsd:integer.
+ self._schema = bsc.Schema(literals={bsc.ROOT_NUMBER.child(ns.xsd.integer)})
self._filter_parser = parse_filter.Filter(self._schema)
# NOTE: mypy and pylint complain about the **kwargs not being listed (contrasting super)
diff --git a/test/apps/schema-2.nt b/test/apps/schema-2.nt
index 525ac99..4c5468f 100644
--- a/test/apps/schema-2.nt
+++ b/test/apps/schema-2.nt
@@ -10,7 +10,8 @@ prefix bse: <http://bsfs.ai/schema/Entity#>
bsfs:Entity rdfs:subClassOf bsfs:Node .
# common definitions
-xsd:integer rdfs:subClassOf bsfs:Literal .
+bsfs:Number rdfs:subClassOf bsfs:Literal .
+xsd:integer rdfs:subClassOf bsfs:Number .
bse:filesize rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Entity ;
diff --git a/test/graph/ac/test_null.py b/test/graph/ac/test_null.py
index c3df393..e35852d 100644
--- a/test/graph/ac/test_null.py
+++ b/test/graph/ac/test_null.py
@@ -34,7 +34,8 @@ class TestNullAC(unittest.TestCase):
bsfs:Entity rdfs:subClassOf bsfs:Node .
bsfs:Tag rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
# predicates mandated by Nodes
bsm:t_created rdfs:subClassOf bsfs:Predicate ;
diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py
index 125084c..f97783b 100644
--- a/test/graph/test_graph.py
+++ b/test/graph/test_graph.py
@@ -125,7 +125,8 @@ class TestGraph(unittest.TestCase):
prefix bse: <http://bsfs.ai/schema/Entity#>
bsfs:Entity rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bse:filename rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Entity ;
@@ -147,7 +148,8 @@ class TestGraph(unittest.TestCase):
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix bsfs: <http://bsfs.ai/schema/>
prefix bsm: <http://bsfs.ai/schema/Meta#>
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bsm:t_created rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Node ;
rdfs:range xsd:integer ;
@@ -162,7 +164,8 @@ class TestGraph(unittest.TestCase):
prefix bse: <http://bsfs.ai/schema/Entity#>
bsfs:Entity rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bse:filename rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Entity ;
@@ -186,7 +189,8 @@ class TestGraph(unittest.TestCase):
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix bsfs: <http://bsfs.ai/schema/>
prefix bsm: <http://bsfs.ai/schema/Meta#>
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bsm:t_created rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Node ;
rdfs:range xsd:integer ;
diff --git a/test/graph/test_nodes.py b/test/graph/test_nodes.py
index 47647bd..e29ab6a 100644
--- a/test/graph/test_nodes.py
+++ b/test/graph/test_nodes.py
@@ -37,7 +37,8 @@ class TestNodes(unittest.TestCase):
bsfs:Tag rdfs:subClassOf bsfs:Node .
bsfs:User rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
# predicates mandated by Nodes
bsm:t_created rdfs:subClassOf bsfs:Predicate ;
@@ -78,7 +79,8 @@ class TestNodes(unittest.TestCase):
(rdflib.URIRef(ns.bsfs.Tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.bsfs.User), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.xsd.string), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
- (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.bsfs.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Number)),
(rdflib.URIRef(ns.bsm.t_created), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.comment), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.filesize), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
diff --git a/test/graph/test_resolve.py b/test/graph/test_resolve.py
index a27e8c9..0e7da99 100644
--- a/test/graph/test_resolve.py
+++ b/test/graph/test_resolve.py
@@ -41,7 +41,8 @@ class TestFilter(unittest.TestCase):
bsfs:Entity rdfs:subClassOf bsfs:Node .
bsfs:Tag rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bse:comment rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Entity ;
diff --git a/test/query/test_validator.py b/test/query/test_validator.py
index 405872c..ea56a57 100644
--- a/test/query/test_validator.py
+++ b/test/query/test_validator.py
@@ -33,7 +33,8 @@ class TestFilter(unittest.TestCase):
bsfs:Tag rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bse:comment rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Node ;
@@ -247,6 +248,9 @@ class TestFilter(unittest.TestCase):
ast.filter.GreaterThan(0))
self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
ast.filter.LessThan(0))
+ # type must be a number
+ self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.xsd.string),
+ ast.filter.LessThan(0))
# bounded accepts correct expressions
self.assertIsNone(self.validate._bounded(self.schema.literal(ns.xsd.integer), ast.filter.LessThan(0)))
self.assertIsNone(self.validate._bounded(self.schema.literal(ns.xsd.integer), ast.filter.GreaterThan(0)))
diff --git a/test/schema/test_schema.py b/test/schema/test_schema.py
index ca21f87..c19c226 100644
--- a/test/schema/test_schema.py
+++ b/test/schema/test_schema.py
@@ -35,7 +35,8 @@ class TestSchema(unittest.TestCase):
bsfs:Unused rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
xsd:boolean rdfs:subClassOf bsfs:Literal .
bse:tag rdfs:subClassOf bsfs:Predicate ;
@@ -56,18 +57,18 @@ class TestSchema(unittest.TestCase):
'''
# nodes
self.n_root = types.ROOT_NODE
- self.n_ent = types.Node(ns.bsfs.Entity, types.Node(ns.bsfs.Node, None))
- self.n_img = types.Node(ns.bsfs.Image, types.Node(ns.bsfs.Entity, types.Node(ns.bsfs.Node, None)))
- self.n_tag = types.Node(ns.bsfs.Tag, types.Node(ns.bsfs.Node, None))
- self.n_unused = types.Node(ns.bsfs.Unused, types.Node(ns.bsfs.Node, None))
+ self.n_ent = self.n_root.child(ns.bsfs.Entity)
+ self.n_img = self.n_ent.child(ns.bsfs.Image)
+ self.n_tag = self.n_root.child(ns.bsfs.Tag)
+ self.n_unused = self.n_root.child(ns.bsfs.Unused)
self.nodes = [self.n_root, self.n_ent, self.n_img, self.n_tag, self.n_unused]
# literals
self.l_root = types.ROOT_LITERAL
self.l_number = types.ROOT_NUMBER
- self.l_string = types.Literal(ns.xsd.string, types.Literal(ns.bsfs.Literal, None))
- self.l_integer = types.Literal(ns.xsd.integer, self.l_number)
- self.l_unused = types.Literal(ns.xsd.boolean, types.Literal(ns.bsfs.Literal, None))
+ self.l_string = self.l_root.child(ns.xsd.string)
+ self.l_integer = self.l_root.child(ns.xsd.integer)
+ self.l_unused = self.l_root.child(ns.xsd.boolean)
self.literals = [self.l_root, self.l_number, self.l_string, self.l_integer, self.l_unused]
# predicates
diff --git a/test/schema/test_serialize.py b/test/schema/test_serialize.py
index b9d8599..f46b3a4 100644
--- a/test/schema/test_serialize.py
+++ b/test/schema/test_serialize.py
@@ -180,7 +180,7 @@ class TestFromString(unittest.TestCase):
# a literal can have multiple children
l_string = types.ROOT_LITERAL.child(ns.xsd.string)
- l_integer = types.ROOT_LITERAL.child(ns.xsd.integer)
+ l_integer = types.ROOT_NUMBER.child(ns.xsd.integer)
l_unsigned = l_integer.child(ns.xsd.unsigned)
l_signed = l_integer.child(ns.xsd.signed)
self.assertEqual(Schema({}, {}, {l_string, l_integer, l_unsigned, l_signed}), from_string('''
@@ -191,7 +191,8 @@ class TestFromString(unittest.TestCase):
# literals inherit from same parent
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
# literals inherit from same parent
xsd:unsigned rdfs:subClassOf xsd:integer .
@@ -893,7 +894,7 @@ class TestFromString(unittest.TestCase):
# literals
l_string = types.ROOT_LITERAL.child(ns.xsd.string)
l_array = types.ROOT_LITERAL.child(ns.bsfs.array)
- l_integer = types.ROOT_LITERAL.child(ns.xsd.integer)
+ l_integer = types.ROOT_NUMBER.child(ns.xsd.integer)
l_boolean = types.ROOT_LITERAL.child(ns.xsd.boolean)
# predicates
p_annotation = types.ROOT_PREDICATE.child(ns.bsfs.Annotation)
@@ -931,7 +932,8 @@ class TestFromString(unittest.TestCase):
xsd:string rdfs:subClassOf bsfs:Literal ;
rdfs:label "A sequence of characters"^^xsd:string .
bsfs:array rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
xsd:boolean rdfs:subClassOf bsfs:Literal .
# abstract predicates
diff --git a/test/triple_store/sparql/test_parse_filter.py b/test/triple_store/sparql/test_parse_filter.py
index 1d96994..f6842c5 100644
--- a/test/triple_store/sparql/test_parse_filter.py
+++ b/test/triple_store/sparql/test_parse_filter.py
@@ -35,7 +35,8 @@ class TestParseFilter(unittest.TestCase):
bsfs:Tag rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bsfs:URI rdfs:subClassOf bsfs:Literal .
bse:comment rdfs:subClassOf bsfs:Predicate ;
diff --git a/test/triple_store/sparql/test_sparql.py b/test/triple_store/sparql/test_sparql.py
index 5342925..5b71016 100644
--- a/test/triple_store/sparql/test_sparql.py
+++ b/test/triple_store/sparql/test_sparql.py
@@ -33,7 +33,8 @@ class TestSparqlStore(unittest.TestCase):
bsfs:Tag rdfs:subClassOf bsfs:Node .
bsfs:User rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
# non-unique literal
bse:comment rdfs:subClassOf bsfs:Predicate ;
@@ -66,7 +67,8 @@ class TestSparqlStore(unittest.TestCase):
(rdflib.URIRef(ns.bsfs.Tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.bsfs.User), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.xsd.string), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
- (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.bsfs.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Number)),
(rdflib.URIRef(ns.bse.comment), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.filesize), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
@@ -310,7 +312,8 @@ class TestSparqlStore(unittest.TestCase):
bsfs:User rdfs:subClassOf bsfs:Node .
xsd:boolean rdfs:subClassOf bsfs:Literal .
- xsd:integer rdfs:subClassOf bsfs:Literal .
+ bsfs:Number rdfs:subClassOf bsfs:Literal .
+ xsd:integer rdfs:subClassOf bsfs:Number .
bse:filesize rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Entity ;
@@ -351,7 +354,8 @@ class TestSparqlStore(unittest.TestCase):
(rdflib.URIRef(ns.bsfs.Tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.bsfs.User), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.xsd.boolean), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
- (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.bsfs.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Number)),
(rdflib.URIRef(ns.bse.shared), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.filesize), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),