возможно ли распарсить многомерное вложение?

vavr

Новичок
возможно ли распарсить многомерное вложение?

Вопрос такой можно ли регулярным выражением вычленить ключевые слова первого уровня?

Поясняю:
есть sql запрос кпримеру: select * from (select * from tbl where id>5 order by id) where id = 10 order by id desc;
понятно что вложенность select может быть любая (теоритически) и располагаться он может почти где угодно (например в IF() ), так вот можно ли составить рег выражение чтобы оно матчило нужно содержимое только первого уровня (под нужным понимается блоки select, from, where, order, limit)? В данном примере это select => "*", from => "(select * from tbl where id>5 order by id)" where=>"id = 10", order by=>"id desc" limit=>""

Создается впечатление что такое рег выражение нельзя написать...
 

vavr

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

dimagolov

Новичок
vavr
ИМХО нужно не весь SQL перебирать не представляя что за данные в него вставили, экранировали их или нет и если экранировали то чем именно, а просто при составлении запросов корректно экранировать пользовательские данные.
 

Фанат

oncle terrible
Команда форума
vavr
а можно поподробнее про экранирование? зачем оно?
 

zerkms

TDD infected
Команда форума
там щас идет посимвольный перебор и экранирование нужных мест, потом идет реплэйс и тд.
а ты в состоянии определить что и как нужно экранировать?

вот тебе запрос:

SELECT * FROM from WHERE where = select

:)))

пусть твой код "проэкранирует" этот запрос так, чтобы он наконец заработал, и при этом заработал так как хочу я ;)
 

vavr

Новичок
Автор оригинала: dimagolov
vavr
ИМХО нужно не весь SQL перебирать не представляя что за данные в него вставили, экранировали их или нет и если экранировали то чем именно, а просто при составлении запросов корректно экранировать пользовательские данные.
Вопрос был совсем не про экранирование конечно же. Моя вина что использовал этот термин, который не правильно поняли (потому как я его не объяснил, а просто написал подразумевая совсем не то что подразумевают многие говоря о sql запросах :) ). Здесь под экранированием понимается промежуточный этап для выявления вложенных блоков (вложенных селектов и тд.) просто эти блоки могут быть только в скобках или в других детиметрах (', " и тд) так вот щас "экранируются" (в моем случае заменяются и запоминаются) содержание между сиволами (, ', " и им парные и все это хранится в массиве и тд. Когда обратно все это склеивается в запрос, то берется нужная инфа.

Достаточно муторный процесс. Он был написан потому как не смог написать рег выражение на поставленную задачу. Вот и спрашиваю а это вообще возможно?

-~{}~ 29.10.07 10:59:

Автор оригинала: zerkms
а ты в состоянии определить что и как нужно экранировать?

вот тебе запрос:

SELECT * FROM from WHERE where = select

:)))

пусть твой код "проэкранирует" этот запрос так, чтобы он наконец заработал, и при этом заработал так как хочу я ;)
Собсно "мой код" выдал следущее:
select => "*"
from => "from"
where => "where=select"
а что ты хотел не знаю :) но код выдал то что и нужно было, а вот правильность запросов конечно же он не проверяет :)) просто выдирает блоки первого уровня - и все!
 

zerkms

TDD infected
Команда форума
просто выдирает блоки первого уровня - и все!
а где вышеозвученное экранирование??
(, ', " и им парные и все это хранится в массиве и тд. Когда обратно все это склеивается в запрос, то берется нужная инфа.
т.е. я так понимаю что в запрос
... WHERE `field` = '$a' вставляется значение, которое никак не обезопасивается, и ты делаешь это уже потом?

ну тогда в $a запишем значение ' OR 1=1 //
и?
 

vavr

Новичок
Автор оригинала: zerkms
а где вышеозвученное экранирование??
Я ж сказал, что экранирование в моем озвучивании совсем не то что квотирование, sql - защита от инъекций и тд.

т.е. я так понимаю что в запрос
... WHERE `field` = '$a' вставляется значение, которое никак не обезопасивается, и ты делаешь это уже потом?

ну тогда в $a запишем значение ' OR 1=1 //
и?
Защита от sql инъекций производится совсем в другом месте.
Задача заключается только в определении "блоков" первого (высшего) уровня, и ничего более.

Объясню немного смысл, чтоб было понятнее.
Например в zendFramework есть такой класс select. Идея этого класса очень понравилась, но есть одно неудобство: исходный запрос не видно, когда его "склеиваешь" из частей. Хочется чтобы эта склейка была на более низком уровне.

Так вот, идея в том, чтоб взять базовый sql запрос, его распарсить на состовляющие (select, where, limit, order) и при некоторых ситуациях добавлять/менять только where например. К примеру есть запрос который берет записи из таблицы news : select * from news, хочется иметь этот запрос на виду (напимер в конструкторе класса news ) а вот метод loadLatest() например использует тот же запрос, но с добавлением в блок where : date > DATE_ADD(NOW(), INTERVAL -3 DAY) к примеру.

Ну вот такаяя идея :). Все это реализовано, но место где парсятся блоки не нравится. Вот и спросил как это можно сделать и можно ли вообще.
 
Сверху