Синтаксическая ошибка 201 при импорте в Informix

Я экспортировал базу данных из Informix 11.50 и хочу импортировать ее в Informix 14.10.

dbexport -ss -c -q iscala

Экспортированный сценарий SQL начинается со следующего:

{ DATABASE iscala  delimiter | }

EXECUTE PROCEDURE ifx_allow_newline ('t');

grant dba to "informix";
grant dba to "waspop";
grant connect to "jzl";


create distinct type 'informix'.vestnik as      decimal(4,0);

grant usage on type 'informix'.vestnik to 'public' as 'informix';

drop cast (decimal(4,0) as vestnik);
create explicit cast (decimal(4,0) as vestnik with 'informix'.date_vestnik);

CREATE FUNCTION "informix".date_vestnik(vestnik DATE) RETURNING vestnik WITH(NOT VARIANT);
RETURN ((CASE WHEN MONTH(vestnik)=12 AND DAY(vestnik)>12 THEN DAY(vestnik) ELSE MONTH(vestnik) END)
        *100+MOD(YEAR(vestnik),100))::NUMERIC(4,0)::vestnik;
END FUNCTION;


create explicit cast (vestnik as integer with 'informix'.vestnik_int);

CREATE FUNCTION "informix".vestnik_int(vestnik vestnik) RETURNING INT WITH(NOT VARIANT);
RETURN vestnik::NUMERIC(4,0)::INT;
END FUNCTION;


create explicit cast (integer as vestnik with 'informix'.int_vestnik);

CREATE FUNCTION "informix".int_vestnik(vestnik INT) RETURNING vestnik WITH(NOT VARIANT);
RETURN vestnik::NUMERIC(4,0)::vestnik;
END FUNCTION;

create explicit cast (vestnik as decimal(4,0) with 'informix'.vestnik_date);

CREATE FUNCTION "informix".vestnik_date(vestnik vestnik) RETURNING DATE WITH(NOT VARIANT);
DEFINE y, m, d INT;
LET y = MOD(vestnik::NUMERIC(4,0),100);
LET m = TRUNC(vestnik::NUMERIC(4,0)/100);
LET d = 1;
IF m<1 THEN RETURN NULL;
ELIF m>20 THEN RETURN NULL;
ELIF m>12 THEN LET m,d = 12,m;
END IF
IF y<0 THEN RETURN NULL;
ELIF y<50 THEN LET y = 2000+y;
ELSE LET y = 1900+y;
END IF
RETURN MDY(m,d,y);
END FUNCTION;


{ TABLE "informix".pbcattbl row size = 369 number of columns = 25 index size = 31 }
{ unload file name = pbcat00100.unl number of rows = 0 }
...
...

Когда я запускаю импорт с помощью этого сценария SQL, я получаю следующую ошибку

[informix@srvbib ~]$ dbimport -c -d datadbs -i /home/informix/ iscala
{ DATABASE iscala  delimiter | }

grant dba to "informix";
grant dba to "waspop";
grant connect to "jzl";






create distinct type 'informix'.vestnik as      decimal(4,0);

grant usage on type 'informix'.vestnik to 'public' as 'informix';



drop cast (decimal(4,0) as vestnik);
create explicit cast (decimal(4,0) as vestnik with 'informix'.date_vestnik);

CREATE FUNCTION "informix".date_vestnik(vestnik DATE) RETURNING vestnik WITH(NOT VARIANT);
RETURN ((CASE WHEN MONTH(vestnik)=12 AND DAY(vestnik)>12 THEN DAY(vestnik) ELSE MONTH(vestnik) END)
        *100+MOD(YEAR(vestnik),100))::NUMERIC(4,0)::vestnik;
END FUNCTION;


create explicit cast (vestnik as integer with 'informix'.vestnik_int);

CREATE FUNCTION "informix".vestnik_int(vestnik vestnik) RETURNING INT WITH(NOT VARIANT);
RETURN vestnik::NUMERIC(4,0)::INT;
END FUNCTION;


create explicit cast (integer as vestnik with 'informix'.int_vestnik);

CREATE FUNCTION "informix".int_vestnik(vestnik INT) RETURNING vestnik WITH(NOT VARIANT);
RETURN vestnik::NUMERIC(4,0)::vestnik;
END FUNCTION;


create explicit cast (vestnik as decimal(4,0) with 'informix'.vestnik_date);
*** prepare sqlobj
201 - A syntax error has occurred.

*** execute sqlobj
201 - A syntax error has occurred.

Когда я удаляю процедуру, она работает нормально. Если я попытаюсь создать функцию с помощью dbaccess, я смогу создать ее без проблем.

Вы знаете или не могли бы вы дать совет или подсказку о том, как решить эту проблему? Спасибо.

Правильно ли я понимаю, что вы имеете в виду «когда я запускаю импорт», а не «когда я запускаю экспорт»? Какую именно команду (импорта) вы выполняете?

