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

Иллюстрированный самоучитель по 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.

SELECTid, nameFROMstates
Тип лексемыКлючевое словоИдентификаторыКлючевое словоИдентификатор
ОписаниеКомандаИмена полейИмя секцииИмя таблицы

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

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

Источник

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

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

sql комментарии в кодеСинтаксические обозначения в 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 ‘ — ключевое слово. Правила для создания идентификаторов указываются в спецификации поставщика. Рассмотрим следующую таблицу:

ПравилаПлатформаОписание
Идентификатор должен содержать доSQL2003128 символов.
DB2128 символов, в зависимости от платформы.
MySQL64 символа.
Oracle30 байт; имена базы данных до 8 байт.
PostgreSQL31 символ.
Идентификатор может содержать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 ):

Литералы SQL

Операторы

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

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

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

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

Результат

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

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

Результат

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

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

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

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

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

Пробелы

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

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

ABSOLUTEACTIONADDADMIN
AFTERAGGREGATEALIASALL
ALLOCATEALTERANDANY
AREARRAYASASC
ASSERTIONASSERTIONATATOMIC
AUTHORIZATIONBEFOREBEGINBIGINT
BINARYBITBLOBBOOLEAN
BOTHBREADTHBYCALL
CASCADECASCADEDCASECAST
CATALOGCHARCHARACTERCHECK
CLASSCLOBCLOSECOLLATE
COLLATIONCOLLECTCOLUMNCOMMIT
COMPLETIONCONDITIONCONNECTCONNECTION
CONSTRAINTCONSTRAINTSCONSTRUCTORCONTAINS
CONTINUECORRESPONDINGCREATECROSS
CUBECURRENTCURRENT_DATECURRENT_PATH
CURRENT_ROLECURRENT_TIMECURRENT_TIMESTAMPCURRENT_USER
CURSORCYCLEDATADATALINK
DATEDAYDEALLOCATEDEC
DECIMALDECLAREDEFAULTDEFERRABLE
DELETEDEPTHDEREFDESC
DESCRIPTORDESTRUCTORDIAGNOSTICSDICTIONARY
DISCONNECTDODOMAINDOUBLE
DROPELEMENTEND-EXECEQUALS
ESCAPEEXCEPTEXCEPTIONEXECUTE
EXITEXPANDEXPANDINGFALSE
FIRSTFLOATFORFOREIGN
FREEFROMFUNCTIONFUSION
GENERALGETGLOBALGOTO
GROUPGROUPINGHANDLERHASH
HOURIDENTITYIFIGNORE
IMMEDIATEININDICATORINITIALIZE
INITIALLYINNERINOUTINPUT
INSERTINTINTEGERINTERSECT
INTERSECTIONINTERVALINTOIS
ISOLATIONITERATEJOINKEY
LANGUAGELARGELASTLATERAL
LEADINGLEAVELEFTLESS
LEVELLIKELIMITLOCAL
LOCALTIMELOCALTIMESTAMPLOCATORLOOP
MATCHMEMBERMEETSMERGE
MINUTEMODIFIESMODIFYMODULE
MONTHMULTISETNAMESNATIONAL
NATURALNCHARNCLOBNEW
NEXTNONONENORMALIZE
NOTNULLNUMERICOBJECT
OFOFFOLDON
ONLYOPENOPERATIONOPTION
ORORDERORDINALITYOUT
OUTEROUTPUTPADPARAMETER
PARAMETERSPARTIALPATHPERIOD
POSTFIXPRECEDESPRECISIONPREFIX
PREORDERPREPAREPRESERVEPRIMARY
PRIORPRIVILEGESPROCEDUREPUBLIC
READREADSREALRECURSIVE
REDOREFREFERENCESREFERENCING
RELATIVEREPEATRESIGNALRESTRICT
RESULTRETURNRETURNSREVOKE
RIGHTROLEROLLBACKROLLUP
ROUTINEROWROWSSAVEPOINT
SCHEMASCROLLSEARCHSECOND
SECTIONSELECTSEQUENCESESSION
SESSION_USERSETSETSSIGNAL
SIZESMALLINTSPECIFICSPECIFICTYPE
SQLSQLEXCEPTIONSQLSTATESQLWARNING
STARTSTATESTATICSTRUCTURE
SUBMULTISETSUCCEEDSSUMSYSTEM_USER
TABLETABLESAMPLETEMPORARYTERMINATE
THANTHENTIMETIMESTAMP
TIMEZONE_HOURTIMEZONE_MINUTETOTRAILING
TRANSACTIONTRANSLATIONTREATTRIGGER
TRUEUESCAPEUNDERUNDO
UNIONUNIQUEUNKNOWNUNTIL
UPDATEUSAGEUSERUSING
VALUEVALUESVARCHARVARIABLE
VARYINGVIEWWHENWHENEVER
WHEREWHILEWITHWRITE
YEARZONE

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

Источник

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

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

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

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

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

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

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

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

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

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

Источник

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

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

Межсетевой экран уровня приложений предназначен для анализа и фильтрации трафика в отношении какого-либо приложения или класса приложений, например веб-приложений или СУБД. При его построении возникает необходимость разговаривать на языке этого приложения. Для реляционной СУБД таким языком становится диалект 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 распознает несколько иные токены:

Поэтому для корректного распознавания специального типа комментария в 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.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *