Код: Выделить всё
tenant_id = '123'У меня есть рабочий прототип, который обрабатывает простые операторы SELECT, UPDATE и DELETE. Однако мой текущий подход предполагает ручную проверку определенных типов выражений (
Код: Выделить всё
InExpressionТекущий подход (вручную)
В настоящее время я разворачиваю выражения вручную. Это работает для запросов верхнего уровня, но быстро становится запутанным:
Код: Выделить всё
public void modifyPlainSelect(PlainSelect plainSelect, String simId) {
// 1. Add to main table
if (plainSelect.getFromItem() instanceof Table) {
addWhereCondition(plainSelect, simId);
}
// 2. Manually check WHERE clause for subqueries
Expression where = plainSelect.getWhere();
if (where instanceof InExpression inExpr) {
// Manually handle the right side
if (inExpr.getRightItemsList() instanceof SubSelect) {
modifySelect(((SubSelect) inExpr.getRightItemsList()).getSelectBody());
}
}
// I have to add manual checks for Exists, Between, BinaryExpression, etc...
}
Это не позволяет автоматически охватить сложные сценарии. Например:
Ввод:
Код: Выделить всё
SELECT * FROM orders o
WHERE o.customer_id IN (
SELECT c.id FROM customers c
WHERE c.status = (SELECT s.code FROM status s WHERE s.active = 1)
)
Код: Выделить всё
SELECT * FROM orders o
WHERE o.simulation_id = '123' -- Injected
AND o.customer_id IN (
SELECT c.id FROM customers c
WHERE c.simulation_id = '123' -- Injected (Recursion Level 1)
AND c.status = (
SELECT s.code FROM status s
WHERE s.simulation_id = '123' -- Injected (Recursion Level 2)
AND s.active = 1
)
)
Существует ли в JSqlParser стандартный шаблон (например, StatementVisitor, TablesNamesFinder или ExpressionDeParser), который позволяет мне:
- Посещать каждый узел в AST (рекурсия обрабатывается библиотека).
- Идентифицируйте каждый раз, когда осуществляется доступ к таблице (в FROM, JOIN, UPDATE или DELETE).
- Внедрите предложение WHERE в родительский элемент Select/объект.
Код: Выделить всё
Update
Подробнее здесь: https://stackoverflow.com/questions/798 ... d-expressi
Мобильная версия