janderland / fql

Foundation DB Query Language
Apache License 2.0
25 stars 2 forks source link

Questions and remarks about supported types, missing types and named variables #213

Open KrzysFR opened 1 day ago

KrzysFR commented 1 day ago

Great idea! I've used tuples for a long time, and always wished there was a standard for representing them and querying them. Hopefully this could be the one :)

I apologize for the flood, they are notes I took when implementing a parser for fql in C#/.NET

I have a few remarks, coming from a long time user of tuples, mostly in the context of writing complex layers in .NET/C#, and not 100% familiar with go conventions.

There are a few types that I use frequently in tuples, and that are missing:

Regarding directories:

On top of querying, I see this as very useful to encoded the "schema" of a layer somehow, so that a UI could automatically decode data into an arbitrary subspace (using the optional Layer Id in directories).

For example, I used the following format to define the schema of a custom layer, like a typical "table with index + change log" mini layer:

Legend:

I think this could be adapted to use fql as the syntax, but this would required adding the support of named variables:

The above could become:

janderland commented 1 day ago

I'll answer all these questions in a follow up comment, but I'll start by saying that I'm almost done with a proper manual for FQL which may clarify a lot of these questions.

janderland commented 1 day ago

Why the distinction between int and uint?

It's modeled after Go's implementation of the tuple layer. Thanks for pointing this out. I will need to think about what I want to do with this. Go's tuple layer makes all the integers look like int64 or uint64.

How do you handle NaN or infinities?

I have not added support yet. This will be supported, most likely as the tokens like nan, inf, -inf.

I find it difficult to parse a UUID that is not bounded by either {...} or any other character.

I haven't encountered any problems with parsing UUIDs myself. The context of the FQL query provided me with enough information to parse them without additional bounding characters.

Bytes: when parsing 0x1234, you first see the 0 which could the be start of a number, a uuid, or a byte sequence.

Ah, this gives me a clue as to why you had problems parsing UUIDs. I allow my parser to look ahead, which allows me to see that the 0x is followed by hexadecimal digits, and hence I know it's a hex number.

Are hexa digits always upper? lower? either? the syntax definition is a bit ambiguous.

I currently use Go's standard library to parse the hex string, which allows for either. In the syntax definition I only allow for uppercase, but I'm planning on changing this. I prefer lower case myself.

For me, 0xFF and 0xFE is ambiguous, because they are the byte prefix for the System subspace and Directory Layer, which are a single byte, where here I think they would be encoded as 01 FF 00 and 01 FE 00 instead?

Yes, you are correct. (0xff) would be packed as 0x01ff00.

Also, FQL doesn't support reading/writing key-value outside of the directory layer. Therefore, it doesn't support reading/writing to the system subspace. I may change this in the future.

How do you handle escaping of unicode characters?

Unicode is not currently supported, only ASCII. I do plan to add unicode support in the future.

does (...) means "any tuple, empy or not?

Yes.

...is ("hello", 123, ..., <int>) supported?

Not currently supported, though I may add support for this in the future.

What would we use here? nil seems weird because it is different (for me) than the concept of "empty".

nil is what I'm using for empty values. This allows the empty value to logically mirror the empty element within a tuple: (nil). I don't plan to change this part, though I am glad you told me your opinion as it helps me see how other people's intuition works.

Version Stamps: maybe add a new stamp or versionstamp or vs type in variables?

Yes, version stamps will be supported sometime in the future. They are not supported yet.

Would it make sense to be able to impose constraints on types? Like a regex on a string, a range on a number, a maximum/minimum/exact size for string/bytes?

Yes, I've considered this. I may add this in the future.

What if I use partitions/sub-partitions ? This is a way to "lock" an application into a specific prefix (ie: if "/foo" is a partition with prefix 15 2A (== (42, )), all keys will have this prefix, even sub-directories of this partition.

I have not added support for partitions yet. I still need to look into this. When you set up an FQL instance, you must provide a root directory which would contain all queries to within that directory. I expect partition to work in a similar way.

Directory names are string, and I also use strings 99%+ of the time, but technically, the names can be any sequence of bytes...

I don't plan to support reading/writing all possible key-values right now. For the near future, I'm focused on supporting the 99% of use cases which only includes key-values encoded using a directory (made of strings) and a tuple. After I have this working, documented, and well tested, then I may implement support for other cases like this one.

This is similar to the question about system keys. Most user don't need to access these, so I will focus on the most common use cases first.

On top of querying, I see this as very useful to encoded the "schema" of a layer somehow, so that a UI could automatically decode data into an arbitrary subspace (using the optional Layer Id in directories).

Yes, this is one of the goals of the project.

named variables...

Yes, this is a feature which I will explain in the manual. The manual should be available within the next week or so.