2013-08-03 26 views
1

是否可以提取Boost.Proto表達式樹的某些部分,單獨評估它們(外部),然後改變表達式樹,用結果替換提取的部分?是否有可能在Boost.Proto中構建和增量評估/改變表達式樹?

在我的特定情況下,我想,以評估,如果我可以重寫一些遺留代碼重複:

  1. 生成SQL
  2. 查詢數據庫
  3. 使用結果生成一個新的SQL查詢
  4. 再次查詢數據庫 ... (等)

我希望做的事情是: 1.生成單個大型表達式樹 2.從表達式樹中獲取SQL。這包括: b。訪問樹並檢查必須評估的子查詢,然後才能生成生成的單個sql c。如果有子查詢,創建sql並返回字符串,從外部評估sql,並修改樹,用結果替換子查詢

(同樣,我想標識相同的子查詢,查詢和評估它們只有一次,如果可能的話)

這可能嗎?它需要難以理解/學習的代碼嗎?

我已經瀏覽了Boost.Proto文檔,但是我不確定它是否適合這種場景,我需要在外部評估子樹,並用結果替換它,直到整個樹被縮減爲單個查詢。

編輯:

可以說我有如下表:

對象 ID |名稱

屬性_link objectid | attributeid

attributes id | parentid |名稱|值

我的查詢以自定義「查詢」對象的形式出現 - 具有多個AND,OR子句的(二元)樹。

示例: QUERY1 = object.id = 10 OR(attribute.name = 「名稱」 OR attribute.name = 「NAME2」)

這轉化爲:獲取屬性(一個或多個),用於對象10,其中該屬性的名稱是「名稱」。注意parentid字段,這意味着我們正在尋找的屬性名稱可以嵌套,並且不直接鏈接到我們的對象

我需要做的是: 1.將此轉換爲具有足夠信息的表達式樹 2.將此樹發送到db層 3。處理所述樹上述

所解釋也許表達式樹看起來像(在多個階段中有時):

find_attributes(的object_id = 10,屬性名稱=( 「名稱」 OR 「NAME2」))

有多個SQL語法不同的數據庫,這就是爲什麼我想這樣做。因此,我需要能夠覆蓋一些基於數據庫的處理步驟。

例如, PostgreSQL的:

  1. 的處理首先承認find_attributes節點,知道我們正在尋找的屬性

  2. 進一步看,該屬性需要鏈接到object.id = 10,我們產生和立即運行一個查詢以獲取所有具有object.id = 10的屬性,並將表達式樹中的object_id = 10節點替換爲實際屬性ids(object_id = 10)=>(attribute_id =(20 OR 21))。

  3. 然後,我們找到了屬性名稱節點,因爲屬性是嵌套的,我們需要找到一個有名字=「名」或「NAME2」

  4. 爲(可選)優化步驟中的所有屬性行,因爲有上百萬的屬性,我們需要將attribute_id和屬性名稱的節點合併成一個單一查詢

生成的查詢可能看起來是這樣的:

  1. (找到attributeids)SELECT ID FROM屬性WHERE OBJECTID = 10)

  2. (最終查詢)---


    get_roots

    AS(SELECT * FROM屬性WHERE(ID = 20或ID = 21 )),
    get_childs AS(SELECT * FROM get_roots,屬性WHERE attributes.parentid = get_roots.id),
    get_grandchilds AS(SELECT * FROM get_childs,屬性WHERE attributes.parentid = get_childs.id)

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

(假設屬性只有三個層次深在這裏,它可能會被改寫爲遞歸CTE)

我想這可能是可能的,但它會太多工作嗎?有一組有限的查詢,這裏提出的查詢是最複雜的。

+0

從Proto描述「它提供了用於構建,類型檢查,轉換和執行表達式模板的工具」,這聽起來像是一個很好的匹配。 –

+0

是的,它的確如此。但是,我沒有在文檔中找到可以評估和轉換子樹的示例。雖然我的看起來並不夠緊密...... – meastp

+0

我不確定我能夠提供幫助,但我喜歡和Boost.Proto一起玩。你能否添加一些示例查詢(包括子查詢)並說出你正在使用的是什麼sql庫? – llonesmiz

回答

1

Proto樹結構是在編譯時設置的,因此不可變。通常你要做的是用你需要的元素重新生成一棵新樹。這可以輕而易舉地完成,因爲一個原型轉換樹並返回一棵新樹。