fluree / db

Fluree database library

Home Page:https://fluree.github.io/db/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

using insert/where/delete with values (predicates) which have no value causing unwanted cardinality changes [bug]

frydj opened this issue · comments

See example below:

create the ledger with an entity "ex:betty"

Transaction:

{
  "ledger": "test123",
  "insert": [
    {
      "@id": "ex:betty",
      "@type": "ex:Yeti",
      "schema:name": "Betty"
    }
  ]
}

Response:

{
  "ledger": "test123",
  "commit": "fluree:file://test123/commit/b3c723c64791f14b0afb9d79761f3d4478891e23733d23d4349dee293bdb632d.json",
  "t": 1,
  "tx-id": "007d3dce61f6233656eb70fb1c5bac6691333f01842a68c46943d7c054252abc"
}

query for betty

Query:

{
  "from": "test123",
  "select": {
    "ex:betty": ["*"]
  }
}

Response:

[
  {
    "@type": "ex:Yeti",
    "schema:name": "Betty",
    "@id": "ex:betty"
  }
]

use insert/where/delete to update some facts about betty

Transaction:

{
  "ledger": "test123",
  "insert": [
    {
      "@id": "ex:betty",
      "schema:name": "Letty",
      "schema:description": "This is the description"
    }
  ],
  "where": {
    "@id": "ex:betty",
    "schema:name": "?name",
    "schema:description": "?description"
  },
  "delete": {
    "@id": "ex:betty",
    "schema:name": "?name",
    "schema:description": "?description"
  }
}

Response:

{
  "ledger": "test123",
  "commit": "fluree:file://test123/commit/3a93e89a4ad6be6ffee4220cb2758df499f2939cd7259c802d53fd70fce7a61d.json",
  "t": 2,
  "tx-id": "9a8fa79e6776a99a18193614fcc28697325bf719ba48d6d6747813a9d95a2fd2"
}

query for betty again

Query:

{
  "from": "test123",
  "select": {
    "ex:betty": ["*"]
  }
}

Response:

[
  {
    "@type": "ex:Yeti",
    "schema:description": "This is the description",
    "schema:name": [
      "Betty", // unexpected multi-cardinal value?
      "Letty"
    ],
    "@id": "ex:betty"
  }
]

update some existing facts again

Transaction:

{
  "ledger": "test123",
  "insert": [
    {
      "@id": "ex:betty",
      "schema:name": "Setty",
      "schema:description": "This is NOT the description"
    }
  ],
  "where": {
    "@id": "ex:betty",
    "schema:name": "?name",
    "schema:description": "?description"
  },
  "delete": {
    "@id": "ex:betty",
    "schema:name": "?name",
    "schema:description": "?description"
  }
}

Response:

{
  "ledger": "test123",
  "commit": "fluree:file://test123/commit/2311efeee5896c1da6e2dc7dcb4ae8472040b3fe9f88e56898698bf4eb0c8dd5.json",
  "t": 3,
  "tx-id": "c530c6456512e0e95ead10a19ce1fcadfda10018ee24ee524395646cae8e8e8a"
}

query again

Query:

{
  "from": "test123",
  "select": {
    "ex:betty": ["*"]
  }
}

Response:

[
  {
    // this looks fine
    "@type": "ex:Yeti",
    "schema:description": "This is NOT the description",
    "schema:name": "Setty",
    "@id": "ex:betty"
  }
]

insert/where/delete again on a field which doesn't have values yet

Transaction:

{
  "ledger": "test123",
  "insert": [
    {
      "@id": "ex:betty",
      "schema:name": "Retty",
      "schema:description": "this is a new description.",
      "schema:age": 20
    }
  ],
  "where": {
    "@id": "ex:betty",
    "schema:name": "?name",
    "schema:description": "?description",
    "schema:age": "?age"
  },
  "delete": {
    "@id": "ex:betty",
    "schema:name": "?name",
    "schema:description": "?description",
    "schema:age": "?age"
  }
}

Response

{
  "ledger": "test123",
  "commit": "fluree:file://test123/commit/97bf769b3ed571397ccbdd28cf66d5555df79998818f4ebc694657cfdf6a33a9.json",
  "t": 4,
  "tx-id": "38e71f6a5e01a58fe2b45365197c9b6d27c656da9562469b346083df759b2f49"
}

query again for betty values

Query:

{
  "from": "test123",
  "select": {
    "ex:betty": ["*"]
  }
}

Response:

[
  {
    "@type": "ex:Yeti",
    "schema:age": 20,
    "schema:description": [ // unexpected multi-cardinal value
      "This is NOT the description",
      "this is a new description."
    ],
    "schema:name": ["Retty", "Setty"], // unexpected multi-cardinal value
    "@id": "ex:betty"
  }
]

it appears that when doing insert/where/delete where you include values which don't exist yet causes this unwanted insertion of multiple values (?)

This was with a docker build of fluree-server at commit 1bcae4ed161bd9b5f43a22f6d4f7e69a3a2737e0

The issue here is that the where clause won't be applied as part of the where clause is trying to assert based on values which aren't present, so it gets dropped (as I understand). So in order to do insert/where/delete when you aren't sure if there's a value on a predicate, you should use optional, as in this example:

{
  "ledger": "test123",
  "insert": [
    {
      "@id": "ex:betty",
      "schema:name": "Letty",
      "schema:description": "This is the description"
    }
  ],
  "where": [
    {
      "@id": "ex:betty",
      "schema:name": "?name"
    },
    [
      "optional",
      {
        "schema:description": "?description"
      }
    ]
  ],
  "delete": [
    {
      "@id": "ex:betty",
      "schema:name": "?name",
      "schema:description": "?description"
    }
  ]
}

You can also do something along the lines of:

"where": { "@id": "ex:betty", "?prop": "?val" },
"delete": { "@id": "ex:betty", "?prop": "?val" },
"insert": { ... whatever you want }

This would just be a way of deleting any facts on the subject, and inserting new ones. So this example isn't really a neat "edit" as much as a rip & replace of the facts on a subject.