Language Management

I’ve been playing with the PL/SQL parser in Language Management and I have several questions that I’m hoping someone can help me with (I’ve searched but haven’t found much concrete documentation on the various options). I’m working 10.5.0.41.

  1. I’m thinking the Toad_ rules are built-in and rely on reference to user_tables or something like that because I can’t copy those rules and have them work. Is that right? Is there any way for me to copy this functionality?

  2. What is the relevance of the (?r) in the pattern “(?r)[\w$#]+”. It looks a little like an extended pattern in Perl regex but I think it would be ?R to be recursive and it doesn’t appear that recursivity would be relevant.

  3. How does the Public Package Procedure expression work “DBMS_\w+?.\w+”. The ungreedy quantifier seems to match DBMS_LOB.S rather than DBMS_LOB.SUBSTR (when I use Oracle regexp_substr). Is this a bug in TOAD or is this a weird non-standard implementation in Oracle?

  4. I gather that not a parent means that the rule can’t be nested (SELECT clause ends with a ‘;’ but an inner SELECT does not while an IF…END IF; can include a nested IF…END IF;). I don’t understand what ‘strict’ does.

  5. Lastly, I’m trying to modify the DML Start to work like the if start in drawing a staple box around the “SELECT” and the “;”. However, when I change the style to Current block, the Caret position to In the range, choose Select minimal range and Draw block staple it doesn’t seem to work. Any guidance? Is the fact that the last token is a symbol and not an identifier frustrate the rule?

Thanks in advance for your patience with all these questions. I just found this group after having searched the web for any hint on these topics.

  1. No. Those rule names must exist as-is because Toad looks for them by name in the PL/SQL language only when a connection is made. If found, Toad automatically populates the rule with your object names to support the highlighting. If you clone the rule then it has a different name and Toad will not populate it. What use case do you have for wanting to clone it?

  2. Interesting. I’ve never paid much attention to the modifier being used there and don’t see any reference to it on http://www.regular-expressions.info. I’ve sent the component developer an email inquiring about it. It’s possibly something custom that is in the editor component as it uses a custom regex engine and not any of the standard ones that are out there.

  3. The lazy plus (+?) seems to be unnecessary. I’ve removed it locally to be sure and I see no differences. It looks like it’s just a mistake, but doesn’t affect the regex match either way. You’ll see the same behavior with or without the ?. If it is intentional then it’s because the custom regex engine has a way to override the default word characters. If that list can be overridden to include “.” then the lazy plus would be required. I’ll investigate that before making any permanent changes. Feel free to modify that regex if you like.

4.Think of “Strict” as being immediate parent. If strict it checked, the parent rule must be the immediate parent. If strict is false, the parent rule must be an ancestor. Consider the following example. I’ve created a new rule named “TEST” and moved it up to the top of the rules list. I set it as a tag detector rule with style of string. On the conditions tab I set a single condition to look for an identifier named “test” and on the advanced tab I set the parent rule to “Begin” (Begin start in your Toad I think), checked strict and cancel next rules. In the Editor I have the following text.

begin
if 1=1
test – This is not highlighted because the immediate parent is an IF block
end if;

test; -- This is highlighted because the immediate parent is BEGIN

end;

  1. I’ll need to investigate this in more detail. It appears as though the syntax highlighter is not scanning backwards far enough at times. This is possibly by design, but there may be a way to improve upon this. The syntax highlighter scans from the start of a line and invalidates everything that follows it. So, if I type…

SELECT * FROM EMP;

And move the caret to before the E in EMP and press return then I see the block staple.

However, if I type…

SELECT * FROM
EMP

And then add the closing ‘;’ to the statement it does not draw the staple because it has started evaluating from the start of the line of your last edit. If you move the caret to any line above EMP; and make an edit the syntax highlighting is invalidated from that position to the end and the staple is drawn.

Michael

Thanks Michael.

I’m trying my hand at an alternative (more involved) styling of my PL/SQL. I wanted to do so without impacting the existing implementation. I guess I’ll simply have to export/import if I wanted to preserve the original implementation.

As to point 3, I’m not sure why you don’t simply use ‘DBMS_\w+’. The issue I’m seeing seems to be a bug with the Oracle regexp_substr implementation (unless I’m understanding the lazy quantifier incorrectly).

Thanks for your explanation of strict. I looked again through the TOAD help and found a similar explanation. I don’t know how I missed it before.

On the parsing implementation you have the pattern associated with String Q5 as
(?s)q’!.*?((!’)|\Z) – this is in both 10.5 and 11.0

Might I suggest the following replacement as it covers the other cases, other than Q1 through Q4, for Oracle’s alternative quoting mechanism [e.g. q’Abl’ahblahb’lahA’ is not covered by Q1 through Q5]
(?s)q’([^[:space:][(\

With regard to the TOAD help on the Rules Tab I find this:
"Rules can have multiple conditions, or only one. All conditions are applied in numerical order, from 1 to 2, and so on.

Rules are, like Parser categories, applied in the order they are listed in the Rules Names list. If a higher priority rule is satisfied, Toad will not apply later rules."

The last sentence doesn’t make sense to me as I would think that all rules are applied in order to handle situations where applicable rules are nested (Keyword and Case --or-- BEGIN and IF).
Joseph

Oops.
(?s)q’([^[:space:][(
= Joseph

I would backup the default PL/SQL language and create a new one having the same name if you are looking for large scale customization. Worst case scenario, if you get into a pickle, close Toad and locate the LexLib.lxl file in your ...\User Files folder for Toad 11 and remove it. Restart Toad and it will get you into a fresh install state WRT the language management stuff.

As to point 3, I'm not sure why you don't simply use 'DBMS_\w+'.

You can use "DBMS_\w+.\w+" if you prefer. "DBMS_\w+" will not suffice as it won't match "DMBS_OUTPUT.PUT_LINE" because "." is not a word character. I don't see where it makes a difference one way or the other as it is defined now. I have not confirmed with the component developer if it makes any difference in his regex implementation, but if you want to treat Perl regex syntax as a standard, it does not, unless there are some performance hits when specifying it when unnecessary. I use www.regular-expressions.info as my resource. I am unfamiliar with Oracle's regex engine and try to treat Perl's implementation as the standard. It seems that every time a new one is introduced some new twist is put into it, our editor component included. Perhaps Oracle treats the lazy plus differently.

Might I suggest the following replacement as it covers the other cases

It does not. Your regex suggests that q'(It's a test(' is correct when I think the reference suggests that q'(It's a test)' would be correct. Thus, your \1 would not match in many cases. Many of the characters require their counterpart to work. { }, , (), <>, etc. Your updated one (from the latest email) is also incorrect for the same reason. If you typically use one style of q-string syntax then I'd setup a single rule to handle that and remove the others.

Rules are, like Parser categories, applied in the order they are listed in the Rules Names list.

This needs a little revision. If the "cancel next rules" (or similarly named option) for a particular rule is checked, that statement is true. If it is unchecked, rule processing continues.

Michael

I was thinking when \w matched alphanumeric or ‘_’ I thought the numeric component included ‘.’. It doesn’t. My mistake.

As for the alternative quote delimiter

select q’(abc)’ from dual
Q’(ABC)’
abc

select q’)abc)’ from dual
Q’)ABC)’
abc

select q’(abc(’ from dual
ORA-01756: quoted string not properly terminated

which is why the pattern I suggested specifically exclude the characters '({
= Joseph

I see. When you said “the other cases” I assumed you meant you had a single regular expression to eliminate all String Q1 - Q5, not that Q5 could represent the other N possibilities that Q1-Q4 did not cover. That should work fine.

Thanks,
Michael