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

Skip to content

Commit c009a86

Browse files
committed
Update code to bring all code into one place.
Still few issues to resolve. TODO : Nested table, collections and some errors to investigate. TODO : Bring a diffs row into one place.
1 parent d9ccc83 commit c009a86

4 files changed

Lines changed: 72 additions & 84 deletions

File tree

source/expectations/data_values/ut_compound_data_helper.pkb

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ create or replace package body ut_compound_data_helper is
183183
l_act_col_filter := get_columns_row_filter(a_exclude_xpath,a_include_xpath,'ucd','act_item_data');
184184
l_exp_col_filter := get_columns_row_filter(a_exclude_xpath,a_include_xpath,'ucd','exp_item_data');
185185

186+
--TODO: Generate a dynamic SQL based on input e.g. no need for PK during unordered and consolidate get_rows_diff
187+
186188
execute immediate q'[with exp as (
187189
select exp_item_data, exp_data_id, item_no rn,rownum col_no,
188190
nvl2(exp_item_data,ut3.ut_compound_data_helper.get_pk_value(i.join_by,exp_item_data),null) pk_value,
@@ -317,12 +319,12 @@ create or replace package body ut_compound_data_helper is
317319
function get_rows_diff(
318320
a_expected_dataset_guid raw, a_actual_dataset_guid raw, a_diff_id raw,
319321
a_max_rows integer, a_exclude_xpath varchar2, a_include_xpath varchar2,
320-
a_join_by_xpath varchar2,a_unorderdered boolean
322+
a_join_by_xpath varchar2,a_unordered boolean
321323
) return tt_row_diffs is
322324
l_result tt_row_diffs := tt_row_diffs();
323325
begin
324326
case
325-
when a_unorderdered then
327+
when a_unordered then
326328
l_result := get_rows_diff_by_sql(a_expected_dataset_guid, a_actual_dataset_guid, a_diff_id,
327329
a_max_rows, a_exclude_xpath, a_include_xpath ,a_join_by_xpath);
328330
else
@@ -559,8 +561,9 @@ create or replace package body ut_compound_data_helper is
559561
return l_sql_stmt;
560562
end;
561563

562-
function gen_compare_sql(a_column_info xmltype, a_exclude_xpath varchar2,
563-
a_include_xpath varchar2, a_join_by_xpath varchar2, a_inclusion_type boolean, a_is_negated boolean ) return clob is
564+
function gen_compare_sql(a_column_info xmltype, a_exclude_xpath varchar2, a_include_xpath varchar2,
565+
a_join_by_xpath varchar2, a_inclusion_type boolean, a_is_negated boolean,
566+
a_unordered boolean) return clob is
564567
l_compare_sql clob;
565568
l_temp_string varchar2(32767);
566569

@@ -613,6 +616,7 @@ create or replace package body ut_compound_data_helper is
613616
dbms_lob.createtemporary(l_compare_sql, true);
614617

615618
--TODO: Resolve issues with collection and nested tables, can we extract by internal column name if defined e.g. xml of colval.id.getclobval()
619+
--TODO: Comment better all pieces
616620
--Check include and exclude columns and create an actual column list that have to be compared.
617621
if a_include_xpath is null and a_exclude_xpath is null then
618622
l_act_col_tab := get_columns_info(a_column_info);
@@ -638,12 +642,19 @@ create or replace package body ut_compound_data_helper is
638642
ut_utils.append_to_clob(l_compare_sql, l_temp_string);
639643
ut_utils.append_to_clob(l_compare_sql, l_select_stmt);
640644

641-
l_temp_string := q'[,x.item_no,x.data_id from (select item_data,item_no,data_id from ]' || l_ut_owner || q'[.ut_compound_data_tmp where data_id = :self_guid) x,]'
645+
l_temp_string := ',x.data_id ,'
646+
|| case when not a_unordered then 'position ' else 'rownum ' end
647+
||'item_no from '|| l_ut_owner || '.ut_compound_data_tmp x, '
642648
||q'[xmltable('/ROWSET/ROW' passing x.item_data columns ]';
643-
ut_utils.append_to_clob(l_compare_sql, l_temp_string);
649+
ut_utils.append_to_clob(l_compare_sql, l_temp_string);
650+
651+
if not a_unordered then
652+
ut_utils.append_to_clob(l_compare_sql,'POSITION for ordinality, ');
653+
end if;
654+
644655
ut_utils.append_to_clob(l_compare_sql,l_xmltable_stmt);
645656

