From 0beec6deaf7b2d10fd5b79bb4246880ff8131992 Mon Sep 17 00:00:00 2001 From: sonhmai <> Date: Fri, 27 Dec 2024 16:23:01 +0700 Subject: [PATCH] doc: add contributing guide for functions --- docs/internals/functions.md | 118 +++++++++++++++++++++ docs/internals/functions_compat_change.png | Bin 0 -> 25571 bytes 2 files changed, 118 insertions(+) create mode 100644 docs/internals/functions.md create mode 100644 docs/internals/functions_compat_change.png diff --git a/docs/internals/functions.md b/docs/internals/functions.md new file mode 100644 index 000000000..c8b871c16 --- /dev/null +++ b/docs/internals/functions.md @@ -0,0 +1,118 @@ +# How to contribute a SQL function implementation? + +Steps +1. Pick a `SQL functions` in [COMPAT.md](../../COMPAT.md) file with a No (not implemented yet) status. +2. Create an issue for that function. +3. Implement the function in a feature branch. +4. Push it as a Merge Request, get it review. + +## An example with function `unixepoch(..)` + +> Note that the files, code location, steps might be not exactly the same because of refactor but the idea of the changes needed in each layer stays. + +[Issue #158](https://github.com/tursodatabase/limbo/issues/158) was created for it. +Refer to commit [525f860](https://github.com/tursodatabase/limbo/commit/525f8600cacaff1dffc9e7fe9d274d89ed519149). + +``` +SQL_function --parser--> Func_enum ----> Instruction --VDBE--> Result +``` + +TODO for implementing the function: +- analysis + - read and try out how the function works in SQLite. + - compare `explain` output of SQLite and Limbo. +- add/ update the function definition in `functions.rs`. +- add/ update how to function is translated from `definition` to `instruction` in virtual machine layer VDBE. +- add/ update the function Rust execution code and tests in vdbe layer. +- add/ update how the bytecode `Program` executes when steps into the function. +- add/ update TCL tests for this function in limbo/testing. +- update doc for function compatibility. + +### Analysis + +How `unixepoch` works in SQLite? +```bash +> sqlite3 + +sqlite> explain select unixepoch('now'); +addr opcode p1 p2 p3 p4 p5 comment +---- ------------- ---- ---- ---- ------------- -- ------------- +0 Init 0 6 0 0 Start at 6 +1 Once 0 3 0 0 +2 Function 0 0 2 unixepoch(-1) 0 r[2]=func() +3 Copy 2 1 0 0 r[1]=r[2] +4 ResultRow 1 1 0 0 output=r[1] +5 Halt 0 0 0 0 +6 Goto 0 1 0 0 +``` + +Comparing that with `Limbo`: +```bash +# created a sqlite database file +> cargo run database.db + +Limbo v0.0.2 +Enter ".help" for usage hints. +limbo> explain select unixtimestamp('now'); +Parse error: unknown function unixtimestamp +``` + +We can see that the function is not implemented yet so the Parser did not understand it and throw an error `Parse error: unknown function unixtimestamp`. +- we only need to pay attention to opcode `Function` at addr 2. The rest is already set up in limbo. +- we have up to 5 registers p1 to p5 for each opcode. + +### Function definition + +For limbo to understand the meaning of `unixtimestamp`, we need to define it as a Function somewhere. +That place can be found currently in `core/functions.rs`. We need to edit 3 places +1. add to ScalarFunc as `unixtimestamp` is a scalar function. +2. add to Display to show the function as string in our program. +3. add to `fn resolve_function(..)` of `impl Func` to enable parsing from str to this function. + +https://github.com/tursodatabase/limbo/blob/69e3dd28f77e59927da4313e517b2b428ede480d/core/function.rs#L86 + +https://github.com/tursodatabase/limbo/blob/69e3dd28f77e59927da4313e517b2b428ede480d/core/function.rs#L131 + +https://github.com/tursodatabase/limbo/blob/69e3dd28f77e59927da4313e517b2b428ede480d/core/function.rs#L331 + +### Function translation + +How to translate the function into bytecode `Instruction`? + +https://github.com/tursodatabase/limbo/blob/525f8600cacaff1dffc9e7fe9d274d89ed519149/core/translate/expr.rs#L971C1-L989C48 + +### Function execution + +https://github.com/tursodatabase/limbo/commit/525f8600cacaff1dffc9e7fe9d274d89ed519149#diff-839435241d4ffb648ad2d162bc6ba6a94f052309865251dc2aff36eaa14fa3c5L94-R111 + +### Program bytecode execution + +https://github.com/tursodatabase/limbo/commit/525f8600cacaff1dffc9e7fe9d274d89ed519149#diff-14ede55920ec82e719d3d39a4c38a6b5c0d3e4fa1e7ff4d75e7f436820920fa7L33-R1392 + +If there is no `time value` (no start register) , we want to execute the function with default param `'now'` as in [SQLite spec](https://www.sqlite.org/lang_datefunc.html#time_values). + +> In all functions other than timediff(), the time-value (and all modifiers) may be omitted, in which case a time value of 'now' is assumed. + +```rust +if *start_reg == 0 { + let unixepoch: String = + exec_unixepoch(&OwnedValue::Text(Rc::new("now".to_string())))?; + state.registers[*dest] = OwnedValue::Text(Rc::new(unixepoch)); +} +``` + +### Adding tests + +Tests for `unixepoch` functions can be referenced from SQLite source code which is already very comprehensive. +- https://github.com/sqlite/sqlite/blob/f2b21a5f57e1a1db1a286c42af40563077635c3d/test/date3.test#L36 +- https://github.com/sqlite/sqlite/blob/f2b21a5f57e1a1db1a286c42af40563077635c3d/test/date.test#L604 + +https://github.com/tursodatabase/limbo/commit/525f8600cacaff1dffc9e7fe9d274d89ed519149#diff-a262766efd02e804b8dc2ac5642f2061fb59a9388e437e9f000ff289110c9ec0L123-R145 + +### Updating doc + +Update the COMPAT.md file to mark this function as implemented. Change Status to +- `Yes` if it is fully supported, +- `Partial` if supported but not fully yet compared to SQLite. + +![functions_compat_change.png](functions_compat_change.png) diff --git a/docs/internals/functions_compat_change.png b/docs/internals/functions_compat_change.png new file mode 100644 index 0000000000000000000000000000000000000000..729f0c4125a07d02302020f38a346ca7fae36b4a GIT binary patch literal 25571 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 literal 0 HcmV?d00001