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

Skip to content

Commit 934df67

Browse files
committed
Optimization fiurther
1 parent f82a3b5 commit 934df67

1 file changed

Lines changed: 45 additions & 56 deletions

File tree

source/core/ut_utils.pkb

Lines changed: 45 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -675,14 +675,13 @@ create or replace package body ut_utils is
675675
l_eq_end_char varchar2(1 char);
676676
l_pos binary_integer;
677677
l_end binary_integer;
678-
l_token_count binary_integer;
679-
l_has_ml_comment boolean := false;
678+
l_has_ml_comment boolean := false;
680679
begin
681680
if a_source.count = 0 then
682681
return a_source;
683682
end if;
684683

685-
-- Fast pre-scan: check if any /* exists at all if not, nothing to do — return source as-is
684+
-- Fast pre-scan to check for presence of multi-line comments; if none, return original source unmodified
686685
for i in 1 .. a_source.count loop
687686
if instr(a_source(i), '/*') > 0 then
688687
l_has_ml_comment := true;
@@ -697,20 +696,20 @@ create or replace package body ut_utils is
697696
for i in 1 .. a_source.count loop
698697
l_line := a_source(i);
699698

700-
-- Fast path: currently inside a multi-line comment, look only for closing */
699+
-- Fast path: inside multi-line comment
701700
if l_in_ml_comment then
702701
l_ml_end := instr(l_line, '*/');
703702
if l_ml_end > 0 then
704703
l_in_ml_comment := false;
705704
l_line := substr(l_line, l_ml_end + 2);
706-
-- fall through to normal scan of remainder of line, in case there are more /* comments on the same line
705+
-- fall through to normal scan
707706
else
708707
l_result(i) := '';
709708
continue;
710709
end if;
711710
end if;
712711

713-
-- Fast path: no special tokens on this line at all, just copy it to result and move on
712+
-- Fast path: no special tokens on this line
714713
if instr(l_line, '/') = 0
715714
and instr(l_line, '-') = 0
716715
and instr(l_line, '''') = 0
@@ -719,7 +718,7 @@ create or replace package body ut_utils is
719718
continue;
720719
end if;
721720

722-
-- Normal scan: consume one token at a time, advance l_remaining until end of line
721+
-- Normal scan
723722
l_remaining := l_line;
724723
l_line := null;
725724

@@ -729,83 +728,71 @@ create or replace package body ut_utils is
729728
l_ml_start := instr(l_remaining, '/*');
730729
l_comment_start := instr(l_remaining, '--');
731730
l_text_start := instr(l_remaining, '''');
732-
-- only search for q' if ' was found — q' always contains ' and would be misidentified otherwise
733-
l_eq_text_start := case when l_text_start > 0 then instr(l_remaining, 'q''') else 0 end;
734-
-- count how many tokens are present to decide if we can skip LEAST/GREATEST and just use the one that is present
735-
l_token_count := sign(l_ml_start) + sign(l_comment_start)
736-
+ sign(l_text_start) + sign(l_eq_text_start);
737-
738-
-- no special tokens left — consume remainder and stop scanning this line
739-
if l_token_count = 0 then
731+
-- q' always puts ' at l_text_start; just check the char immediately before it
732+
l_eq_text_start := case
733+
when l_text_start > 1 and substr(l_remaining, l_text_start - 1, 1) = 'q'
734+
then l_text_start - 1
735+
else 0
736+
end;
737+
-- Sentinel gc_max_plsql_source_len means "not present"; 32767 is beyond any VARCHAR2 position
738+
l_pos := least(
739+
case when l_ml_start > 0 then l_ml_start else gc_max_plsql_source_len end,
740+
case when l_comment_start > 0 then l_comment_start else gc_max_plsql_source_len end,
741+
case when l_text_start > 0 then l_text_start else gc_max_plsql_source_len end,
742+
case when l_eq_text_start > 0 then l_eq_text_start else gc_max_plsql_source_len end
743+
);
744+
745+
if l_pos = gc_max_plsql_source_len then
740746
l_line := l_line || l_remaining;
741747
exit scan_line;
742748
end if;
743749

744-
-- only one token present — skip LEAST, use GREATEST to find it since 0 means not present and any positive value is a valid position
745-
if l_token_count = 1 then
746-
l_pos := greatest(l_ml_start, l_comment_start, l_text_start, l_eq_text_start);
747-
else
748-
l_pos := least(
749-
case when l_ml_start > 0 then l_ml_start else gc_max_plsql_source_len end,
750-
case when l_comment_start > 0 then l_comment_start else gc_max_plsql_source_len end,
751-
case when l_text_start > 0 then l_text_start else gc_max_plsql_source_len end,
752-
case when l_eq_text_start > 0 then l_eq_text_start else gc_max_plsql_source_len end
753-
);
754-
end if;
755-
756-
-- q-quoted string: checked before plain quote because q' contains ' and would be misidentified
757-
if l_pos = l_eq_text_start
758-
and (l_ml_start = 0 or l_eq_text_start < l_ml_start)
759-
and (l_comment_start = 0 or l_eq_text_start < l_comment_start)
760-
and (l_text_start = 0 or l_eq_text_start < l_text_start)
761-
then
762-
l_eq_end_char := translate(substr(l_remaining, l_eq_text_start + 2, 1),gc_open_chars,gc_close_chars);
763-
l_end := instr(l_remaining, l_eq_end_char || '''', l_eq_text_start + 3);
750+
l_line := l_line || substr(l_remaining, 1, l_pos - 1);
751+
l_remaining := substr(l_remaining, l_pos);
752+
-- l_remaining now starts exactly at the token; all branch offsets below are relative to 1
753+
if l_pos = l_eq_text_start then
754+
-- q-quoted string: l_remaining starts at 'q', delimiter is at position 3
755+
l_eq_end_char := translate(substr(l_remaining, 3, 1), gc_open_chars, gc_close_chars);
756+
l_end := instr(l_remaining, l_eq_end_char || '''', 4);
764757
if l_end > 0 then
765-
l_line := l_line || substr(l_remaining, 1, l_end + 1);
758+
l_line := l_line || substr(l_remaining, 1, l_end + 1);
766759
l_remaining := substr(l_remaining, l_end + 2);
767760
else
768761
l_line := l_line || l_remaining;
769762
exit scan_line;
770763
end if;
771-
-- Multi-line comment start: skip it, look for end of comment, continue scanning line after it
772-
elsif l_pos = l_ml_start
773-
and (l_comment_start = 0 or l_ml_start < l_comment_start)
774-
and (l_text_start = 0 or l_ml_start < l_text_start)
775-
and (l_eq_text_start = 0 or l_ml_start < l_eq_text_start)
776-
then
777-
l_line := l_line || substr(l_remaining, 1, l_ml_start - 1);
778-
l_ml_end := instr(l_remaining, '*/', l_ml_start + 2);
764+
765+
elsif l_pos = l_ml_start then
766+
-- Multi-line comment: l_remaining starts at '/*', so end search starts at 3
767+
l_ml_end := instr(l_remaining, '*/', 3);
779768
if l_ml_end > 0 then
780769
l_remaining := substr(l_remaining, l_ml_end + 2);
781770
else
782771
l_in_ml_comment := true;
783772
exit scan_line;
784773
end if;
785-
-- Single-line comment: keep it, stop scanning this line since everything after -- is comment anyway
786-
elsif l_pos = l_comment_start
787-
and (l_ml_start = 0 or l_comment_start < l_ml_start)
788-
and (l_text_start = 0 or l_comment_start < l_text_start)
789-
and (l_eq_text_start = 0 or l_comment_start < l_eq_text_start)
790-
then
774+
775+
elsif l_pos = l_comment_start then
776+
-- Single-line comment: everything from here is comment, keep and stop
791777
l_line := l_line || l_remaining;
792778
exit scan_line;
793-
-- Regular string literal start: keep it, scan forward for closing quote, handle '' escaped quotes properly by skipping them and keep scanning
779+
794780
else
795-
-- scan forward continuously to handle '' escaped quotes
796-
l_end := l_text_start + 1;
781+
-- Regular string literal: l_remaining starts at the opening quote
782+
-- scan from position 2 to skip the opening quote
783+
l_end := 2;
797784
loop
798785
l_end := instr(l_remaining, '''', l_end);
799786
exit when l_end = 0;
800787
if substr(l_remaining, l_end, 2) = '''''' then
801-
l_end := l_end + 2; -- skip escaped quote, keep scanning
788+
l_end := l_end + 2; -- skip escaped quote pair
802789
else
803-
exit; -- found real closing quote
790+
exit; -- real closing quote
804791
end if;
805792
end loop;
806793

807794
if l_end > 0 then
808-
l_line := l_line || substr(l_remaining, 1, l_end);
795+
l_line := l_line || substr(l_remaining, 1, l_end);
809796
l_remaining := substr(l_remaining, l_end + 1);
810797
else
811798
l_line := l_line || l_remaining;
@@ -814,8 +801,10 @@ create or replace package body ut_utils is
814801

815802
end if;
816803
end loop scan_line;
804+
817805
l_result(i) := l_line;
818806
end loop;
807+
819808
return l_result;
820809
end replace_multiline_comments;
821810

0 commit comments

Comments
 (0)