Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quad subject nil after transaction #885

Open
schwankl opened this issue Nov 6, 2019 · 0 comments
Open

quad subject nil after transaction #885

schwankl opened this issue Nov 6, 2019 · 0 comments
Assignees
Labels
Milestone

Comments

@schwankl
Copy link

schwankl commented Nov 6, 2019

Description

quad subject nil after removing 2 quads with same subject and adding a new one the same transaction.

starting with empty store:

2019/11/06 09:18:12 after first transaction:
2019/11/06 09:18:12 (quad.Quad) "a" -- "to" -> "b"
2019/11/06 09:18:12 (quad.Quad) "a" -- "updated" -> "2019-11-06T11:45:26Z"^^<schema:DateTime>
2019/11/06 09:18:12 after second transaction:
2019/11/06 09:18:12 (quad.Quad) <nil> -- "updated" -> "2019-11-06T11:46:26Z"^^<schema:DateTime>
2019/11/06 09:18:12 expected:
2019/11/06 09:18:12 (quad.Quad) "a" -- "updated" -> "2019-11-06T11:46:26Z"^^<schema:DateTime>

Steps to reproduce the issue:

package main

import (
	"log"
	"os"
	"time"

	"github.com/cayleygraph/cayley"
	"github.com/cayleygraph/cayley/graph"
	_ "github.com/cayleygraph/cayley/graph/kv/all"
	"github.com/cayleygraph/quad"

	"github.com/davecgh/go-spew/spew"
)

const (
	dbpath = ".db/leveldb"
	dbtype = "leveldb"
//	dbpath = ".db/bolt"
//	dbtype = "bolt"
)

func main() {
	dbExists, err := exists(dbpath)
	if err != nil {
		log.Fatal(err)
	}

	if !dbExists {
		// initialize the database
		err := graph.InitQuadStore(dbtype, dbpath, nil)
		if err != nil {
			if err != graph.ErrDatabaseExists {
				log.Fatal(err)
			}
		}
	}

	store, err := cayley.NewGraph(dbtype, dbpath, nil)
	if err != nil {
		log.Fatal(err)
	}

	t0, err := time.Parse(time.RFC3339, "2019-11-06T11:45:26.371Z")
	t1, err := time.Parse(time.RFC3339, "2019-11-06T11:46:26.371Z")

	addQuads := []quad.Quad{
		quad.Make("a", "to", "b", nil),
		quad.Make("a", "updated", t0, nil),
	}

	t := cayley.NewTransaction()
	for _, q := range addQuads {
		t.AddQuad(q)
	}
	err = store.ApplyTransaction(t)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("after first transaction:")
	it := store.QuadsAllIterator()
	for it.Next(nil) {
		qu := store.Quad(it.Result())
		log.Printf(spew.Sdump(qu))
	}

	rmQuads := []quad.Quad{
		quad.Make("a", "to", "b", nil),
		quad.Make("a", "updated", t0, nil),
	}

	addQuads = []quad.Quad{
		quad.Make("a", "updated", t1, nil),
	}

	t = cayley.NewTransaction()
	for _, q := range rmQuads {
		t.RemoveQuad(q)
	}
	for _, q := range addQuads {
		t.AddQuad(q)
	}
	err = store.ApplyTransaction(t)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("after second transaction:")
	it = store.QuadsAllIterator()
	for it.Next(nil) {
		qu := store.Quad(it.Result())
		log.Printf(spew.Sdump(qu))
	}

	log.Printf("expected:")
	for _, q := range addQuads {
		log.Printf(spew.Sdump(q))
	}
}


// exists returns whether the given file or directory exists
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

Received results:

2019/11/06 09:18:12 after first transaction:
2019/11/06 09:18:12 (quad.Quad) "a" -- "to" -> "b"
2019/11/06 09:18:12 (quad.Quad) "a" -- "updated" -> "2019-11-06T11:45:26Z"^^schema:DateTime
2019/11/06 09:18:12 after second transaction:
2019/11/06 09:18:12 (quad.Quad) -- "updated" -> "2019-11-06T11:46:26Z"^^schema:DateTime

also dump panics/NPE:
➜ txTest cayley dump -o - -d leveldb -a .db/leveldb
I1106 09:12:15.961568 9765 command.go:805] Cayley version: v0.8.x-dev (dev snapshot)
I1106 09:12:15.961795 9765 database.go:146] using backend "leveldb" (.db/leveldb)
I1106 09:12:16.029981 9765 dump.go:73] writing quads to stdout
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x43dbce6]

goroutine 1 [running]:
github.com/cayleygraph/quad/nquads.(*Writer).writeValue(0xc000448120, 0x0, 0x0, 0x5231378, 0x1)
/Users/mike/zo/pkg/mod/github.com/cayleygraph/quad@v1.1.0/nquads/nquads.go:303 +0x36
github.com/cayleygraph/quad/nquads.(*Writer).WriteQuad(0xc000448120, 0x0, 0x0, 0x54e7c80, 0xc0004500e0, 0x54e7cc0, 0xc0001463a0, 0x0, 0x0, 0x1, ...)
/Users/mike/zo/pkg/mod/github.com/cayleygraph/quad@v1.1.0/nquads/nquads.go:316 +0x58
github.com/cayleygraph/quad/nquads.(*Writer).WriteQuads(0xc000448120, 0xc0057e4000, 0x1, 0x2710, 0x1, 0x54d24a0, 0xc0000da050)
/Users/mike/zo/pkg/mod/github.com/cayleygraph/quad@v1.1.0/nquads/nquads.go:329 +0x10d
...

Expected results:

2019/11/06 09:18:12 after first transaction:
2019/11/06 09:18:12 (quad.Quad) "a" -- "to" -> "b"
2019/11/06 09:18:12 (quad.Quad) "a" -- "updated" -> "2019-11-06T11:45:26Z"^^schema:DateTime
2019/11/06 09:18:12 after second transaction:
2019/11/06 09:18:12 (quad.Quad) "a" -- "updated" -> "2019-11-06T11:46:26Z"^^schema:DateTime

Output of cayley version or commit hash:
v0.7.7

Environment details:
go1.13.3 darwin/amd64
bolt and leveldb both affected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants