@@ -119,8 +119,6 @@ create or replace package body ut_compound_data_helper is
119119 || case when a_order_enforced then q'[
120120 --column position is not matching (both when excluded extra/missing columns as well as when they are included)
121121 or (a_pos_nn != e_pos_nn and exp_col_pos != act_col_pos)]'
122- else
123- null
124122 end ||q'[
125123 order by exp_col_pos, act_col_pos]'
126124 bulk collect into l_results using a_expected, a_actual;
@@ -417,73 +415,100 @@ create or replace package body ut_compound_data_helper is
417415 l_join_xpath varchar2(32767) := ut_utils.to_xpath(a_join_by_list);
418416 l_results tt_row_diffs;
419417 l_sql varchar2(32767);
418+ l_column_order varchar2(100);
420419 begin
420+ if a_enforce_column_order then
421+ l_column_order := 'col_no';
422+ else
423+ l_column_order := 'col_name';
424+ end if;
421425 l_sql := q'[
422- with exp as (
426+ with
427+ exp_cols as (
423428 select
424- exp_item_data, exp_data_id, item_no rn, rownum col_no, pk_value ,
429+ i. exp_item_data, i. exp_data_id, i. item_no rn, rownum col_no, i.diff_id ,
425430 s.column_value col, s.column_value.getRootElement() col_name,
426- nvl(s.column_value.getclobval(),empty_clob()) col_val
431+ nvl( s.column_value.getclobval(), empty_clob() ) col_val
427432 from (
428433 select
429- exp_data_id, extract( ucd.exp_item_data, :column_path ) exp_item_data, item_no ,
430- replace( extract( ucd.exp_item_data, :join_by ).getclobval(), chr(10) ) pk_value
431- from ut_compound_data_diff_tmp ucd
432- where diff_id = :diff_id
434+ ucd. exp_data_id, extract( ucd.exp_item_data, :column_path ) exp_item_data,
435+ ucd.item_no, ucd.diff_id
436+ from ut_compound_data_diff_tmp ucd
437+ where ucd. diff_id = :diff_id
433438 and ucd.exp_data_id = :self_guid
434439 ) i,
435- table( xmlsequence( extract(i.exp_item_data,:extract_path) ) ) s
440+ table( xmlsequence( extract( i.exp_item_data, :extract_path ) ) ) s
436441 ),
437- act as (
442+ act_cols as (
438443 select
439- act_item_data, act_data_id, item_no rn, rownum col_no, pk_value ,
444+ i. act_item_data, i. act_data_id, i. item_no rn, rownum col_no, i.diff_id ,
440445 s.column_value col, s.column_value.getRootElement() col_name,
441- nvl(s.column_value.getclobval(),empty_clob()) col_val
446+ nvl( s.column_value.getclobval(), empty_clob() ) col_val
442447 from (
443448 select
444- act_data_id, extract( ucd.act_item_data, :column_path ) act_item_data, item_no ,
445- replace( extract( ucd.act_item_data, :join_by ).getclobval(), chr(10) ) pk_value
446- from ut_compound_data_diff_tmp ucd
447- where diff_id = :diff_id
449+ ucd. act_data_id, extract( ucd.act_item_data, :column_path ) act_item_data,
450+ ucd.item_no, ucd.diff_id
451+ from ut_compound_data_diff_tmp ucd
452+ where ucd. diff_id = :diff_id
448453 and ucd.act_data_id = :other_guid
449454 ) i,
450- table( xmlsequence( extract(i.act_item_data,:extract_path) ) ) s
455+ table( xmlsequence( extract( i.act_item_data, :extract_path ) ) ) s
456+ ),
457+ data_diff as (
458+ select rn, diff_type, xmlserialize(content data_item no indent) diffed_row, null pk_value, col_name, diff_id
459+ from (
460+ select nvl(exp.rn, act.rn) rn,
461+ exp.diff_id diff_id,
462+ xmlagg(exp.col order by exp.col_no) exp_item,
463+ xmlagg(act.col order by nvl(exp.col_no, act.col_no)) act_item,
464+ max(nvl(exp.col_name,act.col_name)) col_name
465+ from exp_cols exp
466+ join act_cols act
467+ on exp.rn = act.rn and exp.col_name = act.col_name
468+ where dbms_lob.compare(exp.col_val, act.col_val) != 0
469+ group by nvl(exp.rn, act.rn), exp.diff_id
470+ )
471+ unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:') )
472+ ),
473+ unordered_diff as (
474+ select rn, diff_type, xmlserialize(content data_item no indent) diffed_row, null pk_value, col_name, diff_id
475+ from (
476+ select nvl(exp.rn, act.rn) rn,
477+ exp.diff_id diff_id,
478+ xmlagg(exp.col order by exp.col_name) exp_item,
479+ xmlagg(act.col order by act.col_name) act_item,
480+ max(nvl(exp.col_name,act.col_name)) col_name
481+ from exp_cols exp
482+ join act_cols act
483+ on exp.rn = act.rn and exp.col_name = act.col_name
484+ where dbms_lob.compare(exp.col_val, act.col_val) != 0
485+ group by nvl(exp.rn, act.rn), exp.diff_id
486+ )
487+ unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:') )
451488 )
452- select rn, diff_type, diffed_row, pk_value pk_value
489+ select rn, diff_type, diffed_row, pk_value
453490 from (
454491 select rn, diff_type, diffed_row, pk_value,
455492 case when diff_type = 'Actual:' then 1 else 2 end rnk,
456493 1 final_order,
457494 col_name
458495 from ( ]'
459496 || case when a_unordered then q'[
460- select rn, diff_type, xmlserialize(content data_item no indent) diffed_row, pk_value, col_name
461- from (
462- select nvl(exp.rn, act.rn) rn,
463- nvl(exp.pk_value, act.pk_value) pk_value,
464- exp.col exp_item,
465- act.col act_item,
466- nvl(exp.col_name,act.col_name) col_name
467- from exp
468- join act
469- on exp.rn = act.rn and exp.col_name = act.col_name
470- where dbms_lob.compare(exp.col_val, act.col_val) != 0
471- )
472- unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:') ) ]'
497+ select /*+ no_unnest */
498+ u.rn, u.diff_type, u.diffed_row,
499+ replace(
500+ extract( case when i.exp_data_id is null then i.act_item_data else i.exp_item_data end, :join_by ).getclobval(),
501+ chr(10)
502+ ) pk_value,
503+ u.col_name
504+ from data_diff u
505+ join ut_compound_data_diff_tmp i
506+ on i.diff_id = u.diff_id
507+ and i.item_no = u.rn]'
473508 else q'[
474- select rn, diff_type, xmlserialize(content data_item no indent) diffed_row, null pk_value, col_name
475- from (
476- select nvl(exp.rn, act.rn) rn,
477- xmlagg(exp.col order by exp.col_no) exp_item,
478- xmlagg(act.col order by act.col_no) act_item,
479- max(nvl(exp.col_name,act.col_name)) col_name
480- from exp exp
481- join act act
482- on exp.rn = act.rn and exp.col_name = act.col_name
483- where dbms_lob.compare(exp.col_val, act.col_val) != 0
484- group by (exp.rn, act.rn)
485- )
486- unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:') ) ]'
509+ select rn, diff_type, diffed_row, pk_value, col_name
510+ from data_diff
511+ where :join_by is null ]'
487512 end ||q'[
488513 )
489514 union all
@@ -522,14 +547,12 @@ create or replace package body ut_compound_data_helper is
522547 case when final_order = 1 then to_char(rn) else col_name end,
523548 case when final_order = 1 then to_char(rnk) else col_name end
524549 ]'
525- else
526- null
527550 end;
528551 execute immediate l_sql
529552 bulk collect into l_results
530- using l_exp_extract_xpath, l_join_xpath, a_diff_id, a_expected_dataset_guid,a_extract_path,
531- l_act_extract_xpath, l_join_xpath, a_diff_id, a_actual_dataset_guid,a_extract_path,
532- l_join_xpath, l_join_xpath, a_diff_id;
553+ using l_exp_extract_xpath, a_diff_id, a_expected_dataset_guid, a_extract_path,
554+ l_act_extract_xpath, a_diff_id, a_actual_dataset_guid, a_extract_path,
555+ l_join_xpath, l_join_xpath, l_join_xpath, a_diff_id;
533556 return l_results;
534557 end;
535558
0 commit comments