1

Boost.Proto 式ツリーの一部を抽出し、それらを個別に (外部的に) 評価してから、抽出した部分を結果に置き換えて式ツリーを変更することはできますか?

私の特定のケースでは、繰り返し実行されるレガシーコードを書き直すことができるかどうかを評価しようとしています:

  1. SQLを生成します
  2. データベースに問い合わせる
  3. 結果を使用して、新しい SQL クエリを生成します
  4. データベースに再度クエリを実行します... (など)

1. 1 つの大きな式ツリーを生成する 2. 式ツリーから SQL を取得する。これは次のもので構成されます。ツリーにアクセスし、結果の単一の sql を生成する前に評価する必要があるサブクエリを確認します c. サブクエリがある場合は、SQL を作成して文字列として返し、SQL を外部で評価し、ツリーを変更して、サブクエリを結果に置き換えます

(また、同一のサブクエリを特定し、可能であれば一度だけ評価したいと思います)

これは可能ですか?理解/習得が困難なコードが必要になるか?

Boost.Proto ドキュメントをざっと読んだことがありますが、サブツリーを外部で評価し、ツリー全体が単一のクエリになるまで結果に置き換える必要があるこのシナリオを意図しているかどうかはわかりません。

編集:

次のテーブルがあるとしましょう。

オブジェクト ID | 名前

attribute_link objectid | 属性 ID

属性 ID | 親 ID | 名前 | 価値

私のクエリは、カスタムの「クエリ」オブジェクト、つまり複数の AND、OR 句を持つ (バイナリ) ツリーとして入ってきます。

例: query1 = object.id=10 OR (attribute.name = "name" OR attribute.name = "name2")

これは次のように変換されます: 属性の名前が「name」であるオブジェクト 10 の属性を取得します。parentid フィールドに注目してください。これは、探している attribute.name をネストすることができ、 object に直接リンクできないことを意味します。

私がする必要があるのは: 1.これを十分な情報を含む式ツリーに変換する 2.このツリーをデータベース層に送信する 3.上記で説明したようにツリーを処理する (複数の段階で行う場合もある)

おそらく、式ツリーは次のようになります。

find_attributes( object_id = 10 AND attribute_name = ( "name" OR "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. (属性 ID を検索) SELECT id FROM 属性 WHERE objectid = 10)

  2. (最終クエリ) ---

    WITH
    get_roots AS (SELECT * FROM 属性 WHERE (id=20 OR id=21))、
    get_childs AS (SELECT * FROM get_roots、属性 WHERE attributes.parentid = get_roots.id)、
    get_grandchilds AS (SELECT * FROM get_childs、属性 WHERE 属性.parentid = get_childs.id)

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

(属性がここで 3 レベルの深さだけであると仮定すると、再帰的な CTE として書き直される可能性があります)

可能性はあると思いますが、やり過ぎでしょうか?クエリのセットは限られていますが、ここで紹介するクエリは最も複雑です。

4

1 に答える 1

1

Proto ツリー構造はコンパイル時に設定されるため、変更できません。通常、必要な要素を含む新しいツリーを再生成します。これは、ツリーを取得して新しいツリーを返すプロト変換として簡単に実行できます。

于 2013-08-22T17:58:01.997 に答える