Commit graph

27 commits

Author SHA1 Message Date
Linus Groh
6e7459322d AK: Remove StringBuilder::build() in favor of to_deprecated_string()
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-27 20:38:49 +00:00
Timothy Flynn
ab99ed5fba LibIPC+Everywhere: Change IPC::encode's return type to ErrorOr
In doing so, this removes all uses of the Encoder's stream operator,
except for where it is currently still used in the generated IPC code.
So the stream operator currently discards any errors, which is the
existing behavior. A subsequent commit will propagate the errors.
2023-01-04 11:49:15 +01:00
Timothy Flynn
9b483625e6 LibIPC+Everywhere: Change IPC decoders to construct values in-place
Currently, the generated IPC decoders will default-construct the type to
be decoded, then pass that value by reference to the concrete decoder.
This, of course, requires that the type is default-constructible. This
was an issue for decoding Variants, which had to require the first type
in the Variant list is Empty, to ensure it is default constructible.

Further, this made it possible for values to become uninitialized in
user-defined decoders.

This patch makes the decoder interface such that the concrete decoders
themselves contruct the decoded type upon return from the decoder. To do
so, the default decoders in IPC::Decoder had to be moved to the IPC
namespace scope, as these decoders are now specializations instead of
overloaded methods (C++ requires specializations to be in a namespace
scope).
2022-12-26 09:36:16 +01:00
Timothy Flynn
781e3aea8b LibSQL: Convert string values to a double in a locale-independent manner
This currently uses strtod, which is locale-dependent. Use the locale-
independent method added in 65ee9b4134225398f0a5109eb79b0baba98c9cd6.
2022-12-14 15:04:36 +00:00
Timothy Flynn
72e41a7dbd LibSQL: Support 64-bit integer values and handle overflow errors
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-14 09:21:30 -05:00
Timothy Flynn
264db4fc40 LibSQL: Remove unnecessary values from the ENUMERATE_SQL_TYPES macro
Removing the bitmask-esque values from the enumeration necessitates a
Heap version bump.
2022-12-14 09:21:30 -05:00
Timothy Flynn
83bb25611e LibSQL: Add an IPC encoder/decoder for SQL::Value
This will allow clients to send placeholder values for prepared
statements over IPC.
2022-12-07 13:09:00 +01:00
Timothy Flynn
53f8d62ea4 LibSQL: Partially implement the UPDATE command
This implements enough to update rows filtered by a WHERE clause.
2022-12-07 13:09:00 +01:00
Linus Groh
57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
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-06 08:54:33 +01:00
Linus Groh
6e19ab2bbc AK+Everywhere: Rename String to DeprecatedString
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-12-06 08:54:33 +01:00
Timothy Flynn
7464dfa974 LibSQL: Add missing definition of Value's u32 comparator
This was declared but not defined (nor was it used, but an upcoming
commit will be using it).
2022-11-30 11:43:13 +01:00
Timothy Flynn
1524288127 LibSQL: Rewrite the SQL::Value type to be contained within one class
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-14 17:47:44 +03:30
Timothy Flynn
7d41b46a7d LibSQL: Remove infallible type conversions from SQL::Value
Force the callers to either know that the type is convertible, or to
handle the conversion failure.
2022-10-14 17:47:44 +03:30
sin-ack
c8585b77d2 Everywhere: Replace single-char StringView op. arguments with chars
This prevents us from needing a sv suffix, and potentially reduces the
need to run generic code for a single character (as contains,
starts_with, ends_with etc. for a char will be just a length and
equality check).

