powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
15 сообщений из 15, страница 1 из 1
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40132898
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Следующая строка выводит запись со integer значением = 0.
Код: plsql
1.
SELECT ascii( SUBSTRING( '123 5678'::CHAR(8), 4 )::CHAR );

(кодировка базы UTF-8)
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40132903
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,

Код: sql
1.
select char_length(SUBSTRING( '123 5678'::CHAR(8), 4 )::CHAR)


:)
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40132961
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Следующая строка выводит запись со integer значением = 0.
Код: plsql
1.
SELECT ascii( SUBSTRING( '123 5678'::CHAR(8), 4 )::CHAR );

(кодировка базы UTF-8)


потому что ' '::char='';
т.е при приведении к char(N) типу оконечные пробелы удаляются по стандарту
и далее вы делаете acsii('') - который выдаёт 0

Ну или подробнее
Код: sql
1.
2.
3.
4.
select  '|'||(' 5678'::text)::char||'|';
 ?column? 
----------
 ||



сначала ' 5678' обрезаем до 1го символа ' ' а потом смотрим что это пробел и по правилам работы char() типов его превращаем в пустую строку.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133018
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk

потому что ' '::char='';
т.е при приведении к char(N) типу оконечные пробелы удаляются по стандарту
и далее вы делаете acsii('') - который выдаёт 0
По какому стандарту? По стандарту ANSI SQL'92, SQL'95 или по "стандарту" PostgreSQL? :)
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133023
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё вопрос - можно ли переменной типа VARCHAR указать кодировку хранения (CHARACTER SET)?
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133156
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Maxim Boguk

потому что ' '::char='';
т.е при приведении к char(N) типу оконечные пробелы удаляются по стандарту
и далее вы делаете acsii('') - который выдаёт 0
По какому стандарту? По стандарту ANSI SQL'92, SQL'95 или по "стандарту" PostgreSQL? :)


По итогам разбора как оно работает выяснилось что всё несколько сложнее...
' '::char(1) - вполне валидная штука...

НО далее срабатывает следующий механизм из
https://www.postgresql.org/docs/14/functions-string.html
" Except where noted, these functions and operators are declared to accept and return type text. They will interchangeably accept character varying arguments. Values of type character will be converted to text before the function or operator is applied, resulting in stripping any trailing spaces in the character value."

А функция ascii ( text ) → integer как раз принимает текст... и обрезает trailing он же единственный пробел в char(1) типе.

Рекомендация - char(N) не использовать вообще никогда и нигде, это наследие 1970 и ранее годов с текстовыми терминалами.


PS: а ещё есть тонкая разница между типом char и типом "char", но это уже внутренние потроха базы хотя если сильно постараться можно и на них попасть https://www.postgresql.org/docs/14/datatype-character.html#DATATYPE-CHARACTER-SPECIAL-TABLE
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
mboguk=# select 'Ы'::char;
 bpchar 
--------
 Ы
(1 row)

mboguk=# select 'Ы'::"char";
 char 
------
 
(1 row)



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133159
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Ещё вопрос - можно ли переменной типа VARCHAR указать кодировку хранения (CHARACTER SET)?


Нет... ENCODING задаётся при создании базы и не может быть разный в разных полях базы.
Что в общем не мешает произвольные бинарные данные в bytea полях хранить если очень надо.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133163
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk
А функция ascii ( text ) → integer как раз принимает текст... и обрезает trailing он же единственный пробел в char(1) типе.
А почему функция ascii(), призванная давать позицию символа в таблице ASCII кодировки из 128 элементов, принимает параметр типа "text", вместо того, чтобы принимать параметр типа "CHAR(1)"?
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133220
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Maxim Boguk
А функция ascii ( text ) → integer как раз принимает текст... и обрезает trailing он же единственный пробел в char(1) типе.
А почему функция ascii(), призванная давать позицию символа в таблице ASCII кодировки из 128 элементов, принимает параметр типа "text", вместо того, чтобы принимать параметр типа "CHAR(1)"?


Потому что она должна делать только то что в документации описано.
А описано там следующее:

ascii ( text ) → integer
Returns the numeric code of the first character of the argument. In UTF8 encoding, returns the Unicode code point of the character. In other multibyte encodings, the argument must be an ASCII character.
ascii('x') → 120

Если такой вариант вас не устраивает можете свою версию ascii с нужным вам поведением.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133224
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk, забавно!...
Но не понятно - какое отношение многобайтные последовательности кодировки UNICODE имеют к ASCII? Почему нельзя было сделать их конвертацию в что-то типа CHAR(1) COLLATE "ASCII" и использовать это в качестве параметра функции ascii(), а для UNICODE последовательностей использовать иное имя функции, что было бы разумней и корректней?
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133233
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Почему нельзя было сделать их конвертацию в что-то типа CHAR(1) COLLATE "ASCII" и использовать это в качестве параметра функции ascii(), а для UNICODE последовательностей использовать иное имя функции, что было бы разумней и корректней?

Да судя по тому, что расположена реализация функции в весьма намекающем ./src/backend/utils/adt/oracle_compat.c - я предполагаю, что о разумности или корректности речи вовсе не было. А делали с вполне конкретной целью уже заданных извне сигнатур функций, как указано в коммите , "Implement ascii(text), ichar(int4), repeat(text,int4) to help support the ODBC driver". При том свыше 20 лет назад и с тех пор по сути это больше не трогали.
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133245
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблемы с обрезанием CHAR и потерей пробелов есть и в Oracle (сам с таким боролся в Oracle Forms).

Тут поддержу Maxim Boguk, если явно используются "устаревшие" ANSI типы данных, то нужно быть готовым нарваться на грабли.

Но не понятно - какое отношение многобайтные последовательности кодировки UNICODE имеют к ASCII? Почему нельзя было сделать их конвертацию в что-то типа CHAR(1) COLLATE "ASCII" и использовать это в качестве параметра функции ascii(), а для UNICODE последовательностей использовать иное имя функции, что было бы разумней и корректней?

Я как-то ответ Максима понял по другому. Проблема НЕ в Unicode, а в Char. Точнее в преобразовании Char -> Text, при которой удаляются концевые пробелы (а если вся строка один большой пробел, то все пробелы).

Работайте в Text, и проблем не будет.
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133387
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Я как-то ответ Максима понял по другому. Проблема НЕ в Unicode, а в Char. Точнее в преобразовании Char -> Text, при которой удаляются концевые пробелы (а если вся строка один большой пробел, то все пробелы).
Проблема в том, что в качестве параметра для функции ascii() используется text, а преобразование к нему из CHAR приводит к отбрасыванию концевых пробелов.
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133541
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Leonid Kudryavtsev
Я как-то ответ Максима понял по другому. Проблема НЕ в Unicode, а в Char. Точнее в преобразовании Char -> Text, при которой удаляются концевые пробелы (а если вся строка один большой пробел, то все пробелы).
Проблема в том, что в качестве параметра для функции ascii() используется text, а преобразование к нему из CHAR приводит к отбрасыванию концевых пробелов.


При этом я согласен с тем что по сути это поведение таки является багом... но я очень сомневаюсь что это будет кем то и когда либо исправлено (вылечить можно создав отдельную копию ascii фунции принимающую char тип на входе).
Место всем этим oracle compat функциям - в отдельном расширении а не в ядре базы.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
    #40133912
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо за разъяснения!
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]