646-
l_temp_string := q'[ ,item_data xmltype PATH '*' ) ucd ) ucd ) ,]';
657+
l_temp_string := q'[ ,item_data xmltype PATH '*' ) ucd where data_id = :self_guid ) ucd ) ,]';
647658
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
648659

649660
l_temp_string :='act as ( select ucd.* , ';
@@ -654,35 +665,50 @@ create or replace package body ut_compound_data_helper is
654665
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
655666
ut_utils.append_to_clob(l_compare_sql, l_select_stmt);
656667

657-
l_temp_string := q'[, x.item_no,x.data_id from (select item_data,item_no,data_id from ]' || l_ut_owner || q'[.ut_compound_data_tmp where data_id = :other_guid) x,]'
668+
l_temp_string := ',x.data_id, '
669+
|| case when not a_unordered then 'position ' else 'rownum ' end
670+
||'item_no from ' || l_ut_owner || '.ut_compound_data_tmp x,'
658671
||q'[xmltable('/ROWSET/ROW' passing x.item_data columns ]' ;
659672
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
660-
ut_utils.append_to_clob(l_compare_sql,l_xmltable_stmt||q'[ ,item_data xmltype PATH '*') ucd ) ucd ) ]');
661-
662-
if a_join_by_xpath is null then
663-
-- If no key defined do the join on all columns
664-
l_temp_string := ' select a.item_data as act_item_data, a.data_id act_data_id,'
665-
||'e.item_data as exp_item_data, e.data_id exp_data_id, rownum item_no, nvl(e.dup_no,a.dup_no) dup_no '
673+
674+
if not a_unordered then
675+
ut_utils.append_to_clob(l_compare_sql,'POSITION for ordinality, ');
676+
end if;
677+
678+
ut_utils.append_to_clob(l_compare_sql,l_xmltable_stmt||q'[ ,item_data xmltype PATH '*') ucd where data_id = :other_guid ) ucd ) ]');
679+
680+
l_temp_string := ' select a.item_data as act_item_data, a.data_id act_data_id,'
681+
||'e.item_data as exp_item_data, e.data_id exp_data_id, '||
682+
case when a_unordered then 'rownum item_no' else 'nvl(e.item_no,a.item_no) item_no' end ||', nvl(e.dup_no,a.dup_no) dup_no '
666683
||'from act a '||get_join_type(a_inclusion_type,a_is_negated)||' exp e on ( ';
667-
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
668-
ut_utils.append_to_clob(l_compare_sql,generate_equal_sql(l_act_col_tab)||q'[ and e.dup_no = a.dup_no ) where ]');
669-
else
670-
-- If key defined do the join or these and where on diffrences
671-
l_temp_string := q'[ select a.item_data act_item_data, a.data_id act_data_id, ]'
672-
||' e.item_data exp_item_data, e.data_id exp_data_id, rownum item_no,nvl(e.dup_no,a.dup_no) dup_no from act a '||get_join_type(a_inclusion_type,a_is_negated)||' exp e on ( e.dup_no = a.dup_no and ';
673-
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
674-
675-
ut_utils.append_to_clob(l_compare_sql,generate_join_by_on_stmt (l_pk_xpath_tabs,a_column_info,a_join_by_xpath)||' ) where');
676-
684+
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
685+
686+
if a_unordered then
687+
ut_utils.append_to_clob(l_compare_sql,' e.dup_no = a.dup_no and ');
688+
end if;
689+
690+
if a_join_by_xpath is null and a_unordered then
691+
-- If no key defined do the join on all columns
692+
ut_utils.append_to_clob(l_compare_sql,generate_equal_sql(l_act_col_tab));
693+
elsif a_join_by_xpath is not null and a_unordered then
694+
-- If key defined do the join or these and where on diffrences
695+
ut_utils.append_to_clob(l_compare_sql,generate_join_by_on_stmt (l_pk_xpath_tabs,a_column_info,a_join_by_xpath));
696+
elsif not a_unordered then
697+
ut_utils.append_to_clob(l_compare_sql, 'a.item_no = e.item_no ' );
698+
end if;
677699