No functional changes.
2022-07-12 23:11:35 +02:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
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-07-12 23:11:35 +02:00
Timothy Flynn
bfe1bd9726 LibSQL: Convert binary SQL operations to be fallible
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-13 21:30:38 +00:00
Timothy Flynn
b15db851fe LibSQL: Short-circuit single-element tuple comparisons
If a tuple has a single value, perform a comparison using that singular
value. This allows, for example, comparisons of the form "(1) < 4",
where (1) is a single element tuple.
2022-02-13 21:30:38 +00:00
Timothy Flynn
e13c96157c LibSQL: Implement converting float and tuple values to a boolean 2022-02-13 21:30:38 +00:00
Timothy Flynn
8fab99e920 LibSQL: Use absolute value when comparing against floating point epsilon
Otherwise, any value that is less than another value would be considered
about equal by mistake.
2022-02-13 21:30:38 +00:00
Mahmoud Mandour
cd4dba87fa LibSQL: Avoid signed arithmetic in IntegerImpl::compare 2022-02-05 00:35:03 +01:00
Jan de Visser
87f4c1677b LibSQL: Relax assignment rules for Null Values
It should be possible to assign a Value of any type to a Value which
currently is Null.
2021-11-10 14:47:49 +01:00
Jan de Visser
7ea54db430 LibSQL: Add 'schema' and 'table' to TupleElementDescriptor
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-11-10 14:47:49 +01:00
Jan de Visser
73fc023652 LibSQL: Implement binary operators for Value objects
The behaviour of the various operators is supposed to mimic that of
the same operators in PostgreSQL; the '+' operator for example will
successfully add '98' (string) and 2 (integer), but not 'foo' and 2.

Also removed some redundant const& parameter declarations for
intrinsic types (ints and doubles etc). Passing those by const& doesn't
make a lot of sense.
2021-10-25 12:59:42 +02:00
Jan de Visser
85a84b0794 LibSQL: Introduce Serializer as a mediator between Heap and client code
Classes reading and writing to the data heap would communicate directly
with the Heap object, and transfer ByteBuffers back and forth with it.
This makes things like caching and locking hard. Therefore all data
persistence activity will be funneled through a Serializer object which
in turn submits it to the Heap.

Introducing this unfortunately resulted in a huge amount of churn, in
which a number of smaller refactorings got caught up as well.
2021-08-21 22:03:30 +02:00
Jan de Visser
b74721e604 LibSQL: Redesign Value implementation and add new types
The implemtation of the Value class was based on lambda member variables
implementing type-dependent behaviour. This was done to ensure that
Values can be used as stack-only objects; the simplest alternative,
virtual methods, forces them onto the heap. The problem with the the
lambda approach is that it bloats the Values (which are supposed to be
lightweight objects) quite considerably, because every object contains
more than a dozen function pointers.

The solution to address both problems (we want Values to be able to live
on the stack and be as lightweight as possible) chosen here is to
encapsulate type-dependent behaviour and state in an implementation
class, and let the Value be an AK::Variant of those implementation
classes. All methods of Value are now basically straight delegates to
the implementation object using the Variant::visit method.

One issue complicating matters is the addition of two aggregate types,
Tuple and Array, which each contain a Vector of Values. At this point
Tuples and Arrays (and potential future aggregate types) can't contain
these aggregate types. This is limiting and needs to be addressed.

Another area that needs attention is the nomenclature of things; it's
a bit of a tangle of 'ValueBlahBlah' and 'ImplBlahBlah'. It makes sense
right now I think but admit we probably can do better.

Other things included here:
- Added the Boolean and Null types (and Tuple and Array, see above).
- to_string now always succeeds and returns a String instead of an
  Optional. This had some impact on other sources.
- Added a lot of tests.
- Started moving the serialization mechanism more towards where I want
  it to be, i.e. a 'DataSerializer' object which just takes
  serialization and deserialization requests and knows for example how
  to store long strings out-of-line.

One last remark: There is obviously a naming clash between the Tuple
class and the Tuple Value type. This is intentional; I plan to make the
Tuple class a subclass of Value (and hence Key and Row as well).
2021-08-21 22:03:30 +02:00
Ali Mohammad Pur
15f95220ae AK+Everywhere: Delete Variant's default constructor
This was exposed to the user by mistake, and even accumulated a bunch of
users that didn't blow up out of sheer luck.
2021-08-13 17:31:39 +04:30
Jan de Visser
2a46529170 LibSQL: Basic dynamic value classes for SQL Storage layer
This patch adds the basic dynamic value classes used by the SQL Storage
layer. The most elementary class is Value, which holds a typed Value
which can be converted to standard C++ types. A Tuple is a collection
of Values described by a TupleDescriptor, which specifies the names,
types, and ordering of the elements in the Tuple.

Tuples and Values can be serialized and deserialized to and from
ByteBuffers. This is mechanism which is used to save them to disk.

Tuples are used as keys in SQL indexes and rows in SQL tables.

Also included is a test file.
2021-06-19 22:06:45 +02:00