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

Skip to content

Commit 8388276

Browse files
committed
First stab
1 parent 4138d25 commit 8388276

10 files changed

Lines changed: 373 additions & 49 deletions

source/expectations/data_values/ut_compound_data_diff_tmp.sql

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ create global temporary table ut_compound_data_diff_tmp(
1212
See the License for the specific language governing permissions and
1313
limitations under the License.
1414
*/
15-
diff_id raw(128),
16-
item_no integer,
17-
pk_hash raw(128),
18-
item_hash raw(128),
15+
diff_id raw(128),
16+
act_data_id raw(32),
17+
exp_data_id raw(32),
18+
act_item_data xmltype,
19+
exp_item_data xmltype,
20+
item_no integer,
21+
pk_hash raw(128),
22+
item_hash raw(128),
1923
duplicate_no integer,
2024
constraint ut_compound_data_diff_tmp_uk1 unique (diff_id,duplicate_no,item_no,item_hash, pk_hash),
2125
constraint ut_compound_data_diff_tmp_chk check(

source/expectations/data_values/ut_compound_data_helper.pkb

Lines changed: 164 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,54 @@ create or replace package body ut_compound_data_helper is
166166
select replace((extract(a_item_data,a_join_by_xpath).getclobval()),chr(10)) into l_pk_value from dual;
167167
return l_pk_value;
168168
end;
169+
170+
function get_rows_diff_by_sql(
171+
a_expected_dataset_guid raw, a_actual_dataset_guid raw, a_diff_id raw,
172+
a_max_rows integer, a_exclude_xpath varchar2, a_include_xpath varchar2,
173+
a_join_by_xpath varchar2
174+
) return tt_row_diffs is
175+
l_column_filter varchar2(32767);
176+
l_results tt_row_diffs;
177+
begin
178+
l_column_filter := get_columns_row_filter(a_exclude_xpath,a_include_xpath);
179+
180+
execute immediate q'[with diff_info as
181+
( select act_data_id, exp_data_id,
182+
act_item_data,exp_item_data, :join_by join_by, item_no
183+
from ut_compound_data_diff_tmp
184+
where diff_id = :diff_id ),
185+
exp as (
186+
select exp_item_data, exp_data_id, item_no rn,rownum col_no,
187+
nvl2(exp_item_data,ut3.ut_compound_data_helper.get_pk_value(i.join_by,exp_item_data),null) pk_value,
188+
s.column_value col, s.column_value.getRootElement() col_name, s.column_value.getclobval() col_val
189+
from diff_info i,
190+
table( xmlsequence( extract(i.exp_item_data,'/*/*') ) ) s
191+
where i.exp_data_id = :self_guid),
192+
act as (
193+
select act_item_data, act_data_id, item_no rn, rownum col_no,
194+
nvl2(act_item_data,ut3.ut_compound_data_helper.get_pk_value(i.join_by,act_item_data),null) pk_value,
195+
s.column_value col, s.column_value.getRootElement() col_name, s.column_value.getclobval() col_val
196+
from diff_info i,
197+
table( xmlsequence( extract(i.act_item_data,'/*/*') ) ) s
198+
where i.act_data_id = :other_guid)
199+
select rn, diff_type, xmlserialize(content data_item no indent) diffed_row, pk_value pk_value
200+
from (
201+
select nvl(exp.rn, act.rn) rn, nvl(exp.pk_value, act.pk_value) pk_value, exp.col exp_item, act.col act_item
202+
from exp join act
203+
on exp.rn = act.rn and exp.col_name = act.col_name
204+
where dbms_lob.compare(exp.col_val, act.col_val) != 0)
205+
unpivot ( data_item for diff_type in (exp_item as 'Expected:', act_item as 'Actual:') )
206+
union all
207+
select item_no as rn, case when exp_data_id is null then 'Extra' else 'Missing' end as diff_type,
208+
xmlserialize(content nvl(exp_item_data, act_item_data) no indent) diffed_row,
209+
nvl2(i.join_by,ut3.ut_compound_data_helper.get_pk_value(i.join_by,coalesce(exp_item_data,act_item_data)),null) pk_value
210+
from diff_info i
211+
where act_data_id is null or exp_data_id is null]'
212+
bulk collect into l_results
213+
using a_join_by_xpath, a_diff_id, a_expected_dataset_guid,a_actual_dataset_guid;
214+
215+
return l_results;
216+
end;
169217

170218
function get_rows_diff(
171219
a_expected_dataset_guid raw, a_actual_dataset_guid raw, a_diff_id raw,
@@ -438,9 +486,11 @@ create or replace package body ut_compound_data_helper is
438486

439487
end;
440488

441-
function compare_type(a_join_by_xpath in varchar2,a_unordered boolean) return varchar2 is
489+
function compare_type(a_join_by_xpath in varchar2,a_unordered boolean, a_is_sql_diffable integer := 0) return varchar2 is
442490
begin
443491
case
492+
when a_is_sql_diffable = 1 then
493+
return gc_compare_sql;
444494
when a_join_by_xpath is not null then
445495
return gc_compare_join_by;
446496
when a_unordered then
@@ -453,23 +503,26 @@ create or replace package body ut_compound_data_helper is
453503
function get_rows_diff(
454504
a_expected_dataset_guid raw, a_actual_dataset_guid raw, a_diff_id raw,
455505
a_max_rows integer, a_exclude_xpath varchar2, a_include_xpath varchar2,
456-
a_join_by_xpath varchar2,a_unorderdered boolean
506+
a_join_by_xpath varchar2,a_unorderdered boolean, a_is_sql_diffable integer
457507
) return tt_row_diffs is
458-
l_results tt_row_diffs;
459-
l_compare_type varchar2(10):= compare_type(a_join_by_xpath,a_unorderdered);
508+
l_result tt_row_diffs := tt_row_diffs();
509+
l_compare_type varchar2(10):= compare_type(a_join_by_xpath,a_unorderdered, a_is_sql_diffable);
460510
begin
461511
case
512+
when l_compare_type = gc_compare_sql then
513+
l_result := get_rows_diff_by_sql(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
514+
a_max_rows, a_exclude_xpath, a_include_xpath ,a_join_by_xpath);
462515
when l_compare_type = gc_compare_join_by then
463-
return get_rows_diff(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
516+
l_result := get_rows_diff(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
464517
a_max_rows, a_exclude_xpath, a_include_xpath ,a_join_by_xpath);
465518
when l_compare_type = gc_compare_unordered then
466-
return get_rows_diff_unordered(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
519+
l_result := get_rows_diff_unordered(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
467520
a_max_rows, a_exclude_xpath, a_include_xpath);
468521
else
469-
return get_rows_diff(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
522+
l_result := get_rows_diff(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
470523
a_max_rows, a_exclude_xpath, a_include_xpath);
471524
end case;
472-
525+
return l_result;
473526
end;
474527

475528
function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash is
@@ -565,7 +618,8 @@ create or replace package body ut_compound_data_helper is
565618
begin
566619
l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
567620
l_pk_hash_sql := get_column_pk_hash(a_join_by_xpath);
568-
621+
622+
--Use a item hash as pk hash for unordered
569623
execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt
570624
using (
571625
select ucd_out.item_hash,
@@ -690,6 +744,7 @@ create or replace package body ut_compound_data_helper is
690744
return l_sql;
691745
end;
692746

747+
-- TODO:Rebuild as the unordered can be done using join_by compare
693748
function get_refcursor_matcher_sql(a_owner in varchar2,a_inclusion_matcher boolean := false, a_negated_match boolean := false) return varchar2 is
694749
l_sql varchar2(32767);
695750
begin
@@ -704,6 +759,105 @@ create or replace package body ut_compound_data_helper is
704759

705760
return l_sql;
706761
end;
707-
762+
763+
function generate_xmltab_stmt (a_column_info xmltype) return varchar2 is
764+
l_sql_stmt varchar2(32767);
765+
begin
766+
for i in (select /*+ CARDINALITY(xt 100) */
767+
xt.name
768+
from (select a_column_info item_data from dual) x,
769+
xmltable(
770+
'/ROW/*'
771+
passing x.item_data
772+
columns
773+
name varchar2(4000) PATH '@xml_valid_name'
774+
) xt)
775+
loop
776+
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ',' end ||i.name||q'[ varchar2(4000) PATH ']'||i.name||q'[']';
777+
end loop;
778+
return l_sql_stmt;
779+
end;
780+
781+
function generate_equal_sql (a_column_info xmltype) return varchar2 is
782+
l_sql_stmt varchar2(32767);
783+
begin
784+
for i in (select /*+ CARDINALITY(xt 100) */
785+
xt.name
786+
from (select a_column_info item_data from dual) x,
787+
xmltable(
788+
'/ROW/*'
789+
passing x.item_data
790+
columns
791+
name varchar2(4000) PATH '@xml_valid_name'
792+
) xt)
793+
loop
794+
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ' and ' end ||' a.'||i.name||q'[ = ]'||' e.'||i.name;
795+
end loop;
796+
return l_sql_stmt;
797+
end;
798+
799+
function generate_not_equal_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2 is
800+
l_sql_stmt varchar2(32767);
801+
l_pk_xpath_tabs ut_varchar2_list := ut_varchar2_list();
802+
begin
803+
l_pk_xpath_tabs := ut_utils.string_to_table(a_join_by_xpath,'|');
804+
805+
for i in (
806+
with xpaths_tab as (select column_value xpath from table(l_pk_xpath_tabs)),
807+
pk_names as (select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
808+
from xpaths_tab)
809+
select /*+ CARDINALITY(xt 100) */
810+
xt.name
811+
from (select a_column_info item_data from dual) x,
812+
xmltable(
813+
'/ROW/*'
814+
passing x.item_data
815+
columns
816+
name varchar2(4000) PATH '@xml_valid_name'
817+
) xt
818+
where not exists (select 1 from pk_names p where lower(p.name) = lower(xt.name))
819+
)
820+
loop
821+
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ' or ' end ||' a.'||i.name||q'[ <> ]'||' e.'||i.name;
822+
end loop;
823+
return l_sql_stmt;
824+
end;
825+
826+
function generate_join_by_on_stmt (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2 is
827+
l_sql_stmt varchar2(32767);
828+
l_pk_xpath_tabs ut_varchar2_list := ut_varchar2_list();
829+
830+
begin
831+
l_pk_xpath_tabs := ut_utils.string_to_table(a_join_by_xpath,'|');
832+
833+
for i in (with xpaths_tab as (select column_value xpath from table(l_pk_xpath_tabs))
834+
select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
835+
from xpaths_tab)
836+
loop
837+
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ' and ' end ||' a.'||i.name||q'[ = ]'||' e.'||i.name;
838+
end loop;
839+
return l_sql_stmt;
840+
end;
841+
842+
function generate_join_null_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2 is
843+
l_sql_stmt varchar2(32767);
844+
l_pk_xpath_tabs ut_varchar2_list := ut_varchar2_list();
845+
846+
begin
847+
l_pk_xpath_tabs := ut_utils.string_to_table(a_join_by_xpath,'|');
848+
849+
for i in (with xpaths_tab as (select column_value xpath from table(l_pk_xpath_tabs))
850+
select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
851+
from xpaths_tab)
852+
loop
853+
l_sql_stmt := l_sql_stmt || case
854+
when l_sql_stmt is null
855+
then null
856+
else ' or '
857+
end ||' a.'||i.name||q'[ is null or ]'||' e.'||i.name||q'[ is null]';
858+
end loop;
859+
return l_sql_stmt;
860+
end;
861+
708862
end;
709863
/

source/expectations/data_values/ut_compound_data_helper.pks

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ create or replace package ut_compound_data_helper authid definer is
1919
gc_compare_join_by constant varchar2(10):='join_by';
2020
gc_compare_unordered constant varchar2(10):='unordered';
2121
gc_compare_normal constant varchar2(10):='normal';
22+
gc_compare_sql constant varchar2(10):='sql';
2223

2324
type t_column_diffs is record(
2425
diff_type varchar2(1),
@@ -61,12 +62,12 @@ create or replace package ut_compound_data_helper authid definer is
6162

6263
function get_pk_value (a_join_by_xpath varchar2,a_item_data xmltype) return clob;
6364

64-
function compare_type(a_join_by_xpath in varchar2,a_unordered boolean) return varchar2;
65+
function compare_type(a_join_by_xpath in varchar2,a_unordered boolean, a_is_sql_diffable integer := 0) return varchar2;
6566

6667
function get_rows_diff(
6768
a_expected_dataset_guid raw, a_actual_dataset_guid raw, a_diff_id raw,
6869
a_max_rows integer, a_exclude_xpath varchar2, a_include_xpath varchar2,
69-
a_join_by_xpath varchar2,a_unorderdered boolean
70+
a_join_by_xpath varchar2,a_unorderdered boolean, a_is_sql_diffable integer
7071
) return tt_row_diffs;
7172

7273
subtype t_hash is raw(128);
@@ -85,6 +86,15 @@ create or replace package ut_compound_data_helper authid definer is
8586

8687
procedure update_row_and_pk_hash(a_self_data_id in raw, a_other_data_id in raw, a_exclude_xpath varchar2,
8788
a_include_xpath varchar2, a_join_by_xpath varchar2);
89+
90+
function generate_xmltab_stmt (a_column_info xmltype) return varchar2;
91+
92+
function generate_equal_sql (a_column_info xmltype) return varchar2;
8893

94+
function generate_not_equal_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2;
95+
96+
function generate_join_by_on_stmt (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2;
97+
98+
function generate_join_null_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2;
8999
end;
90100
/

0 commit comments

Comments
 (0)