There is an unfortunate pattern of hard coding constants in SQL which I think comes from the fact that there's not an especially good way to encode constants in SQL. Things are a little better In CG/SQL's CQL language because it's normal to run things through the pre-processor first so you can do things like:
Having done so, you could write:
And at least you don't have to see these loose '2' values all over. An especially unfortunate form is the below, in which the auther is clearly crying for a symbol to use:
But if we use
#define the language knows nothing of the names and it can't help you manage them
or export them consistently or anything like that. I guess
#define is pretty useful in several
langauges (C and C++) so you could maybe
#include the macros somehow but that doesn't seem
especially great. And if you need them in Java you're getting no help at all.
So to this world we add enumerated constants. This is a bit short of enumerated types as we'll see later. You can now write something like this:
is the same as
And that is exactly what SQLite will see, the literal 14.
What's going on here? There's just a few rules:
- the enumeration can be any numeric type (bool, integer, long integer, real)
- the values of the enumeration start at 1 (i.e. if there is no
= expressionthe first item will be 1, not 0)
- if you don't specify a value, the next value is the previous value + 1
- if you do specify a value it can be any constant expression and it will be cast to the type of the enumeration (even if thatis lossy)
- the enumeration can refer to previous values in itself with no qualification
(big = 100.0, medium = big/2, small = medium/2)
- the enumeration can refer to previously defined enumerations as usual
(code = business_type.restaurant)
- Once the enumeration is defined you refer to its members in a fully qualified fashion
Why is this better than macros? Well for one thing the enum values can be checked at their declaration site, so if you have errors you will hear about them in a more reasonable place. But additionally since the structure is known to the compiler it can give you useful information in the outputs.
.h files you get:
In case of floating point values such as:
Which is unfortunately the best you can do since C has no floating point enums.
But in both cases the
enums section of the JSON has the name of the enums and their members and values ready to go.
With these values you can readily generate (with moustache or something) the language interfaces of your choice. This
is a real help if you're trying to make helpers to call your CQL from say Java or something.
To do all this we needed to add some constant folding and general evaluation to the compiler. It's not much, just the normal numeric types and null. The supported operations include:
case forms. These are enough to make a lot of very interesting expressions, all of which are envaluated at
While the constant folding was added to allow for rich
enum expressions, there is also the
const() primitive in the
language now which can appear anywhere a literal could appear. This allows you do things that were previously not
allowed such as:
const form is also very useful in macros:
This form ensures that the constant will be evaluated at compile time. Const can also also nest so you can build these
kinds of macros from other macros or you can build enums this way. Anywhere you might need literals, you can use
Importantly, no enumerated data types were added to the language to do any of this. The values can help you to achieve some correctness by avoiding transcription mistakes but there is no additional type-safety provided here. Indeed given the rich mix between these types in SQLite, and with SQLite having no knowledge of enumerations at all it would be tricky to do a complete job. Still, this might happen in the future.
But for now, declaring constants that are really an intimate part of your schema is now possible and the addition
of the constants to the
.h files and the
.json output should hopefully make these generally useful. At least
we might see less of the hard-coded constant business with good values baked right into the schema declarations.