summaryrefslogtreecommitdiff
path: root/Tests/LibSQL
AgeCommit message (Collapse)Author
2023-05-25LibSQL: Free heap storage when deleting rowsJelle Raaijmakers
2023-05-25LibSQL: Implement freeing heap storageJelle Raaijmakers
This allows us to free entire chains of blocks in one go.
2023-05-25LibSQL: Find free blocks when opening a database fileJelle Raaijmakers
The free block list now gets populated on opening a database file. Ideally we persist this list inside the heap itself, but for now this prevents excessive heap growth.
2023-05-25LibSQL: Keep track of free heap blocks when trimming storageJelle Raaijmakers
When overwriting existing heap storage that requires fewer blocks, make sure to free all remaining blocks so they can be reused in the future.
2023-05-25LibSQL: Reuse heap blocks when overwriting storageJelle Raaijmakers
Previously, only the first block in a chain of blocks would be overwritten while all subsequent blocks would be appended to the heap. Now we make sure to reuse all existing blocks in the chain.
2023-05-25LibSQL: Test `SQL::Heap` separatelyJelle Raaijmakers
Move the long storage test from TestSqlStatementExecution into a new test unit called TestSqlHeap. Split it up into a flushed and non-flushed variant so we test the write-ahead log as well.
2023-05-25LibSQL: Clean up TestSqlDatabaseJelle Raaijmakers
Missing imports, make methods static. No functional changes.
2023-05-14Tests: Prefer TRY_OR_FAIL() and MUST() over EXPECT(!.is_error())Ben Wiederhake
Note that in some cases (in particular SQL::Result and PDFErrorOr), there is no Formatter defined for the error type, hence TRY_OR_FAIL cannot work as-is. Furthermore, this commit leaves untouched the places where MUST could be replaced by TRY_OR_FAIL. Inspired by: https://github.com/SerenityOS/serenity/pull/18710#discussion_r1186892445
2023-04-25LibSQL: Handle statements with malformed exists expressions correctlyTim Ledbetter
Previously, statements containing malformed exists expressions such as: `INSERT INTO t(a) VALUES (SELECT 1)`; could cause the parser to crash. The parser will now return an error message instead.
2023-04-23LibSQL: Use `Block::Index` everywhere; rename `pointer` to `block_index`Jelle Raaijmakers
No functional changes.
2023-04-23LibSQL: Redesign heap storage to support arbitrary amounts of dataJelle Raaijmakers
Previously, `Heap` would store serialized data in blocks of 1024 bytes regardless of the actual length. Data longer than 1024 bytes was silently truncated causing database corruption. This changes the heap storage to prefix every block with two new fields: the total data size in bytes, and the next block to retrieve if the data is longer than what can be stored inside a single block. By chaining blocks together, we can store arbitrary amounts of data without needing to change anything of the logic in the rest of LibSQL. As part of these changes, the "free list" is also removed from the heap awaiting an actual implementation: it was never used. Note that this bumps the database version from 3 to 4, and as such invalidates (deletes) any database opened with LibSQL that is not version 4.
2023-04-23LibSQL: Rename `Heap` constants to match our code styleJelle Raaijmakers
No functional changes. The constants are moved to constexpr variables inside `Heap`.
2023-04-23LibSQL: Clean up code style and remove unused includesJelle Raaijmakers
No functional changes.
2023-03-06Everywhere: Stop using NonnullRefPtrVectorAndreas Kling
This class had slightly confusing semantics and the added weirdness doesn't seem worth it just so we can say "." instead of "->" when iterating over a vector of NNRPs. This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
2023-01-27AK: Remove StringBuilder::build() in favor of to_deprecated_string()Linus Groh
Having an alias function that only wraps another one is silly, and keeping the more obvious name should flush out more uses of deprecated strings. No behavior change.
2023-01-01LibSQL: Add parsing and evaluation of BOOLEAN type literalsTimothy Flynn
This allows you to enter TRUE or FALSE in a SQL statement for BOOLEAN types. Note that this differs from SQLite, which requires entering 1 or 0 for BOOLEANs; having explicit keywords feels a bit more natural.
2022-12-14LibSQL: Support 64-bit integer values and handle overflow errorsTimothy Flynn
Currently, integers are stored in LibSQL as 32-bit signed integers, even if the provided type is unsigned. This resulted in a series of unchecked unsigned-to-signed conversions, and prevented storing 64-bit values. Further, mathematical operations were performed without similar checks, and without checking for overflow. This changes SQL::Value to behave like SQLite for INTEGER types. In SQLite, the INTEGER type does not imply a size or signedness of the underlying type. Instead, SQLite determines on-the-fly what type is needed as values are created and updated. To do so, the SQL::Value variant can now hold an i64 or u64 integer. If a specific type is requested, invalid conversions are now explictly an error (e.g. converting a stored -1 to a u64 will fail). When binary mathematical operations are performed, we now try to coerce the RHS value to a type that works with the LHS value, failing the operation if that isn't possible. Any overflow or invalid operation (e.g. bitshifting a 64-bit value by more than 64 bytes) is an error.
2022-12-14LibSQL: Ungracefully handle database version incompatibilitiesTimothy Flynn
In the long run, this is obviously a bad way to handle version changes to the SQL database files. We will want to migrate old databases to new formats. Until we figure out a good way to do that, wipe old databases so that we don't crash trying to read incompatible data.
2022-12-07LibSQL: Parse and execute sequential placeholder valuesTimothy Flynn
This partially implements SQLite's bind-parameter expression to support indicating placeholder values in a SQL statement. For example: INSERT INTO table VALUES (42, ?); In the above statement, the '?' identifier is a placeholder. This will allow clients to compile statements a single time while running those statements any number of times with different placeholder values. Further, this will help mitigate SQL injection attacks.
2022-12-07LibSQL: Partially implement the UPDATE commandTimothy Flynn
This implements enough to update rows filtered by a WHERE clause.
2022-12-06Everywhere: Rename to_{string => deprecated_string}() where applicableLinus Groh
This will make it easier to support both string types at the same time while we convert code, and tracking down remaining uses. One big exception is Value::to_string() in LibJS, where the name is dictated by the ToString AO.
2022-12-06AK+Everywhere: Rename String to DeprecatedStringLinus Groh
We have a new, improved string type coming up in AK (OOM aware, no null state), and while it's going to use UTF-8, the name UTF8String is a mouthful - so let's free up the String name by renaming the existing class. Making the old one have an annoying name will hopefully also help with quick adoption :^)
2022-11-30LibSQL: Partially implement the DELETE commandTimothy Flynn
This implements enough to delete rows filtered by a WHERE clause.
2022-11-30LibSQL+SQLServer: Return a NonnullRefPtr from Database::get_tableTimothy Flynn
Database::get_table currently either returns a RefPtr to an existing table, a nullptr if the table doesn't exist, or an Error if some internal error occured. Change this to return a NonnullRefPtr to an exisiting table, or a SQL::Result with any error, including if the table was not found. Callers can then handle that specific error code if they want. Returning a NonnullRefPtr will enable some further cleanup. This had some fallout of needing to change some other methods' return types from AK::ErrorOr to SQL::Result so that TRY may continue to be used.
2022-11-30LibSQL+SQLServer: Return a NonnullRefPtr from Database::get_schemaTimothy Flynn
Database::get_schema currently either returns a RefPtr to an existing schema, a nullptr if the schema doesn't exist, or an Error if some internal error occured. Change this to return a NonnullRefPtr to an exisiting schema, or a SQL::Result with any error, including if the schema was not found. Callers can then handle that specific error code if they want. Returning a NonnullRefPtr will enable some further cleanup. This had some fallout of needing to change some other methods' return types from AK::ErrorOr to SQL::Result so that TRY may continue to be used.
2022-11-26LibSQL: Fix BTree corruption in `TreeNode::split`Jelle Raaijmakers
After splitting a node, the new node was written to the same pointer as the current node - probably a copy / paste error. This new code requires a `.pointer() -> u32` to exist on the object to be serialized, preventing this issue from happening again. Fixes #15844.
2022-10-14LibSQL: Rewrite the SQL::Value type to be contained within one classTimothy Flynn
Currently, the Value class is essentially a "pImpl" wrapper around the ValueImpl hierarchy of classes. This is a bit difficult to follow and reason about, as methods jump between the Value class and its impl classes. This changes the Variant held by Value to instead store the specified types (String, int, etc.) directly. In doing so, the ValueImpl classes are removed, and all methods are now just concise Variant visitors. As part of this rewrite, support for the "array" type is dropped (or rather, just not re-implemented) as it was unused. If it's needed in the future, support can be re-added. This does retain the ability for non-NULL types to store NULL values (i.e. an empty Optional). I tried dropping this support as well, but it is depended upon by the on-disk storage classes in non-trivial ways.
2022-10-14LibSQL: Remove infallible type conversions from SQL::ValueTimothy Flynn
Force the callers to either know that the type is convertible, or to handle the conversion failure.
2022-07-12Everywhere: Add sv suffix to strings relying on StringView(char const*)sin-ack
Each of these strings would previously rely on StringView's char const* constructor overload, which would call __builtin_strlen on the string. Since we now have operator ""sv, we can replace these with much simpler versions. This opens the door to being able to remove StringView(char const*). No functional changes.
2022-04-01Everywhere: Run clang-formatIdan Horowitz
2022-02-13LibSQL: Convert binary SQL operations to be fallibleTimothy Flynn
Now that expression evaluation can use TRY, we can allow binary operator methods to fail as well. This also fixes a few instances of converting a Value to a double when we meant to convert to an integer.
2022-02-13LibSQL: Implement converting float and tuple values to a booleanTimothy Flynn
2022-02-10LibSQL+SQLServer: Introduce and use ResultOr<ValueType>Timothy Flynn
The result of a SQL statement execution is either: 1. An error. 2. The list of rows inserted, deleted, selected, etc. (2) is currently represented by a combination of the Result class and the ResultSet list it holds. This worked okay, but issues start to arise when trying to use Result in non-statement contexts (for example, when introducing Result to SQL expression execution). What we really need is for Result to be a thin wrapper that represents both (1) and (2), and to not have any explicit members like a ResultSet. So this commit removes ResultSet from Result, and introduces ResultOr, which is just an alias for AK::ErrorOrr. Statement execution now returns ResultOr<ResultSet> instead of Result. This further opens the door for expression execution to return ResultOr<Value> in the future. Lastly, this moves some other context held by Result over to ResultSet. This includes the row count (which is really just the size of ResultSet) and the command for which the result is for.
2022-02-10LibSQL: Do not crash when SELECTing from an empty tableTimothy Flynn
The crash was caused by getting the first element of an empty vector.
2022-02-10LibSQL+SQLServer: Move LibSQL/SQLResult.[h,cpp] to LibSQL/Result.[h,cpp]Timothy Flynn
Rename the file to match the new class name.
2022-02-10LibSQL+SQLServer: Return the new Result class from statement executionsTimothy Flynn
We can now TRY anything that returns a SQL::Result or an AK::Error.
2022-02-05LibSQL: Implement DESCRIBE TABLE testsMahmoud Mandour
2022-01-31Everywhere: Update copyrights with my new serenityos.org e-mail :^)Timothy Flynn
2022-01-23LibSQL: Add simple REGEXP matchmnlrsn
The implementation of LIKE uses regexes under the hood, and this implementation of REGEXP takes the same approach. It employs PosixExtended from LibRegex with case insensitive and Unicode flags set. The implementation of LIKE is based on SQLlite specs, but SQLlite does not offer directions for a built-in regex functionality, so this one uses LibRegex.
2022-01-16LibSQL: Introduce SELECT ... LIMIT xxx OFFSET yyyJan de Visser
What it says on the tin.
2022-01-16LibSQL+SQLServer: Implement first cut of SELECT ... ORDER BY fooJan de Visser
Ordering is done by replacing the straight Vector holding the query result in the SQLResult object with a dedicated Vector subclass that inserts result rows according to their sort key using a binary search. This is done in the ResultSet class. There are limitations: - "SELECT ... ORDER BY 1" (or 2 or 3 etc) is supposed to sort by the n-th result column. This doesn't work yet - "SELECT ... column-expression alias ... ORDER BY alias" is supposed to sort by the column with the given alias. This doesn't work yet What does work however is something like ```SELECT foo FROM bar SORT BY quux``` i.e. sorted by a column not in the result set. Once functions are supported it should be possible to sort by random functions.
2022-01-07LibSQL: Implement LIKE SQL expressionsGuilherme Gonçalves
2022-01-07LibSQL: Properly parse ESCAPE expressionsGuilherme Gonçalves
The evaluation order of method parameters is unspecified in C++, and so we couldn't rely on parse_statement() being called before parse_escape() when building a MatchExpression. With this patch, we explicitly parse what we need in the right order, before building the MatchExpression object.
2021-12-05Tests: Cast unused smart-pointer return values to voidSam Atkins
2021-12-04LibSQL: Gracefully react to unimplemented valid SQLJan de Visser
Fixes a crash that was caused by a syntax error which is difficult to catch by the parser: usually identifiers are accepted in column lists, but they are not in a list of column values to be inserted in an INSERT. Fixed this by putting in a heuristic check; we probably need a better way to do this. Included tests for this case. Also introduced a new SQL Error code, `NotYetImplemented`, and return that instead of crashing when encountering unimplemented SQL.
2021-12-04LibSQL: Improve error handlingJan de Visser
The handling of filesystem level errors was basically non-existing or consisting of `VERIFY_NOT_REACHED` assertions. Addressed this by * Adding `open` methods to `Heap` and `Database` which return errors. * Changing the interface of methods of these classes and clients downstream to propagate these errors. The constructors of `Heap` and `Database` don't open the underlying filesystem file anymore. The SQL statement handlers return an `SQLErrorCode::InternalError` error code if an error comes back from the lower levels. Note that some of these errors are things like duplicate index entry errors that should be caught before the SQL layer attempts to actually update the database. Added tests to catch attempts to open weird or non-existent files as databases. Finally, in between me writing this patch and submitting the PR the AK::Result<Foo, Bar> template got deprecated in favour of ErrorOr<Foo>. This resulted in more busywork.
2021-11-10LibSQL: Implement table joinsJan de Visser
This patch introduces table joins. It uses a pretty dumb algorithm- starting with a singleton '__unity__' row consisting of a single boolean value, a cartesian product of all tables in the 'FROM' clause is built. This cartesian product is then filtered through the 'WHERE' clause, again without any smarts just using brute force. This patch required a bunch of busy work to allow for example the ColumnNameExpression having to deal with multiple tables potentially having columns with the same name.
2021-11-10LibSQL: Add current statement to the ExecutionContextJan de Visser
Because SQL is the craptastic language that it is, sometimes expressions need to know details about the calling statement. For example the tables in the 'FROM' clause may be needed to determine which columns are referenced in 'WHERE' expressions. So the current statement is added to the ExecutionContext and a new 'execute' overload on Statement is created which takes the Database and the Statement and builds an ExecutionContaxt from those.
2021-11-10LibSQL: Add 'schema' and 'table' to TupleElementDescriptorJan de Visser
These are needed to distinguish columns from different tables with the same column name in one and the same (joined) Tuple. Not quite happy yet with this API; I think some sort of hierarchical structure would be better but we'll burn that bridge when we get there :^)
2021-10-25LibSQL Tests: Add tests for `SELECT ... WHERE ...`Jan de Visser