関数特性
言語: PLPGSQL
戻り値: text
determineAttKindUnique (tab_fqname, indexname) tablename を仮定し、(ログトリガーで使用される) Slony-I 特有の attkind を返します。特定された一意のインデックスもしくは(indexname が NULL)であれば主キーを使用します。declare p_tab_fqname alias for $1; v_tab_fqname_quoted text default ''; p_idx_name alias for $2; v_idx_name_quoted text; v_idxrow record; v_attrow record; v_i integer; v_attno int2; v_attkind text default ''; v_attfound bool; begin v_tab_fqname_quoted := slon_quote_input(p_tab_fqname); v_idx_name_quoted := slon_quote_brute(p_idx_name); -- -- テーブルが存在するかの確証 -- if (select PGC.relname from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN where slon_quote_brute(PGN.nspname) || '.' || slon_quote_brute(PGC.relname) = v_tab_fqname_quoted and PGN.oid = PGC.relnamespace) is null then raise exception 'Slony-I: table % not found', v_tab_fqname_quoted; end if; -- -- テーブル主キーもしくは特定の一意インデックスを参照します。 -- if p_idx_name isnull then raise exception 'Slony-I: index name must be specified'; else select PGXC.relname, PGX.indexrelid, PGX.indkey into v_idxrow from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN, "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC where slon_quote_brute(PGN.nspname) || '.' || slon_quote_brute(PGC.relname) = v_tab_fqname_quoted and PGN.oid = PGC.relnamespace and PGX.indrelid = PGC.oid and PGX.indexrelid = PGXC.oid and PGX.indisunique and slon_quote_brute(PGXC.relname) = v_idx_name_quoted; if not found then raise exception 'Slony-I: table % has no unique index %', v_tab_fqname_quoted, v_idx_name_quoted; end if; end if; -- -- テーブル属性をループしてそれらがインデックス属性か検査します。 -- インデックス属性であれば返り値に "k" を付け -- さもなければ "v" を付けます。 -- for v_attrow in select PGA.attnum, PGA.attname from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN, "pg_catalog".pg_attribute PGA where slon_quote_brute(PGN.nspname) || '.' || slon_quote_brute(PGC.relname) = v_tab_fqname_quoted and PGN.oid = PGC.relnamespace and PGA.attrelid = PGC.oid and not PGA.attisdropped and PGA.attnum > 0 order by attnum loop v_attfound = 'f'; v_i := 0; loop select indkey[v_i] into v_attno from "pg_catalog".pg_index where indexrelid = v_idxrow.indexrelid; if v_attno isnull or v_attno = 0 then exit; end if; if v_attrow.attnum = v_attno then v_attfound = 't'; exit; end if; v_i := v_i + 1; end loop; if v_attfound then v_attkind := v_attkind || 'k'; else v_attkind := v_attkind || 'v'; end if; end loop; -- -- 結果の attkind を返します。 -- return v_attkind; end;