Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b05dbd7

Browse files
committed
Fix to issue #770 when the merge statement is run via current user which can result in error due to missing privs to internal function
1 parent 013cba3 commit b05dbd7

3 files changed

Lines changed: 59 additions & 44 deletions

File tree

source/expectations/data_values/ut_compound_data_helper.pkb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,5 +541,58 @@ create or replace package body ut_compound_data_helper is
541541
return l_no_missing_keys;
542542
end;
543543

544+
procedure update_row_and_pk_hash(a_self_data_id in raw, a_other_data_id in raw, a_exclude_xpath varchar2,
545+
a_include_xpath varchar2, a_join_by_xpath varchar2) is
546+
l_ut_owner varchar2(250) := ut_utils.ut_owner;
547+
l_column_filter varchar2(32767);
548+
l_pk_hash_sql varchar2(32767);
549+
550+
function get_column_pk_hash(a_join_by_xpath varchar2) return varchar2 is
551+
l_column varchar2(32767);
552+
begin
553+
/* due to possibility of key being to columns we cannot use xmlextractvalue
554+
usage of xmlagg is possible however it greatly complicates code and performance is impacted.
555+
xpath to be looked at or regex
556+
*/
557+
if a_join_by_xpath is not null then
558+
l_column := l_ut_owner ||'.ut_compound_data_helper.get_hash(extract(ucd.item_data,:join_by_xpath).GetClobVal()) pk_hash';
559+
else
560+
l_column := ':join_by_xpath pk_hash';
561+
end if;
562+
return l_column;
563+
end;
564+
565+
begin
566+
l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
567+
l_pk_hash_sql := get_column_pk_hash(a_join_by_xpath);
568+
569+
execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt
570+
using (
571+
select ucd_out.item_hash,
572+
ucd_out.pk_hash,
573+
ucd_out.item_no,
574+
ucd_out.data_id,
575+
row_number() over (partition by ucd_out.pk_hash,ucd_out.item_hash,ucd_out.data_id order by 1,2) duplicate_no
576+
from
577+
(
578+
select '||l_ut_owner ||'.ut_compound_data_helper.get_hash(ucd.item_data.getclobval()) item_hash,
579+
pk_hash, ucd.item_no, ucd.data_id
580+
from
581+
(
582+
select '||l_column_filter||','||l_pk_hash_sql||', item_no, data_id
583+
from ' || l_ut_owner || q'[.ut_compound_data_tmp ucd
584+
where data_id = :self_guid or data_id = :other_guid
585+
) ucd
586+
)ucd_out
587+
) src
588+
on (tgt.item_no = src.item_no and tgt.data_id = src.data_id)
589+
when matched then update
590+
set tgt.item_hash = src.item_hash,
591+
tgt.pk_hash = src.pk_hash,
592+
tgt.duplicate_no = src.duplicate_no]'
593+
using a_exclude_xpath, a_include_xpath,a_join_by_xpath,a_self_data_id, a_other_data_id;
594+
595+
end;
596+
544597
end;
545598
/

source/expectations/data_values/ut_compound_data_helper.pks

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,8 @@ create or replace package ut_compound_data_helper authid definer is
8181
function is_pk_exists(a_expected_cursor xmltype, a_actual_cursor xmltype, a_exclude_xpath varchar2, a_include_xpath varchar2,a_join_by_xpath varchar2)
8282
return tt_missing_pk;
8383

84+
procedure update_row_and_pk_hash(a_self_data_id in raw, a_other_data_id in raw, a_exclude_xpath varchar2,
85+
a_include_xpath varchar2, a_join_by_xpath varchar2);
86+
8487
end;
8588
/

source/expectations/data_values/ut_compound_data_value.tpb

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -197,27 +197,11 @@ create or replace type body ut_compound_data_value as
197197
member function compare_implementation(a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2, a_join_by_xpath varchar2, a_unordered boolean ) return integer is
198198
l_other ut_compound_data_value;
199199
l_ut_owner varchar2(250) := ut_utils.ut_owner;
200-
l_column_filter varchar2(32767);
201200
l_diff_id ut_compound_data_helper.t_hash;
202201
l_result integer;
203202
l_row_diffs ut_compound_data_helper.tt_row_diffs;
204203
c_max_rows constant integer := 20;
205204

206-
function get_column_pk_hash(a_join_by_xpath varchar2) return varchar2 is
207-
l_column varchar2(32767);
208-
begin
209-
/* due to possibility of key being to columns we cannot use xmlextractvalue
210-
usage of xmlagg is possible however it greatly complicates code and performance is impacted.
211-
xpath to be looked at or regex
212-
*/
213-
if a_join_by_xpath is not null then
214-
l_column := l_ut_owner ||'.ut_compound_data_helper.get_hash(extract(ucd.item_data,:join_by_xpath).GetClobVal()) pk_hash';
215-
else
216-
l_column := ':join_by_xpath pk_hash';
217-
end if;
218-
return l_column;
219-
end;
220-
221205
begin
222206
if not a_other is of (ut_compound_data_value) then
223207
raise value_error;
@@ -226,37 +210,12 @@ create or replace type body ut_compound_data_value as
226210
l_other := treat(a_other as ut_compound_data_value);
227211

228212
l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
229-
l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
230-
213+
231214
/**
232215
* Due to incompatibility issues in XML between 11 and 12.2 and 12.1 versions we will prepopulate pk_hash upfront to
233216
* avoid optimizer incorrectly rewrite and causing NULL error or ORA-600
234-
**/
235-
execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt
236-
using (
237-
select ucd_out.item_hash,
238-
ucd_out.pk_hash,
239-
ucd_out.item_no,
240-
ucd_out.data_id,
241-
row_number() over (partition by ucd_out.pk_hash,ucd_out.item_hash,ucd_out.data_id order by 1,2) duplicate_no
242-
from
243-
(
244-
select '||l_ut_owner ||'.ut_compound_data_helper.get_hash(ucd.item_data.getclobval()) item_hash,
245-
pk_hash, ucd.item_no, ucd.data_id
246-
from
247-
(
248-
select '||l_column_filter||','||get_column_pk_hash(a_join_by_xpath)||', item_no, data_id
249-
from ' || l_ut_owner || q'[.ut_compound_data_tmp ucd
250-
where data_id = :self_guid or data_id = :other_guid
251-
) ucd
252-
)ucd_out
253-
) src
254-
on (tgt.item_no = src.item_no and tgt.data_id = src.data_id)
255-
when matched then update
256-
set tgt.item_hash = src.item_hash,
257-
tgt.pk_hash = src.pk_hash,
258-
tgt.duplicate_no = src.duplicate_no]'
259-
using a_exclude_xpath, a_include_xpath,a_join_by_xpath,self.data_id, l_other.data_id;
217+
**/
218+
ut_compound_data_helper.update_row_and_pk_hash(self.data_id, l_other.data_id, a_exclude_xpath,a_include_xpath,a_join_by_xpath);
260219

261220
/* Peform minus on two sets two get diffrences that will be used later on to print results */
262221
execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id,item_hash,pk_hash,duplicate_no)

0 commit comments

Comments
 (0)