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

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

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


:)
...
Рейтинг: 0 / 0
09.02.2022, 22:58
    #40132961
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
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
10.02.2022, 09:39
    #40133018
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
Maxim Boguk

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


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

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
10.02.2022, 14:23
    #40133163
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
Maxim Boguk
А функция ascii ( text ) → integer как раз принимает текст... и обрезает trailing он же единственный пробел в char(1) типе.
А почему функция ascii(), призванная давать позицию символа в таблице ASCII кодировки из 128 элементов, принимает параметр типа "text", вместо того, чтобы принимать параметр типа "CHAR(1)"?
...
Рейтинг: 0 / 0
10.02.2022, 15:37
    #40133220
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
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
10.02.2022, 15:43
    #40133224
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
Maxim Boguk, забавно!...
Но не понятно - какое отношение многобайтные последовательности кодировки UNICODE имеют к ASCII? Почему нельзя было сделать их конвертацию в что-то типа CHAR(1) COLLATE "ASCII" и использовать это в качестве параметра функции ascii(), а для UNICODE последовательностей использовать иное имя функции, что было бы разумней и корректней?
...
Рейтинг: 0 / 0
10.02.2022, 16:02
    #40133233
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
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
10.02.2022, 16:16
    #40133245
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Подскажите, с каких пор печатный ASCII символ 'SPACE' стал непечатным 'NUL'?
Проблемы с обрезанием CHAR и потерей пробелов есть и в Oracle (сам с таким боролся в Oracle Forms).

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

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

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

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


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

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


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