Jonathan Leffler 14.09.2022 01:00

Хм… похоже, это ошибка. Сообщение об ошибке вводит в заблуждение — оператор, который не может быть подготовлен, является оператором DROP CAST, который создает DB-Import. В тексте оператора отсутствует закрывающая скобка, потому что он не ожидает DECIMAL(4, 0) — он думает, что закрывающая скобка в имени этого типа означает, что его не нужно добавлять, тогда как на самом деле его нужно добавить. Некоторый ленивый синтаксический анализ должен стать неленивым. Вам нужно будет связаться с вашим каналом технической поддержки Informix.

Jonathan Leffler 14.09.2022 01:58

Я создал ошибку CQ idsdb00111253. Вы можете использовать это в разговорах со своей службой поддержки.

Jonathan Leffler 14.09.2022 04:39

Привет, @JonathanLeffler. Спасибо за расследование. Что касается вашего наблюдения, я ожидаю, что если я удалю drop case, ошибка исчезнет, ​​но ошибка все еще существует, даже если drop cast был удален. Не могли бы вы поделиться со мной, как вы отлаживаете это поведение? Спасибо.

Ondřej Žižka 14.09.2022 06:50

По причинам, которые мне не вполне ясны, DB-Import берет оператор CREATE EXPLICIT CAST и создает из него оператор DROP CAST, но делает при этом ошибку. В какой-то момент я проверю, является ли это новым дефектом, но я чувствую, что он будет присутствовать и в более старых версиях. Вы можете отладить это, установив переменную среды SQLIDEBUG при запуске DB-Import, а затем используя sqliprint, чтобы показать, какие сообщения отправляются на сервер и с сервера.

Jonathan Leffler 14.09.2022 10:38

Что касается обходных путей, самым простым было бы удалить оскорбительные операторы CREATE CAST из файла импорта (iscala.exp/iscala.sql) и завершить импорт без них. Затем используйте DB-Access для выполнения пропущенных операторов. Это, несомненно, неприятно, но должно позволить вам завершить импорт.

Jonathan Leffler 14.09.2022 10:42
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
1
6
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Converting comments into an answer.

Это похоже на ошибку. Вам нужно будет связаться с вашим каналом технической поддержки Informix. Я создал ошибку CQ idsdb00111253. Вы можете использовать это в разговорах со своей службой поддержки.

Анализ

Сообщение об ошибке не очень полезно — оператор, который не может быть подготовлен, является оператором DROP CAST, который DB-Import создает после анализа CREATE CAST. В тексте сгенерированного оператора отсутствует закрывающая скобка, потому что он не ожидает DECIMAL(4, 0) — он думает, что закрывающая скобка в имени этого типа означает, что ему не нужно добавлять ее, тогда как на самом деле ее нужно добавить. Некоторый ленивый синтаксический анализ должен стать менее ленивым.

Согласно синтаксическим диаграммам существует два варианта оператора CREATE CAST:

CREATE [{ IMPLICIT | EXPLICIT }] CAST (<type1> AS <type2>)
CREATE [{ IMPLICIT | EXPLICIT }] CAST (<type1> AS <type2> WITH <function>)

Проблема возникает из-за того, что ваш <type2> — это DECIMAL(4,0), а код обнаруживает скобку ) и предполагает (ошибочно), что ) относится к первому варианту, а не ко второму:

create explicit cast (vestnik as decimal(4,0) with 'informix'.vestnik_date);

Спасибо за ваше расследование. Что касается вашего наблюдения, я ожидаю, что если я уберу футляр, ошибка исчезнет, ​​но ошибка все еще существует, даже если бросок был удален. Не могли бы вы поделиться со мной, как вы отлаживаете это поведение?

По причинам, которые мне не вполне ясны, DB-Import берет оператор CREATE EXPLICIT CAST и создает из него оператор DROP CAST, но делает при этом ошибку. В какой-то момент я проверю, является ли это новым дефектом, но я чувствую, что он будет присутствовать и в более старых версиях.

Вы можете отладить это, установив переменную среды SQLIDEBUG при запуске DB-Import, а затем используя sqliprint, чтобы показать, какие сообщения отправляются на сервер и с сервера. Я могу найти ссылки на SQLIDEBUG только в контексте JDBC, но они более общие.

export SQLIDEBUG=2:${TMPDIR:-/tmp}/sqdbg

Когда вы подключаетесь к серверу с этим набором, клиентский код создаст файл, например /tmp/sqdbg_a3715. Затем вы можете запустить sqliprint /tmp/sqdbg_a3715.

Обходные пути

Что касается обходных путей, самым простым было бы удалить оскорбительные операторы CREATE CAST из файла импорта (iscala.exp/iscala.sql) и завершить импорт без них. Затем используйте DB-Access для выполнения пропущенных операторов. Это, несомненно, неприятно, но должно позволить вам завершить импорт.

Другие вопросы по теме