Можно ли создавать и инкрементно оценивать / мутировать деревья выражений в Boost.Proto?

Можно ли извлечь части дерева выражений Boost.Proto, оценить их индивидуально (внешне), а затем изменить дерево выражений, заменив извлеченные части результатом?

В моем конкретном случае я пытаюсь оценить, могу ли я переписать какой-то устаревший код, который повторяется:

  1. генерирует sql
  2. запрашивает базу данных
  3. использует результат для генерации нового SQL-запроса
  4. снова запрашивает базу данных

    (и так далее)

То, что я надеялся сделать, было:
1. Создайте одно большое дерево выражений
2. Получить SQL из дерева выражений. Это состоит из:
б. посетите дерево и проверьте подзапросы, которые должны быть оценены до того, как будет получен отдельный sql
с. если есть подзапросы, создайте sql и верните в виде строки, оцените sql извне и измените дерево, заменив подзапросы результатами

(также я хотел бы идентифицировать идентичные подзапросы и оценивать их только один раз, если это возможно)

Возможно ли это сделать? Требуется ли код, который трудно понять / изучить?

Я просмотрел документацию Boost.Proto, но не уверен, предназначен ли он для этого сценария, где мне нужно внешне оценивать поддеревья и заменять его результатом, пока все дерево не будет сведено к одному запросу.

РЕДАКТИРОВАТЬ:

Допустим, у меня есть следующие таблицы:

объекты
id | название

attribute_link
объект | attributeid

атрибуты
id | парентид | имя | значение

Мои запросы поступают как пользовательский объект «запрос» — (двоичное) дерево с несколькими предложениями AND, OR.

Пример:
query1 = object.id = 10 OR (attribute.name = «name» ИЛИ attribute.name = «name2»)

Это означает: получить атрибут (ы) для объекта 10, где именем атрибута является «имя». Обратите внимание на поле parentid, которое означает, что мы ищем attribute.name может быть вложенным и напрямую не связанным с нашим объектом.

Что мне нужно сделать, это:
1. Переведите это в дерево выражений с достаточным количеством информации.
2. Отправить это дерево в слой БД
3. Обработайте дерево (иногда в несколько этапов), как описано выше

Возможно, дерево выражений будет выглядеть примерно так:

find_attributes (object_id = 10 AND attribute_name = («name» ИЛИ «name2»))

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

Например, PostgreSQL:

  1. обработка сначала распознает узел find_attributes и узнает, что мы ищем атрибуты

  2. Если посмотреть дальше, атрибут должен быть связан с object.id = 10, мы сразу генерируем и запускаем запрос, чтобы получить все атрибуты с object.id = 10, и заменяем узел object_id = 10 в дереве выражений фактическим атрибутом. ids (object_id = 10) => (attribute_id = (20 ИЛИ 21)).

  3. затем мы находим узел attribute_name и, поскольку атрибуты вложены, нам нужно найти все строки атрибутов, которые имеют name = «name» или «name2»

  4. в качестве (необязательного) шага оптимизации, поскольку существуют миллионы атрибутов, нам необходимо объединить узлы attribute_id и attribute_name в один запрос

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

  1. (найти атрибуты) SELECT ID ИЗ атрибутов, ГДЕ objectid = 10)

  2. (окончательный запрос) —

    С
    get_roots AS (SELECT * FROM атрибутов WHERE (id = 20 или id = 21)),
    get_childs AS (SELECT * FROM get_roots, атрибуты WHERE attribute.parentid = get_roots.id),
    get_grandchilds AS (SELECT * FROM get_childs, атрибуты WHERE attribute.parentid = get_childs.id)

    SELECT * FROM get_roots
    UNION
    SELECT * FROM get_childs
    UNION
    SELECT * FROM get_grandchilds

(если предположить, что атрибуты здесь всего три уровня, его можно переписать как рекурсивный CTE)

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

1

Решение

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

1

Другие решения

Других решений пока нет …