Closed pvretano closed 3 years ago
Just to note that such a change would break existing CQL implementations. If we make changes like these, then we should reconsider other changes that we have discarded because of the existing CQL grammar (and also change the name to differentiate the CSW CQL and the new CQL).
2021-05-10: For implementations that support arithmetic expressions, we need a delimiter to disambiguate a temporal literal from an arithmetic expression. Question is whether it is sufficient to make it a string or if we need an explicit function/cast like in SQL? Discuss this again in the next meeting. Check also what other languages are using, but if a string is sufficient we should keep it simple.
Meeting 2021-06-07: If the context is always clear, then a wrapper function like toDate()
would be uncessary and a quoted literal would be sufficient. @pvretano will analyze this and make a proposal.
Did a survey of how popular databases handle dates.
Here is a brief survey of some of the popular databases:
In most cases these function take other arguments too but I don't think they are relevant to CQL since they are mostly pattern arguments so that the date string does not need to be in ISO8601 format. That is not the case for CQL.
Assuming that we start with the proposition that we need, at the very least, to change bare temporal literals to string literals then, there are numerous places in the current CQL grammar where it would be difficult to disambiguate a string literal from a date literal without referring to an external schema. This makes parsing a CQL expression a little inconvenient and so, I think we should go for the least ambiguous and simplest to parse approach and change the definition of instant
from this:
instant = fullDate | fullDate "T" utcTime;
to this:
instant = "DATE" leftParen dateStringLiteral rightParen;
dateStringLiteral = quote fullDate quote | quote fullDate "T" utcTime quote;
The change would make temporal intervals a little more bulky (i.e. DATE('1970-01-01')/DATE('2021-01-01') ).
Sounds reasonable. Two thoughts:
fullDate
) and TIMESTAMP for timestamps (fullDate "T" utcTime
)?So, something like:
instant = dateInstant | timestampInstant;
dateInstant = "DATE" leftParen dateInstantString rightParen;
dateInstantString = quote fullDate quote;
timestampInstant = "TIMESTAMP" leftParen timestampInstantString rightParen;
timestampInstantString = quote fullDate "T" utcTime quote;
TIMESTAMP('2021-06-15T00:00:00Z')/TIMESTAMP('2021-06-15T12:00:00Z')
? Could also lead to disambiguation issues with arithmetic expressions due to the /
?Maybe we should use something like INTERVAL('2021-06-15T00:00:00Z', '2021-06-15T12:00:00Z')
. INTERVAL() could support arguments that are instants, date/timestamp strings (for simplicity, there are no disambiguation issues), ".." for open intervals as well as properties that are instants.
interval = "INTERVAL" leftParen instantParameter comma instantParameter rightParen;
instantParameter = instant
| dateInstantString
| timestampInstantString
| quote dotdot quote
| propertyName
| function;
As an aside, this would also remove the normative reference to 8601-1 / 8601-2, just the RFC 3339 reference is needed.
Meeting 2021-06-21: Agreed as proposed.
Temporal literal might be problematic to parse as defined. Without looking at the queryables and conformance classes one might think that 1969-07-16 is an arithmetic expression equalling 1946. Similarly 1969-07-16/1969-07-24 could also be interpreted as the numeric expression 1930.99187404774.
We should probably consider what SQL does ... e.g. date('1969-07-16'). That is a builtin function with a date string.
As I mentioned, you can figure out the context of the value by looking at the queryables and conformance classes but that seems like a heavy lift just to parse a date.