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

Skip to content

Commit 816a1c1

Browse files
committed
Beautify sql generation
1 parent b4113fd commit 816a1c1

3 files changed

Lines changed: 125 additions & 147 deletions

File tree

source/expectations/data_values/ut_compound_data_helper.pkb

Lines changed: 115 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,8 @@ create or replace package body ut_compound_data_helper is
175175
) return tt_row_diffs is
176176
l_column_filter varchar2(32767);
177177
l_results tt_row_diffs;
178-
t1 integer;
179178
begin
180179
l_column_filter := get_columns_row_filter(a_exclude_xpath,a_include_xpath);
181-
t1 := dbms_utility.get_time;
182180

183181
execute immediate q'[with diff_info as
184182
( select act_data_id, exp_data_id,
@@ -214,9 +212,7 @@ create or replace package body ut_compound_data_helper is
214212
where act_data_id is null or exp_data_id is null]'
215213
bulk collect into l_results
216214
using a_join_by_xpath, a_diff_id, a_expected_dataset_guid,a_actual_dataset_guid;
217-
218-
dbms_output.put_line((dbms_utility.get_time - t1)/100 || ' seconds - get col info');
219-
215+
220216
return l_results;
221217
end;
222218

@@ -765,105 +761,141 @@ create or replace package body ut_compound_data_helper is
765761
return l_sql;
766762
end;
767763

768-
function generate_xmltab_stmt (a_column_info xmltype) return varchar2 is
769-
l_sql_stmt varchar2(32767);
770-
begin
771-
for i in (select /*+ CARDINALITY(xt 100) */
772-
xt.name
773-
from (select a_column_info item_data from dual) x,
774-
xmltable(
775-
'/ROW/*'
776-
passing x.item_data
777-
columns
778-
name varchar2(4000) PATH '@xml_valid_name'
779-
) xt)
780-
loop
781-
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'[']';
764+
function generate_xmltab_stmt (a_column_info ut_varchar2_list, a_inc_filter ut_varchar2_list, a_exc_filter ut_varchar2_list) return clob is
765+
l_sql_stmt clob;
766+
begin
767+
for i in 1..a_column_info.count loop
768+
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ',' end ||a_column_info(i)||q'[ varchar2(4000) PATH ']'||a_column_info(i)||q'[']';
782769
end loop;
783770
return l_sql_stmt;
784771
end;
785-
786-
function generate_equal_sql (a_column_info xmltype) return varchar2 is
787-
l_sql_stmt varchar2(32767);
772+
773+
function generate_equal_sql (a_column_info ut_varchar2_list, a_inc_filter ut_varchar2_list, a_exc_filter ut_varchar2_list) return clob is
774+
l_sql_stmt clob;
788775
begin
789-
for i in (select /*+ CARDINALITY(xt 100) */
790-
xt.name
791-
from (select a_column_info item_data from dual) x,
792-
xmltable(
793-
'/ROW/*'
794-
passing x.item_data
795-
columns
796-
name varchar2(4000) PATH '@xml_valid_name'
797-
) xt)
776+
for i in 1..a_column_info.count loop
777+
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ' and ' end ||' a.'||a_column_info(i)||q'[ = ]'||' e.'||a_column_info(i);
778+
end loop;
779+
780+
return l_sql_stmt;
781+
end;
782+
783+
function generate_join_by_on_stmt (a_join_by_xpath_tab ut_varchar2_list) return clob is
784+
l_sql_stmt clob;
785+
begin
786+
for i in (with xpaths_tab as (select column_value xpath from table(a_join_by_xpath_tab))
787+
select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
788+
from xpaths_tab)
798789
loop
799790
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;
800791
end loop;
801792
return l_sql_stmt;
802793
end;
803-
804-
function generate_not_equal_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2 is
805-
l_sql_stmt varchar2(32767);
806-
l_pk_xpath_tabs ut_varchar2_list := ut_varchar2_list();
807-
begin
808-
l_pk_xpath_tabs := ut_utils.string_to_table(a_join_by_xpath,'|');
809-
794+
795+
function generate_not_equal_sql (a_column_info ut_varchar2_list, a_join_by_xpath ut_varchar2_list) return clob is
796+
l_sql_stmt clob;
797+
begin
810798
for i in (
811-
with xpaths_tab as (select column_value xpath from table(l_pk_xpath_tabs)),
799+
with xpaths_tab as (select column_value xpath from table(a_join_by_xpath)),
812800
pk_names as (select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
813801
from xpaths_tab)
814-
select /*+ CARDINALITY(xt 100) */
815-
xt.name
816-
from (select a_column_info item_data from dual) x,
817-
xmltable(
818-
'/ROW/*'
819-
passing x.item_data
820-
columns
821-
name varchar2(4000) PATH '@xml_valid_name'
822-
) xt
823-
where not exists (select 1 from pk_names p where lower(p.name) = lower(xt.name))
824-
)
802+
select /*+ CARDINALITY(xt 100) */
803+
column_value as name
804+
from table(a_column_info) xt
805+
where not exists (select 1 from pk_names p where lower(p.name) = lower(xt.column_value))
806+
)
825807
loop
826808
l_sql_stmt := l_sql_stmt || case when l_sql_stmt is null then null else ' or ' end ||' (decode(a.'||i.name||','||' e.'||i.name||',1,0) = 0)';
827809
end loop;
828810
return l_sql_stmt;
829-
end;
811+
end;
830812

