This PR adds support for IsNot Operator which was not working as shown
below.
```
❯ ./target/debug/limbo
Limbo v0.0.12
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database
limbo> select 1 is not 0;
thread 'main' panicked at core\translate\expr.rs:626:40:
not yet implemented: IsNot
stack backtrace:
```
Closes#731
This PR adds support for `Is` Operator which was not working as shown
below. I have also added compare.test for all compare operations on
which we can expand upon.
```
❯ .\target\debug\limbo.exe
Limbo v0.0.12
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database
limbo> select 1 is 2;
thread 'main' panicked at core\translate\expr.rs:613:40:
not yet implemented: Is
```
Closes#729
#708
This PR adds basic support for the following API for defining
Aggregates, and changes the existing API for scalars.
```rust
register_extension! {
scalars: { Double },
aggregates: { MedianState },
}
#[derive(ScalarDerive)]
struct Double;
impl Scalar for Double {
fn name(&self) -> &'static str {
"double"
}
fn call(&self, args: &[Value]) -> Value {
if let Some(arg) = args.first() {
match arg.value_type() {
ValueType::Float => {
let val = arg.to_float().unwrap();
Value::from_float(val * 2.0)
}
ValueType::Integer => {
let val = arg.to_integer().unwrap();
Value::from_integer(val * 2)
}
_ => {
println!("arg: {:?}", arg);
Value::null()
}
}
} else {
Value::null()
}
}
}
#[derive(AggregateDerive)]
struct MedianState;
impl AggFunc for MedianState {
type State = Vec<f64>;
fn name(&self) -> &'static str {
"median"
}
fn args(&self) -> i32 { 1 }
fn step(state: &mut Self::State, args: &[Value]) {
if let Some(val) = args.first().and_then(Value::to_float) {
state.push(val);
}
}
fn finalize(state: Self::State) -> Value {
if state.is_empty() {
return Value::null();
}
let mut sorted = state;
sorted.sort_by(|a, b| a.partial_cmp(b).unwrap());
let len = sorted.len();
if len % 2 == 1 {
Value::from_float(sorted[len / 2])
} else {
let mid1 = sorted[len / 2 - 1];
let mid2 = sorted[len / 2];
Value::from_float((mid1 + mid2) / 2.0)
}
}
}
```
I know it's a bit more verbose than the previous version, but I think in
the long run this will be more robust, and it matches the aggregate API
of implementing a trait on a struct that you derive the relevant trait
on.
Also this allows for better registration of functions, I think passing
in the struct identifiers just feels much better than the `"func_name"
=> function_ptr`
Closes#721
## Purpose of this PR
- Minimal implementation of `execute`
## Changes
### Java side
- Implement `execute`
- Along the way, rename classes and methods which have the same meanings
- `fileName` -> `filePath`
- unify file names for rust code to java code e.g.
`limbo_connection.rs` will match `LimboConnection.java`
### Rust side
- Replace `pointer to struct` and `struct to pointer` functions close
together
- Rename rust files to match java files
## Note
- Implementation differs from that of `sqlite-java`. It's because we can
easily add JNI code and thereby implementing bindings is less restriced.
## References
https://github.com/tursodatabase/limbo/issues/615Closes#723
This PR improves comment handling in Limbo to precisely match SQLite's
behavior:
Fixes some edge cases involving #711
Inline comments mess up queries --

Query in the left terminal is current limbo state, upper right is limbo
in the state of this PR
and lower right is sqlite behavior.

Added support for inline comments using "--" syntax
Comments are now properly stripped before query execution
Maintains correct query execution when comments appear mid-query
Preserves multiline query functionality with comments
Ensures consistent behavior between pasted and typed queries
Testing:
Added test cases for single-line comments
Added test cases for inline comments
Added test cases for multiline queries with comments
Verified behavior matches SQLite CLI

Reviewed-by: Preston Thorpe (@PThorpe92)
Closes#722