Skip to content

Commit bad7fd1

Browse files
committed
add range functions
And rework key datastructure
1 parent a7a3a17 commit bad7fd1

18 files changed

+522
-213
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ TODOs:
106106
`sqlite_autoindex_...` indexes
107107
- optimize loading when all requested columns are available in the index
108108
- expose the locking so you can do bigger read transactions
109-
- IndexedSelectRange()
109+
- Scan time values
110110

111111
# &c.
112112

ci/pk_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// +build ci
2+
3+
package ci
4+
5+
import (
6+
"testing"
7+
8+
"github.com/alicebob/sqlittle"
9+
)
10+
11+
func TestPKSelect(t *testing.T) {
12+
Compare(
13+
t,
14+
`
15+
CREATE TABLE foo (a NOT NULL PRIMARY KEY, b, c);
16+
INSERT INTO foo values ("aa", "bb1", "1");
17+
INSERT INTO foo values ("a2", "bb2", "2");
18+
INSERT INTO foo values ("a3", "bb3", "3");
19+
INSERT INTO foo values ("a4", "bb4", "4");
20+
INSERT INTO foo values ("a5", "bb5", "5");
21+
`,
22+
`SELECT b, c FROM foo WHERE a='a3'`,
23+
func(t *testing.T, db *sqlittle.DB) [][]string {
24+
var rows [][]string
25+
cb := func(r sqlittle.Row) {
26+
rows = append(rows, r.ScanStrings())
27+
}
28+
err := db.PKSelect("foo", sqlittle.Key{"a3"}, cb, "b", "c")
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
return rows
33+
},
34+
)
35+
}
36+
37+
func TestPKDesc(t *testing.T) {
38+
Compare(
39+
t,
40+
`
41+
CREATE TABLE foo (a not null, b not null, primary key (a, b DESC));
42+
INSERT INTO foo values ("a1", 1);
43+
INSERT INTO foo values ("a1", 2);
44+
INSERT INTO foo values ("a1", 3);
45+
INSERT INTO foo values ("a2", 1);
46+
INSERT INTO foo values ("a2", 2);
47+
INSERT INTO foo values ("a2", 3);
48+
INSERT INTO foo values ("a3", 1);
49+
INSERT INTO foo values ("a3", 2);
50+
INSERT INTO foo values ("a3", 3);
51+
INSERT INTO foo values ("a4", 1);
52+
INSERT INTO foo values ("a4", 2);
53+
INSERT INTO foo values ("a4", 3);
54+
INSERT INTO foo values ("a5", 1);
55+
INSERT INTO foo values ("a5", 2);
56+
INSERT INTO foo values ("a5", 3);
57+
`,
58+
`SELECT a, b FROM foo WHERE a='a2' and b==2`,
59+
func(t *testing.T, db *sqlittle.DB) [][]string {
60+
var rows [][]string
61+
cb := func(r sqlittle.Row) {
62+
rows = append(rows, r.ScanStrings())
63+
}
64+
err := db.PKSelect("foo", sqlittle.Key{"a2", 2}, cb, "a", "b")
65+
if err != nil {
66+
t.Fatal(err)
67+
}
68+
return rows
69+
},
70+
)
71+
}
72+
73+
func TestPKNonrowidDesc(t *testing.T) {
74+
Compare(
75+
t,
76+
`
77+
CREATE TABLE foo (a not null, b not null, primary key (a, b DESC)) WITHOUT ROWID;
78+
INSERT INTO foo values ("a1", 1);
79+
INSERT INTO foo values ("a1", 2);
80+
INSERT INTO foo values ("a1", 3);
81+
INSERT INTO foo values ("a2", 1);
82+
INSERT INTO foo values ("a2", 2);
83+
INSERT INTO foo values ("a2", 3);
84+
INSERT INTO foo values ("a3", 1);
85+
INSERT INTO foo values ("a3", 2);
86+
INSERT INTO foo values ("a3", 3);
87+
INSERT INTO foo values ("a4", 1);
88+
INSERT INTO foo values ("a4", 2);
89+
INSERT INTO foo values ("a4", 3);
90+
INSERT INTO foo values ("a5", 1);
91+
INSERT INTO foo values ("a5", 2);
92+
INSERT INTO foo values ("a5", 3);
93+
`,
94+
`SELECT a, b FROM foo WHERE a='a2' and b==2`,
95+
func(t *testing.T, db *sqlittle.DB) [][]string {
96+
var rows [][]string
97+
cb := func(r sqlittle.Row) {
98+
rows = append(rows, r.ScanStrings())
99+
}
100+
err := db.PKSelect("foo", sqlittle.Key{"a2", 2}, cb, "a", "b")
101+
if err != nil {
102+
t.Fatal(err)
103+
}
104+
return rows
105+
},
106+
)
107+
}

