sql комментарии в коде

technology 792180 1920 Операционные системы

Иллюстрированный самоучитель по PostgreSQL

Комментарии

Комментарием называется фрагмент обычного текста, оформленный специальным образом и внедренный в код SQL. Комментарии не влияют на выполнение программы, поскольку PostgreSQL удаляет их из входного потока и интерпретирует как обычные пропуски. Существует две разновидности комментариев: однострочные и многострочные.

Однострочные комментарии начинаются с двух дефисов () и либо находятся в отдельной строке, либо следуют за лексемами SQL (модуль лексического разбора PostgreSQL не считает комментарии лексемами, а все символы, следующие за последовательностью , интерпретирует как пропуски). Пример однострочного комментария приведен в листинге 3.11.

Листинг 3.11. Однострочные комментарии.

Многострочные комментарии начинаются с последовательности /* и завершаются последовательностью */. Такой способ оформления комментариев хорошо знаком программистам С, но между интерпретатором PostgreSQL и компилятором С существует одно принципиальное отличие: комментарии PostgreSQL могут быть вложенными. Иначе говоря, если внутри многострочного комментария имеется другой многострочный комментарий, то закрывающая последовательность */ внутреннего комментария не закрывает внешний комментарий. Пример многострочного комментария приведен в листинге 3.12.

Листинг 3.12. Многострочные комментарии.

Допустим, имеется файл с кодом SQL, в котором необходимо закомментировать большой фрагмент и передать остаток PostgreSQL для интерпретации и выполнения. Если в этом фрагменте встречаются многострочные комментарии, PostgreSQL правильно заключает, что закрывающая последовательность */ относится к последнему открытому комментарию, а не ко всему закомментированному блоку.

Примечание
Звездочка (без смежного символа косой черты) не имеет особой интерпретации в комментариях. Дополнительные звездочки были включены в листинг 3.12 исключительно по эстетическим сообщениям
.

Выводы

Итак, команда SQL состоит из отдельных лексем, каждая из которых может быть ключевым словом, идентификатором, защищенным идентификатором, константой или специальным символом. В табл. 3.7 структура команд SQL поясняется на примере простой команды SELECT.

Таблица 3.7. Простой запрос SQL.

SELECT id, name FROM states
Тип лексемы Ключевое слово Идентификаторы Ключевое слово Идентификатор
Описание Команда Имена полей Имя секции Имя таблицы

Как видно из таблицы, команда SELECT содержит ключевые слова SELECT и FROM. Ключевое слово FROM с лексемой states образует секцию, уточняющую смысл команды SELECT.

Лексемы id, name и states в приведенном примере являются идентификаторами. Идентификаторы Id и name определяют выбираемые поля, а идентификатор states определяет имя таблицы, из которой производится выборка. Таким образом, приведенный выше запрос приказывает PostgreSQL выбрать поля Id и name каждой записи таблицы states. В листинге 3.13 показаны результаты выполнения этого запроса.

Источник

Косая черта-звездочка (блочный комментарий) (Transact-SQL)

Обозначает текст комментария пользователя. Текст, помещенный между /* и */, не вычисляется сервером.

topic linkСинтаксические обозначения в Transact-SQL

Синтаксис

Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.

Аргументы

text_of_comment
Текст комментария. Это одна или более символьных строк.

Комментарии

Комментарии могут вставляться в отдельную строку или в пределах инструкции Transact-SQL. Многострочные комментарии необходимо отмечать сочетаниями символов /* и */. Для многострочных комментариев часто используется следующий стиль: первую строку начинают с сочетания символов /*, последующие строки — с сочетания символов **, а заканчивают комментарий сочетанием символов */.

Длина комментариев не ограничена.

Поддерживаются вложенные комментарии. Если сочетание символов /* используется в пределах существующего комментария, оно рассматривается как начало вложенного комментария и, следовательно, требует метки */, закрывающей этот комментарий. Если метки, закрывающей комментарий, нет, выдается ошибка.

Например, следующий код вызовет ошибку:

Чтобы избежать этой ошибки, внесите следующее изменение:

Примеры

В приведенном ниже примере комментарии используются для пояснения действий, выполняемых блоком кода.

Источник

Синтаксис SQL

Ключевые слова SQL

