Skip to content

Commit 976ee92

Browse files
committed
data + ci tests for index col and where expressions
1 parent 37eba3a commit 976ee92

File tree

6 files changed

+148
-14
lines changed

6 files changed

+148
-14
lines changed

ci/expr_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// +build ci
2+
3+
package ci
4+
5+
import (
6+
"testing"
7+
8+
"github.com/alicebob/sqlittle"
9+
)
10+
11+
func TestExprCol(t *testing.T) {
12+
// index with expression column
13+
Compare(
14+
t,
15+
`
16+
CREATE TABLE expr (name varchar(255));
17+
CREATE INDEX expr_name ON expr (substr(name, 0, 10));
18+
INSERT INTO expr values ("aap"), ("foo"), ("qqq"), ("longestnameever");
19+
`,
20+
`SELECT name FROM expr ORDER BY name`,
21+
func(t *testing.T, db *sqlittle.DB) [][]string {
22+
var rows [][]string
23+
cb := func(r sqlittle.Row) {
24+
rows = append(rows, r.ScanStrings())
25+
}
26+
if err := db.IndexedSelect("expr", "expr_name", cb, "name"); err != nil {
27+
t.Fatal(err)
28+
}
29+
return rows
30+
},
31+
)
32+
}
33+
34+
func TestExprWhere(t *testing.T) {
35+
// index with WHERE expression
36+
Compare(
37+
t,
38+
`
39+
CREATE TABLE expr (name varchar(255));
40+
CREATE INDEX expr_where ON expr (name) WHERE name > "foo";
41+
INSERT INTO expr values ("aap"), ("foo"), ("qqq"), ("longestnameever");
42+
`,
43+
`SELECT name FROM expr WHERE name > "foo" ORDER BY name`,
44+
func(t *testing.T, db *sqlittle.DB) [][]string {
45+
var rows [][]string
46+
cb := func(r sqlittle.Row) {
47+
rows = append(rows, r.ScanStrings())
48+
}
49+
if err := db.IndexedSelect("expr", "expr_where", cb, "name"); err != nil {
50+
t.Fatal(err)
51+
}
52+
return rows
53+
},
54+
)
55+
}

db/schema.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ type SchemaIndex struct {
4040
}
4141

4242
type IndexColumn struct {
43-
Column string
44-
Collate string
45-
SortOrder sql.SortOrder
43+
Column string
44+
Expression string
45+
Collate string
46+
SortOrder sql.SortOrder
4647
}
4748

4849
func newSchema(table string, master []sqliteMaster) (*Schema, error) {
@@ -200,19 +201,23 @@ func (st *Schema) addCreateIndex(ci sql.CreateIndexStmt) {
200201
func (st *Schema) toIndexColumns(ci []sql.IndexedColumn) []IndexColumn {
201202
var cs []IndexColumn
202203
for _, col := range ci {
203-
base := st.column(col.Column)
204-
if base == nil {
205-
base = &TableColumn{} // shouldn't happen
204+
c := IndexColumn{
205+
Column: col.Column,
206+
Expression: col.Expression,
207+
SortOrder: col.SortOrder,
206208
}
207-
collate := base.Collate
208-
if col.Collate != "" {
209-
collate = col.Collate
209+
if col.Column != "" {
210+
// not an expression column
211+
base := st.column(col.Column)
212+
if base != nil {
213+
collate := base.Collate
214+
if col.Collate != "" {
215+
collate = col.Collate
216+
}
217+
c.Collate = collate
218+
}
210219
}
211-
cs = append(cs, IndexColumn{
212-
Column: col.Column,
213-
Collate: collate,
214-
SortOrder: col.SortOrder,
215-
})
220+
cs = append(cs, c)
216221
}
217222
return cs
218223
}

indexed_select_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,65 @@ func TestIndexedSelectDesc(t *testing.T) {
145145
t.Errorf("diff:\n%s", diff.LineDiff(spew.Sdump(want), spew.Sdump(have)))
146146
}
147147
}
148+
149+
func TestIndexedSelectExprWhere(t *testing.T) {
150+
// index with a WHERE expression
151+
db, err := Open("testdata/expr.sqlite")
152+
if err != nil {
153+
t.Fatal(err)
154+
}
155+
defer db.Close()
156+
157+
var words []string
158+
cb := func(r Row) {
159+
w, _ := r.ScanString()
160+
words = append(words, w)
161+
}
162+
if err := db.IndexedSelect(
163+
"expr",
164+
"expr_where",
165+
cb,
166+
"name",
167+
); err != nil {
168+
t.Fatal(err)
169+
}
170+
want := []string{
171+
"longestnameever",
172+
"qqq",
173+
}
174+
if have, want := words, want; !reflect.DeepEqual(have, want) {
175+
t.Errorf("diff:\n%s", diff.LineDiff(spew.Sdump(want), spew.Sdump(have)))
176+
}
177+
}
178+
179+
func TestIndexedSelectExprCol(t *testing.T) {
180+
// index with an expression column
181+
db, err := Open("testdata/expr.sqlite")
182+
if err != nil {
183+
t.Fatal(err)
184+
}
185+
defer db.Close()
186+
187+
var words []string
188+
cb := func(r Row) {
189+
w, _ := r.ScanString()
190+
words = append(words, w)
191+
}
192+
if err := db.IndexedSelect(
193+
"expr",
194+
"expr_name",
195+
cb,
196+
"name",
197+
); err != nil {
198+
t.Fatal(err)
199+
}
200+
want := []string{
201+
"aap",
202+
"foo",
203+
"longestnameever", // substr() expression, but we get the value from the row
204+
"qqq",
205+
}
206+
if have, want := words, want; !reflect.DeepEqual(have, want) {
207+
t.Errorf("diff:\n%s", diff.LineDiff(spew.Sdump(want), spew.Sdump(have)))
208+
}
209+
}

testdata/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
ALL:= \
44
alter.sqlite \
55
empty.sqlite \
6+
expr.sqlite \
67
four.sqlite \
78
funkykey.sqlite \
89
index.sqlite \

testdata/expr.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
set -eu
3+
TABLE=expr.sqlite
4+
5+
rm -f ${TABLE}
6+
sqlite3 --batch ${TABLE} <<HERE
7+
CREATE TABLE expr (name varchar(255));
8+
CREATE INDEX expr_name ON expr (substr(name, 0, 10));
9+
CREATE INDEX expr_where ON expr (name) WHERE name > "foo";
10+
INSERT INTO expr values ("aap"), ("foo"), ("qqq"), ("longestnameever");
11+
HERE

testdata/expr.sqlite

16 KB
Binary file not shown.

0 commit comments

Comments
 (0)