831-
function generate_join_by_on_stmt (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2 is
832-
l_sql_stmt varchar2(32767);
833-
l_pk_xpath_tabs ut_varchar2_list := ut_varchar2_list();
813+
function gen_compare_sql(a_column_info xmltype, a_exclude_xpath varchar2,
814+
a_include_xpath varchar2, a_join_by_xpath varchar2) return clob is
815+
l_compare_sql clob;
816+
l_column_filter varchar2(32767);
817+
l_temp_string varchar2(32767);
834818

835-
begin
836-
l_pk_xpath_tabs := ut_utils.string_to_table(a_join_by_xpath,'|');
837-
838-
for i in (with xpaths_tab as (select column_value xpath from table(l_pk_xpath_tabs))
839-
select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
840-
from xpaths_tab)
841-
loop
842-
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;
843-
end loop;
844-
return l_sql_stmt;
845-
end;
846-
847-
function generate_join_null_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2 is
848-
l_sql_stmt varchar2(32767);
849819
l_pk_xpath_tabs ut_varchar2_list := ut_varchar2_list();
820+
l_xpath_inc_tab ut_varchar2_list := ut_varchar2_list();
821+
l_xpath_exc_tab ut_varchar2_list := ut_varchar2_list();
822+
l_col_info_tab ut_varchar2_list := ut_varchar2_list();
823+
824+
l_ut_owner varchar2(250) := ut_utils.ut_owner;
825+
l_xmltable_stmt clob;
826+
l_where_stmt clob;
850827

828+
function get_columns_names (a_xpath_tab in ut_varchar2_list) return ut_varchar2_list is
829+
l_names_tab ut_varchar2_list := ut_varchar2_list();
830+
begin
831+
select REGEXP_SUBSTR (column_value,'[^(/\*/)](.+)$')
832+
bulk collect into l_names_tab
833+
from table(a_xpath_tab);
834+
return l_names_tab;
835+
end;
836+
837+
function get_columns_info (a_columns_info in xmltype) return ut_varchar2_list is
838+
l_columns_info ut_varchar2_list := ut_varchar2_list();
839+
begin
840+
select /*+ CARDINALITY(xt 100) */
841+
xt.name
842+
bulk collect into l_columns_info
843+
from (select a_column_info item_data from dual) x,
844+
xmltable(
845+
'/ROW/*'
846+
passing x.item_data
847+
columns
848+
name varchar2(4000) PATH '@xml_valid_name'
849+
) xt;
850+
return l_columns_info;
851+
end;
852+
851853
begin
852-
l_pk_xpath_tabs := ut_utils.string_to_table(a_join_by_xpath,'|');
853-
854-
for i in (with xpaths_tab as (select column_value xpath from table(l_pk_xpath_tabs))
855-
select REGEXP_SUBSTR (xpath,'[^(/\*/)](.+)$') name
856-
from xpaths_tab)
857-
loop
858-
l_sql_stmt := l_sql_stmt || case
859-
when l_sql_stmt is null
860-
then null
861-
else ' or '
862-
end ||' a.'||i.name||q'[ is null or ]'||' e.'||i.name||q'[ is null]';
863-
end loop;
864-
return l_sql_stmt;
865-
end;
866-
854+
dbms_lob.createtemporary(l_compare_sql, true);
855+
l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
856+
l_pk_xpath_tabs := get_columns_names(ut_utils.string_to_table(a_join_by_xpath,'|'));
857+
l_xpath_inc_tab := get_columns_names(ut_utils.string_to_table(a_include_xpath,'|'));
858+
l_xpath_exc_tab := get_columns_names(ut_utils.string_to_table(a_exclude_xpath,'|'));
859+
l_col_info_tab := get_columns_info(a_column_info);
860+
l_xmltable_stmt := generate_xmltab_stmt(l_col_info_tab, l_xpath_inc_tab, l_xpath_exc_tab);
861+
862+
l_temp_string := q'[with exp as (select ucd.*,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,]'
863+
||q'[xmltable('/ROWSET/ROW' passing x.item_data columns ]';
864+
ut_utils.append_to_clob(l_compare_sql, l_temp_string);
865+
ut_utils.append_to_clob(l_compare_sql,l_xmltable_stmt);
866+
867+
l_temp_string := q'[ ,item_data xmltype PATH '*' ) ucd),]'
868+
||q'[act as (select ucd.*, 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,]'
869+
||q'[xmltable('/ROWSET/ROW' passing x.item_data columns ]' ;
870+
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
871+
ut_utils.append_to_clob(l_compare_sql,l_xmltable_stmt||q'[ ,item_data xmltype PATH '*') ucd)]');
872+
873+
if a_join_by_xpath is null then
874+
-- If no key defined do the join on all columns
875+
l_temp_string := q'[select xmlelement( name "ROW", a.item_data) act_item_data, a.data_id act_data_id, xmlelement( name "ROW", e.item_data) exp_item_data, e.data_id exp_data_id, rownum item_no ]'
876+
|| q'[from act a full outer join exp e on ( ]';
877+
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
878+
ut_utils.append_to_clob(l_compare_sql,ut_compound_data_helper.generate_equal_sql(l_col_info_tab, l_xpath_inc_tab, l_xpath_exc_tab)||q'[ ) where a.data_id is null or e.data_id is null]');
879+
else
880+
-- If key defined do the join or these and where on diffrences
881+
l_temp_string := 'select a.item_data act_item_data, a.data_id act_data_id,'
882+
||' e.item_data exp_item_data, e.data_id exp_data_id, rownum item_no from act a full outer join exp e on ( ';
883+
ut_utils.append_to_clob(l_compare_sql,l_temp_string);
884+
885+
ut_utils.append_to_clob(l_compare_sql,ut_compound_data_helper.generate_join_by_on_stmt (l_pk_xpath_tabs)||' ) where ');
886+
887+
l_where_stmt := ut_compound_data_helper.generate_not_equal_sql(l_col_info_tab, l_pk_xpath_tabs);
888+
case
889+
when l_where_stmt is null then
890+
null;
891+
else
892+
ut_utils.append_to_clob(l_compare_sql,'( '||l_where_stmt||' ) or ( a.data_id is null or e.data_id is null )');
893+
end case;
894+
end if;
895+
896+
return l_compare_sql;
897+
end;
898+
867899
procedure insert_diffs_result(a_diff_tab t_diff_tab, a_diff_id raw) is
868900
begin
869901
forall idx in 1..a_diff_tab.count

source/expectations/data_values/ut_compound_data_helper.pks

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,9 @@ create or replace package ut_compound_data_helper authid definer is
9696
procedure update_row_and_pk_hash(a_self_data_id in raw, a_other_data_id in raw, a_exclude_xpath varchar2,
9797
a_include_xpath varchar2, a_join_by_xpath varchar2);
9898

99-
function generate_xmltab_stmt (a_column_info xmltype) return varchar2;
100-
101-
function generate_equal_sql (a_column_info xmltype) return varchar2;
102-
103-
function generate_not_equal_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2;
104-
105-
function generate_join_by_on_stmt (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2;
106-
107-
function generate_join_null_sql (a_column_info xmltype, a_join_by_xpath varchar2) return varchar2;
108-
99+
function gen_compare_sql(a_column_info xmltype, a_exclude_xpath varchar2,
100+
a_include_xpath varchar2, a_join_by_xpath varchar2) return clob;
101+
109102
procedure insert_diffs_result(a_diff_tab t_diff_tab, a_diff_id raw);
110103

111104
procedure set_rows_diff(a_rows_diff integer);

source/expectations/data_values/ut_compound_data_value.tpb

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -270,17 +270,9 @@ create or replace type body ut_compound_data_value as
270270

271271
member function compare_implementation_by_sql(a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2, a_join_by_xpath varchar2, a_inclusion_compare boolean := false) return integer is
272272

273-
l_ut_owner varchar2(250) := ut_utils.ut_owner;
274273
l_actual ut_data_value_refcursor := treat(a_other as ut_data_value_refcursor);
275274
l_diff_id ut_compound_data_helper.t_hash;
276-
277-
--Variable for dynamic SQL - to review and simplify ??
278-
l_table_stmt clob;
279-
l_where_stmt clob;
280-
l_join_by_stmt clob;
281-
l_exec_sql clob;
282-
l_compare_sql clob;
283-
275+
284276
l_other ut_compound_data_value;
285277
l_result integer;
286278
--We will start with number od differences being displayed.
@@ -289,55 +281,18 @@ create or replace type body ut_compound_data_value as
289281
l_loop_curs sys_refcursor;
290282
l_diff_tab ut_compound_data_helper.t_diff_tab;
291283
l_sql_rowcount integer :=0;
292-
293-
--TEST
294-
t1 pls_integer;
295284

296285
begin
297286

298-
-- TODO : Add column filters!!!!
299-
l_other := treat(a_other as ut_compound_data_value);
300-
l_table_stmt := ut_compound_data_helper.generate_xmltab_stmt(l_actual.columns_info);
301-
l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
302-
303-
l_compare_sql := q'[with exp as (select xt.*,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,]'
304-
||q'[xmltable('/ROWSET/ROW' passing x.item_data columns ]'
305-
||l_table_stmt||q'[ ,item_data xmltype PATH '*' ) xt),]'
306-
||q'[act as (select xt.*, 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,]'
307-
||q'[xmltable('/ROWSET/ROW' passing x.item_data columns ]' ||
308-
l_table_stmt||q'[ ,item_data xmltype PATH '*') xt)]';
309-
310-
if a_join_by_xpath is null then
311-
-- If no key defined do the join on all columns
312-
l_join_by_stmt := ut_compound_data_helper.generate_equal_sql(l_actual.columns_info);
313-
l_compare_sql := l_compare_sql || q'[select xmlelement( name "ROW", a.item_data) act_item_data, a.data_id act_data_id, xmlelement( name "ROW", e.item_data) exp_item_data, e.data_id exp_data_id, rownum item_no ]'
314-
|| q'[from act a full outer join exp e on ( ]'
315-
||l_join_by_stmt||q'[ ) where a.data_id is null or e.data_id is null]';
316-
else
317-
-- If key defined do the join or these and where on diffrences
318-
l_where_stmt := ut_compound_data_helper.generate_not_equal_sql(l_actual.columns_info, a_join_by_xpath);
319-
--l_join_is_null := ut_compound_data_helper.generate_join_null_sql(l_actual.columns_info, a_join_by_xpath);
320-
l_join_by_stmt := ut_compound_data_helper.generate_join_by_on_stmt (l_actual.columns_info, a_join_by_xpath);
321-
l_compare_sql := l_compare_sql || 'select a.item_data act_item_data, a.data_id act_data_id,'
322-
||' e.item_data exp_item_data, e.data_id exp_data_id, rownum item_no from act a full outer join exp e on ( '
323-
||l_join_by_stmt||' ) '
324-
||' where '||
325-
case
326-
when l_where_stmt is null then
327-
null
328-
else
329-
'( '||l_where_stmt||' ) or'
330-
end
331-
||'( a.data_id is null or e.data_id is null )';
332-
end if;
333-
334-
open l_loop_curs for l_compare_sql using self.data_id,l_actual.data_id;
335-
287+
l_other := treat(a_other as ut_compound_data_value);
288+
l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
289+
290+
open l_loop_curs for ut_compound_data_helper.gen_compare_sql(l_actual.columns_info, a_exclude_xpath,
291+
a_include_xpath, a_join_by_xpath) using self.data_id,l_actual.data_id;
336292
loop
337293
fetch l_loop_curs bulk collect into l_diff_tab limit l_max_rows;
338294
exit when l_diff_tab.count = 0;
339295
--Pass it to helper as authid as definer
340-
341296
if (ut_utils.gc_diff_max_rows > l_sql_rowcount ) then
342297
ut_compound_data_helper.insert_diffs_result(l_diff_tab,l_diff_id);
343298
end if;
@@ -347,11 +302,9 @@ create or replace type body ut_compound_data_value as
347302
if (ut_utils.gc_diff_max_rows <= l_sql_rowcount and l_max_rows != ut_utils.gc_bc_fetch_limit ) then
348303
l_max_rows := ut_utils.gc_bc_fetch_limit;
349304
end if;
350-
351305
end loop;
352306

353-
ut_compound_data_helper.set_rows_diff(l_sql_rowcount);
354-
307+
ut_compound_data_helper.set_rows_diff(l_sql_rowcount);
355308
--result is OK only if both are same
356309
if l_sql_rowcount = 0 and self.elements_count = l_other.elements_count then
357310
l_result := 0;

0 commit comments

Comments
 (0)