2013-08-03 4 views
1

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

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

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

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

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

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

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

EDIT:

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

объектов идентификаторов | имя

attribute_link objectid | attributeid

ID | родительский | имя | значение

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

Пример: Query1 = object.id = 10 ИЛИ (attribute.name = "Название" ИЛИ attribute.name = "имя2")

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

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

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

find_attributes (object_id = 10 И attribute_name = ("имя" ИЛИ "name2"))

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

См., Например, PostgreSQL:

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

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

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

  4. как (по желанию) этап оптимизации, так как есть миллионы атрибутов, нам нужно объединить attribute_id и ATTRIBUTE_NAME узлы в одном запросе

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

  1. (найти attributeids) Выберите идентификатор из атрибутов, ГДЕ ObjectID = 10)

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

    С
    get_roots AS (SELECT * FROM атрибутов WHERE (ID = 20 или идентификатор = 21)),
    get_childs AS (SELECT * FROM get_roots, атрибуты, ГДЕ attributes.parentid = get_roots.id),
    get_grandchilds AS (SELECT * FROM get_childs, атрибуты, ГДЕ attributes.parentid = get_childs.id)

    SELECT * FROM get_rootsUNION
    SELECT * FROM get_childs UNION
    SELECT * FROM get_grandchilds

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

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

+0

Из описания прототипа «Он предоставляет инструменты для построения, проверки типов, преобразования и выполнения шаблонов выражений», это похоже на хорошее совпадение. –

+0

Да, да. Однако я не нашел примера в документации, которая могла бы оценивать и преобразовывать поддеревья. Возможно, я не смотрел достаточно близко, хотя ... – meastp

+0

Я не уверен, что смогу помочь, но мне нравится играть с Boost.Proto. Не могли бы вы добавить несколько примерных запросов (включая подзапросы) и сказать, какую библиотеку sql вы используете? – llonesmiz

ответ

1

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