Skip to content

Commit 94fbab1

Browse files
committed
fix minor issues
LiveReview Pre-Commit Check: skipped (iter:1, coverage:0%)
1 parent ce2f395 commit 94fbab1

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

internal/reviewquery/engine.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
)
1010

1111
// QueryResult is a generic tabular result: column headers + stringified rows.
12+
// Invariant: every row in Rows has exactly len(Columns) cells. storage.QueryRows
13+
// guarantees this when building a QueryResult; preserve it in any other
14+
// construction path (formatters rely on it).
1215
type QueryResult struct {
1316
Columns []string
1417
Rows [][]string

internal/reviewquery/engine_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,49 @@ func TestRunOnRecordsEmpty(t *testing.T) {
5656
}
5757
}
5858

59+
func TestValidateReadOnlySQL(t *testing.T) {
60+
valid := []string{
61+
"SELECT 1",
62+
" select * from review_log ",
63+
"SELECT * FROM review_log;",
64+
"SELECT * FROM review_log ; ",
65+
"With x AS (SELECT 1) SELECT * FROM x",
66+
"select action, count(*) from review_log group by action",
67+
}
68+
for _, sqlText := range valid {
69+
t.Run("valid: "+sqlText, func(t *testing.T) {
70+
if err := validateReadOnlySQL(sqlText); err != nil {
71+
t.Errorf("validateReadOnlySQL(%q) = %v; want nil", sqlText, err)
72+
}
73+
})
74+
}
75+
76+
invalid := []string{
77+
"",
78+
" ",
79+
"DROP TABLE review_log",
80+
"DELETE FROM review_log",
81+
"INSERT INTO review_log VALUES (1)",
82+
"UPDATE review_log SET action='x'",
83+
"CREATE TABLE evil (x)",
84+
"ALTER TABLE review_log ADD COLUMN x",
85+
"ATTACH DATABASE '/tmp/evil.db' AS evil",
86+
"PRAGMA writable_schema=1",
87+
"REPLACE INTO review_log VALUES (1)",
88+
"SELECT 1; DROP TABLE review_log",
89+
"SELECT 1;DROP TABLE review_log",
90+
"SELECT 1; SELECT 2",
91+
"-- comment\nSELECT 1",
92+
}
93+
for _, sqlText := range invalid {
94+
t.Run("invalid: "+sqlText, func(t *testing.T) {
95+
if err := validateReadOnlySQL(sqlText); err == nil {
96+
t.Errorf("validateReadOnlySQL(%q) = nil; want an error", sqlText)
97+
}
98+
})
99+
}
100+
}
101+
59102
// BenchmarkRunOnRecords measures load+query cost at various repo sizes.
60103
// Run: go test -run=^$ -bench=RunOnRecords -benchmem ./internal/reviewquery/
61104
func BenchmarkRunOnRecords(b *testing.B) {

storage/sqlite_query_io.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99

1010
// OpenInMemorySQLite opens a fresh in-memory sqlite database via the storage
1111
// boundary. Used by the review-query engine to build an ephemeral table that is
12-
// discarded when the handle is closed.
12+
// discarded when the handle is closed. The caller owns the returned handle and
13+
// must Close() it; the in-memory database (and all its data) is destroyed once
14+
// the last connection closes.
1315
func OpenInMemorySQLite() (*sql.DB, error) {
1416
db, err := sql.Open("sqlite", ":memory:")
1517
if err != nil {

0 commit comments

Comments
 (0)