678-
if not a_is_negated then
700+
ut_utils.append_to_clob(l_compare_sql,' ) where ');
701+
702+
if (a_join_by_xpath is not null) and (a_unordered) and (a_inclusion_type) and (not a_is_negated) then
679703
l_where_stmt := generate_not_equal_sql(l_act_col_tab, l_pk_xpath_tabs);
680704
if l_where_stmt is not null then
681705
ut_utils.append_to_clob(l_compare_sql,' ( '||l_where_stmt||' ) or ');
682706
end if;
683-
end if;
684-
end if;
685-
707+
elsif not a_unordered then
708+
l_where_stmt := generate_not_equal_sql(l_act_col_tab, l_pk_xpath_tabs);
709+
ut_utils.append_to_clob(l_compare_sql,' ( '||l_where_stmt||' ) or ');
710+
end if;
711+
686712
--If its inlcusion we expect a actual set to fully match and have no extra elements over expected
687713
if a_inclusion_type and not(a_is_negated) then
688714
l_temp_string := ' ( a.data_id is null ) ';

source/expectations/data_values/ut_compound_data_helper.pks

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ create or replace package ut_compound_data_helper authid definer is
7474
function get_rows_diff(
7575
a_expected_dataset_guid raw, a_actual_dataset_guid raw, a_diff_id raw,
7676
a_max_rows integer, a_exclude_xpath varchar2, a_include_xpath varchar2,
77-
a_join_by_xpath varchar2,a_unorderdered boolean
77+
a_join_by_xpath varchar2,a_unordered boolean
7878
) return tt_row_diffs;
7979

8080
subtype t_hash is raw(128);
@@ -89,8 +89,9 @@ create or replace package ut_compound_data_helper authid definer is
8989
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)
9090
return tt_missing_pk;
9191

92-
function gen_compare_sql(a_column_info xmltype, a_exclude_xpath varchar2,
93-
a_include_xpath varchar2, a_join_by_xpath varchar2, a_inclusion_type boolean, a_is_negated boolean ) return clob;
92+
function gen_compare_sql(a_column_info xmltype, a_exclude_xpath varchar2, a_include_xpath varchar2,
93+
a_join_by_xpath varchar2, a_inclusion_type boolean, a_is_negated boolean,
94+
a_unordered boolean ) return clob;
9495

9596
procedure insert_diffs_result(a_diff_tab t_diff_tab, a_diff_id raw);
9697

source/expectations/data_values/ut_compound_data_value.tpb

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,7 @@ create or replace type body ut_compound_data_value as
119119
-- First tell how many rows are different
120120

121121
--TODO: that is a bit mess ?? Can we use global variable for all matchers.
122-
if a_unordered then
123-
l_diff_row_count := ut_compound_data_helper.get_rows_diff;
124-
else
125-
execute immediate 'select count('
126-
||case when ( a_join_by_xpath is not null )
127-
then 'distinct pk_hash'
128-
else '*'
129-
end
130-
||') from '|| l_ut_owner || '.ut_compound_data_diff_tmp '
131-
||'where diff_id = :diff_id'
132-
into l_diff_row_count using l_diff_id;
133-
end if;
122+
l_diff_row_count := ut_compound_data_helper.get_rows_diff;
134123

