Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / plperl (pack unpack и кодировка) / 7 сообщений из 7, страница 1 из 1
09.12.2014, 10:41:50
    #38828677
inforse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
Доброе утро!!

Столкнулся с проблемой написания функций на plperl. Точнее даже с не написанием, а возможно с кодировкой.

Суть проблемы. Есть функция, которая запоковывает в двоичный вид по маске определенную последовательность переменных (float float int shortint). И соответственно записывает в базу. Ну и в обратную сторону unpack, зеркально.

Вот функция на сервере версии
Код: plsql
1.
"PostgreSQL 8.4.0 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1astra4.se1) 4.3.2, 64-bit"



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE OR REPLACE FUNCTION nku.sp_testsss3()
  RETURNS bytea AS
$BODY$
	my $val = 14.1234567;
	my $timer = 54.489748656;
	my $nka = 725564;
	my $nip = 14;
	$record = pack 'd1 d1 i1 s1', $val, $timer, $nka, $nip;  
	#$query1 = "insert into nku.table(val, timer, nka, nip) values($val, $timer, $nka, $nip);";
	#$rv = spi_exec_query($query1);
	
	
	#$_SHARED{my_plan} = spi_prepare('update nku.table set bytealen = $1;','BYTEA');
	#$rv = spi_exec_prepared($_SHARED{my_plan},$record); 
	($val, $timer, $nka, $nip) = unpack('d d i s',$record);

return $record;

$BODY$
  LANGUAGE plperlu VOLATILE
  COST 100;
ALTER FUNCTION nku.sp_testsss3()
  OWNER TO postgres;



Она работает, добавляет в базу, возвращает bytea. Все как говориться без проблем. unpack так же нормально распаковывает, и возвращает в первозданном виде.

Проверил, работает, обрадовался, перенес на другой сервер функцию. И..
Таже самая функция начала сыпаться с ошибками:
Код: plsql
1.
неверная последовательность байт для кодировки "UTF8": 0xb5



Версия сервера:
Код: plsql
1.
"PostgreSQL 9.1.4 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.1-2) 4.7.1, 64-bit"



Дальше начал копать в сторону кодировок. Кодировки серверов одинаковые:
Код: plsql
1.
2.
       LC_COLLATE = 'ru_RU.CP1251'
       LC_CTYPE = 'ru_RU.CP1251'



Ну думаю может из-за новой версии надо явно указывать что то. Докапался до этого:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE OR REPLACE FUNCTION nku.sp_test_9992()
  RETURNS bytea AS
$BODY$
	use Encode qw(encode decode is_utf8);
	
	my $val = 14.1234567;
	my $timer = 54.489748656;
	my $nka = 725564;
	my $nip = 14;
		
	#my $record = pack 'd1 d1 s1 s1', $val, $timer, $nka, $nip;  
	#my $record = pack 'd1d1',$val,$timer; # работает!!!!

	my $record = pack 'd1 d1 i1 s1 @19', $val, $timer, $nka ,$nip;
	
	my $str = decode('cp1251', $record);
	($val, $timer, $nka, $nip) = unpack('d d i s',$str);

	#$query1 = "insert into nku.table(val,timer,nka,nip) values($val, $timer, $nka, $nip);";
	#$rv = spi_exec_query($query1);
	
	$_SHARED{my_plan} = spi_prepare('update nku.table set bytealen = $1;','BYTEA');
	$rv = spi_exec_prepared($_SHARED{my_plan},$str); 

return $str;

$BODY$
  LANGUAGE plperlu VOLATILE
  COST 100;
ALTER FUNCTION nku.sp_test_9992()
  OWNER TO postgres;



Но то что я подогнал, всеравно работает через пень колоду. Во первых в базу не вставляется, хотя выводит такой же результат как и на другом сервере ошибка идентичная при вставке:
Код: plsql
1.
ОШИБКА:  неверная последовательность байт для кодировки "UTF8": 0xeef8e8


опытным путем выяснил, что она конкретно из-за inserta выскакивает.

Во вторых pack как мне кажется не совсем правильный получился. Без танцев с бубном он не совсем хорошо работает.

В третьих unpack возвращает float вроде бы нормально но с потерей точности, всепоследющие цифры заполняет 9ми. Инты вообще не те, послейдний инт просто пустой.

Уважаемые знатоки. Не подскажете в чем может быть дело? Что изменилось в perl при переходе на 9ую версию постгрес? Что еще можно предпринять? Может кто подскажет синтаксис pack правильный. Вроде почитал, вроде все так сделал.

Как мне кажется дело в пустых символах, их как то надо заполнять, что бы точность не тирялась, и обратно возращались инты нормально. Или я не прав? Если увеличить цифру до 20 после собаки, то сразу выкидывает ошибка:
Код: plsql
1.
ОШИБКА:  неверная последовательность байт для кодировки "UTF8": 0x00


а при update:
Код: plsql
1.
ОШИБКА:  неверная последовательность байт для кодировки "UTF8": 0xede5e2



Но на прошлой версии без танцев все чики пуки =(
...
Рейтинг: 0 / 0
09.12.2014, 11:37:06
    #38828732
SmeL_md
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
Код: sql
1.
select current_setting('bytea_output')


попробуйте выполнить, не помню когда появилось bytea_output и hex по умолчанию
...
Рейтинг: 0 / 0
09.12.2014, 11:53:54
    #38828752
inforse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
SmeL_md,

на 9е:
Код: plsql
1.
"escape"



На 8.4 : "не распознанный параметр конфигурации"
...
Рейтинг: 0 / 0
09.12.2014, 14:53:49
    #38829049
inforse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
И все равно на 8.4 работает, на 9.1 не хочет((( Что ж такое.
После этой команды тож не изменилось ничего.
Код: plsql
1.
select current_setting('bytea_output')
...
Рейтинг: 0 / 0
09.12.2014, 23:37:37
    #38829665
Гость_0
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
...
Рейтинг: 0 / 0
11.12.2014, 16:37:18
    #38831636
inforse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
Гость_0,

Большое спасибо!!! Получилось нормально записать в базу)
...
Рейтинг: 0 / 0
16.12.2014, 11:47:49
    #38834861
inforse
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
plperl (pack unpack и кодировка)
Гость_0inforse,

http://www.postgresql.org/docs/9.1/static/plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS

encode_bytea(string)

Аналог для 8.4 существует? В 9-ку записалось нормально. А вот в 8.4 отказывается.

Код: powershell
1.
ОШИБКА:  error from Perl function "sp_test_read_all": неверный входной синтаксис для типа bytea at line 107.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / plperl (pack unpack и кодировка) / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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