Closes#3892Closes#3888
Stuff like:
```sql
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select case (select y, z from t2) when 1 then 'one' else 'other' end from t1;
× Parse error: base expression in CASE must return 1 value
turso> create table t(x, y);
insert into t values (1, 2);
select (select x, y from t) as result;
× Parse error: result column must return 1 value, got 2
turso> create table t1(x,y);
create table t2(y);
insert into t1 values (1,1);
insert into t2 values (1);
select * from t2 where y = (select x,y from t1);
× Parse error: all arguments to binary operator = must return the same number of
│ values. Got: (1) = (2)
turso> create table orders(customer_id, amount);
create table thresholds(min_amount, max_amount);
insert into orders values (100, 50), (100, 150);
insert into thresholds values (100, 200);
select customer_id, sum(amount) as total
from orders
group by customer_id
having total > (select min_amount, max_amount from thresholds);
× Parse error: all arguments to binary operator > must return the same number of
│ values. Got: (1) > (2)
turso> create table items(id);
create table config(max_results, other_col);
insert into items values (1), (2), (3);
insert into config values (2, 3);
select * from items limit (select max_results, other_col from config);
× Parse error: limit expression must return 1 value, got 2
turso> create table items(id);
create table config(skip_count, other_col);
insert into items values (1), (2), (3);
insert into config values (1, 2);
select * from items limit 1 offset (select skip_count, other_col from config);
× Parse error: offset expression must return 1 value, got 2
turso> create table items(id, name);
create table sort_order(priority, other_col);
insert into items values (1, 'a'), (2, 'b');
insert into sort_order values (1, 2);
select * from items order by (select priority, other_col from sort_order);
× Parse error: order by expression must return 1 value, got 2
turso> create table sales(product_id, amount);
create table grouping(category, other_col);
insert into sales values (1, 100), (2, 200);
insert into grouping values (1, 2);
select sum(amount) from sales group by (select category, other_col from grouping);
× Parse error: group by expression must return 1 value, got 2
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select case when (select y, z from t2) then 'yes' else 'no' end from t1;
× Parse error: when expression in CASE must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select case when x = 1 then (select y, z from t2) else 0 end from t1;
× Parse error: then expression in CASE must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select case when x = 2 then 0 else (select y, z from t2) end from t1;
× Parse error: else expression in CASE must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select max((select y, z from t2)) from t1;
× Parse error: argument 0 to function call max must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select x + (select y, z from t2) from t1;
× Parse error: all arguments to binary operator + must return the same number of
│ values. Got: (1) + (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (5);
insert into t2 values (1, 2);
select * from t1 where x between (select y, z from t2) and 10;
× Parse error: all arguments to binary operator <= must return the same number of
│ values. Got: (2) <= (1)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select cast((select y, z from t2) as integer) from t1;
× Parse error: argument to CAST must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values ('a', 'b');
select (select y, z from t2) collate nocase from t1;
× Parse error: argument to COLLATE must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select * from t1 where (select y, z from t2) is null;
× Parse error: all arguments to binary operator IS must return the same number of
│ values. Got: (2) IS (1)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select * from t1 where (select y, z from t2) not null;
× Parse error: argument to NOT NULL must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values ('a', 'b');
select * from t1 where (select y, z from t2) like 'a%';
× Parse error: left operand of LIKE must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select -(select y, z from t2) from t1;
× Parse error: argument to unary operator - must return 1 value. Got: (2)
turso> create table t1(x);
create table t2(y, z);
insert into t1 values (1);
insert into t2 values (1, 2);
select abs((select y, z from t2)) from t1;
× Parse error: argument 0 to function call abs must return 1 value. Got: (2)
```
Closes#3906
closes https://github.com/tursodatabase/turso/issues/3773
## Before
```rust
#[derive(Debug, Clone)]
pub struct Column {
pub name: Option<String>,
pub ty: Type,
// many sqlite operations like table_info retain the original string
pub ty_str: String,
pub primary_key: bool,
pub is_rowid_alias: bool,
pub notnull: bool,
pub default: Option<Box<Expr>>,
pub unique: bool,
pub collation: Option<CollationSeq>,
pub hidden: bool,
}
```
obviously not ideal. so lets pack `type`, `hidden`, `primary_key`,
`is_rowid_alias`, `notnull` and `collation` into a u16.
## After:
```rust
#[derive(Debug, Clone)]
pub struct Column {
pub name: Option<String>,
pub ty_str: String,
pub default: Option<Box<Expr>>,
raw: u16,
}
```
Also saw a place to replace a `Mutex<Enum>` with `AtomicEnum`, so I
snuck that in here too
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#3905
Fixes#3673
We were only considering the right `SelectPlan` for determining the
collation sequence when creating the `EphemeralIndex` for
`CompoundSelect` statements. Now, we pass both the left and the right
plans, and correctly select the collation sequence prioritizing the left
plan collation.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#3851
People have discovered various bugs in autovacuum so let's disable it by
default for now.
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#3899
closes https://github.com/tursodatabase/turso-go/issues/55
In `apply_affinity_char`: we have things like the following:
```rust
if matches!(value, Value::Blob(_)) {
return true;
}
````
Then at the call site in `op_seek_rowid` in execute.rs, we were saying
it was an unreachable condition that a blob was in the register..
```rust
let converted = apply_affinity_char(&mut temp_reg, Affinity::Numeric);
if converted {
match temp_reg.get_value() {
Value::Integer(i) => Some(*i),
Value::Float(f) => Some(*f as i64),
_ => unreachable!(),
}
```
Closes#3897
This makes `nix build .#turso_cli` succeed.
#835 argueed to remove nix packaging from the repo. I agree and hope
that a talented maintainer will include `turso_cli` in nixpkgs.
Given the currently broken state and the recent Beta release, maybe it's
worth to unbreak it for some last time.
Closes#3879
* Fixes bug #3674
* With this fix:
```
turso> WITH t AS (SELECT 1), t AS (SELECT 2) SELECT * FROM x;
× Parse error: duplicate WITH table name: t
```
Reviewed-by: Preston Thorpe <preston@turso.tech>
Reviewed-by: Mikaël Francoeur (@LeMikaelF)
Closes#3719
## Purpose
* Implement `setObject(int, Object)` to support binding of common Java
types to SQL parameters in JDBC4.
* This implementation currently covers only standard JDBC4 supported
types. LOB and stream bindings are not yet implemented.
## Changes
* Implemented JDBC4PreparedStatement#setObject(int, Object) handling for
* `String`, `Integer`, `Long`, `Boolean`, `Double`, `Float`, `Byte`,
`Short`
* `byte[]`, `Date`, `Time`, `Timestamp`, `BigDecimal`
* Added validation for unsupported types (`Blob`, `Clob`, `InputStream`,
`Reader`)
* Added corresponding unit test `testSetObjectCoversAllSupportedTypes`
to verify correctness
## Note
* Additional work (e.g., LOB/Stream handling) will be addressed
separately once driver support is available.
## Related Issue
#615
Reviewed-by: Kim Seon Woo (@seonWKim)
Closes#3864
The Antithesis config image was not being uploaded during CI runs, only
the workload image. This caused experiment failures when the config
image expired from the registry after 6 months of inactivity.
Closes#3863
The Antithesis config image was not being uploaded during CI runs, only
the workload image. This caused experiment failures when the config
image expired from the registry after 6 months of inactivity.