@@ -167,68 +167,76 @@ create or replace package body ut_compound_data_helper is
167167 ) return tt_row_diffs is
168168 l_column_filter varchar2(32767);
169169 l_results tt_row_diffs;
170- l_sql varchar2(32767); -- REMOVE LATER also for unorder
171170 begin
172171 l_column_filter := get_columns_filter(a_exclude_xpath,a_include_xpath);
173172
174173 /**
175174 * Since its unordered search we cannot select max rows from diffs as we miss some comparision records
176175 * We will restrict output on higher level of select
177- */
176+ ** /
178177
179- l_sql := q'[
180- with
181- diff_info as (select item_hash from ut_compound_data_diff_tmp ucdc where diff_id = :diff_guid)
178+ execute immediate q'[
179+ with diff_info as (select item_hash from ut_compound_data_diff_tmp ucdc where diff_id = :diff_guid)
182180 select rn,diff_type,diffed_row
183- from (select dense_rank() over (order by pk_hash) as rn, diff_type,data_item diffed_row
184- from (select nvl(exp.pk_hash, act.pk_hash) pk_hash,
185- xmlserialize(content exp.row_data no indent) exp_item,
186- xmlserialize(content act.row_data no indent) act_item
187- from
188- (select ucd.*, row_number() over(partition by pk_hash order by row_hash) duplicate_no
189- from
190- (select ucd.column_value row_data,
191- dbms_crypto.hash( value(ucd).getclobval(),3) row_hash,
192- dbms_crypto.hash( extract(value(ucd),']'|| a_join_by_xpath ||q'[').getClobVal(),3/*HASH_SH1*/) pk_hash
193- from
194- (select ]'||l_column_filter||q'[, ucd.item_no, ucd.item_data item_data_no_filter
195- from ut_compound_data_tmp ucd
196- where ucd.data_id = :self_guid
197- and ucd.item_hash in (select i.item_hash from diff_info i)
198- ) r,
199- table( xmlsequence( extract(r.item_data,'/*') ) ) ucd
200- ) ucd
201- ) exp
202- join (
203- select ucd.*, row_number() over(partition by pk_hash order by row_hash) duplicate_no
204- from
205- (select ucd.column_value row_data,
206- dbms_crypto.hash( value(ucd).getclobval(),3/*HASH_SH1*/) row_hash,
207- dbms_crypto.hash( extract(value(ucd),']'|| a_join_by_xpath ||q'[').getClobVal(),3/*HASH_SH1*/) pk_hash
208- from
209- (select ]'||l_column_filter||q'[, ucd.item_no, ucd.item_data item_data_no_filter
210- from ut_compound_data_tmp ucd
211- where ucd.data_id = :other_guid
212- and ucd.item_hash in (select i.item_hash from diff_info i)
213- ) r,
214- table( xmlsequence( extract(r.item_data,'/*') ) ) ucd
215- ) ucd
216- ) act
217- on exp.pk_hash = act.pk_hash and exp.duplicate_no = act.duplicate_no
218- where exp.row_hash != act.row_hash
219- or exp.row_hash is null
220- or act.row_hash is null
221- )
222- unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:') )
223- )
224- where rownum < :max_rows
225- order by 1, 2]';
226-
227- execute immediate l_sql
181+ from
182+ (select dense_rank() over (order by pk_hash) as rn, diff_type,data_item diffed_row
183+ from
184+ (select pk_hash
185+ ,case when exp_item is not null and act_item is not null then exp_item else null end exp_item
186+ ,case when exp_item is not null and act_item is not null then act_item else null end act_item
187+ ,case when exp_item is not null and act_item is null then exp_item else null end miss_item
188+ ,case when exp_item is null and act_item is not null then act_item else null end ext_item
189+ from
190+ (select nvl(exp.pk_hash, act.pk_hash) pk_hash,
191+ xmlserialize(content exp.row_data no indent) exp_item,
192+ xmlserialize(content act.row_data no indent) act_item
193+ from
194+ (select ucd.*, row_number() over(partition by pk_hash order by row_hash) duplicate_no
195+ from
196+ (select ucd.column_value row_data,
197+ dbms_crypto.hash( value(ucd).getclobval(),3) row_hash,
198+ dbms_crypto.hash( extract(value(ucd), :join_by_xpath ).getClobVal(),3/*HASH_SH1*/) pk_hash
199+ from
200+ (select ]'||l_column_filter||q'[, ucd.item_no, ucd.item_data item_data_no_filter
201+ from ut_compound_data_tmp ucd
202+ where ucd.data_id = :self_guid
203+ and ucd.item_hash in (select i.item_hash from diff_info i)
204+ ) r,
205+ table( xmlsequence( extract(r.item_data,'/*') ) ) ucd
206+ ) ucd
207+ ) exp
208+ full outer join (
209+ select ucd.*, row_number() over(partition by pk_hash order by row_hash) duplicate_no
210+ from
211+ (select ucd.column_value row_data,
212+ dbms_crypto.hash( value(ucd).getclobval(),3/*HASH_SH1*/) row_hash,
213+ dbms_crypto.hash( extract(value(ucd), :join_by_xpath ).getClobVal(),3/*HASH_SH1*/) pk_hash
214+ from
215+ (select ]'||l_column_filter||q'[, ucd.item_no, ucd.item_data item_data_no_filter
216+ from ut_compound_data_tmp ucd
217+ where ucd.data_id = :other_guid
218+ and ucd.item_hash in (select i.item_hash from diff_info i)
219+ ) r,
220+ table( xmlsequence( extract(r.item_data,'/*') ) ) ucd
221+ ) ucd
222+ ) act
223+ on exp.pk_hash = act.pk_hash and exp.duplicate_no = act.duplicate_no
224+ where (exp.row_hash != act.row_hash and act.pk_hash = exp.pk_hash) or
225+ (
226+ (exp.pk_hash is null or act.pk_hash is null) and
227+ (exp.row_hash is null or act.row_hash is null)
228+ )
229+ )
230+ )
231+ unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:'
232+ ,miss_item as 'Missing:', ext_item as 'Extra:') )
233+ )
234+ where rownum <= :max_rows
235+ order by 1, 2]'
228236 bulk collect into l_results
229237 using a_diff_id,
230- a_exclude_xpath, a_include_xpath, a_expected_dataset_guid,
231- a_exclude_xpath, a_include_xpath, a_actual_dataset_guid,
238+ a_join_by_xpath, a_exclude_xpath, a_include_xpath, a_expected_dataset_guid,
239+ a_join_by_xpath, a_exclude_xpath, a_include_xpath, a_actual_dataset_guid,
232240 a_max_rows;
233241 return l_results;
234242 end;
@@ -325,8 +333,8 @@ create or replace package body ut_compound_data_helper is
325333 coalesce(exp.duplicate_no,act.duplicate_no) duplicate_no,
326334 case
327335 when act.row_hash is null then
328- 'miss row '
329- else 'extra row '
336+ 'Missing: '
337+ else 'Extra: '
330338 end diffed_type,
331339 case when exp.row_hash is null then
332340 xmlserialize(content act.row_data no indent)
0 commit comments