Приведение к типу TIMESTAMP_NS
Описание
TIMESTAMP_NS имеет фиксированную наносекундную точность и точный диапазон [1677-09-21 00:12:43.145224192, 2262-04-11 23:47:16.854775807]. Параметр точности не поддерживается.
Для строковых и числовых значений в целом используется то же сопоставление полей, что и для DATETIME. В строгом и нестрогом режимах приведения TIMESTAMP_NS поддерживает ровно те же строковые форматы, что и DATETIME в соответствующем режиме. Единственное различие в поддержке строковых форматов заключается в том, что TIMESTAMP_NS поддерживает до девяти цифр в дробной части секунды, а DATETIME поддерживает до шести.
Синтаксис
CAST(<source_expr> AS TIMESTAMP_NS)
TRY_CAST(<source_expr> AS TIMESTAMP_NS)
Поддерживаемые исходные типы
| Исходный тип | Поведение при преобразовании |
|---|---|
CHAR, VARCHAR, STRING | Разбирает строку даты и времени по соответствующим строгим или нестрогим правилам синтаксиса строк DATETIME с точностью до девяти цифр в дробной части секунды. |
| Целочисленные типы | Интерпретирует значение как компактное представление даты или даты и времени. |
FLOAT | Использует значение, фактически представленное входным числом одинарной точности; потеря значащих цифр может сделать большое компактное представление даты и времени недопустимым. |
DOUBLE | Использует значение, фактически представленное входным числом двойной точности; дробная часть задаёт доли секунды. |
Типы DECIMAL | Интерпретирует целую часть как компактное представление даты или даты и времени, а дробную часть как доли секунды. |
DATE | Добавляет 00:00:00.000000000. |
DATETIME(p) | Сохраняет календарные дату и время и дополняет дробную часть нулями до девяти цифр. |
TIME(p) | Прибавляет входную длительность к полуночи текущей даты. |
TIMESTAMPTZ(p) | Преобразует момент времени в текущий часовой пояс сеанса, а затем удаляет сведения о часовом поясе. |
TIMESTAMP_NS | Возвращает значение без изменений. |
VARIANT | Извлекает совместимое скалярное значение и применяет соответствующее правило преобразования строкового, числового значения или значения даты и времени. |
NULL | Возвращает NULL. |
Преобразования из неподдерживаемых типов, включая BOOLEAN, JSON, IP, двоичные и сложные типы, завершаются ошибкой на этапе анализа. Это ошибка типа, а не ошибка преобразования значения, поэтому ни нестрогий CAST, ни TRY_CAST не заменяет её на NULL.
Из строки
Строгий режим
При enable_strict_cast = true поддерживаемые форматы и правила разбора полностью совпадают с правилами преобразования строк в DATETIME в строгом режиме. Это включает правила для полей даты и времени, годов из двух цифр, пропущенных полей времени, последовательностей цифр, пробельных символов и суффиксов часового пояса.
Нестрогий режим
При enable_strict_cast = false поддерживаемые форматы и правила разбора полностью совпадают с правилами преобразования строк в DATETIME в нестрогом режиме. Все форматы строгого режима остаются допустимыми, а дополнительные разделители, ограничители и пробельные символы в начале или конце строки, допустимые для нестрогого DATETIME, также принимаются типом TIMESTAMP_NS.
Различие между двумя режимами при приведении к TIMESTAMP_NS такое же, как для DATETIME: при ошибке формата или недопустимом значении строгий режим выдаёт ошибку, а нестрогий возвращает NULL.
Дробные секунды
Единственное отличие от соответствующих строковых форматов DATETIME заключается в поддерживаемой точности дробной части секунды:
- Целевой масштаб всегда равен 9. Дробная часть, содержащая менее девяти цифр, дополняется справа нулями.
- Дробная часть, содержащая более девяти цифр, округляется по правилу «половина вверх». Десятая цифра определяет, увеличивается ли девятая; последующие цифры не влияют на результат.
- Перенос при округлении обычным образом распространяется на секунду, дату или год.
- Doris проверяет диапазон
TIMESTAMP_NSпосле округления дробной части и преобразования часового пояса.
Обработка часовых поясов
TIMESTAMP_NS не хранит часовой пояс:
- Если суффикс часового пояса отсутствует, разобранные календарные дата и время сохраняются без изменений.
- Если указан числовой сдвиг, обозначение UTC или имя часового пояса IANA, Doris преобразует входной момент времени в текущий часовой пояс сеанса и сохраняет полученные календарные дату и время без часового пояса.
- Изменение часового пояса сеанса после сохранения значения не меняет сохранённое значение.
Допустимые суффиксы и имена часовых поясов описаны в разделах Правила преобразования строк в DATETIME и Часовой пояс.
В следующих примерах предполагается, что time_zone = '+08:00':
| Строка | Режим | Результат | Пояснение |
|---|---|---|---|
2024-02-29 12:34:56.123456 | Оба режима | 2024-02-29 12:34:56.123456000 | Дополняет дробную часть до девяти цифр. |
2024-02-29 12:34:56.1234567894 | Оба режима | 2024-02-29 12:34:56.123456789 | Десятая цифра меньше 5, поэтому значение округляется в меньшую сторону. |
2024-02-29 12:34:56.1234567895 | Оба режима | 2024-02-29 12:34:56.123456790 | Десятая цифра равна 5, поэтому значение округляется в большую сторону. |
2024-02-29 12:34:56.9999999995 | Оба режима | 2024-02-29 12:34:57.000000000 | Перенос при округлении увеличивает секунду. |
2024-02-29T04:34:56.123456789Z | Оба режима | 2024-02-29 12:34:56.123456789 | Преобразует UTC в часовой пояс сеанса и удаляет сведения о часовом поясе. |
2023-7-4T9-5-3.1Z | Только нестрогий | 2023-07-04 17:05:03.100000000 | Использует разделители нестрогого режима и пробельные символы в начале или конце строки. |
2024-02-30 12:34:56 | Оба режима | Недопустимо | 30 февраля не является датой григорианского календаря. |
2024-01-01 00:00:00.123.456 | Оба режима | Недопустимо | Недопустимый синтаксис дробной части секунды. |
Округление у границ диапазона
Округление выполняется до окончательной проверки диапазона. Поэтому входное значение, расположенное сразу за границей диапазона, может стать допустимым после округления, а значение на верхней границе может стать недопустимым после округления вверх.
| Строка | Результат |
|---|---|
1677-09-21 00:12:43.1452241914 | Недопустимо: после округления значение ниже нижней границы |
1677-09-21 00:12:43.1452241915 | 1677-09-21 00:12:43.145224192 |
2262-04-11 23:47:16.8547758074 | 2262-04-11 23:47:16.854775807 |
2262-04-11 23:47:16.8547758075 | Недопустимо: после округления значение выше верхней границы |
Из числовых типов
Все целочисленные типы, типы с плавающей запятой и десятичные типы можно преобразовать в TIMESTAMP_NS. Тип BOOLEAN не поддерживается.
Сопоставление полей целой части, правило для двухзначного года и допустимые компактные представления такие же, как при преобразовании чисел в DATETIME. В частности, допустимые представления содержат 3, 4, 5, 6, 8 или 14 цифр в целой части. Дробная часть задаёт доли секунды.
Компактное представление даты и времени вместе с дробной частью должно давать значение в диапазоне TIMESTAMP_NS. Дробная часть секунды дополняется нулями или округляется ровно до девяти цифр по тому же правилу «половина вверх», что и для строковых значений.
Из целочисленных типов
Целочисленные типы не имеют дробной части. Doris применяет сопоставление полей компактного числового представления и добавляет к результату .000000000.
| Целочисленное значение | Результат | Пояснение |
|---|---|---|
123 | 2000-01-23 00:00:00.000000000 | Трёхзначное компактное представление даты. |
20240229 | 2024-02-29 00:00:00.000000000 | Восьмизначное компактное представление даты. |
20240229123456 | 2024-02-29 12:34:56.000000000 | Четырнадцатизначное компактное представление даты и времени. |
16770921001243 | Недопустимо | Полученное время ниже нижней границы. |
22620412000000 | Недопустимо | Полученное время выше верхней границы. |
Из FLOAT
Для FLOAT используется десятичное значение, представленное входным числом одинарной точности до приведения. Его ограниченного числа значащих цифр обычно недостаточно для 14-значного компактного представления даты и времени, поэтому большое входное значение может потерять цифры и стать недопустимым представлением даты и времени. Для больших компактных значений используйте DOUBLE или DECIMAL.
| Входное выражение FLOAT | Результат в строгом режиме | Результат в нестрогом режиме | Пояснение |
|---|---|---|---|
CAST(123 AS FLOAT) | 2000-01-23 00:00:00.000000000 | 2000-01-23 00:00:00.000000000 | Значение представлено точно. |
CAST(20240229123456.125 AS FLOAT) | Ошибка | NULL | Из-за потери значащих цифр представленное компактное значение даты и времени становится недопустимым. |
Из DOUBLE
Для DOUBLE используется десятичное значение, представленное входным числом двойной точности до приведения. Этот тип может точно представить 14-значную целую часть каждого компактного значения TIMESTAMP_NS, но десятичная дробь, не имеющая точного двоичного представления, всё же может быть округлена до преобразования. Используйте DECIMAL, если необходимо сохранить каждую цифру дробной части входного значения.
| Входное выражение DOUBLE | Результат | Пояснение |
|---|---|---|
CAST(20240229123456.125 AS DOUBLE) | 2024-02-29 12:34:56.125000000 | Целая и дробная части представимы точно. |
Из DECIMAL
DECIMAL сохраняет десятичное представление литерала. Цифры за пределами наносекундной точности округляются по правилу «половина вверх» до девяти цифр дробной части.
| Входное выражение DECIMAL | Результат | Пояснение |
|---|---|---|
CAST(20240229123456.1234567895 AS DECIMAL(24, 10)) | 2024-02-29 12:34:56.123456790 | Дробная часть округляется до наносекунд. |
Обработка ошибок
Для числовых значений строгий и нестрогий режимы используют одинаковое сопоставление полей. Если представленное числовое значение не позволяет получить допустимое значение TIMESTAMP_NS в пределах диапазона, строгий режим выдаёт ошибку, а нестрогий возвращает NULL. Входное значение NULL возвращает NULL в обоих режимах.
Из типов даты и времени
Из DATE
Doris добавляет 00:00:00.000000000 к входной дате, а затем проверяет диапазон TIMESTAMP_NS. Поскольку полночь даты нижней границы находится вне диапазона, значение 1677-09-21 преобразовать нельзя; самое раннее допустимое для преобразования значение DATE равно 1677-09-22. Самое позднее допустимое для преобразования значение DATE равно 2262-04-11.
Входное значение DATE | Результат |
|---|---|
1677-09-21 | Недопустимо |
1677-09-22 | 1677-09-22 00:00:00.000000000 |
2262-04-11 | 2262-04-11 00:00:00.000000000 |
2262-04-12 | Недопустимо |
Из DATETIME
DATETIME и TIMESTAMP_NS не содержат сведений о часовом поясе, поэтому Doris сохраняет календарные дату и время без поправки на часовой пояс. Дробная часть DATETIME(p) дополняется справа нулями до девяти цифр; добавленные нули не повышают точность исходного значения.
Результат после дополнения нулями должен находиться в диапазоне TIMESTAMP_NS. Поскольку DATETIME поддерживает точность не выше микросекундной, самое раннее допустимое для преобразования значение у нижней границы равно 1677-09-21 00:12:43.145225, а самое позднее у верхней границы равно 2262-04-11 23:47:16.854775.
Входное значение DATETIME(6) | Результат |
|---|---|
1677-09-21 00:12:43.145224 | Недопустимо |
1677-09-21 00:12:43.145225 | 1677-09-21 00:12:43.145225000 |
2024-02-29 12:34:56.123456 | 2024-02-29 12:34:56.123456000 |
2262-04-11 23:47:16.854775 | 2262-04-11 23:47:16.854775000 |
2262-04-11 23:47:16.854776 | Недопустимо |
Из TIME
Doris берёт полночь текущей даты в часовом поясе сеанса и прибавляет длительность TIME с учётом знака. При этом возможен переход через границу даты. Дробная часть имеет точность не выше микросекундной и дополняется нулями до девяти цифр. Затем Doris проверяет, входят ли итоговые дата и время в диапазон TIMESTAMP_NS.
Например, если текущая дата равна 2025-04-29:
Входное значение TIME(6) | Результат |
|---|---|
12:34:56.123456 | 2025-04-29 12:34:56.123456000 |
500:00:00.000000 | 2025-05-19 20:00:00.000000000 |
-128:00:00.000000 | 2025-04-23 16:00:00.000000000 |
Поскольку это преобразование зависит от текущей даты, указывайте явное значение DATE или DATETIME, если требуется воспроизводимая календарная дата.
Из TIMESTAMPTZ
Doris преобразует представленный момент времени в текущий часовой пояс сеанса, удаляет сведения о часовом поясе и дополняет дробную часть исходного значения нулями до девяти цифр. Итоговые локальные дата и время должны находиться в диапазоне TIMESTAMP_NS.
Поэтому изменение time_zone может изменить результат приведения и переместить граничное значение внутрь поддерживаемого диапазона или за его пределы.
SET time_zone = '+08:00';
SELECT CAST(CAST('2024-02-29 04:34:56.123456+00:00' AS TIMESTAMPTZ(6)) AS TIMESTAMP_NS) AS ts;
+-------------------------------+
| ts |
+-------------------------------+
| 2024-02-29 12:34:56.123456000 |
+-------------------------------+
Из TIMESTAMP_NS и VARIANT
Приведение значения TIMESTAMP_NS к тому же типу сохраняет его в точности. Для совместимых строковых и числовых значений, дат и временных меток, хранящихся в VARIANT, применяется соответствующее правило выше. Временные метки с часовым поясом преобразуются в текущий часовой пояс сеанса; временные метки без часового пояса сохраняют свои календарные поля. Несовместимое содержимое VARIANT приводит к возврату NULL или ошибке в зависимости от режима приведения.
Связанные преобразования
При преобразовании TIMESTAMP_NS в DATETIME(p) или TIMESTAMPTZ(p) дробная часть округляется до целевой точности. Например, преобразование 2024-02-29 12:34:56.123456789 к точности 6 даёт 2024-02-29 12:34:56.123457.
Когда значения TIMESTAMP_NS и DATETIME объединяются в сравнениях, соединениях, CASE, COALESCE или операциях над множествами, Doris использует TIMESTAMP_NS как общий тип, если это позволяет сохранить значения в точности.
Обработка ошибок
| Ситуация | enable_strict_cast = true | enable_strict_cast = false | TRY_CAST |
|---|---|---|---|
| Недопустимый формат или некорректное календарное значение | Ошибка | NULL | NULL |
Значение вне диапазона TIMESTAMP_NS | Ошибка | NULL | NULL |
Исходное значение равно NULL | NULL | NULL | NULL |
| Неподдерживаемая пара исходного и целевого типов | Ошибка на этапе анализа | Ошибка на этапе анализа | Ошибка на этапе анализа |
Для строковых значений enable_strict_cast выбирает соответствующие строгие или нестрогие правила разбора DATETIME и управляет обработкой ошибок преобразования. Для числовых значений он меняет только обработку ошибок; сопоставление полей числового значения одинаково в обоих режимах.
Примеры
Преобразуйте строки с наносекундной точностью и посмотрите на результат округления:
SELECT
CAST('2024-02-29 12:34:56.123456' AS TIMESTAMP_NS) AS padded,
CAST('2024-02-29 12:34:56.1234567895' AS TIMESTAMP_NS) AS rounded;
+-------------------------------+-------------------------------+
| padded | rounded |
+-------------------------------+-------------------------------+
| 2024-02-29 12:34:56.123456000 | 2024-02-29 12:34:56.123456790 |
+-------------------------------+-------------------------------+
Преобразуйте числовое представление даты и времени:
SELECT CAST(CAST(20240229123456.1234567895 AS DECIMAL(24, 10)) AS TIMESTAMP_NS) AS ts;
+-------------------------------+
| ts |
+-------------------------------+
| 2024-02-29 12:34:56.123456790 |
+-------------------------------+
В нестрогом режиме для недопустимых значений и значений вне диапазона возвращается NULL:
SET enable_strict_cast = false;
SELECT
CAST('2024-02-30 00:00:00' AS TIMESTAMP_NS) AS invalid_date,
CAST('2262-04-11 23:47:16.8547758075' AS TIMESTAMP_NS) AS overflow;
+--------------+----------+
| invalid_date | overflow |
+--------------+----------+
| NULL | NULL |
+--------------+----------+