compatible: can be cast, keeps sort order
value-compatible: can be cast, may change sort order
frozen: values participate in sort order
unfrozen: only sort keys participate in sort order
Fixes#740.
Boost::date_time doesn't accept some of the date and time formats that
the origin do (e.g. 2013-9-22 or 2013-009-22).
Signed-off-by: Paweł Dziepak <pdziepak@scylladb.com>
timestamp_from_string() is used by both timestamp and date types, so it
is better to move the try { } catch { } to the functions itself instead
of expecting its callers to catch exceptions.
Signed-off-by: Paweł Dziepak <pdziepak@scylladb.com>
Frozen collection type names must be wrapped in FrozenType so that we
are able to store the types correctly in system tables.
This fixes#646 and fixes#580.
Signed-off-by: Pekka Enberg <penberg@scylladb.com>
Print a map in the form of [(]{ key0 : value0 }[, { keyN : valueN }]*[)]
The map is printed inside () brackets if it's frozen.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
An empty serialized representation means an empty value, not NULL.
Fix up the confusion by converting incorrect make_null() calls to a new
make_empty(), and removing make_null() in empty-capable types like
bytes_type.
Collections don't support empty serialized representations, so remove
the call there.
Origin supports (https://issues.apache.org/jira/browse/CASSANDRA-5648) "empty"
values even for non-container types such as int. Use maybe_empty<> to
encapsulate abstract_type::native_type, adding an empty flag if needed.
schema_tables manages some boolean columns stored in system tables; it
dynamically creates them from C++ values. But as we lacked bool->data_value
conversion, the C++ value was converted to a int32_type. Somehow this didn't
cause any problems, but with some pending patches I have, it does.
Add a bool->data_value converting constructor to fix this.
We use boost::any to convert to and from database values (stored in
serlialized form) and native C++ values. boost::any captures information
about the data type (how to copy/move/delete etc.) and stores it inside
the boost::any instance. We later retrieve the real value using
boost::any_cast.
However, data_value (which has a boost::any member) already has type
information as a data_type instance. By teaching data_type intances about
the corresponding native type, we can elimiante the use of boost::any.
While boost::any is evil and eliminating it improves efficiency somewhat,
the real goal is growing native type support in data_type. We will use that
later to store native types in the cache, enabling O(log n) access to
collections, O(1) access to tuples, and more efficient large blob support.
We call the conversion function that expectes a NUL terminated string,
but provide a string view, which is not.
Fix by using the begin/end variant, which doesn't require a NUL terminator.
Fixes#437.
cql2_type is a simple wrapper around data_type. But some data_types
(collection_type_impl) contain a cql3_type as a cache to avoid recomputing
it, resulting in a circular reference. This leaks memory when as_cql3_type()
is called.
Fix by using a static hash table for the cache.
In preparation for reducing type name duplication, introduce classes for
ascii and utf8 types.
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
The CQL tokenizer recognizes "COUNTER" token but the parser rule for
counter type is disabled. This causes users to see the following error
in cqlsh, for example:
CREATE TABLE count (u int PRIMARY KEY, c counter);
SyntaxException: <ErrorMessage code=2000 [Syntax error in CQL query] message=" : cannot match to any predicted input... ">
We cannot disable the "COUNTER" token because it's also used in batch
statements. Instead, fix the issue by implementing a stub counter type.
Fixes#195.
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
any_cast<X> is supposed to return X, but boost 1.55's any_cast<X> returns
X&&. This means the lifetime-extending construct
auto&& x = boost::any_cast<X>(...);
will not work, because the result of the expression is an rvalue reference,
not a true temporary.
Fix by using a temporary, not a lifetime-extending reference.
Fixes#163.
In an expression like:
tuple_type_impl(make_name(types), std::move(types));
the order in which arguments are evaluated is unspecified and it
is possible that make_name() is called with types already moved
away.
This is fixed by using initialization list (for which order of
evalutaion is specified). Unfortunately, this also requires some code
duplication.
Signed-off-by: Paweł Dziepak <pdziepak@cloudius-systems.com>
The logger class constructor registers itself with the logger registry,
in order to enable dynamically setting log levels. However, since
thread_local variables may be (and are) initialized at the time of first
use, when the program starts up no loggers are registered.
Fix by making loggers global, not thread_local. This requires that the
registry use locking to prevent registration happening on different threads
from corrupting the registry.
Note that technically global variables can also be initialized at the
point of first use, and there is no portable way for classes to self-register.
However this is the best we can do.
In Java method compareTo() of Float and Double types doesn't strictly
follow IEEE 754. Firstly, NaN is equal NaN and is greater than any other
value. Secondly, positive zero is larger than negative zero.
Signed-off-by: Paweł Dziepak <pdziepak@cloudius-systems.com>
Fix data type naming to follow Origin's conventions so that we can
serialize the names to database.
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Add a parse_type() function for parsing a serialized type name and
returning a data_type for it. Please note that collection types are
handled elsewhere.
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Convert code to use the deserialize() function and drop the duplicate
compose() wrapper that we inherited from Origin.
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>