Commit graph

68 commits

Author SHA1 Message Date
pedrocarlo
3e05496078 add integrity check to write tests 2025-06-09 17:44:00 -03:00
pedrocarlo
c7799c8ec5 add sleep to allow file lock to be removed 2025-06-09 16:29:58 -03:00
Pekka Enberg
c6ef19396d Merge 'Add support for pragma table-valued functions' from Piotr Rżysko
This PR adds support for table-valued functions for PRAGMAs (see the
[PRAGMA functions section](https://www.sqlite.org/pragma.html)).
Additionally, it introduces built-in table-valued functions. I
considered using extensions for this, but there are several reasons in
favor of a dedicated mechanism:
* It simplifies the use of internal functions, structs, etc. For
example, when implementing `json_each` and `json_tree`, direct access to
internals was necessary:
https://github.com/tursodatabase/limbo/pull/1088
* It avoids FFI overhead. [Benchmarks](https://github.com/piotrrzysko/li
mbo/blob/pragma_vtabs_bench/core/benches/pragma_benchmarks.rs) on my
hardware show that `pragma_table_info()` implemented as an extension is
2.5× slower than the built-in version.

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #1642
2025-06-04 09:08:10 +03:00
Piotr Rzysko
d1d8ead475 Add support for pragma table-valued functions 2025-06-01 10:25:42 +02:00
pedrocarlo
2ddbb7eeed adjust move_to and seek functions to make them truly reentrant + adding return_if_locked_maybe_load in some places so that we read loaded pages 2025-06-01 01:01:35 -03:00
pedrocarlo
d688cfd547 make find_cell and process_overflow_page reentrant 2025-05-31 23:31:59 -03:00
pedrocarlo
e97227ccb9 added delete operations to blobs in memory and write tests 2025-05-31 14:47:49 -03:00
Jussi Saurio
d52a9a635c fix: use tempfile as db path in constraint.py 2025-05-29 21:03:10 +03:00
Jussi Saurio
3d42f85c98 tests/python/writes: use tempfile instead of permanent file 2025-05-29 11:23:50 +03:00
Jussi Saurio
b843ad0a58 Add INSERT INTO ... SELECT * FROM generate_series() regression test 2025-05-27 10:54:55 +03:00
PThorpe92
c5d364064a
Add python tests for xConnect behavior and testing extension 2025-05-24 14:49:59 -04:00
PThorpe92
687edefcdf
Add option to py tests to create temporary db with clone of testing.db 2025-05-24 14:49:59 -04:00
Piotr Rzysko
ad9d044a04 Add CSV extension 2025-05-21 09:22:59 +02:00
PThorpe92
c62d3e464f
Output rust backtrace in python tests 2025-05-20 09:20:59 -04:00
pedrocarlo
6d7a73fd60 More tests 2025-05-19 15:22:15 -03:00
pedrocarlo
bf1fe9e0b3 Actually fixed group by and order by collation 2025-05-19 15:22:15 -03:00
pedrocarlo
0df6c87f07 Fixed Group By collation 2025-05-19 15:22:14 -03:00
pedrocarlo
bba9689674 Fixed matching bug for defining collation context to use 2025-05-19 15:22:14 -03:00
pedrocarlo
a818b6924c Removed repeated binary expression translation. Adjusted the set_collation to capture additional context of whether it was set by a Collate expression or not. Added some tests to prove those modifications were necessary. 2025-05-19 15:22:14 -03:00
pedrocarlo
af1f9492ef fix updating single value 2025-05-17 19:43:24 -03:00
pedrocarlo
758dfff2fe modified tests as we do not have rollback yet. Also correctly raise a contraint error on primary keys only 2025-05-14 13:30:39 -03:00
pedrocarlo
3aaf4206b7 altered constraint tests to create bad update statements. Tests caught a bug where I was copying the wrong values from the registers 2025-05-14 13:30:39 -03:00
Jussi Saurio
6926d7b931 testing/py: rename debug_print() to run_debug() 2025-05-12 10:52:13 +03:00
Piotr Rzysko
d5984445a9 Fix panic on CREATE VIRTUAL TABLE IF NOT EXISTS by halting VM properly
Fixes a runtime panic caused by failing to halt the virtual machine
after executing CREATE VIRTUAL TABLE IF NOT EXISTS.

Previously resulted in:
thread 'main' panicked at core/vdbe/mod.rs:408:52:
index out of bounds: the len is 3 but the index is 3
2025-05-11 21:21:18 +02:00
Piotr Rzysko
fdffbc9534 Ensure virtual table name uniqueness 2025-05-11 21:21:18 +02:00
Preston Thorpe
d837f89d74
Merge branch 'main' into vtab_schema 2025-04-28 22:09:10 -04:00
pedrocarlo
2e147b20a8 Adjustments and explicitely just emitting NoConflict on unique indexes 2025-04-24 13:13:39 -03:00
pedrocarlo
9dd1ced5ad added tests 2025-04-23 20:38:08 -03:00
PThorpe92
7f170756ae
Add python script to benchmark vfs against eachother 2025-04-21 12:22:20 -04:00
PThorpe92
d02900294e
Remove 2nd shell in vtab tests, fix expr translation in main loop 2025-04-17 14:01:45 -04:00
pedrocarlo
bd5531987e adjusting memory test to use UV 2025-04-15 12:51:43 -03:00
pedrocarlo
3cd2017df4 introduce test theme 2025-04-15 12:51:43 -03:00
pedrocarlo
321def3c30 adjust stack_offset for test_limbo_cli 2025-04-15 12:51:43 -03:00
pedrocarlo
4c0bd50ac9 force terminal colors 2025-04-15 12:50:35 -03:00
pedrocarlo
d71029cda7 Overhaul in printing using rich 2025-04-15 12:50:35 -03:00
pedrocarlo
b34e7e011e Prettier console 2025-04-15 12:45:46 -03:00
pedrocarlo
bdef83dc1c update test 2025-04-15 12:45:46 -03:00
pedrocarlo
0c137d6dff Cleaner and less error prone Write Tests 2025-04-15 12:45:46 -03:00
pedrocarlo
58e091cb23 setup uv for limbo 2025-04-15 12:45:46 -03:00
pedrocarlo
46eaa52400 write tests for file backed db 2025-04-15 12:45:45 -03:00
Jussi Saurio
d2a1433345 Merge 'Fix truncation of error output in tests' from Pedro Muniz
When the python tests fail, they will sometimes truncate the output if
it is smaller than the `PIPE_BUFF` size. With this fix we can now
properly print the backtrace, when the program panics.
# Before
This is the problematic CI output from #1331  that led me to fix this.
In this case, it was already truncating the output of the `assert`
prints.
```
./testing/cli_tests/extensions.py
Extension ./target/debug/liblimbo_regexp loaded successfully.
Testing: uuid functions are registered properly with ext loaded
Testing: scalar alias's are registered properly
Testing: median agg function returns null when ext not loaded
Testing: median agg function works
Testing: median agg function works with odd number of elements
Testing: test aggregate percentile function with 2 arguments works
Testing: test aggregate percentile function with 1 argument works
Testing: crypto_blake3 returns null when ext not loaded
Testing: blake3 should encrypt correctly
Testing: md5 should encrypt correctly
Testing: sha1 should encrypt correctly
Testing: sha256 should encrypt correctly
Testing: sha384 should encrypt correctly
Testing: sha512 should encrypt correctly
Testing: base32 should encode correctly
Testing: base32 should decode correctly
Testing: base64 should encode correctly
Testing: base64 should decode correctly
Testing: base85 should encode correctly
Testing: base85 should decode correctly
Testing: hex should encode correctly
Testing: hex should decode correctly
Testing: url should encode correctly
Testing: url should decode correctly
Testing: ipfamily function returns null when ext not loaded
Testing: ipfamily function returns 4 for IPv4
Testing: ipfamily function returns 6 for IPv6
Testing: ipcontains function returns 1 for IPv4
Testing: ipcontains function returns 0 for IPv4
Testing: iphost function returns the host for IPv4
Testing: iphost function returns the host for IPv6
Testing: ipmasklen function returns the mask length for IPv4
Testing: ipmasklen function returns the mask length for IPv6
Testing: ipnetwork function returns the flattened CIDR for IPv4
Testing: ipnetwork function returns the network for IPv6
Testing: testvfs not loaded
Testing: testvfs extension loaded
thread 'main' panicked at core/storage/pager.rs:61:38:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Test FAILED: Error encountered in Limbo shell.
make: *** [Makefile:70: test-extensions] Error 1
```
# After
```
with-env {RUST_BACKTRACE:1} {make test-extensions}
cargo build
   Compiling limbo_regexp v0.0.19-pre.4 (/Users/pedro/Projects/limbo/extensions/regexp)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.51s
cargo build --package limbo_regexp
   Compiling limbo_regexp v0.0.19-pre.4 (/Users/pedro/Projects/limbo/extensions/regexp)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
./testing/cli_tests/extensions.py
Extension ./target/debug/liblimbo_regexp loaded successfully.
Testing: uuid functions are registered properly with ext loaded
Testing: scalar alias's are registered properly
Testing: median agg function returns null when ext not loaded
Testing: median agg function works
Testing: median agg function works with odd number of elements
Testing: test aggregate percentile function with 2 arguments works
Testing: test aggregate percentile function with 1 argument works
Testing: crypto_blake3 returns null when ext not loaded
Testing: blake3 should encrypt correctly
Testing: md5 should encrypt correctly
Testing: sha1 should encrypt correctly
Testing: sha256 should encrypt correctly
Testing: sha384 should encrypt correctly
Testing: sha512 should encrypt correctly
Testing: base32 should encode correctly
Testing: base32 should decode correctly
Testing: base64 should encode correctly
Testing: base64 should decode correctly
Testing: base85 should encode correctly
Testing: base85 should decode correctly
Testing: hex should encode correctly
Testing: hex should decode correctly
Testing: url should encode correctly
Testing: url should decode correctly
Testing: ipfamily function returns null when ext not loaded
Testing: ipfamily function returns 4 for IPv4
Testing: ipfamily function returns 6 for IPv6
Testing: ipcontains function returns 1 for IPv4
Testing: ipcontains function returns 0 for IPv4
Testing: iphost function returns the host for IPv4
Testing: iphost function returns the host for IPv6
Testing: ipmasklen function returns the mask length for IPv4
Testing: ipmasklen function returns the mask length for IPv6
Testing: ipnetwork function returns the flattened CIDR for IPv4
Testing: ipnetwork function returns the network for IPv6
Testing: testvfs not loaded
Testing: testvfs extension loaded
thread 'main' panicked at core/storage/pager.rs:61:38:
called `Option::unwrap()` on a `None` value
stack backtrace:
   0: rust_begin_unwind
             at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/core/src/panicking.rs:74:14
   2: core::panicking::panic
             at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/core/src/panicking.rs:148:5
   3: core::option::unwrap_failed
             at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/core/src/option.rs:2012:5
   4: core::option::Option<T>::unwrap
             at /Users/pedro/.rustup/toolchains/1.83.0-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:972:21
   5: limbo_core::storage:📟:Page::get_contents
             at ./core/storage/pager.rs:61:9
   6: limbo_core::storage::btree::BTreeCursor::balance_non_root
             at ./core/storage/btree.rs:1723:40
   7: limbo_core::storage::btree::BTreeCursor::balance
             at ./core/storage/btree.rs:1570:35
   8: limbo_core::storage::btree::BTreeCursor::insert_into_page
             at ./core/storage/btree.rs:1512:35
   9: limbo_core::storage::btree::BTreeCursor::insert
             at ./core/storage/btree.rs:3024:31
  10: limbo_core::vdbe::execute::op_insert
             at ./core/vdbe/execute.rs:3654:23
  11: limbo_core::vdbe::Program::step
             at ./core/vdbe/mod.rs:379:23
  12: limbo_core::Statement::step
             at ./core/lib.rs:582:9
  13: limbo::app::Limbo::print_query_result
             at ./cli/app.rs:657:27
  14: limbo::app::Limbo::run_query
             at ./cli/app.rs:420:20
  15: limbo::app::Limbo::handle_input_line
             at ./cli/app.rs:527:13
  16: limbo::main
             at ./cli/main.rs:29:31
  17: core::ops::function::FnOnce::call_once
             at /Users/pedro/.rustup/toolchains/1.83.0-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Testing: Tested large write to testfs
Test FAILED: Test failed
SQL: SELECT count(*) FROM test;
Actual:
None
make: *** [test-extensions] Error 1
```

Closes #1346
2025-04-15 15:02:58 +03:00
pedrocarlo
53eb2204ce Fix truncation of error output in tests 2025-04-14 13:35:49 -03:00
pedrocarlo
6249cd67e9 added print statement to test that VDestroy is being called 2025-04-13 17:10:43 -03:00
pedrocarlo
000d8756ec Implment VDestroy opcode 2025-04-13 17:06:12 -03:00
PThorpe92
5643a0abba
Dont emit ansi codes when outputting logs to a file 2025-04-09 19:31:35 -04:00
PThorpe92
7993857020
Add py tests for vtab update behavior 2025-04-09 11:06:41 -04:00
Pekka Enberg
3025b71406 Merge 'Memory tests to track large blob insertions' from Pedro Muniz
My PR #972 always keeps breaking when there are changes in how Btree
works lol. I'm extracting the memory tests I created there here, so we
can track problems earlier.

Closes #1228
2025-04-09 16:45:06 +03:00
PThorpe92
a0f71e27be
Fix cli tests 2025-04-08 20:10:49 -04:00
Preston Thorpe
62e0a137dd
Merge branch 'main' into update_offset 2025-04-06 12:34:23 -04:00
Pekka Enberg
2d3fd01f91 Merge 'Support Create Index' from Preston Thorpe
Closes #1193
```console
│limbo> explain create index idxp on products(price);
│addr  opcode             p1    p2    p3    p4             p5  comment
│----  -----------------  ----  ----  ----  -------------  --  -------
│0     Init               0     39    0                    0   Start at 39
│1     CreateBtree        0     1     2                    0   r[1]=root iDb=0 flags=2
│2     OpenWriteAsync     0     1     0                    0
│3     OpenWriteAwait     0     0     0                    0
│4     NewRowId           0     2     0                    0
│5     String8            0     3     0     index          0   r[3]='index'
│6     String8            0     4     0     idxp           0   r[4]='idxp'
│7     String8            0     5     0     products       0   r[5]='products'
│8     Copy               1     6     1                    0   r[6]=r[1]
│9     String8            0     7     0     CREATE INDEX idxp ON products (price)  0   r[7]='CREATE INDEX idxp ON products (price)'
│10    MakeRecord         3     5     8                    0   r[8]=mkrec(r[3..7])
│11    InsertAsync        0     8     2                    0
│12    InsertAwait        0     0     0                    0
│13    SorterOpen         3     1     0     k(1,B)         0   cursor=3
│14    OpenPseudo         4     9     2                    0   2 columns in r[9]
│15    OpenReadAsync      2     273   0                    0   table=products, root=273
│16    OpenReadAwait      0     0     0                    0
│17    RewindAsync        2     0     0                    0
│18    RewindAwait        2     25    0                    0   Rewind table products
│19      Column           2     2     10                   0   r[10]=products.price
│20      RowId            2     11    0                    0   r[11]=products.rowid
│21      MakeRecord       10    2     12                   0   r[12]=mkrec(r[10..11])
│22      SorterInsert     3     12    0     0              0   key=r[12]
│23    NextAsync          2     0     0                    0
│24    NextAwait          2     19    0                    0
│25    OpenWriteAsync     1     1     0                    0
│26    OpenWriteAwait     0     0     0                    0
│27    SorterSort         3     33    0                    0
│28      SorterData       3     13    4                    0   r[13]=data
│29      SeekEnd          1     0     0                    0
│30      IdxInsertAsync   1     13    0                    0   key=r[13]
│31      IdxInsertAwait   1     0     0                    0
│32    SorterNext         3     28    0                    0
│33    Close              3     0     0                    0
│34    Close              2     0     0                    0
│35    Close              1     0     0                    0
│36    ParseSchema        0     0     0     name = 'idxp' AND type = 'index'  0   name = 'idxp' AND type = 'index'
│37    Close              0     0     0                    0
│38    Halt               0     0     0                    0
│39    Transaction        0     1     0                    0   write=true
│40    Goto               0     1     0                    0
```
This will create the initial index btree and insert whatever relevant
records that need to be inserted, it doesn't handle the case of
inserting new index keys when normal records are created afterwards.
That will prob be added in next PR to keep this one concise.
Limbo will properly use the index in a subsequent query:
![image](https://github.com/user-
attachments/assets/eb41e985-4a70-49a5-8218-62c25e4d16c5)
Creating a unique index on a column that has 2 existing identical rows:
![image](https://github.com/user-
attachments/assets/ea46c720-5235-4451-81f0-25497ed9ee92)

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #1199
2025-04-06 19:32:36 +03:00