Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4   вперед  Ctrl      все
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7129
Ivan Rabashchenko
...Просто в начале пакета сделать фейковую функцию вида...

IMHO жесть какая
Не проще пакет на несколько пакетов разделить?

Ну и самый интересный вопрос: а что говорит Oracle Support на эту багу?
7 дек 17, 19:38    [21016381]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
xtender
Member

Откуда: Мск
Сообщений: 4940
А эти неправильные значения в коде не встречаются случайно? Может тупо переполнение индекса идет
7 дек 17, 20:41    [21016535]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
Леонид, нет не проще.
Для этого нужно изменить не только код генератора пакетов, но и всю парадигму системы, а это тьма кода, который работает поверх этих нелепых, неповоротливых, гигантских пакетов. К этому добавлю, что нарвались мы на этот bug только лишь у одного клиента (а их сонм), у которого и OS и БД знакомые (связка такая много у кого Solaris + 11.2.0.4) и затевать глобальный рефакторинг это очень смелый и дорогой шаг. Возможно, обойдемся малой кровью. Сначала решил сам поколупаться - не получилось (не хватает знания матчасти) , затем решил спросить умных людей (спасибо всем кто откликается), если решения не найдем, зарегим официальную ноту на Oracle Support.
7 дек 17, 20:48    [21016549]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
xtender
А эти неправильные значения в коде не встречаются случайно? Может тупо переполнение индекса идет


Вполне возможно, на сегодня забрали доступ, завтра с утра предоставлю такую информацию.
7 дек 17, 20:54    [21016559]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
MaximaXXL
Member

Откуда: Киев
Сообщений: 594
Ivan Rabashchenko,

А можете попробовать с числом 268435455 и написать полученный результат?
7 дек 17, 20:54    [21016561]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
MaximaXXL
Ivan Rabashchenko,

А можете попробовать с числом 268435455 и написать полученный результат?


Мне наверное стоило в моем первом комментарии уточнить вот такой факт:
Если оперировать не большими числами, например:

function fIr$Tmp return number is
nRes number;
begin        
  nRes :=  268;
  return nRes;
end;


то все работает корректно независимо от положения в пакете. А если 268435456, например, то натыкаемся на некорректное поведение. Чтобы было понятнее, структура пакета такая:

......
function fIr$Tmp_110 return number is 
nRes number;
begin        
  nRes :=  268435456;
  return nRes;
end;
function fIr$Tmp_111 return number is 
nRes number;
begin        
  nRes :=  268;
  return nRes;
end;
function fIr$Tmp_112 return number is 
nRes number;
begin        
  nRes :=  268435457;
  return nRes;
end;
......



и получается, что fIr$Tmp_110 и fIr$Tmp_112 возвращают ересь, а fIr$Tmp_111 - норм.
7 дек 17, 21:16    [21016591]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5142
Расплющенная принцесса
Ivan Rabashchenko
Starting with release 7.3.4, the DIANA for package bodies is thrown away, not used, and not stored in the database
Это откуда? Смотри в доке plsql лимиты, там есть что посчитать. По объему parsed_code грозятся ошибкой pls-123.

+ И она даже возникает.

declare
   n           integer := 6551;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

select pkg.f6551 from dual;

     F6551
----------
      6551

declare
   n           integer := 6552;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

alter package pkg compile;

Warning: Package altered with compilation errors.

sho err
Errors for PACKAGE PKG:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1      PLS-00123: program too large (Diana nodes)

Linux, 11.2.0.4
7 дек 17, 21:35    [21016617]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
dbms_photoshop
Member

Откуда: sqlmdx.net
Сообщений: 5142
Ivan Rabashchenko,

А если включить
alter session set plsql_warnings = 'enable:all';
?
7 дек 17, 21:35    [21016619]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
К сожалению, только завтра смогу все проверить.
7 дек 17, 21:48    [21016641]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 48451
Ivan Rabashchenko,

еще можно попробовать дропнуть полностью пакет
и заново создать
7 дек 17, 22:44    [21016785]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7129
Ivan Rabashchenko
Для этого нужно изменить не только код генератора пакетов, но и всю парадигму системы, а это тьма кода, который работает поверх этих нелепых, неповоротливых, гигантских пакетов.

Как программист - не понимаю.

Если с размером specification проблем нет, а только с размером body, то никто не мешает точку входа в API оставить в одном пакете. Сделать пакет-прокси со старым именем, который просто будет вызывать функции из других пакетов. Код приложения, кроме генератора, менять не нужно

Единственная проблема чисто технического разделения - возможные связи между private (не вынесенные в спецификацию) функциями и глобальные переменные в пакете.

