@@ -89,29 +89,25 @@ create or replace type body ut_compound_data_value as
8989 l_row_diffs ut_compound_data_helper.tt_row_diffs;
9090 l_compare_type varchar2(10);
9191 l_self ut_compound_data_value;
92- l_is_sql_diff integer := 0;
9392
94- function get_diff_message (a_row_diff ut_compound_data_helper.t_row_diffs,a_compare_type varchar2 ) return varchar2 is
93+ function get_diff_message (a_row_diff ut_compound_data_helper.t_row_diffs,a_is_unordered boolean ) return varchar2 is
9594 begin
96- if a_compare_type in (ut_compound_data_helper.gc_compare_join_by,ut_compound_data_helper.gc_compare_sql)
97- and a_row_diff.pk_value is not null then
98- return ' PK '||a_row_diff.pk_value||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
99- elsif a_compare_type = ut_compound_data_helper.gc_compare_join_by or a_compare_type = ut_compound_data_helper.gc_compare_normal then
95+
96+ if a_is_unordered then
97+ if a_row_diff.pk_value is not null then
98+ return ' PK '||a_row_diff.pk_value||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
99+ else
100+ return rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
101+ end if;
102+ else
100103 return ' Row No. '||a_row_diff.rn||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
101- elsif a_compare_type in (ut_compound_data_helper.gc_compare_unordered,ut_compound_data_helper.gc_compare_sql)
102- and a_row_diff.pk_value is null then
103- return rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
104- end if;
104+ end if;
105105 end;
106106
107107 begin
108108 if not a_other is of (ut_compound_data_value) then
109109 raise value_error;
110- end if;
111-
112- if self is of (ut_data_value_refcursor) then
113- l_is_sql_diff := treat(self as ut_data_value_refcursor).is_sql_diffable;
114- end if;
110+ end if;
115111
116112 l_actual := treat(a_other as ut_compound_data_value);
117113
@@ -122,12 +118,12 @@ create or replace type body ut_compound_data_value as
122118
123119 -- First tell how many rows are different
124120
125- --REDO that is a bit mess ??
126- if l_is_sql_diff = 1 then
121+ --TODO: that is a bit mess ?? Can we use global variable for all matchers.
122+ if a_unordered then
127123 l_diff_row_count := ut_compound_data_helper.get_rows_diff;
128124 else
129125 execute immediate 'select count('
130- ||case when ( a_join_by_xpath is not null and l_is_sql_diff = 0 )
126+ ||case when ( a_join_by_xpath is not null )
131127 then 'distinct pk_hash'
132128 else '*'
133129 end
@@ -137,10 +133,9 @@ create or replace type body ut_compound_data_value as
137133 end if;
138134
139135 if l_diff_row_count > 0 then
140- l_compare_type := ut_compound_data_helper.compare_type(a_join_by_xpath,a_unordered, l_is_sql_diff);
141136 l_row_diffs := ut_compound_data_helper.get_rows_diff(
142137 self.data_id, l_actual.data_id, l_diff_id, c_max_rows, a_exclude_xpath,
143- a_include_xpath, a_join_by_xpath, a_unordered, l_is_sql_diff );
138+ a_include_xpath, a_join_by_xpath, a_unordered);
144139 l_message := chr(10)
145140 ||'Rows: [ ' || l_diff_row_count ||' differences'
146141 || case when l_diff_row_count > c_max_rows and l_row_diffs.count > 0 then ', showing first '||c_max_rows end
@@ -150,7 +145,7 @@ create or replace type body ut_compound_data_value as
150145 ut_utils.append_to_clob( l_result, l_message );
151146 for i in 1 .. l_row_diffs.count loop
152147 l_results.extend;
153- l_results(l_results.last) := get_diff_message(l_row_diffs(i),l_compare_type );
148+ l_results(l_results.last) := get_diff_message(l_row_diffs(i),a_unordered );
154149 end loop;
155150 ut_utils.append_to_clob(l_result,l_results);
156151 end if;
@@ -164,6 +159,9 @@ create or replace type body ut_compound_data_value as
164159 l_column_filter varchar2(32767);
165160 l_diff_id ut_compound_data_helper.t_hash;
166161 l_result integer;
162+
163+ l_sql varchar2(32767);
164+
167165 --the XML stylesheet is applied on XML representation of data to exclude column names from comparison
168166 --column names and data-types are compared separately
169167 --user CHR(38) instead of ampersand to eliminate define request when installing through some IDEs
@@ -184,20 +182,40 @@ create or replace type body ut_compound_data_value as
184182 if not a_other is of (ut_compound_data_value) then
185183 raise value_error;
186184 end if;
187-
185+
188186 l_other := treat(a_other as ut_compound_data_value);
189187
190188 l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
191189 l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
192190 -- Find differences
193- execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id, item_no )
194- select :diff_id, nvl(exp.item_no, act.item_no)
195- from (select '||l_column_filter||', ucd.item_no
196- from ' || l_ut_owner || '.ut_compound_data_tmp ucd where ucd.data_id = :self_guid) exp
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
197204 full outer join
198- (select '||l_column_filter||', ucd.item_no
199- from ' || l_ut_owner || '.ut_compound_data_tmp ucd where ucd.data_id = :l_other_guid) act
200- on exp.item_no = act.item_no '||
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 ]'||
201219 'where nvl( dbms_lob.compare(' ||
202220 /*the xmltransform removes column names and leaves column data to be compared only*/
203221 ' xmltransform(exp.item_data, :l_xml_data_fmt).getclobval()' ||
@@ -206,6 +224,7 @@ create or replace type body ut_compound_data_value as
206224 ') != 0'
207225 using in l_diff_id, a_exclude_xpath, a_include_xpath, self.data_id,
208226 a_exclude_xpath, a_include_xpath, l_other.data_id, l_xml_data_fmt, l_xml_data_fmt;
227+
209228 --result is OK only if both are same
210229 if sql%rowcount = 0 and self.elements_count = l_other.elements_count then
211230 l_result := 0;
@@ -234,12 +253,6 @@ create or replace type body ut_compound_data_value as
234253
235254 l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
236255
237- /**
238- * Due to incompatibility issues in XML between 11 and 12.2 and 12.1 versions we will prepopulate pk_hash upfront to
239- * avoid optimizer incorrectly rewrite and causing NULL error or ORA-600
240- **/
241- 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);
242-
243256 /*!*
244257 * Comparision is based on type of search, for inclusion based search we will look for left join only.
245258 * For normal two side diff we will peform minus on two sets two get diffrences.
@@ -283,7 +296,7 @@ create or replace type body ut_compound_data_value as
283296 l_sql_rowcount integer :=0;
284297
285298 begin
286-
299+ --TODO : Error on xml when same column is more then once in item data xml.Do we need to cleanup ??
287300 l_other := treat(a_other as ut_compound_data_value);
288301 l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
289302
@@ -292,7 +305,6 @@ create or replace type body ut_compound_data_value as
292305 loop
293306 fetch l_loop_curs bulk collect into l_diff_tab limit l_max_rows;
294307 exit when l_diff_tab.count = 0;
295- --Pass it to helper as authid as definer
296308 if (ut_utils.gc_diff_max_rows > l_sql_rowcount ) then
297309 ut_compound_data_helper.insert_diffs_result(l_diff_tab,l_diff_id);
298310 end if;
@@ -303,14 +315,15 @@ create or replace type body ut_compound_data_value as
303315 l_max_rows := ut_utils.gc_bc_fetch_limit;
304316 end if;
305317 end loop;
306-
318+
307319 ut_compound_data_helper.set_rows_diff(l_sql_rowcount);
308- --result is OK only if both are same
320+ --result is OK only if both are same
309321 if l_sql_rowcount = 0 and self.elements_count = l_other.elements_count then
310- l_result := 0;
322+ l_result := 0;
311323 else
312324 l_result := 1;
313325 end if;
326+
314327 return l_result;
315328
316329 end;
0 commit comments