SELECT * FROM EMPLOYEES ;
Select * FROM EMPLOYEES ;
select * FROM EMPLOYEES ;

DESCRIBE EMPLOYEES;
DESC EMPLOYEES;

Идентификаторы

Идентификаторы – это имена заданные разработчиками для структурных элементов базы данных: таблицы, столбцы, псевдонимы, индексы, представления. В синтаксисе последнего SQL запроса ‘EMPLOYEES’ — это идентификатор, а ‘ SELECT ‘ — ключевое слово. Правила для создания идентификаторов указываются в спецификации поставщика. Рассмотрим следующую таблицу:

Правила Платформа Описание
Идентификатор должен содержать до SQL2003 128 символов.
DB2 128 символов, в зависимости от платформы.
MySQL 64 символа.
Oracle 30 байт; имена базы данных до 8 байт.
PostgreSQL 31 символ.
Идентификатор может содержать SQL2003 Любые цифры, символы и нижнее подчеркивание.
DB2 Любые цифры, символы в верхнем регистре или символ нижнего подчеркивания.
MySQL Любые цифры или символы.
Oracle Любые цифры, символы и нижнее подчеркивание (_), знак фунта стерлингов (#) или доллара ($).
PostgreSQL Любые цифры, символы и нижнее подчеркивание (_).
Первый символ должен быть SQL2003 Буквой.
DB2 Буквой.
MySQL Буквой или цифрой (но не должен содержать только цифры).
Oracle Буквой.
PostgreSQL Буквой или нижним подчеркиванием (_).
Идентификатор не может содержать SQL2003 Специальные символы или пробелы.
DB2 Специальные символы или пробелы.
MySQL Точку (.), слэш (/) или ASCII(0) и ASCII(255). Кавычки (‘) и двойные кавычки («) допускаются только в ссылающихся идентификаторах.
Oracle Пробелы, двойные кавычки («) или специальные символы.
PostgreSQL Двойные кавычки («).
В синтаксисе SQL запросов символ идентификатора SQL2003 Двойные кавычки («).
DB2 Двойные кавычки («).
MySQL Кавычки ( ‘ ) или двойные кавычки (» ) в режиме совместимости с ANSI.
Oracle Двойные кавычки («).
PostgreSQL Двойные кавычки («).
Идентификатор может быть зарезервирован SQL2003 Нет, кроме ссылающихся идентификаторов.
DB2 Да.
MySQL Нет, кроме ссылающихся идентификаторов.
Oracle Нет, кроме ссылающихся идентификаторов.
PostgreSQL Нет, кроме ссылающихся идентификаторов.
Адресация к схеме SQL2003 Каталог.схема.объект.
DB2 Схема.объект.
MySQL База_данных.объект.
Oracle Схема.объект.
PostgreSQL База_данных.схема.объект.
Идентификатор должен быть уникальным SQL2003 Да.
DB2 Да.
MySQL Да.
Oracle Да.
PostgreSQL Да.

Конвенции имен

Стандарт SQL не содержит никаких точных указаний по наименованиям, поэтому нужно следовать следующим основным принципам ( в том числе и в синтаксисе SQL запросов UPDATE ):

Читайте также:  her код для турции

Литералы SQL

Операторы

Смотрите таблицу ниже:

Операторы Работают во
Арифметические операторы Всех базах данных.
Операторы присвоения Всех базах данных.
Побитовые операторы Microsoft SQL Server.
Операторы сравнения Всех базах данных.
Логические операторы DB2, Oracle, SQL Server и PostgreSQL.
Унарные операторы DB2, Oracle и SQL Server.

Приоритетность операторов

Если в выражении есть круглые скобки, то операторы в них вычисляется в первую очередь, а остальные части выражения, которые находятся вне скобок, вычисляются после этого. В следующей таблице перечислены уровни приоритетности операторов SQL от высокого к низкому.

Результат

Приоритетность операторов

sql operator precedence e 250411

Результат

Приоритетность операторов

sql operator precedence e 250411

Комментарии SQL

Комментарии в синтаксисе SQL запросов — это необязательный текст, который описывает, что делает программа и почему код был изменен. Компилятор всегда игнорирует комментарии. Комментарий вводится через двойное тире и пробел:
— Это комментарий SQL

В качестве альтернативы, можно использовать блок комментариев C-стиля :

Пробелы

select syntax 250412

Список ключевых слов SQL:

ABSOLUTE ACTION ADD ADMIN
AFTER AGGREGATE ALIAS ALL
ALLOCATE ALTER AND ANY
ARE ARRAY AS ASC
ASSERTION ASSERTION AT ATOMIC
AUTHORIZATION BEFORE BEGIN BIGINT
BINARY BIT BLOB BOOLEAN
BOTH BREADTH BY CALL
CASCADE CASCADED CASE CAST
CATALOG CHAR CHARACTER CHECK
CLASS CLOB CLOSE COLLATE
COLLATION COLLECT COLUMN COMMIT
COMPLETION CONDITION CONNECT CONNECTION
CONSTRAINT CONSTRAINTS CONSTRUCTOR CONTAINS
CONTINUE CORRESPONDING CREATE CROSS
CUBE CURRENT CURRENT_DATE CURRENT_PATH
CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER
CURSOR CYCLE DATA DATALINK
DATE DAY DEALLOCATE DEC
DECIMAL DECLARE DEFAULT DEFERRABLE
DELETE DEPTH DEREF DESC
DESCRIPTOR DESTRUCTOR DIAGNOSTICS DICTIONARY
DISCONNECT DO DOMAIN DOUBLE
DROP ELEMENT END-EXEC EQUALS
ESCAPE EXCEPT EXCEPTION EXECUTE
EXIT EXPAND EXPANDING FALSE
FIRST FLOAT FOR FOREIGN
FREE FROM FUNCTION FUSION
GENERAL GET GLOBAL GOTO
GROUP GROUPING HANDLER HASH
HOUR IDENTITY IF IGNORE
IMMEDIATE IN INDICATOR INITIALIZE
INITIALLY INNER INOUT INPUT
INSERT INT INTEGER INTERSECT
INTERSECTION INTERVAL INTO IS
ISOLATION ITERATE JOIN KEY
LANGUAGE LARGE LAST LATERAL
LEADING LEAVE LEFT LESS
LEVEL LIKE LIMIT LOCAL
LOCALTIME LOCALTIMESTAMP LOCATOR LOOP
MATCH MEMBER MEETS MERGE
MINUTE MODIFIES MODIFY MODULE
MONTH MULTISET NAMES NATIONAL
NATURAL NCHAR NCLOB NEW
NEXT NO NONE NORMALIZE
NOT NULL NUMERIC OBJECT
OF OFF OLD ON
ONLY OPEN OPERATION OPTION
OR ORDER ORDINALITY OUT
OUTER OUTPUT PAD PARAMETER
PARAMETERS PARTIAL PATH PERIOD
POSTFIX PRECEDES PRECISION PREFIX
PREORDER PREPARE PRESERVE PRIMARY
PRIOR PRIVILEGES PROCEDURE PUBLIC
READ READS REAL RECURSIVE
REDO REF REFERENCES REFERENCING
RELATIVE REPEAT RESIGNAL RESTRICT
RESULT RETURN RETURNS REVOKE
RIGHT ROLE ROLLBACK ROLLUP
ROUTINE ROW ROWS SAVEPOINT
SCHEMA SCROLL SEARCH SECOND
SECTION SELECT SEQUENCE SESSION
SESSION_USER SET SETS SIGNAL
SIZE SMALLINT SPECIFIC SPECIFICTYPE
SQL SQLEXCEPTION SQLSTATE SQLWARNING
START STATE STATIC STRUCTURE
SUBMULTISET SUCCEEDS SUM SYSTEM_USER
TABLE TABLESAMPLE TEMPORARY TERMINATE
THAN THEN TIME TIMESTAMP
TIMEZONE_HOUR TIMEZONE_MINUTE TO TRAILING
TRANSACTION TRANSLATION TREAT TRIGGER
TRUE UESCAPE UNDER UNDO
UNION UNIQUE UNKNOWN UNTIL
UPDATE USAGE USER USING
VALUE VALUES VARCHAR VARIABLE
VARYING VIEW WHEN WHENEVER
WHERE WHILE WITH WRITE
YEAR ZONE

Пожалуйста, оставьте свои комментарии по текущей теме статьи. Мы крайне благодарны вам за ваши комментарии, отклики, дизлайки, лайки, подписки!

Источник

Комментарии в PL/SQL

этого обычно бывает недостаточно для того, чтобы обеспечить полное понимание сложной программы.

PL/SQL поддерживает два вида комментариев: однострочные и многострочные.

Синтаксис однострочного комментария

Однострочный комментарий начинается двумя дефисами (—), между которыми не может стоять пробел или какой-либо другой символ. Весь текст после двойного дефиса и до физического конца строки воспринимается как комментарий и игнорируется компилятором. Если двойной дефис стоит в начале строки, то вся строка является комментарием.

В следующем операторе IF для пояснения его логики использован однострочный комментарий:

Синтаксис многострочного комментария

Однострочные комментарии удобны для создания кратких пояснений к фрагментам кода или для временного исключения строки программы из исполнения, тогда как многострочные комментарии позволяют включать в программу длинные поясняющие тексты.

Многострочные комментарии начинаются после символов «косая черта-звездочка» (/*) и заканчиваются символами «звездочка-косая черта» (*/). Весь текст, находящийся между этими двумя последовательностями символов, PL/SQL воспринимает как комментарий, и компилятор его игнорирует.

Рассмотрим в качестве примера многострочного комментария блок текста в заголовке процедуры. Символы вертикальной черты в левой части строк использованы для того, чтобы заострить внимание читателя на комментарии:

Источник

Грамматика MySQL на ANTLR 4

59d4c94d20b25300224783

Межсетевой экран уровня приложений предназначен для анализа и фильтрации трафика в отношении какого-либо приложения или класса приложений, например веб-приложений или СУБД. При его построении возникает необходимость разговаривать на языке этого приложения. Для реляционной СУБД таким языком становится диалект SQL. Предположим, что необходимо построить межсетевой экран для СУБД. В этом случае потребуется распознавать и анализировать предложения SQL для принятия решения об их соответствии заданной политике безопасности. В зависимости от решаемых задач (например, обнаружение атак типа SQL-инъекция, управление доступом, корреляция SQL- и HTTP-запросов) будет необходима та или иная глубина анализа SQL. Так или иначе, потребуется выполнять лексический, синтаксический и семантический анализ предложений SQL.

Введение

Формальная грамматика языка

Для того чтобы получить полное представление о структуре языка и проводить его анализ, можно использовать формальную грамматику этого языка. С ее помощью можно как порождать предложения языка, так и, воспользовавшись синтаксическим анализатором, распознавать предложения в нем.

Согласно иерархии Хомского, выделяют четыре основных типа языков и, соответственно, четыре типа грамматик. Грамматики отличаются своими порождающими возможностями. MySQL является контекстно-зависимым языком. Тем не менее, перечень языковых конструкций, которые могут быть порождены только контекстно-зависимой грамматикой, невелик. Как правило, на практике используются языковые конструкции, для порождения порождения которых достаточно контекстно-свободной грамматики. В данной статье описываются детали разработки контекстно-свободной грамматики для MySQL.

Используемая терминология

Язык определяется на основе алфавита — множества символов. Буквы алфавита объединяются в значащие последовательности, называемые лексемами. Лексемы могут быть разных типов (идентификаторы, строки, ключевые слова и т. п.). Токеном называется кортеж, состоящий из лексемы и имени типа. Фраза — это последовательность лексем, расположенных в особом порядке. Из фраз могут быть построены предложения. Далее под предложением понимается некоторая законченная последовательность лексем, которая в контексте заданного языка имеет самостоятельное значение. Понятие предложение имеет смысл только в прикладной сфере.

Читайте также:  проклятый сид в майнкрафте

Приложения, построенные на основе какого-либо языка, оперируют предложениями этого языка, например выполняют или интерпретируют их. Фразы, с прикладной точки зрения, являются незаконченными конструкциями, они могут являться частью предложения. Но при построении грамматики удобно использовать именно фразы. По сути, фразы и предложения не отличаются с точки зрения грамматики — они соответствуют некоторым ее правилам, в правой части которых присутствуют нетерминальные символы.

Использование языка предполагает построение или распознавание предложений. Задача распознавания предполагает, что на вход подается последовательность лексем, а на выходе выдается ответ на вопрос, является ли эта последовательность набором корректных предложений в этом языке.

Язык MySQL

Язык MySQL — это диалект языка SQL для написания запросов к СУБД MySQL. Под языком SQL подразумевается стандарт или, формально, серия стандартов ISO/IEC 9075 “Information technology – Database languages – SQL”.

Диалект MySQL — это конкретная реализация стандарта с некоторыми ограничениями и дополнениями. Большая часть предложений MySQL может быть описана контекстно-свободной грамматикой, но есть некоторые предложения, для описания которых требуются правила контекстно-зависимой грамматики. Если говорить простым языком, то, если лексема влияет на дальнейшее распознавание фраз, такая фраза описывается правилом контекстно-зависимой грамматики.

В MySQL есть некоторые выражения, построенные по этому принципу. Например:

В процедурном расширении операторы циклов и блочные предложения могут быть помечены метками. Их структура выглядит следующим образом:

В данном случае идентификаторы меток должны быть одинаковыми. Вывести такое предложение можно только в контекстно-зависимой грамматике.

ANTLR

Для разработки MySQL-парсера был выбран генератор парсеров ANTLR. Главные преимущества данного генератора:

ANTLR предполагает двухэтапный алгоритм генерации распознающего кода. Сначала описывается лексическая структура языка, то есть определяется, что является токенами. Далее описывается синтаксическая структура языка, то есть распознанные токены группируются в предложения. Лексическая и синтаксическая структуры в ANTLR описываются с помощью правил. Лексическая структура определяется типом (описателем лексемы) и значением. Для описания значения используется язык с элементами регулярных выражений, но с поддержкой рекурсии. Правило синтаксической структуры составляется из описателей лексем на основе правил построения предложений в ANTLR 4, позволяющих определить структуру расположения лексем в предложении или фразе внутри предложения.

При построении правил следует учесть базовый принцип лексического анализа, реализованный в том числе и в ANTLR. Лексер в первую очередь пытается распознать наиболее длинную последовательность символов из входного потока, подходящую под какое-либо лексическое правило. Если же таких правил несколько, то задействуется первое в порядке определения.

Без использования семантических предикатов в ANTLR можно построить только контекстно-свободную грамматику. Плюсом является то, что в этом случае полученная грамматика будет независимой от среды выполнения. Предлагаемая в статье грамматика для диалекта MySQL построена без использования семантических предикатов.

Лексер

С чего начать

При разработке грамматики первое, что нужно сделать, — это определить перечень типов лексем, встречающихся в языке. При распознавании лексем на вход распознавателя будут поступать символы алфавита языка, из которых нужно составлять лексемы; при этом символы, не участвующие в составлении лексем, можно отфильтровать. Такими символами являются пробельные символы и комментарии. После фильтрации в дальнейшем анализе будут участвовать только значимые лексемы языка. Отфильтровать пробельные символы и комментарии можно так:

Также можно сразу учитывать потенциальные лексические ошибки и пропускать неизвестные символы:

Теперь можно приступать к выделению лексем. Как правило, можно выделить следующие типы лексем:

В случае если в языке нет явного (или неявного) пересечения этих типов лексем, проблем не возникает и требуется просто описать все лексемы. Однако если где-то возникают пересечения, их нужно разрешить. Ситуация осложняется тем, что для распознавания отдельных лексем используется регулярная грамматика. В MySQL такая проблема возникает с «идентификаторами с точкой» (fully qualified name) и с ключевыми словами, которые могут быть идентификаторами.

Идентификаторы с точкой

При распознавании лексем MySQL, таких как идентификаторы, начинающиеся с цифр, есть некоторые проблемы: символ «.» может встретиться как в полных именах столбцов, так и в вещественных литералах:

Таким образом, необходимо корректно распознать полное имя столбца в первом случае и вещественный литерал во втором. Пересечение возникает из-за того, что идентификаторы в MySQL могут начинаться с цифр.

С точки зрения языка MySQL фраза:

является последовательностью из трех токенов:

Для этого вполне естественно использовать правила:

После токенизации получается последовательность из четырех токенов:

Для того чтобы избежать проблему неоднозначности, можно ввести вспомогательную конструкцию для распознавания идентификаторов:

и определить правила, отсортированные по приоритетам:

Поскольку ANTLR распознает последовательности максимальной длины, можно не опасаться что «.» будет распознана как отдельный символ.

Строки

На примере строк можно привести еще одно правило лексического анализа, реализованное в ANTLR. Строка в MySQL — это последовательность почти любых символов, заключенных в одинарные или двойные кавычки. Строки, обособленные одинарными кавычками, не могут содержать в себе одиночный обратный слеш и кавычку, потому что лексер не определит, где строка заканчивается. Если же все-таки нужно использовать такие знаки, то применяется экранирование, которое заключается в замене одной кавычки на две подряд идущие. Кроме того, символ экранирования внутри строки не может встречаться сам по себе, он должен что-то экранировать. Поэтому отдельные появления этого символа также необходимо запретить. В итоге получается следующий фрагмент лексического правила:

(‘\» | ‘\\’) — запрещает появление отдельной одинарной кавычки или отдельного символа экрана.

Ключевые слова

Лексер ANTLR, в отличие от парсера, использует правила в порядке их приоритета. Правила, определенные раньше, имеют больший приоритет, чем описанные позже. Это дает очевидную инструкцию по сортировке правил: сначала располагаются конкретные правила, которые определяют ключевые слова и специальные символы, а затем — общие, которые определяют литералы, переменные, идентификаторы и т.п.

Специальный тип комментария в MySQL

В MySQL используется многострочный комментарий специального вида. Такие комментарии позволяют создавать совместимые с другими СУБД запросы, изолируя специфику MySQL. MySQL при формировании запроса будет анализировать текст из таких комментариев. Для распознавания специальных комментариев MySQL можно использовать правило:

Однако одного его недостаточно для корректного парсинга запросов.

Предположим, что на вход приходит запрос вида:

При использовании такого правила получится следующая последовательность токенов:

При этом стандартный лексер MySQL распознает несколько иные токены:

Читайте также:  промокоды на аризона рп yuma

Поэтому для корректного распознавания специального типа комментария в MySQL требуется дополнительная обработка:

Лексер для предварительной обработки разбивает входной поток на фразы относящиеся:

и может быть построен следующим образом:

Регистронезависимость

Практически все лексемы в MySQL регистронезависимы, а это значит, что два следующих запроса идентичны:

К сожалению, в ANTLR нет поддержки регистронезависимых токенов, и для токенов приходится использовать следующую запись с использованием фрагментных токенов, которые используются для построения реальных токенов:

Это уменьшает читабельность грамматики. Более того, для каждого символа лексеру приходится выбирать из двух вариантов — символа в верхнем или нижнем регистрах — что негативно влияет на производительность.

Для того чтобы код лексера был более чистым, а производительность выше, входной поток символов нужно нормализовать, то есть привести к верхнему или нижнему регистру. ANTLR поддерживает специальный поток, который не учитывает регистр во время лексического анализа, однако сохраняет регистр оригинальных значений токенов. Эти токены можно использовать во время обхода дерева.

Реализация такого потока под разные рантаймы была предложена KvanTTT. Ее можно найти в проекте DAGE, кроссплатформенного редактора грамматик ANTLR 4.

В итоге все лексемы записываются либо в нижнем, либо в верхнем регистре. Так как обычно ключевые слова SQL в запросах записываются в верхнем регистре, было решено использовать его и для грамматики:

Парсер

Для описания синтаксической структуры языка нужно определить порядок записи:

Структура текста на языке MySQL

Мощности контекстно-свободной грамматики не хватает для полной поддержки этих правил, так как MySQL-клиент может использовать команду DELIMITER, с помощью которой можно устанавливать текущий разделитель. В этом случае требуется запомнить и использовать разделитель в других правилах. Таким образом, если использовать эту директиву, корректно написанные SQL-предложения при помощи рассматриваемой грамматики распознаны не будут.

Типы предложений в MySQL

Предложения в MySQL бывают следующих типов:

После перевода документации в грамматику ANTLR 4 корневое правило предложения будет выглядеть следующим образом:

Также существует пустое предложение, состоящее из одной точки с запятой:

Последующие пункты официальной документации трансформируются в правила ANTLR аналогичным образом.

SELECT

Пожалуй, самым интересным и обширным предложением в SQL вообще и в MySQL в частности является предложение SELECT. При написании грамматики основное внимание было уделено следующим его частям:

Начнем с определения таблиц. В языке MySQL довольно серьезное описание того, что можно использовать в поле FROM запроса типа SELECT (далее будем называть это «табличными ссылками»). После внимательного изучения и тестирования на действующих версиях становится ясно, что «табличные ссылки» представляют собой конструкцию вида:

в которой «Табличный объект» представляет собой одну из четырех конструкций:

Если начать с менее общего, то получаем, что табличный объект индуктивно определяется как таблица или как конструкция на основе таблиц. Последняя может представлять собой:

Далее получаем, что в поле FROM просто определяется последовательность табличных объектов, состоящая как минимум из одного табличного объекта. Конечно, в грамматике определяются дополнительные конструкции типа «условий соединения», ссылок на партиции (PARTITION) и т. п., но общая структура выглядит следующим образом:

Выражения

Выражения (expressions) в языке MySQL используются повсеместно — везде, где возникает потребность в вычислении значения (вектора значений). Индуктивно выражение можно определить следующим образом:

К числу преобразований относятся операции, операторы (в том числе теоретико-множественные, операторы сравнения), функции, запросы, скобки.

UNION

В отличие от других диалектов, в MySQL есть только две теоретико-множественные операции над таблицами. Первая — JOIN — уже была рассмотрена. Экспериментальным путем было выяснено, что описание UNION в официальной документации несколько неполное. Нами оно было дополнено следующим образом:

Использование грамматики

Грамматика пишется для решения задач синтаксического и лексического анализа. С одной стороны, необходимо, чтобы распознавание осуществлялось максимально быстро, а с другой — чтобы код сгенерированного лексера и парсера можно было безболезненно использовать в собственных приложениях без влияния на возможности и скорость.

Приложение, использующее парсер, скорее всего будет задействовать один из двух паттернов проектирования — Visitor или Observer. Каждый из них предполагает анализ определенного подмножества узлов дерева разбора. Узлы дерева разбора, не являющиеся листьями, соответствуют каким-либо синтаксическим правилам грамматики. При анализе узлов дерева разбора нужно обращаться к дочерним узлам, соответствующим фрагментам исходного правила. Причем обращаться можно как к отдельным узлам, так и к группам узлов.

Поэтому важным условием создания хорошей грамматики является возможность получения «простого» доступа к любой части правила. Интуитивно «простой» доступ можно описать как возможность получения этой части в виде объекта, не используя поиск и перебор. Для этого в ANTLR есть такие сущности как альтернативные и элементные метки. Альтернативные метки позволяют разбить сложное правило на альтернативные фразы и, в случае использования паттерна проектирования Visitor, обрабатывать каждую такую фразу в отдельном методе. Например, табличный объект в MySQL может быть задан правилом:

Можно заметить, что табличный объект определяется как один из трех возможных вариантов:

Поэтому вместо обработки конструкции целиком определяются альтернативные метки и предоставляется возможность обработки каждого варианта независимо от остальных:

Элементными метками помечаются отдельные нетерминалы или последовательности терминалов. Они предоставляют доступ к содержимому контекста правила в виде поля с заданным именем. Таким образом, вместо вычисления (извлечения) отдельного элемента содержимого некоторого контекста достаточно просто обратиться к такой элементной метке. Вычисление же производится в зависимости от конструкции правила. Чем сложнее написано правило, тем сложнее производить вычисление.

Например, для правила:

Для того чтобы не производить вычисления, а сразу получать в коде требуемые значения, можно использовать элементные метки:

Вместе с упрощением кода целевого приложения упрощается и грамматика, так как имена альтернативных меток улучшают читаемость.

Заключение

Разрабатывать грамматики для SQL-языков непросто, так как они регистронезависимые, содержат большое количество ключевых слов, неоднозначности, контекстно-зависимые конструкции. В частности, при разработке грамматики MySQL мы реализовали обработку специальных типов комментариев, разработали лексер, способный отличать идентификаторы с точкой от вещественных литералов, и написали грамматику парсера, которая покрывает большую часть синтаксических конструкций MySQL из документации. С помощью разработанной грамматики MySQL можно распознавать запросы, генерируемые фреймворками WordPress и Bitrix, а также другими приложениями, в которых не требуется точная обработка контекстно-зависимых случаев. Ее исходники хранятся в официальном репозитории грамматик grammars-v4 под лицензией MIT.

Источник

Поделиться с друзьями
Компьютеры и программы
Adblock
detector