135124
if l_diff_row_count > 0 then
136125
l_row_diffs := ut_compound_data_helper.get_rows_diff(
@@ -159,9 +148,6 @@ create or replace type body ut_compound_data_value as
159148
l_column_filter varchar2(32767);
160149
l_diff_id ut_compound_data_helper.t_hash;
161150
l_result integer;
162-
163-
l_sql varchar2(32767);
164-
165151
--the XML stylesheet is applied on XML representation of data to exclude column names from comparison
166152
--column names and data-types are compared separately
167153
--user CHR(38) instead of ampersand to eliminate define request when installing through some IDEs
@@ -182,40 +168,20 @@ create or replace type body ut_compound_data_value as
182168
if not a_other is of (ut_compound_data_value) then
183169
raise value_error;
184170
end if;
185-
171+
186172
l_other := treat(a_other as ut_compound_data_value);
187173

188174
l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
189175
l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
190176
-- Find differences
191-
execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id, item_no,exp_item_data, act_item_data,exp_data_id, act_data_id )
192-
select :diff_id, nvl(exp.item_no, act.item_no) , exp.item_data, act.item_data, exp.data_id, act.data_id
193-
from ( select '||l_column_filter||', rownum item_no, ucd.data_id
194-
from
195-
(select xmlelement(name "ROW" ,xt.item_data) item_data, t.data_id
196-
from ' || l_ut_owner || q'[.ut_compound_data_tmp t,
197-
xmltable('/ROWSET/ROW'
198-
passing t.item_data
199-
columns
200-
item_data xmltype path '*'
201-
) xt
202-
where t.data_id = :self_guid) ucd
203-
) exp
177+
execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id, item_no )
178+
select :diff_id, nvl(exp.item_no, act.item_no)
179+
from (select '||l_column_filter||', ucd.item_no
180+
from ' || l_ut_owner || '.ut_compound_data_tmp ucd where ucd.data_id = :self_guid) exp
204181
full outer join
205-
(select ]'||l_column_filter||', rownum item_no, ucd.data_id
206-
from
207-
(
208-
select xmlelement(name "ROW" ,xt.item_data) item_data, t.data_id
209-
from ' || l_ut_owner || q'[.ut_compound_data_tmp t,
210-
xmltable('/ROWSET/ROW'
211-
passing t.item_data
212-
columns
213-
item_data xmltype path '*'
214-
) xt
215-
where t.data_id = :l_other_guid
216-
) ucd
217-
) act
218-
on exp.item_no = act.item_no ]'||
182+
(select '||l_column_filter||', ucd.item_no
183+
from ' || l_ut_owner || '.ut_compound_data_tmp ucd where ucd.data_id = :l_other_guid) act
184+
on exp.item_no = act.item_no '||
219185
'where nvl( dbms_lob.compare(' ||
220186
/*the xmltransform removes column names and leaves column data to be compared only*/
221187
' xmltransform(exp.item_data, :l_xml_data_fmt).getclobval()' ||
@@ -224,11 +190,11 @@ create or replace type body ut_compound_data_value as
224190
') != 0'
225191
using in l_diff_id, a_exclude_xpath, a_include_xpath, self.data_id,
226192
a_exclude_xpath, a_include_xpath, l_other.data_id, l_xml_data_fmt, l_xml_data_fmt;
227-
228193
--result is OK only if both are same
229194
if sql%rowcount = 0 and self.elements_count = l_other.elements_count then
230195
l_result := 0;
231196
else
197+
ut_compound_data_helper.set_rows_diff(sql%rowcount);
232198
l_result := 1;
233199
end if;
234200
return l_result;
@@ -253,7 +219,7 @@ create or replace type body ut_compound_data_value as
253219
l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
254220

255221
open l_loop_curs for ut_compound_data_helper.gen_compare_sql(treat(a_other as ut_data_value_refcursor).columns_info, a_exclude_xpath,
256-
a_include_xpath, a_join_by_xpath, a_inclusion_compare, a_is_negated) using self.data_id,l_other.data_id;
222+
a_include_xpath, a_join_by_xpath, a_inclusion_compare, a_is_negated, a_unordered ) using self.data_id,l_other.data_id;
257223
loop
258224
fetch l_loop_curs bulk collect into l_diff_tab limit l_max_rows;
259225
exit when l_diff_tab.count = 0;
@@ -267,12 +233,12 @@ create or replace type body ut_compound_data_value as
267233
l_max_rows := ut_utils.gc_bc_fetch_limit;
268234
end if;
269235
end loop;
270-
271-
ut_compound_data_helper.set_rows_diff(l_sql_rowcount);
236+
272237
--result is OK only if both are same
273238
if l_sql_rowcount = 0 and ( self.elements_count = l_other.elements_count or a_inclusion_compare )then
274239
l_result := 0;
275240
else
241+
ut_compound_data_helper.set_rows_diff(l_sql_rowcount);
276242
l_result := 1;
277243
end if;
278244

source/expectations/data_values/ut_data_value_refcursor.tpb

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,8 @@ create or replace type body ut_data_value_refcursor as
250250
l_result := 1;
251251
end if;
252252

253-
254-
if a_unordered then
255-
l_result := l_result + (self as ut_compound_data_value).compare_implementation(a_other, a_exclude_xpath, a_include_xpath,
253+
l_result := l_result + (self as ut_compound_data_value).compare_implementation(a_other, a_exclude_xpath, a_include_xpath,
256254
a_join_by_xpath,a_unordered, a_inclusion_compare, a_is_negated);
257-
else
258-
l_result := l_result + (self as ut_compound_data_value).compare_implementation(a_other, a_exclude_xpath, a_include_xpath);
259-
end if;
260255
end if;
261256

262257
return l_result;

0 commit comments

Comments
 (0)