2013-06-25 1 views
1

Я пытаюсь написать собственное правило в сонаре (plsql) с помощью правила копирования xpath. Задача этого правила состоит в том, чтобы пометить инструкцию rollback to savepoint, где отсутствует инструкция сохранения точки.XPath-1.0: отметьте узел, где отсутствует противоположный узел

Для 2 и 3 точки сохранения отката отчетности AST (Abstract Syntax Tree) выглядит следующим образом:

<PROCEDURE_DEFINITION> 
    ... 
    <SAVEPOINT> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spA" /> 
    <SEMICOLON tokenValue=";" /> 
    </SAVEPOINT> 
    ... 
    <SAVEPOINT> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spB" /> 
    <SEMICOLON tokenValue=";" /> 
    </SAVEPOINT> 
    ... 
    <ROLLBACK> 
    <IDENTIFIER tokenValue="ROLLBACK" /> 
    <TO /> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spB" /> 
    <SEMICOLON tokenValue=";" /> 
    </ROLLBACK> 
    ... 
    <ROLLBACK> 
    <IDENTIFIER tokenValue="ROLLBACK" /> 
    <TO /> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spA" /> 
    <SEMICOLON tokenValue=";" /> 
    </ROLLBACK> 
    ... 
    <ROLLBACK> 
    <IDENTIFIER tokenValue="ROLLBACK" /> 
    <TO /> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spX" /> 
    <SEMICOLON tokenValue=";" /> 
    </ROLLBACK> 
    ... 
</PROCEDURE_DEFINITION> 

Я ищу XPath запрос, который отмечает последний откат, потому что точка сохранения SPX отсутствует. Но этот XPath марка последней как откатов

//PROCEDURE_DEFINITION//ROLLBACK[ 
    IDENTIFIER[ 
     @tokenValue = 
      ./ancestor::PROCEDURE_DEFINITION 
       //SAVEPOINT/IDENTIFIER[2]/@tokenValue 
    ] 
] 

Любые предложения?

EDIT:
Я нашел это неоптимальное решение:

//PROCEDURE_DEFINITION//ROLLBACK 
[ 
    not(
    ./IDENTIFIER[3]/@tokenValue = 
    ancestor::PROCEDURE_DEFINITION//SAVEPOINT/IDENTIFIER[2]/@tokenValue 
) 
] 

PLSQL чувствителен к регистру. Но когда я добавляю функцию перевода, я получаю отмеченный первый и последний узел ROLLBACK. Я думаю, что все имена отката будут согласованы с именем первой точки сохранения?

ответ

1

Прежде всего, в соответствии с AST вы показываете, как мне кажется, что это/SQL кода PL вы хотите запустить XPath запрос на:

DECLARE 
    PROCEDURE foo AS 
    BEGIN 
    SAVEPOINT spA; 
    SAVEPOINT spB; 

    ROLLBACK spB; -- Compliant 
    ROLLBACK spA; -- Compliant 

    ROLLBACK spX; -- Non-Compliant 
    END; 
BEGIN 
    NULL; 
END; 
/

Когда я запускаю свой первый запрос XPath с использованием инструментария SSL/PL/SQL, откаты от «spB» и «spA» выбраны, но не «spX».

Ваш второй запрос XPath выбирает все из них.

Мне кажется, что вы хотите выбрать только «spX», так как нет соответствующей точки сохранения.

тривиальное изменение вашего первого запрос позволяет полностью изменить выбранные узлы, отрицая условие использования нет():

//PROCEDURE_DEFINITION//ROLLBACK[ 
    not(IDENTIFIER[ 
     @tokenValue = 
      ./ancestor::PROCEDURE_DEFINITION 
       //SAVEPOINT/IDENTIFIER[2]/@tokenValue 
    ]) 
] 

Но я бы на самом деле рекомендую вам отказаться от PROCEDURE_DEFINITION части запроса, так как Заявления SAVEPOINT и ROLLBACK также действительны в рамках функций или анонимных блоков:

//ROLLBACK[not(IDENTIFIER[@tokenValue = //SAVEPOINT/IDENTIFIER[2]/@tokenValue])] 
+0

Спасибо Dinesh. Вы догадались, что правильно скорректируйте код PL/SQL (эта процедура является частью пакета). В любом случае ваш запрос xpath wokrs прекрасен. Но он не работает в этом «спасительном резерве SpA; rollback spA;», потому что PL/SQL является случайным по сравнению с XPath. – MintiSE

+0

Вы правы @MintiSE, в то время как это разрешимо в чистом XPath 1.0, у нас есть билет на SSLR, чтобы сделать это намного проще: [SSLR-310] (http://jira.sonarsource.com/browse/SSLR-310) –

+0

Кроме того, FYI, это правило будет включено в следующий выпуск плагинов PL/SQL, поскольку он ценен для всех (а не только для вас): [PLSQL-443] (http://jira.sonarsource.com/browse/ PLSQL-443) –