вызов libpq дает UTF8: 0xe6 0x62 0x40

Я бывший инженер Digital Equipment Co (работал с Rdb/RTR/VMS на множестве очень больших систем и имею 10-летний опыт обработки распределенных систем в C-летах... но довольно давно).

Я ищу совета о том, что эта ошибка означает на практике, поскольку я занимаюсь диагностикой проблемы. Вот сообщение об ошибке Postgres

ERROR: invalid byte sequence for encoding "UTF8": 0xe6 0x62 0x40

Среда MAC Maveriks XOS, GNU C, Xcode, Postgres 9.3. (серверная сторона) с libpq

Я новичок в Postgres, но написал набор запросов C, чтобы извлечь все метаданные о пользовательских таблицах, столбцах, типах данных, длинах, порядковых позициях из Postgres, сохранить их в памяти в моем собственном каталоге и создать все простые пользовательские таблицы запросы динамически.

Этот запрос прошел вызов подготовки запроса.

Написав в обороне, я дважды проверил на наличие ошибок:

 if ((res = PQprepare(db, statement_name, insert_query, data->nParam, NULL)) == NULL)
     Dbms_Crash(db, NULL, "Dbms_insert() PQprepare returned NULL");

 if (PQresultStatus(res) != PGRES_COMMAND_OK)
     Dbms_Crash(db, res, "Dbms_insert() Failed");

 PQclear(res);

Вот мой дамп синтаксического анализатора моего сгенерированного запроса

insert_query:
INSERT INTO image_metadata (latitude,longitude,altitude,filename,utc_datetime)
VALUES ($1::double precision,$2::double precision,$3::double precision,$4::character varying,$5::timestamp without time zone);

Вот вызов, который терпит неудачу:

    res = PQexecPrepared(db,
                         statement_name,
                         data->nParam,
                         (const char* const *)data->ptParam[i],
                         data->pdlParam[i],
                         data->pParamfmt,
                         PGFORMAT_STRING);

ERROR: invalid byte sequence for encoding "UTF8": 0xe6 0x62 0x40

Я преодолел проблему с форматом даты в utc_datetime, где Postgres ожидает YYYY-MM-DD HH:MM:SS для универсальных скоординированных дат времени OSI, и я вводил его YYYY:MM:DD, и эта ошибка стала следующей. (Таким образом, моя косвенность массива, индексация и т. Д. Работают, поскольку Postgres печатает дату нарушения пятого параметра)

Я пишу очевидный дампер параметров, чтобы посмотреть, что я ему подаю, но я знаю, что он получил правильную дату, когда ошибка исчезла, когда я исправил формат даты.

Является ли сообщение UTF8 исходящим из строки имени файла или из одного из полей двойной точности?
Является ли передача двоичного файла плохой идеей и просто передача строк может вызвать меньше проблем?

Моя схема в конечном итоге будет иметь, скажем, 30 таблиц, и этот тип ошибки в выравнивании памяти на стороне сервера очень беспокоит. Моя цель - написать нулевой код SQL.


person user3624412    schedule 10.05.2014    source источник
comment
Какую строку вы передали в качестве параметра filename?   -  person klin    schedule 11.05.2014
comment
Итак, мне только что удалось загрузить 15 строк, ошибка UTF8 прерывистая. Имя файла правильное, как и временная метка, когда я смотрю из PGAdmin. Двойная точность - это дерьмо для всех трех значений высоты, долготы и широты. Так что поищу там. Мой дампер придумал строку параметра дампа bms_Diagnostics для строки: [0] Имя столбца [широта] длина параметра: 8 Имя столбца [долгота] длина параметра: 8 Имя столбца [высота] длина параметра: 8 Имя столбца [имя файла] длина параметра: 94 Имя столбца [utc_datetime] длина параметра: 19   -  person user3624412    schedule 11.05.2014
comment
Что такое определение структуры данных data->ptParam[] должно быть массивом указателей на указатели на строку, что выглядит неуклюже. Может быть, опустить индексацию [i]?   -  person wildplasser    schedule 11.05.2014
comment
Это символ ***, так как я обрабатываю наборы, а не строки и не элементы кортежа. Наборы являются фундаментальной абстракцией реляционных баз данных. Какой позор, что люди, занимающиеся языком, правят днем, а мы так зацикливаемся на синтаксисе, а не на семантике. т. е. большая часть кода, который я пишу, — это обмен данными... Exif с Core Foundations, с C на Postgress. Я родом из того времени, когда Джим Грей и Фил Бернстайн изобретали физическую производительность OLTP в DEC. В фирме, где я изучал разработку программного обеспечения, мы написали свой собственный компилятор SQL из lex и yacc в язык двоичных запросов BLR ... Rdb не имел SQL.   -  person user3624412    schedule 12.05.2014
comment
В дополнение к комментарию наборов, если вы сделаете их самоописываемыми, инкапсулированными и отображенными в непрерывную виртуальную память (мы написали диспетчер кучи друзей ... Кнут, который идеально подходит для наборов), вы можете отправить их в общем виде как один вещь из СУБД по сети в приложение и наоборот как одна вещь (по имени)! Перевод базы данных/языка/сети становится тривиальным и общим. Он отлично подходит для управления финансовыми рынками (заказы, сделки и котировки). Сила семантики... по сравнению с искусственной сложностью языков... xml и т. д. Все это появилось, когда умерли объектно-ориентированные базы данных.   -  person user3624412    schedule 12.05.2014


Ответы (1)


В вашей функции PQprepare() последний параметр равен NULL. Это означает, что все параметры запроса представлены в текстовом формате. Если вы передали некоторые из них как двоичные, вы отправили просто мусор. Мой совет — использовать текстовый формат для параметров в подготовленных запросах.

person klin    schedule 11.05.2014
comment
Спасибо так и сделаю. - person user3624412; 11.05.2014
comment
Исправление выполнено, еще раз спасибо. Я заметил структуры SQLCA и SQLDA в Postgres в системных таблицах, но они не отображаются интерфейсом libpq. Если к этому есть уровень доступа, вы можете принудительно выравнивать память и перетаскивать шаблоны структуры C по непрерывным блокам памяти и решать множество проблем как в определении данных, так и в отображении. Также сократить выделение памяти с гиззионов до одного или двух вызовов. Я использовал это раньше, чтобы сгенерировать 70% схем уровня доступа к данным с сотнями таблиц без несоответствия импеданса. Думаю, я мог бы посмотреть исходный код Postgres. - person user3624412; 11.05.2014
comment
Пожалуйста, сделай. Если вы видите возможности для улучшения в определенных областях и можете предложить подробные предложения, пожалуйста, сообщите об этом pgsql-hackers. Патчи еще лучше, но не тратьте кучу времени на патч, прежде чем поднять его для обсуждения; иногда что-то не делается определенным образом по какой-то причине. Кроме того, я предлагаю вам проверить libpqtypes (который я бы хотел внести в libpq), это может упростить задачу. - person Craig Ringer; 11.05.2014