|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
Здравствуйте Подскажите, пожалуйста. Есть PG10, хочу создать с-функцию для работы с массивом Однако возникают проблемы для любых функций, в которых параметры не число (строка, массив) Вот мои действия: Создаю с-функию #include "postgres.h" #include "fmgr.h" #include <winsock.h> #include "string.h" #include "utils/array.h" // подключаем заголовочный файл для работы с массивами #include "catalog/pg_type.h" // INT4OID PG_MODULE_MAGIC; Datum array_add(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(array_add); Datum array_add(PG_FUNCTION_ARGS) { ArrayType *array1; text *res; array1 = PG_GETARG_ARRAYTYPE_P(0); res=(text*)"тест"; PG_RETURN_TEXT_P(res); } Компилирую её SET d1=C:/PROGRA~1/POSTGR~1/10/include C:\mingw-w64\mingw64\bin\gcc -I%d1%/server/port/win32 -I%d1%/server -I%d1% -fpic -c vlads.c -DHAVE_LONG_INT_64 C:\mingw-w64\mingw64\bin\gcc -shared -LC:/PROGRA~1/POSTGR~1/10/lib -o vlads.so vlads.o -l postgres Запускаю функцию: CREATE OR REPLACE FUNCTION public.array_add ( t text [] ) RETURNS text AS 'vlads.so', 'array_add' LANGUAGE 'c' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER PARALLEL UNSAFE COST 1; SELECT array_add(array['1','2']::text[]); На селекте возникает ошибка: server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. Где копать В чём проблема? Убираю строку array1 = PG_GETARG_ARRAYTYPE_P(0); и всё сразу работает. Пробую менять - вместо массива передавать текст (изменяя соответственно функцию с и в PG) - Такая же ерунда. Если менять алгоритм - параметры числа - такой вариант проходит на ура (пробовал функцию суммирования двух параметров) В чём может быть проблема? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.06.2020, 04:55 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko В чём может быть проблема? Сишный код выглядит слишком самоуверенно. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.06.2020, 05:35 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
crutchmaster, я пока убрал максимально из него, хочу понять в чём причина, а уж потом возвращать весь код обратно ... |
|||
:
Нравится:
Не нравится:
|
|||
04.06.2020, 14:14 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
Код: plaintext 1.
Я не эксперт в си, но даже мне от этого не по себе. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2020, 04:06 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko, res=(text*)"тест"; да, строчка от балды написана. с текстом внутри постгрес надо работать через VARDATA - структуру специального вида для хранения текста. Вам ее надо подготовить сначала (выделить память через palloc как минимум), чтобы потом вернуть указатель на эту память через GET_RETURN_TEXT_P см. примеры здесь https://www.postgresql.org/docs/12/xfunc-c.html ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2020, 08:55 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
grgdvo, я подозреваю, что проблема не в алгоритме. Взял пример с Вашей ссылки. Из примера so файл компилируется на ура. #include "postgres.h" #include <string.h> #include "fmgr.h" #include "utils/geo_decls.h" PG_MODULE_MAGIC; /* by value */ PG_FUNCTION_INFO_V1(add_one); Datum add_one(PG_FUNCTION_ARGS) { int32 arg = PG_GETARG_INT32(0); PG_RETURN_INT32(arg + 1); } /* by reference, fixed length */ PG_FUNCTION_INFO_V1(add_one_float8); Datum add_one_float8(PG_FUNCTION_ARGS) { /* The macros for FLOAT8 hide its pass-by-reference nature. */ float8 arg = PG_GETARG_FLOAT8(0); PG_RETURN_FLOAT8(arg + 1.0); } PG_FUNCTION_INFO_V1(makepoint); Datum makepoint(PG_FUNCTION_ARGS) { /* Here, the pass-by-reference nature of Point is not hidden. */ Point *pointx = PG_GETARG_POINT_P(0); Point *pointy = PG_GETARG_POINT_P(1); Point *new_point = (Point *) palloc(sizeof(Point)); new_point->x = pointx->x; new_point->y = pointy->y; PG_RETURN_POINT_P(new_point); } /* by reference, variable length */ PG_FUNCTION_INFO_V1(copytext); Datum copytext(PG_FUNCTION_ARGS) { text *t = PG_GETARG_TEXT_PP(0); /* * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the * VARHDRSZ or VARHDRSZ_SHORT of its header. Construct the copy with a * full-length header. */ text *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ); SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ); /* * VARDATA is a pointer to the data region of the new struct. The source * could be a short datum, so retrieve its data through VARDATA_ANY. */ memcpy((void *) VARDATA(new_t), /* destination */ (void *) VARDATA_ANY(t), /* source */ VARSIZE_ANY_EXHDR(t)); /* how many bytes */ PG_RETURN_TEXT_P(new_t); } PG_FUNCTION_INFO_V1(concat_text); Datum concat_text(PG_FUNCTION_ARGS) { text *arg1 = PG_GETARG_TEXT_PP(0); text *arg2 = PG_GETARG_TEXT_PP(1); int32 arg1_size = VARSIZE_ANY_EXHDR(arg1); int32 arg2_size = VARSIZE_ANY_EXHDR(arg2); int32 new_text_size = arg1_size + arg2_size + VARHDRSZ; text *new_text = (text *) palloc(new_text_size); SET_VARSIZE(new_text, new_text_size); memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size); memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size); PG_RETURN_TEXT_P(new_text); } Для примера беру функцию concat_text. --Функция создается успешно CREATE FUNCTION d.concat_text(text,text) RETURNS text AS 'C:/PROGRA~1/POSTGR~1/10/lib/vlads1.so', 'concat_text' LANGUAGE C STRICT; --А вот тут server closed the connection unexpectedly -- This probably means the server terminated abnormally -- before or while processing the request. SELECT d.concat_text('1'::text,'2'::text); Аналогично и с функциями из примера add_one(double precision) copytext(text) При этом функция с интерегром: CREATE FUNCTION add_one(integer) RETURNS integer AS 'DIRECTORY/funcs', 'add_one' LANGUAGE C STRICT; выполняется на ура и возвращает то что нужно. С-компилятор minigw-x64 Может быть что-то не так с ключами или настройками? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.06.2020, 18:16 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko, Под win не возможности проверить, под lin - работает, как в примере. Что-то со сборкой у вас видимо. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2020, 04:49 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
Вы вот кстати уверены, что -DHAVE_LONG_INT_64 это надо. по идее правильный конфиг postgres.h вам скажет как должно быть. Я могу конечно ошибиться, но Datum - это поинтер на непомню какой тип, как бы не unsigned long int, который может быть 32 или 64 бита в зависимости от вашей системы. может в этом у вас какой-то скрытый подвох ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2020, 13:14 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
grgdvo, Поскажите тогда, try-catch дополнение, чтобы моя функция хоть как-то сообщала, что с ней не так. Может тогда пойму в чём проблема, ОС у меня 10x32, PG 10x32, компилятор с официального сайта. Может, конечно, надо компилятор сменить или компьютер святой водой побрызгать. Но это всё танцы с бубном. PS А подскажите пример С функции, которая могла бы сама запустить SELECT и работала с результатом запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2020, 13:35 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko Может, конечно, надо компилятор сменить или компьютер святой водой побрызгать. Но это всё танцы с бубном. Уберите сначала -DHAVE_LONG_INT_64 из компиляции. Насколько я знаю mingw64 придерживается модель данных LLP64 (собственно как и msvc на windows), он трактует простой long как 32-битное значение. И таким дефайном вы вносите явное противоречие межде тем, что поддерживает компилятор, и тем, что будет "настроено" в инклудах постгреса. Демон в деталях. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.06.2020, 18:16 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
grgdvo, Если убрать, тогда возникают проблемы: C:/PROGRA~1/POSTGR~1/10/include/server/c.h:364:2: error: #error must have a working 64-bit integer datatype #error must have a working 64-bit integer datatype ^~~~~ C:/PROGRA~1/POSTGR~1/10/include/server/c.h:1019:2: error: unknown type name 'int64' int64 force_align_i64; ^~~~~ C:/PROGRA~1/POSTGR~1/10/include/server/c.h:1027:2: error: unknown type name 'int64' int64 force_align_i64; ^~~~~ In file included from vlads.c:1: C:/PROGRA~1/POSTGR~1/10/include/server/postgres.h:627:28: error: unknown type name 'int64'; did you mean 'int32'? extern Datum Int64GetDatum(int64 X); Эту проблему я изучал. https://sourceforge.net/p/mingw/mailman/mingw-users/thread/4EA17E67.4080804@users.sourceforge.net]здесь предложили использовать это флаг ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2020, 04:26 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko, Тогда подробно рассказывайте, что у вас за сборка. Что за версия postgresql (сделать select version()), откуда ее качали, как устанавливали (или сами собирали?) Вы написали, что у вас ОС 32-бита и PG 32-бита, тогда почему надо LONG_INT_64=1 ??? Что-то во всем этом не так. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2020, 08:21 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
grgdvo, Может вот так надо было -DHAVE_LONG_LONG_INT_64 ??? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.06.2020, 10:55 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
grgdvo, не помогло -DHAVE_LONG_LONG_INT_64. Ставил как 32 битный PG, так и 64 битный Пробовал на двух разных машинах. PostgreSQL 10.13, compiled by Visual C++ build 1800, 64-bit На первой машине аналогичная версия PG только 32 бита Взято с официального сайта, не компилировал, брал стандартный дистрибутив. ОС win10x32проф на одной машине, win10x64корп на другой. Компилятор взят с сайта https://sourceforge.net/projects/mingw-w64/ https://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win32/Personal Builds/mingw-builds/installer/mingw-w64-install.exe version 8.1.0 Architecture x68_64 Treads posix Exception seh Build version 0 На x86 машине аналогично, только архитектура i686 и Exeption dwarf ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2020, 04:58 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
crutchmaster Код: plaintext 1.
Я не эксперт в си, но даже мне от этого не по себе. ну, во-первых, это красиво ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2020, 09:28 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko grgdvo, не помогло -DHAVE_LONG_LONG_INT_64. Ставил как 32 битный PG, так и 64 битный Пробовал на двух разных машинах. PostgreSQL 10.13, compiled by Visual C++ build 1800, 64-bit На первой машине аналогичная версия PG только 32 бита Взято с официального сайта, не компилировал, брал стандартный дистрибутив. ОС win10x32проф на одной машине, win10x64корп на другой. Компилятор взят с сайта https://sourceforge.net/projects/mingw-w64/ https://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win32/Personal Builds/mingw-builds/installer/mingw-w64-install.exe version 8.1.0 Architecture x68_64 Treads posix Exception seh Build version 0 На x86 машине аналогично, только архитектура i686 и Exeption dwarf Возможно, архитектура не подходит ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2020, 09:30 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
Ролг Хупин, так я оба варианта архитектуры выбирал ставил, не помогло, тем более, что компилируется же успешно. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2020, 14:14 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko grgdvo, не помогло -DHAVE_LONG_LONG_INT_64. ошибки или что?? мало информации по "не помогло" у других же работает. шансов, что в примере на сайте ошибка, практически 0. значит, что-то не так на вашей стороне. где-то вы ошибаетесь в компиляции и линковке. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.06.2020, 15:11 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
grgdvo, Всё отработало точно также. Компилируется без ошибок, функция из so файла подрубается в постгрисе без проблем, а когда делаешь селект в функцию, где параметры не числа а строки или массивы - точно такая же ошибка. Думаю, либо надо менять компилятор, либо поднимать линукс. Под виндой не получается, хотя делал на двух разных машинах ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2020, 05:11 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
pakko grgdvo, PostgreSQL 10.13, compiled by Visual C++ build 1800, 64-bit Компилятор взят с сайта https://sourceforge.net/projects/mingw-w64/ Эээээ... А где-нибудь обещается, что такая комбинация должна работать? У вас два очень разных компилятора - mingw и msvc. В документации по mingw пишут , что могут наблюдаться различные проблемы совместимости. Там про C++, но всевозможные выравнивания структур в памяти и несовместимость malloc/free - это и к простому C относится. Или, например, char имеет разный размер в mingw и msvc (я не проверял). Я подозреваю, что в случае компиляции с использованием visual studio и его тулкита у вас больше шансов на успех. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2020, 21:16 |
|
Проблема с С-функцией
|
|||
---|---|---|---|
#18+
maxkar, идея хороша Однако есть проблема в другом. Начинаю компилировать в вижуал студио 12 он не видит Ошибка 1 error C1083: Не удается открыть файл включение: winsock2.h: No such file or directory Поискал этот файл - вообще его нету на компьютере, только в minigw лежит. А для visual studio где его брать? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.06.2020, 06:25 |
|
|
start [/forum/topic.php?fid=53&msg=39966999&tid=1994653]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
35ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 156ms |
0 / 0 |