Лично я бы, первым делом, все глобальные переменные из пакета вынес в отдельный пакет (что бы на них всегда можно было ссылаться из всех генерированных пакетов), дальше бы разбирался, какие блоки функций можно отделить друг от друга. Сомневаюсь, что все 100 000 строк сгенерированного кода настолько сильно связаны друг с другом, что их не разделить.

Второе возможное решение, запрос в Oracle и фиксенье бага.

Поиск мелодии для бубна, который заставит обратно заработать систему у одного неудачливого заказчика.... это конечно хорошо, но как-то вызывает опасение. Если один раз свалилось на 100 000 строк кода, то кто может гарантировать, что в следующий раз не свалится на пакете в 101 000 строк кода и прошлогодняя мелодия и бубен поможет и в следующий раз?

IMHO & AFAIK
7 дек 17, 23:06    [21016822]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
xtender
А эти неправильные значения в коде не встречаются случайно? Может тупо переполнение индекса идет

select count(*) from all_source
 where owner = 'XXXXXXX' 
   and type = 'PACKAGE BODY' 
   and name = 'SVC$23532PKG'
   and text like '%(429514,%'
   --
   130 --  429514 - некорректное значение, возвращаемое fIr$Tmp

select count(*) from all_source
 where owner = 'XXXXXXX' 
   and type = 'PACKAGE BODY' 
   and name = 'SVC$23532PKG'
   and text like '%26843545%'
   --
   3 -- это одна штатная fIr$Tmp + две, которые ввел по ходу обсуждения: fIr$Tmp2 + fIr$Tmp3


Есть такое. Чем мне (нам) этот факт может помочь?

MaximaXXL
Ivan Rabashchenko,

А можете попробовать с числом 268435455 и написать полученный результат?


function fIr$Tmp return number is
nRes number;
 begin        
    nRes :=  268435455;
    return nRes;
 end;
 
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
-------
 VER_0
 429514


Ожидаемо, некорректный результат.
8 дек 17, 09:40    [21017216]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
andreymx
Ivan Rabashchenko,

еще можно попробовать дропнуть полностью пакет
и заново создать

drop package SVC$23532PKG;   
create or replace package SVC$23532PKG as...
create or replace package body SVC$23532PKG as...
    
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
-------
 VER_0
 429514
8 дек 17, 09:48    [21017236]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 48451
Ivan Rabashchenko,

а так?
:)
drop package SVC$23532PKG;   
--create or replace package SVC$23532PKG as...
--create or replace package body SVC$23532PKG as...
    
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
???
8 дек 17, 10:07    [21017280]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
andreymx
Ivan Rabashchenko,

а так?
:)
drop package SVC$23532PKG;   
--create or replace package SVC$23532PKG as...
--create or replace package body SVC$23532PKG as...
    
select SVC$23532PKG.fIR$Tmp as ver_0 from dual
???


Намекаете, что drop не отрабатывает?

drop package SVC$23532PKG;

select SVC$23532PKG.fIr$Tmp from dual

ORA-00904: "SVC$23532PKG"."FIR$TMP": invalid identifier
8 дек 17, 10:25    [21017320]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
-2-
Member

Откуда:
Сообщений: 13843
Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Более 16 бит заносится в некую хеш-таблицу. При превышении количества 32767/65535 констант результат парса теряется. На выполнении из хеш-таблицы выбирается по индексу младших 15/16 бит.
8 дек 17, 10:31    [21017332]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
-2-
Member

Откуда:
Сообщений: 13843
set serveroutput on
declare
   c clob;
begin
   c := 'declare n number;begin'||chr(10);
   for i in 1..32768 loop
      c := c || ' n := ' || to_char(i+1000000) || ';' || chr(10);
   end loop;
   c := c || ' dbms_output.put_line(''n=''||n);' || chr(10);
   c := c || 'end;' || chr(10);
   dbms_output.put_line(substr(c, -53));
   execute immediate c;
end;
/

-- 32767/+1000000
 n := 1032767;
 dbms_output.put_line('n='||n);
end;

n=1032767

-- 32768/+1000000
 n := 1032768;
 dbms_output.put_line('n='||n);
end;

n=0

-- 32768/+0
 n := 32768;
 dbms_output.put_line('n='||n);
end;

n=32768
8 дек 17, 10:43    [21017369]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
dbms_photoshop
Ivan Rabashchenko,

А если включить
alter session set plsql_warnings = 'enable:all';
?


alter session set plsql_warnings = 'enable:all';
alter package SVC$23532PKG compile;

