Перейти к содержимому
Последнее обновление

Приведение к типу 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.14522419151677-09-21 00:12:43.145224192
2262-04-11 23:47:16.85477580742262-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.

Целочисленное значениеРезультатПояснение
1232000-01-23 00:00:00.000000000Трёхзначное компактное представление даты.
202402292024-02-29 00:00:00.000000000Восьмизначное компактное представление даты.
202402291234562024-02-29 12:34:56.000000000Четырнадцатизначное компактное представление даты и времени.
16770921001243НедопустимоПолученное время ниже нижней границы.
22620412000000НедопустимоПолученное время выше верхней границы.

Из FLOAT​

Для FLOAT используется десятичное значение, представленное входным числом одинарной точности до приведения. Его ограниченного числа значащих цифр обычно недостаточно для 14-значного компактного представления даты и времени, поэтому большое входное значение может потерять цифры и стать недопустимым представлением даты и времени. Для больших компактных значений используйте DOUBLE или DECIMAL.

Входное выражение FLOATРезультат в строгом режимеРезультат в нестрогом режимеПояснение
CAST(123 AS FLOAT)2000-01-23 00:00:00.0000000002000-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-221677-09-22 00:00:00.000000000
2262-04-112262-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.1452251677-09-21 00:12:43.145225000
2024-02-29 12:34:56.1234562024-02-29 12:34:56.123456000
2262-04-11 23:47:16.8547752262-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.1234562025-04-29 12:34:56.123456000
500:00:00.0000002025-05-19 20:00:00.000000000
-128:00:00.0000002025-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 = trueenable_strict_cast = falseTRY_CAST
Недопустимый формат или некорректное календарное значениеОшибкаNULLNULL
Значение вне диапазона TIMESTAMP_NSОшибкаNULLNULL
Исходное значение равно NULLNULLNULLNULL
Неподдерживаемая пара исходного и целевого типовОшибка на этапе анализаОшибка на этапе анализаОшибка на этапе анализа

Для строковых значений 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 |
+--------------+----------+