fluree / core

Fluree releases and public bug reports
0 stars 0 forks source link

Updating (retract-and-replace) multi-card ref property causes ledger-breaking behavior #5

Closed aaj3f closed 1 year ago

aaj3f commented 1 year ago

Currently, any update to a property's value on a subject where that subject already has a value on that property will perform a retract-and-replace. In this bug, however, the retract-and-replace commit causes a fatal ledger issue where subsequent queries/commits fail with a "Cannot invoke \"java.lang.Character.charValue()\" because \"x\" is null" error.

Creation transaction 1:

{
    "ledger": "issue/nodeshape",
    "context": {
        "d3f": "http://d3fend.mitre.org/ontologies/d3fend.owl#",
        "dbr": "http://dbpedia.org/resource/",
        "dc": "http://purl.org/dc/elements/1.1/",
        "owl": "http://www.w3.org/2002/07/owl#",
        "xsd": "http://www.w3.org/2001/XMLSchema#",
        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
        "sh": "http://www.w3.org/ns/shacl#",
        "skos": "http://www.w3.org/2008/05/skos#",
        "f": "https://ns.flur.ee/ledger#",
        "ex": "http://example.com/ns/",
        "schema": "http://schema.org/"
    },
    "txn": {
        "@type": [
            "sh:NodeShape"
        ],
        "sh:targetClass": {
            "id": "schema:Person"
        },
        "sh:name": "schema:Person",
        "sh:property": [
            {
                "sh:path": {
                    "id": "schema:familyName"
                },
                "sh:name": "schema:familyName",
                "sh:datatype": {
                    "id": "xsd:string"
                }
            }
        ]
    }
}

Query (to retrieve blank node id)

{
    "ledger": "issue/nodeshape",
    "query": {
        "select": {"?s": ["*"]},
        "where": [["?s", "sh:property", "?property"]]
    }
}

Retract-and-replace transaction

{
    "ledger": "issue/nodeshape",
    "txn": {
        "@id": "_:f211106232532992",
        "sh:property": [
            {
                "sh:path": {
                    "id": "schema:age"
                },
                "sh:name": "schema:age",
                "sh:datatype": {
                    "id": "xsd:string"
                }
            }
        ]
    }
}

Any subsequent queries or transactions return

{
    "spec": "(spec-tools.core/spec {:spec clojure.core/string?, :type :string, :leaf? true})",
    "problems": [
        {
            "path": [],
            "pred": "clojure.core/string?",
            "val": {
                "error": "Cannot invoke \"java.lang.Character.charValue()\" because \"x\" is null"
            },
            "via": [],
            "in": []
        }
    ],
    "type": "reitit.coercion/response-coercion",
    "coercion": "spec",
    "value": {
        "error": "Cannot invoke \"java.lang.Character.charValue()\" because \"x\" is null"
    },
    "in": [
        "response",
        "body"
    ]
}
dpetran commented 1 year ago

I ran through this in a db repl and wasn't able to replicate the error, so I suspect this is a context related bug. Once the context fixing has landed I will re-evaluate.

Here's my repro attempt for the record:

(comment
  (def conn (test-utils/create-conn))

  (def ledger @(fluree/create conn "retract-and-replace"))

  (def db0 (fluree/db ledger))

  (def db1 @(fluree/stage db0 {"@type" "sh:NodeShape",
                               "sh:targetClass" {"id" "schema:Person"},
                               "sh:name" "schema:Person",
                               "sh:property"
                               [{"sh:path" {"id" "schema:familyName"},
                                 "sh:name" "schema:familyName",
                                 "sh:datatype" {"id" "xsd:string"}}]}))

  @(fluree/query db1 {:select {"?s" ["*"]}, :where [["?s" "sh:property" "?property"]]})
  [{:id "_:f211106232532992",
    :rdf/type ["sh:NodeShape"],
    "sh:targetClass" {:id "_:f211106232532993"},
    "sh:name" "schema:Person",
    "sh:property" {:id "_:f211106232532994"}}]

  (def db2 @(fluree/stage @(fluree/commit! ledger db1)
                          {"@id" "_:f211106232532992",
                           "sh:property"
                           [{"sh:path" {"id" "schema:age"},
                             "sh:name" "schema:age",
                             "sh:datatype" {"id" "xsd:string"}}]}))

  @(fluree/query db1 {:select {"?s" ["*"]}, :where [["?s" "sh:property" "?property"]]})
  [{:id "_:f211106232532992",
    :rdf/type ["sh:NodeShape"],
    "sh:targetClass" {:id "_:f211106232532993"},
    "sh:name" "schema:Person",
    "sh:property" {:id "_:f211106232532994"}}]

  )
aaj3f commented 1 year ago

Thanks, @dpetran -- I'm making a list of all the bugs/issues that are probably http-api-gateway context/serialization-specific, and this is one of them. I have a collection of tests for each of them in Postman and once the topic branch is PR'd and merged, I do plan to test them w/ that collection and if they're fixed out-of-the-box, I'll just close them outright

I wonder if we want to add a label for that temporarily to make it easier to flag them