Skip to content

ZTDをFunction表対応させ、実質Viewな table-valued function をDDLから判定して引数付きViewとして扱えるようにする #630

@mk3008

Description

@mk3008

背景

現実のSQLでは、FROM my_func(...) のように、表のように扱うFunctionが使われることがある。

これらは見た目としてはテーブルやViewに近く、実質的には「引数付きView」とみなせるケースがある。
一方で、すべてのFunction表を一般に扱うのは難しい。

特に以下のような要素が入ると、静的解析は一気に難しくなる。

  • PL/pgSQL など手続き言語
  • dynamic SQL
  • record など呼び出し側依存の戻り型
  • 副作用のある処理
  • temp table や複雑な制御構文

そのため、まずは「実質View」とみなせる table-valued function に限定して対応するのがよい。

目的

ZTDをFunction表対応させる。

ただし最初から一般化はせず、まずは「実質ViewなFunction表」のみを対象とする。

具体的には以下を実現したい。

  • DDLから対象オブジェクトがFunction表であることを判定できる
  • そのうち、静的解析可能な subset を選別できる
  • 対象subsetについては、引数付きViewとして内部的に扱える
  • 依存関係や列形状を、可能な範囲で基底表まで追跡できる

スコープ

今回の対象は、以下の条件を満たす Function表を第一候補とする。

  • LANGUAGE SQL
  • RETURNS TABLE(...) など戻り列が明示されている
  • 本体が単一の SELECT
  • dynamic SQL を含まない
  • 副作用を持たない
  • 呼び出し側文脈に依存する record ではない

実施したいこと:

  • DDLからFunction定義を抽出する
  • Function表かどうかを判定する
  • 対応可能subsetかどうかを判定する
  • 対応可能なものは、引数付きView相当として内部表現へ落とし込む
  • FROM my_func(...) のような参照から、列形状や依存関係を追跡できるようにする

非スコープ

今回は以下は対象外とする。

  • scalar function
  • 式中関数呼び出しの一般対応
  • PL/pgSQL function の一般対応
  • dynamic SQL を含む function
  • returns setof record など戻り形状が静的に確定しない function
  • 副作用を持つ function
  • 完全な function inlining 一般解

未対応ケースは、無理に展開せず unsupported として扱う。

期待するふるまい

たとえば以下のようなFunctionは対象にしたい。

create function search_users(p_keyword text)
returns table(id int, name text)
language sql
as $$
  select id, name
  from users
  where name ilike '%' || p_keyword || '%'
$$;

このとき、

select *
from search_users(:keyword);

のような参照を、内部的には「引数付きView」に近いものとして扱い、
列形状や依存表 users を追跡できることが望ましい。

受け入れ条件

  • DDLからFunction表を判定できる
  • 対応可能subsetと未対応subsetを分けて扱える
  • 対応可能subsetについては、内部的に引数付きView相当として扱える
  • 単純な LANGUAGE SQL + RETURNS TABLE + 単一SELECT のケースで列形状が追跡できる
  • 少なくとも単純な1段の依存関係を取得できる
  • 未対応ケースを unsupported として明示できる

メモ

これはView対応の次にやる。

Function表の一般対応は難しいが、実質Viewな subset に限れば価値が高く、ZTDの説明力も大きく上がる。
一方で、scalar function や式中関数呼び出しは別課題とする。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions