Преобразование типа
Оператор преобразования типа создает свойство, которое преобразует объект одного встроенного класса к объекту другого встроенного класса. Результат принадлежит целевому встроенному классу. Объект пользовательского класса преобразуется к числовому или строковому классу — результатом является его внутренний идентификатор, целое число либо его текстовая запись, — а к логическому классу — в TRUE. Преобразования к пользовательскому классу нет: объект по идентификатору находят группировкой (см. корректность операции), а значение, суженное до пользовательского класса, даёт классификация.
Поддерживаемые преобразования
Какие преобразования имеют смысл, зависит от семейств встроенных классов, к которым принадлежат исходный и целевой классы:
- В пределах семейства чисел значение сохраняется настолько, насколько это допускает целевой класс. Если значение не помещается в целевой класс, результатом является
NULL. При явном преобразовании к целочисленному классу в PostgreSQL значение округляется до ближайшего целого. Если значение находится ровно посередине между двумя целыми, дляNUMERICвыбирается целое дальше от нуля: 2,5 преобразуется в 3, а −2,5 — в −3. ДляDOUBLEобычно выбирается чётное целое: 2,5 преобразуется в 2. Чтобы отбросить дробную часть значения классаNUMERIC, используют свойствоtrunc[…, …]системного модуляUtilsсо вторым аргументом 0. Свойствоfloor[…]округляет вниз, что для отрицательных дробных значений отличается от усечения к нулю. - Между числами и строками значение преобразуется между числовой и текстовой формами. Если исходную строку нельзя прочитать как число целевого класса, результатом является
NULL. Строка с дробной частью к целочисленному классу округляется так же, какNUMERIC. - Строки также преобразуются в классы
JSON,JSONTEXT,XMLиHTMLи обратно. - В пределах семейства дат и времени
DATETIMEпреобразуется в свою дату (DATE) и своё время (TIME), аDATE— вDATETIMEна полночь этой даты. При преобразованииZDATETIMEвDATE,TIMEилиDATETIMEвозвращаются дата, время или дата и время этого момента в часовом поясе текущей локали. При обратном преобразованииDATETIMEтрактуется как местные дата и время в том же поясе, аDATE— как полночь этой даты.TIMEнельзя преобразовать в остальные классы семейства, аDATE— вTIME: такое преобразование завершается ошибкой при выполнении запроса.
Строковые и файловые типы
Строковые типы можно преобразовывать в файловые human-readable типы (CSVFILE, XMLFILE, JSONFILE, HTMLFILE и т.д.), и наоборот - файловые human-readable типы можно преобразовывать в строковые типы. Файл конкретного типа также можно преобразовать в файл динамического типа (FILE, NAMEDFILE) и обратно с сохранением содержимого файла. Файл динамического типа дополнительно несёт расширение, а NAMEDFILE — ещё и имя.
Файлы динамического типа (FILE, NAMEDFILE) преобразуются к строкам и обратно напрямую: содержимое файла читается как текст в кодировке UTF-8 (если оно не является корректным текстом UTF-8, результат — NULL), а строка записывается как содержимое файла с расширением dat (значение класса HTML — с расширением html). Чтобы получить другое расширение, преобразуйте строку сначала к файлу конкретного типа — к примеру, к CSVFILE, а уже потом к FILE: у результирующего файла будет расширение csv
Неявные преобразования
Помимо явного оператора преобразования, платформа в ряде случаев преобразует значение к другому классу неявно, без написанного разработчиком преобразования:
- Когда объединяются значения разных, но совместимых классов — при сложении или вычитании (см. арифметические операторы), в операторах выбора или в операторах экстремума — каждое значение преобразуется к их общему предку, который становится классом результата. В частности, так расширяются числовые классы (
INTEGER, объединённый сNUMERIC, становится этимNUMERIC). - При объединении строк операнд, не являющийся строкой, преобразуется к строке.
- Когда значение записывается в свойство другого, но совместимого класса, оно преобразуется к этому классу. Строка, присваиваемая свойству без параметров или для одного фиксированного набора значений аргументов, может неявно обрезаться до длины более короткого целевого строкового класса. Изменение над множеством объектов такого обрезания не гарантирует: слишком длинная строка может вызвать ошибку базы данных уже при присваивании, в том числе хранимому свойству, а если присваивание хранимому свойству прошло без ошибки — при применении изменений. Чтобы ограничить длину строки явно, её преобразуют к целевому строковому классу.
- Файл конкретного типа преобразуется к файлу динамического типа (
FILE,NAMEDFILE) неявно — например, при импорте данных без указания формата или при взаимодействии с внешней системой. Результирующее расширение определяется так же, как при явном преобразовании.
Язык
Для реализации преобразования используется оператор преобразования типа.
Примеры
itemCount = DATA INTEGER (Store);
itemCountToString(s) = BPSTRING[10](itemCount(s));
barcode = DATA STRING[15] (Item);
longBarcode(Item i) = LONG(barcode(i));