@@ -116,18 +116,89 @@ create or replace type body ut_data_value_refcursor as
116116 return l_result_string;
117117 end;
118118
119+ member function get_data_diff(a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2,
120+ a_join_by_xpath varchar2, a_unordered boolean,a_join_by_list ut_varchar2_list:=ut_varchar2_list()) return clob is
121+ c_max_rows integer := ut_utils.gc_diff_max_rows;
122+ l_result clob;
123+ l_results ut_utils.t_clob_tab := ut_utils.t_clob_tab();
124+ l_message varchar2(32767);
125+ l_ut_owner varchar2(250) := ut_utils.ut_owner;
126+ l_diff_row_count integer;
127+ l_actual ut_compound_data_value;
128+ l_diff_id ut_compound_data_helper.t_hash;
129+ l_row_diffs ut_compound_data_helper.tt_row_diffs;
130+ l_compare_type varchar2(10);
131+ l_self ut_compound_data_value;
132+
133+ function get_diff_message (a_row_diff ut_compound_data_helper.t_row_diffs,a_is_unordered boolean) return varchar2 is
134+ begin
135+
136+ if a_is_unordered then
137+ if a_row_diff.pk_value is not null then
138+ return ' PK '||a_row_diff.pk_value||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
139+ else
140+ return rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
141+ end if;
142+ else
143+ return ' Row No. '||a_row_diff.rn||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
144+ end if;
145+ end;
146+
147+ begin
148+ if not a_other is of (ut_compound_data_value) then
149+ raise value_error;
150+ end if;
151+
152+ l_actual := treat(a_other as ut_compound_data_value);
153+
154+ dbms_lob.createtemporary(l_result,true);
155+
156+ l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_actual.data_id);
157+
158+ -- First tell how many rows are different
159+ l_diff_row_count := ut_compound_data_helper.get_rows_diff_count;
160+ --TODO : Change message when the types not matching
161+ if l_diff_row_count > 0 then
162+ l_row_diffs := ut_compound_data_helper.get_rows_diff(
163+ self.data_id, l_actual.data_id, l_diff_id, c_max_rows, a_exclude_xpath,
164+ a_include_xpath, a_join_by_xpath, a_other is of (ut_data_value_refcursor), a_unordered);
165+ l_message := chr(10)
166+ ||'Rows: [ ' || l_diff_row_count ||' differences'
167+ || case when l_diff_row_count > c_max_rows and l_row_diffs.count > 0 then ', showing first '||c_max_rows end
168+ ||' ]'||chr(10)|| case when l_row_diffs.count = 0 then ' All rows are different as the columns are not matching.' else null end;
169+ ut_utils.append_to_clob( l_result, l_message );
170+ for i in 1 .. l_row_diffs.count loop
171+ l_results.extend;
172+ l_results(l_results.last) := get_diff_message(l_row_diffs(i),a_unordered);
173+ end loop;
174+ ut_utils.append_to_clob(l_result,l_results);
175+ else
176+ l_message:= chr(10)||'Rows: [ all different ]'||chr(10)||' All rows are different as the columns are not matching.';
177+ ut_utils.append_to_clob( l_result, l_message );
178+ end if;
179+ return l_result;
180+ end;
181+
119182 member function diff( a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2, a_join_by_xpath varchar2,
120183 a_unordered boolean := false, a_join_by_list ut_varchar2_list:=ut_varchar2_list() ) return varchar2 is
121184 l_result clob;
122185 l_results ut_utils.t_clob_tab := ut_utils.t_clob_tab();
123186 l_result_string varchar2(32767);
124187 l_actual ut_data_value_refcursor;
125188 l_column_diffs ut_compound_data_helper.tt_column_diffs := ut_compound_data_helper.tt_column_diffs();
126- l_exclude_xpath varchar2(32767) := a_exclude_xpath;
127189
190+ l_act_cols ut_cursor_column_tab;
191+ l_exp_cols ut_cursor_column_tab;
192+
128193 l_missing_pk ut_compound_data_helper.tt_missing_pk := ut_compound_data_helper.tt_missing_pk();
129194 l_col_diffs ut_compound_data_helper.tt_column_diffs := ut_compound_data_helper.tt_column_diffs();
130195
196+ c_max_rows integer := ut_utils.gc_diff_max_rows;
197+ l_diff_id ut_compound_data_helper.t_hash;
198+ l_diff_row_count integer;
199+ l_row_diffs ut_compound_data_helper.tt_row_diffs;
200+ l_message varchar2(32767);
201+
131202 function get_col_diff_text(a_col ut_compound_data_helper.t_column_diffs) return varchar2 is
132203 begin
133204 return
@@ -155,59 +226,90 @@ create or replace type body ut_data_value_refcursor as
155226 return l_message;
156227 end;
157228
158- function add_incomparable_cols_to_xpath(
159- a_column_diffs ut_compound_data_helper.tt_column_diffs, a_exclude_xpath varchar2
160- ) return varchar2 is
229+ function remove_incomparable_cols( a_cursor_details ut_cursor_column_tab,a_column_diffs ut_compound_data_helper.tt_column_diffs) return ut_cursor_column_tab is
161230 l_incomparable_cols ut_varchar2_list := ut_varchar2_list();
162- l_result varchar2(32767) ;
231+ l_filter_out ut_cursor_column_tab ;
163232 begin
164233 for i in 1 .. a_column_diffs.count loop
165234 if a_column_diffs(i).diff_type in ('-','+') then
166235 l_incomparable_cols.extend;
167- l_incomparable_cols(l_incomparable_cols.last) := ut_utils.xmlgen_escaped_string( coalesce(a_column_diffs(i).expected_name,a_column_diffs(i).actual_name) );
168- end if;
236+ l_incomparable_cols(l_incomparable_cols.last) := coalesce(a_column_diffs(i).expected_name,a_column_diffs(i).actual_name);
237+ end if;
169238 end loop;
170- l_result := ut_utils.to_xpath(l_incomparable_cols);
171- if a_exclude_xpath is not null and l_result is not null then
172- l_result := l_result ||'|'||a_exclude_xpath;
173- else
174- l_result := coalesce(a_exclude_xpath, l_result);
175- end if;
176- return l_result;
239+
240+ return ut_compound_data_helper.remove_incomparable_cols(a_cursor_details,l_incomparable_cols);
177241 end;
178242
243+ function get_diff_message (a_row_diff ut_compound_data_helper.t_row_diffs,a_is_unordered boolean) return varchar2 is
244+ begin
245+
246+ if a_is_unordered then
247+ if a_row_diff.pk_value is not null then
248+ return ' PK '||a_row_diff.pk_value||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
249+ else
250+ return rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
251+ end if;
252+ else
253+ return ' Row No. '||a_row_diff.rn||' - '||rpad(a_row_diff.diff_type,10)||a_row_diff.diffed_row;
254+ end if;
255+ end;
256+
179257 begin
180258 if not a_other is of (ut_data_value_refcursor) then
181259 raise value_error;
182260 end if;
183261 l_actual := treat(a_other as ut_data_value_refcursor);
184262
185- dbms_lob.createtemporary(l_result,true);
263+ l_act_cols := l_actual.cursor_details.cursor_info;
264+ l_exp_cols := self.cursor_details.cursor_info;
186265
266+ dbms_lob.createtemporary(l_result,true);
187267 --diff columns
188268 if not self.is_null and not l_actual.is_null then
189269 l_column_diffs := ut_compound_data_helper.get_columns_diff(self.cursor_details.cursor_info,l_actual.cursor_details.cursor_info);
190270
191271 if l_column_diffs.count > 0 then
192272 ut_utils.append_to_clob(l_result,chr(10) || 'Columns:' || chr(10));
193273 end if;
194-
195274 for i in 1 .. l_column_diffs.count loop
196275 l_results.extend;
197276 l_results(l_results.last) := get_col_diff_text(l_column_diffs(i));
198277 end loop;
199278 ut_utils.append_to_clob(l_result, l_results);
200- l_exclude_xpath := add_incomparable_cols_to_xpath(l_column_diffs, a_exclude_xpath);
279+ l_act_cols := remove_incomparable_cols(l_actual.cursor_details.cursor_info,l_column_diffs);
280+ l_exp_cols := remove_incomparable_cols(self.cursor_details.cursor_info,l_column_diffs);
201281 end if;
202282
203283 --check for missing pk
204284 if a_join_by_list.count > 0 then
205- l_missing_pk := ut_compound_data_helper.get_missing_pk(self.cursor_details.cursor_info,l_actual.cursor_details.cursor_info ,a_join_by_list);
285+ l_missing_pk := ut_compound_data_helper.get_missing_pk(l_exp_cols,l_act_cols ,a_join_by_list);
206286 end if;
207287
208288 --diff rows and row elements if the pk is not missing
209289 if l_missing_pk.count = 0 then
210- ut_utils.append_to_clob(l_result, self.get_data_diff(a_other, a_exclude_xpath, a_include_xpath, a_join_by_xpath, a_unordered));
290+ l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_actual.data_id);
291+
292+ -- First tell how many rows are different
293+ l_diff_row_count := ut_compound_data_helper.get_rows_diff_count;
294+ l_results := ut_utils.t_clob_tab();
295+ if l_diff_row_count > 0 then
296+ l_row_diffs := ut_compound_data_helper.get_rows_diff(
297+ self.data_id, l_actual.data_id, l_diff_id, c_max_rows, a_exclude_xpath,
298+ a_include_xpath, a_join_by_xpath, a_other is of (ut_data_value_refcursor), a_unordered);
299+ l_message := chr(10)
300+ ||'Rows: [ ' || l_diff_row_count ||' differences'
301+ || case when l_diff_row_count > c_max_rows and l_row_diffs.count > 0 then ', showing first '||c_max_rows end
302+ ||' ]'||chr(10)|| case when l_row_diffs.count = 0 then ' All rows are different as the columns are not matching.' else null end;
303+ ut_utils.append_to_clob( l_result, l_message );
304+ for i in 1 .. l_row_diffs.count loop
305+ l_results.extend;
306+ l_results(l_results.last) := get_diff_message(l_row_diffs(i),a_unordered);
307+ end loop;
308+ ut_utils.append_to_clob(l_result,l_results);
309+ else
310+ l_message:= chr(10)||'Rows: [ all different ]'||chr(10)||' All rows are different as the columns are not matching.';
311+ ut_utils.append_to_clob( l_result, l_message );
312+ end if;
211313 else
212314 ut_utils.append_to_clob(l_result,chr(10) || 'Unable to join sets:' || chr(10));
213315 for i in 1 .. l_missing_pk.count loop
@@ -242,13 +344,11 @@ create or replace type body ut_data_value_refcursor as
242344
243345 l_actual := treat(a_other as ut_data_value_refcursor);
244346
245- --if we join by key and key is missing fail and report error
246347 if a_join_by_list.count > 0 then
247348 l_pk_missing_tab := ut_compound_data_helper.get_missing_pk(self.cursor_details.cursor_info,l_actual.cursor_details.cursor_info,a_join_by_list);
248349 l_result := case when (l_pk_missing_tab.count > 0) then 1 else 0 end;
249350 end if;
250351
251-
252352 if l_result = 0 then
253353 if (self.cursor_details is not null and l_actual.cursor_details is not null) and (self.cursor_details != l_actual.cursor_details) then
254354 l_result := 1;
0 commit comments