ci/cmp_test.go renamed to ci/select_test.go

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,35 @@ INSERT INTO foo values ("a5", "bb", "cc");
5656
)
5757
}
5858

59-
func TestPKSelect(t *testing.T) {
59+
func TestSelectIndexEqDesc(t *testing.T) {
6060
Compare(
6161
t,
6262
`
63-
CREATE TABLE foo (a NOT NULL PRIMARY KEY, b, c);
64-
INSERT INTO foo values ("aa", "bb1", "1");
65-
INSERT INTO foo values ("a2", "bb2", "2");
66-
INSERT INTO foo values ("a3", "bb3", "3");
67-
INSERT INTO foo values ("a4", "bb4", "4");
68-
INSERT INTO foo values ("a5", "bb5", "5");
63+
CREATE TABLE foo (a, b);
64+
INSERT INTO foo values ("a1", 1);
65+
INSERT INTO foo values ("a1", 2);
66+
INSERT INTO foo values ("a1", 3);
67+
INSERT INTO foo values ("a2", 1);
68+
INSERT INTO foo values ("a2", 2);
69+
INSERT INTO foo values ("a2", 3);
70+
INSERT INTO foo values ("a3", 1);
71+
INSERT INTO foo values ("a3", 2);
72+
INSERT INTO foo values ("a3", 3);
73+
INSERT INTO foo values ("a4", 1);
74+
INSERT INTO foo values ("a4", 2);
75+
INSERT INTO foo values ("a4", 3);
76+
INSERT INTO foo values ("a5", 1);
77+
INSERT INTO foo values ("a5", 2);
78+
INSERT INTO foo values ("a5", 3);
79+
CREATE INDEX foo_desc ON foo (a DESC, b DESC);
6980
`,
70-
`SELECT b, c FROM foo WHERE a='a3'`,
81+
`SELECT a, b FROM foo WHERE a='a3' ORDER BY a DESC, b DESC`,
7182
func(t *testing.T, db *sqlittle.DB) [][]string {
7283
var rows [][]string
7384
cb := func(r sqlittle.Row) {
7485
rows = append(rows, r.ScanStrings())
7586
}
76-
err := db.PKSelect("foo", sqlittle.Key{"a3"}, cb, "b", "c")
87+
err := db.IndexedSelectEq("foo", "foo_desc", sqlittle.Key{"a3"}, cb, "a", "b")
7788
if err != nil {
7889
t.Fatal(err)
7990
}
@@ -82,11 +93,39 @@ INSERT INTO foo values ("a5", "bb5", "5");
8293
)
8394
}
8495

85-
func TestSelectIndexEqDesc(t *testing.T) {
96+
func TestIndexedSelectDescNonrowid(t *testing.T) {
8697
Compare(
8798
t,
8899
`
89-
CREATE TABLE foo (a, b);
100+
CREATE TABLE foo (a, b, primary key(a, b DESC)) WITHOUT ROWID;
101+
INSERT INTO foo values ("a1", 1);
102+
INSERT INTO foo values ("a1", 2);
103+
INSERT INTO foo values ("a1", 3);
104+
INSERT INTO foo values ("a2", 1);
105+
INSERT INTO foo values ("a2", 2);
106+
INSERT INTO foo values ("a2", 3);
107+
CREATE INDEX foo_desc ON foo (a, b DESC);
108+
`,
109+
`SELECT a, b FROM foo ORDER by a, b DESC`,
110+
func(t *testing.T, db *sqlittle.DB) [][]string {
111+
var rows [][]string
112+
cb := func(r sqlittle.Row) {
113+
rows = append(rows, r.ScanStrings())
114+
}
115+
err := db.IndexedSelect("foo", "foo_desc", cb, "a", "b")
116+
if err != nil {
117+
t.Fatal(err)
118+
}
119+
return rows
120+
},
121+
)
122+
}
123+
124+
func TestIndexedSelectEqDescNonrowid(t *testing.T) {
125+
Compare(
126+
t,
127+
`
128+
CREATE TABLE foo (a, b, primary key(a, b DESC)) WITHOUT ROWID;
90129
INSERT INTO foo values ("a1", 1);
91130
INSERT INTO foo values ("a1", 2);
92131
INSERT INTO foo values ("a1", 3);
@@ -102,15 +141,15 @@ INSERT INTO foo values ("a4", 3);
102141
INSERT INTO foo values ("a5", 1);
103142
INSERT INTO foo values ("a5", 2);
104143
INSERT INTO foo values ("a5", 3);
105-
CREATE INDEX foo_desc ON foo (a DESC, b DESC);
144+
CREATE INDEX foo_desc ON foo (a, b DESC);
106145
`,
107-
`SELECT a, b FROM foo WHERE a='a3' ORDER BY a DESC, b DESC`,
146+
`SELECT a, b FROM foo WHERE a='a3' AND b=2`,
108147
func(t *testing.T, db *sqlittle.DB) [][]string {
109148
var rows [][]string
110149
cb := func(r sqlittle.Row) {
111150
rows = append(rows, r.ScanStrings())
112151
}
113-
err := db.IndexedSelectEq("foo", "foo_desc", sqlittle.Key{"a3"}, cb, "a", "b")
152+
err := db.IndexedSelectEq("foo", "foo_desc", sqlittle.Key{"a3", 2}, cb, "a", "b")
114153
if err != nil {
115154
t.Fatal(err)
116155
}

ci/support_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ func execute(
7979
file string,
8080
sql string,
8181
) [][]string {
82+
t.Helper()
8283
r, err := sqlite(file, sql)
8384
if err != nil {
8485
t.Fatal(err)

db/benchmark_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func Benchmark_RandomIndex(b *testing.B) {
5151
for i := 0; i < b.N; i++ {
5252
for _, w := range words {
5353
index.ScanEq(
54-
Key{w},
54+
Key{KeyCol{V: w}},
5555
func(r Record) bool {
5656
if have, want := r[0].(string), w; have != want {
5757
b.Errorf("have %v, want %v", have, want)

db/btree.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type iterCB func(rowid int64, pl cellPayload) (bool, error)
3232
type tableBtree interface {
3333
// Iter goes over every record
3434
Iter(int, *Database, iterCB) (bool, error)
35-
// Scan starting from a key
35+
// Scan starting from a rowid
3636
IterMin(int, *Database, int64, iterCB) (bool, error)
3737
// Count counts the number of records. For debugging.
3838
Count(*Database) (int, error)
@@ -41,10 +41,11 @@ type tableBtree interface {
4141
// indexIterCB gets the Record. It returns true when the iter should be
4242
// stopped.
4343
type indexIterCB func(row Record) (bool, error)
44+
4445
type indexBtree interface {
4546
// Iter goes over every record
4647
Iter(int, *Database, indexIterCB) (bool, error)
47-
// Scan starting from an index value
48+
// Scan starting from a key
4849
IterMin(int, *Database, Key, indexIterCB) (bool, error)
4950
// Count counts the number of records. For debugging.
5051
Count(*Database) (int, error)
@@ -379,7 +380,7 @@ func (l *indexInterior) IterMin(r int, db *Database, key Key, cb indexIterCB) (b
379380
return false, ErrRecursion
380381
}
381382

382-
// binary search the most likely page
383+
// binary search the page containing the range of the key
383384
var searchErr error
384385
n := sort.Search(len(l.cells), func(n int) bool {
385386
r, err := indexBinSearch(db, l.cells[n].payload, key)
@@ -573,5 +574,5 @@ func indexBinSearch(db *Database, pl cellPayload, key Key) (bool, error) {
573574
return true, err
574575
}
575576

576-
return Compare(key, rec) <= 0, nil
577+
return Search(key, rec), nil
577578
}

db/btree_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ func TestIndexIterMin(t *testing.T) {
375375
if _, err := root.IterMin(
376376
maxRecursion,
377377
db,
378-
Key{"improvise"},
378+
Key{KeyCol{V: "improvise"}},
379379
func(r Record) (bool, error) {
380380
rows = append(rows, r)
381381
return false, nil
@@ -415,7 +415,7 @@ func TestIndexIterMin2(t *testing.T) {
415415
if _, err := root.IterMin(
416416
maxRecursion,
417417
db,
418-
Key{int64(15)},
418+
Key{KeyCol{V: int64(15)}},
419419
func(r Record) (bool, error) {
420420
rows = append(rows, r)
421421
return false, nil

0 commit comments

Comments
 (0)