Skip to content

Commit

Permalink
ci: Run tests against any version of V
Browse files Browse the repository at this point in the history
There are some minor syntax changes to bring it up to V 0.4.2 4bc9a8f.
This also adds a new environment variable that lets you run tests at
any version (tag or commit), such as:

    OLDV=0.3.5 make sql-test
  • Loading branch information
elliotchance committed Oct 15, 2023
1 parent 210c29f commit cb54295
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 43 deletions.
34 changes: 27 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
.PHONY: bench bench-on-disk bench-memory fmt fmt-verify test examples grammar sql-test docs clean-docs
.PHONY: bench bench-on-disk bench-memory fmt fmt-verify test examples grammar sql-test docs clean-docs oldv

# Is not used at the moment. It is useful for testing options like different
# `-gc` values.
BUILD_OPTIONS =

PROD = -prod

# OLDV let's you specify a differnt V version rather than the default one. This
# is important for testing V language changes or legacy performance tests. It is
# documented in testing.rst.
ifdef OLDV
V_DIR := $(shell dirname `which v`)
V := "/tmp/oldv/v_at_$(OLDV)/v"
else
V := $(shell which v)
endif

# Ready is a some quick tasks that can easily be forgotten when preparing a
# diff.

Expand All @@ -22,6 +32,16 @@ bin/vsql.exe:
v $(BUILD_OPTIONS) $(PROD) cmd/vsql
mv cmd/vsql/vsql.exe bin/vsql.exe

oldv:
ifdef OLDV
@mkdir -p /tmp/oldv/
@# VJOBS and VFLAGS needs to be provided for macOS. I'm not sure if they also
@# have to be removed for linux.
cd $(V_DIR) && VJOBS=1 VFLAGS='-no-parallel' cmd/tools/oldv $(OLDV) -w /tmp/oldv/
@# Print out the version to make sure the V build was successful.
$(V) version
endif

# Documentation

snippets:
Expand Down Expand Up @@ -50,14 +70,14 @@ fmt-verify:

# Tests

test:
v -stats $(BUILD_OPTIONS) $(PROD) test vsql
test: oldv
$(V) -stats $(BUILD_OPTIONS) $(PROD) test vsql

btree-test:
v -stats $(BUILD_OPTIONS) $(PROD) test vsql/btree_test.v
btree-test: oldv
$(V) -stats $(BUILD_OPTIONS) $(PROD) test vsql/btree_test.v

sql-test:
v -stats $(BUILD_OPTIONS) test vsql/sql_test.v
sql-test: oldv
$(V) -stats $(BUILD_OPTIONS) test vsql/sql_test.v

# CLI Tests

Expand Down
15 changes: 15 additions & 0 deletions docs/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,18 @@ Running the specific test again can be done with:
.. code-block:: sh
TEST=subquery:32 make sql-test
Using Different V Versions
--------------------------

Sometimes there are V language changes which might break tests, or otherwise
cause issues on newer versions. Fortunatly there is a `oldv` tool which can be
used to compile older version of `v` for testing. You can run tests simply by
supplying a different version of V:

.. code-block:: sh
OLDV=0.3.5 make sql-test
You can use any commit or tag for ``OLDV``. All tags can be
`found here <https://github.com/vlang/v/tags>`_.
8 changes: 4 additions & 4 deletions docs/v-client-library-docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ enum Boolean
pub enum Boolean {
// These must not be negative values because they are encoded as u8 on disk.
is_unknown = 0 // same as NULL
is_false = 1
is_true = 2
is_false = 1
is_true = 2
}
Expand All @@ -351,7 +351,7 @@ struct VirtualTable
pub struct VirtualTable {
create_table_sql string
create_table_stmt CreateTableStmt
data VirtualTableProviderFn
data VirtualTableProviderFn [required]
mut:
is_done bool
rows []Row
Expand Down Expand Up @@ -413,7 +413,7 @@ struct Connection
// now allows you to override the wall clock that is used. The Time must be
// in UTC with a separate offset for the current local timezone (in positive
// or negative minutes).
now fn () (time.Time, i16)
now fn () (time.Time, i16) [required]
// warnings are SQLSTATE errors that do not stop the execution. For example,
// if a value must be truncated during a runtime CAST.
//
Expand Down
4 changes: 2 additions & 2 deletions vsql/btree.v
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ fn (mut p Btree) split_page(path []int, page Page, obj PageObject, kind u8) ! {
mut inserted_at := -1
for pos, object in objects {
if compare_bytes(obj.key, object.key) <= 0 {
mut new_objects := objects[..pos]
mut new_objects := objects[..pos].clone()
new_objects << obj
new_objects << objects[pos..]
objects = new_objects.clone()
Expand Down Expand Up @@ -362,7 +362,7 @@ fn (mut p Btree) split_page(path []int, page Page, obj PageObject, kind u8) ! {
// usually quite small. However, they are not a fixed size because the
// keys can be variable length.
if page3.used > p.page_size - p2.length() {
mut new_path := path[..path.len - 1]
mut new_path := path[..path.len - 1].clone()
p.split_page(new_path, page3, p2, kind_not_leaf)!
} else {
page3.add(p2)!
Expand Down
4 changes: 2 additions & 2 deletions vsql/btree_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ fn test_btree_test() ! {
blob_sizes := [
// 48 means all objects will fit in pages (and several per page) and
// never have to use blob storage.
48
48,
// 148 is larger than half a page so we always end up with one object
// per page, but no need to use blob storage, yet.
148
148,
// 348 is larger than a page so all items must go into blob storage.
348,
]
Expand Down
14 changes: 6 additions & 8 deletions vsql/connection.v
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub mut:
// now allows you to override the wall clock that is used. The Time must be
// in UTC with a separate offset for the current local timezone (in positive
// or negative minutes).
now fn () (time.Time, i16)
now fn () (time.Time, i16) [required]
// warnings are SQLSTATE errors that do not stop the execution. For example,
// if a value must be truncated during a runtime CAST.
//
Expand Down Expand Up @@ -116,9 +116,7 @@ fn open_connection(path string, options ConnectionOptions) !&Connection {
query_cache: options.query_cache
current_catalog: catalog_name
current_schema: vsql.default_schema_name
now: fn () (time.Time, i16) {
return time.utc(), i16(time.offset() / 60)
}
now: default_now
}

register_builtin_funcs(mut conn)!
Expand Down Expand Up @@ -244,9 +242,9 @@ fn (mut c CatalogConnection) release_read_connection() {

// prepare returns a precompiled statement that can be executed multiple times
// with different provided parameters.
pub fn (mut c Connection) prepare(sql string) !PreparedStmt {
pub fn (mut c Connection) prepare(sql_stmt string) !PreparedStmt {
t := start_timer()
stmt, params, explain := c.query_cache.parse(sql) or {
stmt, params, explain := c.query_cache.parse(sql_stmt) or {
mut catalog := c.catalog()
catalog.storage.transaction_aborted()
return err
Expand All @@ -257,14 +255,14 @@ pub fn (mut c Connection) prepare(sql string) !PreparedStmt {
}

// query executes a statement. If there is a result set it will be returned.
pub fn (mut c Connection) query(sql string) !Result {
pub fn (mut c Connection) query(sql_stmt string) !Result {
mut catalog := c.catalog()

if catalog.storage.transaction_state == .aborted {
return sqlstate_25p02()
}

mut prepared := c.prepare(sql) or {
mut prepared := c.prepare(sql_stmt) or {
catalog.storage.transaction_aborted()
return err
}
Expand Down
2 changes: 1 addition & 1 deletion vsql/eval.v
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ fn time_value(conn &Connection, prec int, include_offset bool) string {
mut s := now.strftime('%H:%M:%S')

if prec > 0 {
microseconds := left_pad(now.microsecond.str(), '0', 6)
microseconds := left_pad(int(now.nanosecond / 1000).str(), '0', 6)
s += '.' + microseconds.substr(0, prec)
}

Expand Down
2 changes: 1 addition & 1 deletion vsql/funcs.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct Func {
name string
arg_types []Type
is_agg bool
func fn ([]Value) !Value
func fn ([]Value) !Value [required]
return_type Type
}

Expand Down
4 changes: 2 additions & 2 deletions vsql/lexer.v
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ pub:
value string
}

fn tokenize(sql string) []Token {
fn tokenize(sql_stmt string) []Token {
mut tokens := []Token{}
cs := sql.trim(';').runes()
cs := sql_stmt.trim(';').runes()
mut i := 0

next: for i < cs.len {
Expand Down
2 changes: 1 addition & 1 deletion vsql/pager.v
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn (mut p FilePager) fetch_page(page_number int) !Page {
return Page{
kind: b.read_u8()
used: b.read_u16()
data: buf[page_header_size..]
data: buf[page_header_size..].clone()
}
}

Expand Down
2 changes: 1 addition & 1 deletion vsql/query_cache.v
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ fn (mut q QueryCache) parse(query string) !(Stmt, map[string]Value, bool) {
mut explain := false
if tokens[0].value.to_upper() == 'EXPLAIN' {
explain = true
tokens = tokens[1..]
tokens = tokens[1..].clone()
}

key, params, new_tokens := q.prepare(tokens)
Expand Down
5 changes: 3 additions & 2 deletions vsql/server.v
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub fn new_server(options ServerOptions) Server {

return Server{options, &Connection{
query_cache: new_query_cache()
now: default_now
catalogs: {
catalog_name: catalog
}
Expand Down Expand Up @@ -95,7 +96,7 @@ fn (mut s Server) handle_conn(mut c net.TcpConn) ! {
for {
msg_type := conn.read_byte()!
match msg_type {
`Q` /* Query */ {
`Q` { // Query
mut query := conn.read_query()!

// A missing "FROM" clause is valid in PostgreSQL, but it's not
Expand Down Expand Up @@ -126,7 +127,7 @@ fn (mut s Server) handle_conn(mut c net.TcpConn) ! {

conn.write_ready_for_query()!
}
`X` /* Terminate */ {
`X` { // Terminate
// Don't bother consuming the message since we're going to
// disconnect anyway.
break
Expand Down
2 changes: 1 addition & 1 deletion vsql/sql_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ fn run_single_test(test SQLTest, query_cache &QueryCache, verbose bool, filter_l
hour: 14
minute: 5
second: 3
microsecond: 120056
nanosecond: 120056000
}), 300
}
register_pg_functions(mut db)!
Expand Down
10 changes: 7 additions & 3 deletions vsql/time.v
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ fn new_time_from_components(typ Type, year int, month int, day int, hour int, mi
hour: hour
minute: minute
second: second
microsecond: microsecond
nanosecond: microsecond * 1000
})}
}

Expand Down Expand Up @@ -237,7 +237,7 @@ fn (t Time) i64() i64 {
// See i64() for details.
fn (t Time) time_i64() i64 {
return t.t.hour * vsql.hour_period + t.t.minute * vsql.minute_period +
t.t.second * vsql.second_period + t.t.microsecond
t.t.second * vsql.second_period + int(t.t.nanosecond / 1000)
}

// See i64() for details.
Expand Down Expand Up @@ -312,7 +312,7 @@ fn (t Time) str_fractional_seconds(prec int) string {
}

// Round down first, if needed.
mut s := t.t.microsecond.str()
mut s := int(t.t.nanosecond / 1000).str()
if prec < s.len {
s = s[..prec]
}
Expand Down Expand Up @@ -392,3 +392,7 @@ fn time_zone_value(conn &Connection) string {

return s
}

fn default_now() (time.Time, i16) {
return time.utc(), i16(time.offset() / 60)
}
2 changes: 1 addition & 1 deletion vsql/utils.v
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn compare_bytes(a []u8, b []u8) int {

for i in 0 .. min {
if a[i] != b[i] {
return a[i] - b[i]
return int(a[i]) - int(b[i])
}
}

Expand Down
4 changes: 2 additions & 2 deletions vsql/value.v
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import regex
pub enum Boolean {
// These must not be negative values because they are encoded as u8 on disk.
is_unknown = 0 // same as NULL
is_false = 1
is_true = 2
is_false = 1
is_true = 2
}

// Returns ``TRUE``, ``FALSE`` or ``UNKNOWN``.
Expand Down
2 changes: 1 addition & 1 deletion vsql/virtual_table.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type VirtualTableProviderFn = fn (mut t VirtualTable) !
pub struct VirtualTable {
create_table_sql string
create_table_stmt CreateTableStmt
data VirtualTableProviderFn
data VirtualTableProviderFn [required]
mut:
is_done bool
rows []Row
Expand Down
10 changes: 6 additions & 4 deletions vsql/walk.v
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn (mut iter PageIterator) next() ?PageObject {

// Load all the objects for this leaf. Making sure to skip over any keys
// that are out of bounds.
iter.objects = (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1])!).objects()
iter.objects = (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1]) or { return none }).objects()
for object in iter.objects {
// TODO(elliotchance): It would be more efficient to do a binary
// search here since the page is already sorted.
Expand All @@ -55,20 +55,22 @@ fn (mut iter PageIterator) next() ?PageObject {
iter.depth_iterator = iter.depth_iterator[..iter.depth_iterator.len - 1]
iter.depth_iterator[iter.depth_iterator.len - 1]++

if iter.depth_iterator[iter.depth_iterator.len - 1] < (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1])!).objects().len {
if iter.depth_iterator[iter.depth_iterator.len - 1] < (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1]) or {
return none
}).objects().len {
break
}
}

for (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1])!).kind == kind_not_leaf {
objects := (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1])!).objects()
objects := (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1]) or { return none }).objects()

mut buf := new_bytes(objects[iter.depth_iterator[iter.depth_iterator.len - 1]].value)
iter.path << buf.read_i32()
iter.depth_iterator << 0
}

iter.objects = (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1])!).objects()
iter.objects = (iter.btree.pager.fetch_page(iter.path[iter.path.len - 1]) or { return none }).objects()
}

o := iter.objects[iter.depth_iterator[iter.depth_iterator.len - 1]]
Expand Down

0 comments on commit cb54295

Please sign in to comment.