select  text, count(1) from dba_errors where name = 'SVC$23532PKG'  group by text
-----
PLW-06010: keyword "RESULT" used as a defined name	149
PLW-07203: parameter 'OP' may benefit from use of the NOCOPY compiler hint	1452
PLW-06002: Unreachable code	473
PLW-05018: unit SVC$23532PKG omitted optional AUTHID clause; default value DEFINER used	1
8 дек 17, 10:49    [21017401]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
dbms_photoshop
Расплющенная принцесса
пропущено...
Это откуда? Смотри в доке plsql лимиты, там есть что посчитать. По объему parsed_code грозятся ошибкой pls-123.

+ И она даже возникает.

declare
   n           integer := 6551;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

select pkg.f6551 from dual;

     F6551
----------
      6551

declare
   n           integer := 6552;
   spec_list   dbms_sql.varchar2a;
   body_list   dbms_sql.varchar2a;
   l_cursor    integer default dbms_sql.open_cursor;
   res         integer;
begin
   spec_list(1)                     := 'create or replace package pkg as';
   for i in 1 .. n
   loop
      spec_list(spec_list.count + 1):= 'function f' || i || ' return number;';
   end loop;
   spec_list(spec_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, spec_list, spec_list.first, spec_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);

   body_list(1)                     := 'create or replace package body pkg as';
   for i in 1 .. n
   loop
      body_list(body_list.count + 1):= 'function f' || i || ' return number as
                                        begin return ' || i || '; end;';
   end loop;
   body_list(body_list.count + 1)   := 'end;';
   dbms_sql.parse(l_cursor, body_list, body_list.first, body_list.last, true, dbms_sql.native);
   res                              := dbms_sql.execute(l_cursor);
end;
/

PL/SQL procedure successfully completed.

alter package pkg compile;

Warning: Package altered with compilation errors.

sho err
Errors for PACKAGE PKG:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1      PLS-00123: program too large (Diana nodes)

Linux, 11.2.0.4


Указанный вам пример порождает PLS-00123 и у меня на разных платформах (Win\Linus\Solaris + 11.2.0.4\12.1.0.2)
8 дек 17, 11:03    [21017438]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
-2-
Member

Откуда:
Сообщений: 13843
declare n number;
begin
 n := 1000001;
 n := 1000002;
...
 n := 1032766;
 n := 1032767;
 dbms_output.put_line('32770='||32770);
 dbms_output.put_line('32769='||32769);
 dbms_output.put_line('32768='||32768);
 dbms_output.put_line('32767='||32767);
 dbms_output.put_line('1000001='||1000001);
 dbms_output.put_line('1032767='||1032767);
end;
/

32770=0
32769=1000001
32768=1000002
32767=32767
1000001=1000003
1032767=1000004
8 дек 17, 11:06    [21017447]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
-2-
Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Более 16 бит заносится в некую хеш-таблицу. При превышении количества 32767/65535 констант результат парса теряется. На выполнении из хеш-таблицы выбирается по индексу младших 15/16 бит.


О, это уже горячо. Уважаемый, -2-, подскажите пжл документ, в котором указано такое ограничение.
8 дек 17, 11:15    [21017475]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
Ivan Rabashchenko
Member

Откуда: Minsk
Сообщений: 35
Stax
Ivan Rabashchenko,

на правах версии
переполняется "таблица констант"

если в конец пакета добавить еще одну ф-цию
fIr$Tmp2 с константой (напр 268435457),
они будут правильно работать?

ps
перемещая по телу пакета ф-цию, возможно можно определить когда перестает работать

.....
stax


Мне сразу дали намек, а его не понял...
8 дек 17, 11:21    [21017498]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
xtender
Member

Откуда: Мск
Сообщений: 4940
-2-,

Имхо не хэш а переполнение индекса
8 дек 17, 11:36    [21017576]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
PL/SQL Program Limits
Guest
Читаем доки
PL/SQL Program Limits
8 дек 17, 11:48    [21017618]     Ответить | Цитировать Сообщить модератору
 Re: Странное поведение переменных в пакетах, с большим количеством строк  [new]
xtender
Member

Откуда: Мск
Сообщений: 4940
-2-
Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Более 16 бит заносится в некую хеш-таблицу. При превышении количества 32767/65535 констант результат парса теряется. На выполнении из хеш-таблицы выбирается по индексу младших 15/16 бит.

Имхо как-то так должно быть:
-2-
Предполагаю, что проблема в количестве констант (нод). Возможно малая константа имеет в пкоде "непосредственную адресацию". Для оптимизации, константы Более 16 бит заносятся в некий массив, а вместо константы указывается ее индекс в этой таблице. На выполнении из-за переполнения из массива выбирается по индексу младших 15/16 бит.



PL/SQL Program Limits
Читаем доки
PL/SQL Program Limits
лимита на количество литералов там нет
8 дек 17, 12:24    [21017730]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4   вперед  Ctrl      все
Все форумы / Oracle Ответить