diff --git a/RFCs/0047-datetime-data-type.md b/RFCs/0047-datetime-data-type.md new file mode 100644 index 0000000..b126fd1 --- /dev/null +++ b/RFCs/0047-datetime-data-type.md @@ -0,0 +1,598 @@ +# PartiQL Datetime RFC + +## Summary + +This RFC purposes the formal syntax and semantics for PartiQL’s datetime data types. + +## Motivation + +Date time types is among the primitive types specified in SQL spec. However, the PartiQL Specification as it stands today does not specify the syntax and semantics of date time types. The Kotlin reference implementation has put together an initial attempt for date time types but its syntax/semantics is not completed or documented anywhere. The motivation is to provide guidance to customers and library implementors through a formalized semantics of Date Time date type. + +## Guide-level explanation + +### Terminology + +* Datetime types: The data types DATE, TIME, and TIMESTAMP are collectively referred to as datetime types. +* Coordinated Universal Time (UTC): the primary [time standard](https://en.wikipedia.org/wiki/Time_standard) by which the world regulates clocks and time. +* Time zone: For the purpose of this RFC, we define three representation of Time Zone: + * UTC offset: Defined by ISO 8601, represents the difference between UTC time and local time. + * Time Zone Abbreviations: Represented by alphabetic abbreviations such as "EST", "WST", and "CST" + * Unknown Time Zone: Defined by RFC 3339. If the time in UTC is known, but the offset to local time is unknown, this can be represented with an offset of "-00:00" + +### Out of Scope + +* Time Zone Abbreviations is out of the scope for this RFC. + * Many commercial database support evaluation of Time Zone Abbreviation by keeping a copy of [**IANA**](https://en.wikipedia.org/wiki/Internet_Assigned_Numbers_Authority) time zone data in the system table. But rarely would one store such information in persistent format. + * Oracle is a noticeable exception, as it stores Time Zone Abbreviation in the original input. + * SQL spec defines Time zone to be UTC offset, PartiQL will follow SQL spec on this matter for now, and left time zone abbreviation out of the scope in this RFC. +* Datetime arithmetic is out of scope for this RFC. + * A complete set of datetime arithmetic requires `INTERVAL` type (representation of a span of time) to properly explain. As `INTERVAL` type is not yet defined in PartiQL, and it is out of scope for this RFC, the Datetime arithmetic will be covered in a follow-up RFC in the future. + +### Datetime Data Type + +PartiQL defines 5 datetime data types: +- DATE +- TIME WITH TIME ZONE +- TIME WITHOUT TIME ZONE +- TIMESTAMP WITH TIME ZONE +- TIMESTAMP WITHOUT TIME ZONE. + +The data type `TIME WITHOUT TIME ZONE` and `TIME WITH TIME ZONE` are collective referred to as **TIME** types. The data type `TIMESTAMP WITHOUT TIME ZONE` and `TIMESTAMP WITH TIME ZONE` are collectively referred to as **TIMESTAMP** type. The data types `DATE`, `TIME`, and `TIMESTAMP` are collectively referred to as **DATETIME** types. Values of `DATETIME` types are referred to as **datetimes**. + +Table1 “Fields in datetime values”, specifies the fields that can make up a datetime value; a datetime value is made up of a subset of those fields. + + +| Keyword | Meaning | +|------------------|-------------------------------------------| +| YEAR | Proleptic Year | +| MONTH | Month of Year | +| DAY | Day of Month | +| HOUR | Hour of Day | +| MINUTE | Minute of Hour | +| SECOND | Second and possibly fraction of a second | +| TIMEZONE_HOUR | Hour value of UTC offset | +| TIMEZONE_MINUTE | Minute value of UTC offset | + +Table1: Fields in datetime values + +The `YEAR`, `MONTH`, `DAY`, `HOUR`, `MINUTE`, and `SECOND` are called **primary datetime field**, and is listed by the order of significant. The primary datetime fields other than SECOND contain non-negative integer values, constrained by the natural rules for dates using the Gregorian calendar. SECOND, contains non-negative decimal values. The number before the decimal point represents whole second, constrained by natural rules using Gregorian calendar. The number after the decimal point represents fractional second. PartiQL implementation **SHALL** permit arbitrary precision for fraction second. + +A datetime value, of data type `TIME WITHOUT TIME ZONE` or `TIMESTAMP WITHOUT TIME ZONE`, MAY represent a local time, whereas a datetime value of data type `TIME WITH TIME ZONE` or `TIMESTAMP WITH TIME ZONE` MUST represent UTC. + +On occasion, UTC is adjusted by the omission of a second or the insertion of a “[leap second](https://www.nist.gov/pml/time-and-frequency-division/leap-seconds-faqs)” in order to maintain synchronization with time. Whether a PartiQL-implementation supports leap seconds, and the consequences of such support for date and interval arithmetic, is implementation-defined. + +For conformance of SQL spec, PartiQL permits implicit conversion between a datetime value with time zone and a datetime value without time zone. See [Conversion Between Datetime Types](https://quip-amazon.com/x1qAAhtS8m36#temp:C:ZMf21e817dd22c9470c9579d39d2) for detail. + +### Operational Semantics + +#### Data Type + +``` + ::= + DATE + | TIME [ ] + [ ] + | TIMESTAMP [ ] + [ ] + + ::= + WITH TIME ZONE + | WITHOUT TIME ZONE + + ::= +``` + +Rules: + +1. `` defines the number of decimal digits following the decimal point in the SECOND ``. +2. If `` is not specified in TIME type, then 0 is implicit. +3. If `` is not specified in TIMESTAMP type, then 6 is implicit. +4. If `` is not specified, then WITHOUT TIME ZONE is implicit. + 1. SQL-1999 - Section 6.1 - Syntax Rules - 30/ 31 + +>Item 2,3,4 is to confirm with SQL spec ( see section 2,3,4). However, doing so means PartiQL currently does not have the syntactical ability to declare a type with arbitrary precision. See Unresolved question. + +5. If `DATE` is specified, then the data type contains the ``s YEAR, MONTH, and DAY. +6. If `TIME` is specified, then the data type contains the ``s HOUR, MINUTE, and SECOND. +7. If `TIMESTAMP` is specified, then the data type contains the ``s YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND. +8. Table 2, Valid Values for datetime fields, specifies the constraints on the values of the date time fields. The values of `TIMEZONE_HOUR` and `TIMEZONE_MINUTE` shall either both be non-negative or both be non-positive. + +| Keyword | Valid Values | +|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| YEAR | 0001 to 9999 | +| MONTH | 01 to 12 | +| DAY | With in the range 1 to 31, but further constrained by the value of MONTH and YEAR fields, according to the Gregorian Calendar. | +| HOUR | 00 to 23 | +| MINUTE | 00 to 59 | +| SECOND | 00 to 60 (excluded) if not supporting leap second; 00 to 62(excluded) if supporting leap second. Whether or not Leap Second is supported is up to implementation. | +| TIMEZONE_HOUR | -23 to 23 | +| TIMEZONE_MINUTE | -59 to 59 | + +Table 2 : Valid Value for datetime fields. + + +| Name | Description | Min Value | Max Value | +|--------------------------------------|---------------------------------------|----------------------------|----------------------------------| +| Date | date (no time of day; no time zone) | 0001-01-01 | 9999-12-31 | +| time [(p)] [WITHOUT TIME ZONE] | time of day ( no date, no time zone) | 00:00:00 | 23:59:59.999... | +| time [(p)] WITH TIME ZONE | time of day (no date, has time zone) | 00:00:00-23:59 | 23:59:59.999...+23:59 | +| timestamp [(p)] [WITHOUT TIME ZONE] | both date and time (no time zone). | 0001-01-01 00:00:00 | 9999-12-31 23:59:59.999 | +| timestamp [(p)] WITH TIME ZONE | both date and time (has time zone). | 0001-01-01 00:00:00-23:59 | 9999-12-31 23:59:59.999 + 23:59 | + +Table 3 DateTime Types + +#### Datetime Literal + +Grammar: + +``` + ::= + + |