SELECT * против SELECT * - PullRequest
       36

SELECT * против SELECT *

5 голосов
/ 06 августа 2011

Вчера коллега показал мне следующий запрос postgres.Мы оба были удивлены, что это сработало:

SELECT* FROM mytable;

Поскольку я недавно закодировал синтаксический анализатор для другого языка, я пытаюсь глубже понять, почему этот запрос «компилируется» и возвращает те же результаты, что и SELECT * FROM mytable;.

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

Кроме того, лексер / синтаксический анализатор postgres оказался достаточно надежным для понимания этого запроса, или другие базы данных будут понимать аналогичный запрос SELECT*?

Ответы [ 3 ]

5 голосов
/ 06 августа 2011

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

Итак, здесь происходит то, что лексер сглатывает SELECT и видит, что следующим символом является *, который, поскольку он собирает слово, не может принадлежать SELECT. Таким образом, он останавливается, анализирует SELECT, который оказывается ключевым словом, и начинается заново с *, который он распознает, и так далее. По той же причине вы получаете 4 от 2*2 и 2 * 2 на других языках программирования.

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

3 голосов
/ 06 августа 2011

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

Вот BNF операторов SELECT: h2database.com :

SELECT [ TOP term ] [ DISTINCT | ALL ] selectExpression [,...]
FROM tableExpression [,...] [ WHERE expression ]
[ GROUP BY expression [,...] ] [ HAVING expression ]
[ { UNION [ ALL ] | MINUS | EXCEPT | INTERSECT } select ] [ ORDER BY order [,...] ]
[ LIMIT expression [ OFFSET expression ] [ SAMPLE_SIZE rowCountInt ] ]
[ FOR UPDATE ]
2 голосов
/ 06 августа 2011

Насколько я знаю, SQL пропускает синтаксический анализ пробела, поэтому вы можете сделать SELECT*FROM or SELECT * FROM, это в основном то же самое

Он также использует ` и ', чтобы понять, что к чему.Так что SELECT * FROM myTable WHERE id = my string будет неверным запросом, потому что «строка» в и не понята.

...