版管理システムを用いた コードクローン履歴分析 川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 背景 コードクローン プログラム中の重複コード 保守工程における重大な障害のひとつ ある部分に修正が必要 → その部分のクローン全ての修正を検討 コードクローン(あるいは単にクローン) 類似文字列が存在するコード片 クローンの位置は (ファイル名、開始行 番号、終了行番号) で指定 クローンペア クローンA-1 とクローンA-2 が類似文字 列であるときに、これらをクローンペアと よぶ クローンセット クローンペア関係において推移関係が 成り立つクローンの集合 Clone A-1 Clone A-3 Clone A-2 Clone B-2 Clone B-1 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 2 クローン検出技法 コードクローンを自動的に検出 字句解析ベース CCFinder (神谷ら)* CloneDr (Baxter et al.)** メトリクスベース 関数単位のメトリクスに基づく手法(Kontgiannis)*** * T. Kamiya, S. Kusumoto and K. Inoue: “CCFinder: A Multi-Linguistic Token-based Code Clone Detection System for Large Scale Source Code”, IEEE Trans. Software Engineering, 28, 7, pp.654–670, 2002. ** I. D. Baxter, A. Yahin, L. M. de Moura, M. Sant'Anna, and L. Bier. Clone detection using abstract syntax trees. In Proc. of the Int'l Conf. on Software Maintenance, pages 368-377, 1998. *** K. Kontogiannis, “Evaluation Experiments on the Detection of Programming Patterns Using Software etrics,” Proc. Working Conf. Reverse Eng. (WCRE-97), pp. 577-586, Oct. 1997. 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 3 問題点 既存のクローン分析手法はある時点でのクローン抽 出 クローンの変遷を考慮に入れていない クローンの履歴を考慮しないと見えない関係 ・・・ Vt-2 Vt-1 Vt 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 4 本研究の目的 履歴を考慮したクローン分析 クローン履歴関係を抽出する クローン履歴の応用 1. クローン履歴によるクローングループの分割 2. クローン履歴による関連クローンの提示 3. 全体の傾向を分析するための材料 クローンの行数 全行数に対する割合 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 5 クローン履歴 1. ひとつのクローンセットを クローン発生時期から分類 Clone A-3 追加 Clone A-1 Clone A-1 Clone B-1 Clone B-1 Clone A-3 Clone A-1 Clone B-1 Clone A-3 Clone A-4 Clone A-4, A-5 追加 Clone A-2 Clone B-2 Clone B-3 Clone A-2 Clone B-5 Clone B-4 Clone B-2 Clone B’-3 Clone A-2 Clone B’-2 Clone B’-1 Clone B-3, B-4, B-5 が編集 されて別クローンセットに 3.コード中に含まれるコード クローンの変化を分析 Clone B’-2 Clone B-2 Clone B’-3 Clone A-5 Clone B’-1 Clone B’-3 削除 2.過去に同じクローンセットだった クローンセットの発見 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 6 提案手法の概要 “クローン履歴関係” の定義 時系列をまたがるクローンペア間の関係 抽出するべきデータ構造 クローン履歴関係抽出手法 クローン履歴関係を抽出するためのアルゴリズム 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 7 クローン履歴関係 ファイル1 ファイル1 挿入 Clone A クローン履歴関係 Clone A Clone A クローン関係 CCFinder に よって発見され たクローンペア ファイル2 ファイル2 Clone A Clone A 挿入 ファイル3 Clone B 2005/08/04 Clone B (過去のク ローン関係, 現在のク ローン関係) のペア 削除 ファイル3 Clone B Clone B Vt-1 Vt Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 8 クローン履歴関係抽出手法(1/2) 版管理システム(ex. cvs, subversion, ...)を用いて過去の時点のプ ロダクトを取得 となりあうバージョン間について分析 V0, V1 をリポジトリから取得 V0, V1 間のクローン履歴関係を分析 Vt をリポジトリから取得 Vt-1, Vt 間を分析 分析を行う期間、間隔は別途指定する ・・・ V0 V1 Vt-1 Vt 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 9 クローン履歴関係抽出手法(2/2) 隣あうバージョン Vt-1, Vt について以下を行う 1. クローン分析 クローン分析には CCFinder を使用する クローンの行数、総行数に対する割合も計算 2. クローン履歴関係分析 1. バージョン間で変更されていないクローンの履歴関係抽 出 2. Vt において新規に追加されたクローンの履歴関係抽出 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 10 Step1: クローン分析 ファイル1 ファイル1 Clone A クローン 関係 Clone A Clone A Vt 全体を CCFinder で分析 ファイル2 Clone A クローン 履歴関係 ファイル2 Clone A Clone B ファイル3 Clone B ファイル3 Clone B Clone B Vt-1 Vt 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 11 Step2-1: 編集されていないクローンの 履歴関係抽出 行番号 行番号 ファイル1 Clone A ファイル1 25 31 7 18 Clone A 37 43 Clone A ファイル2 Clone A クローン 関係 クローン 履歴関係 ファイル2 22 28 22 28 Clone A 編集操作による行番号のズレを吸収Clone B ファイル3 Clone B 11 22 Clone B 42 48 Vt-1 ファイル3 30 36 Clone B Vt の各クローンについて、Vt-1 の対応する Vt 行にクローンが存在するかどうか検索 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 12 行番号の調整 行番号 Vt-1 Vt 9 9 削除 22 Clone A 31 Clone A Vt 行番号 8 Clone A 15 18 24 29 34 39 行番号 挿入 8 18 衝突 Clone A 15 18 18 24 22 29 34 31 36 Vt-1 行番号 衝突時には対応行が一意でない 2005/08/04 最小、最大の推定値両方を考慮 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 13 Step2-2: 追加されたクローンの 履歴関係抽出 ファイル1 ファイル1 Clone A クローン 関係 Clone A Clone A ファイル2 ファイル2 Clone A Clone A クローン 履歴関係 Clone B ファイル3 Clone B ファイル3 Clone B Clone B Vt-1 2005/08/04 Vt-1 と 差分との間で CCFinder を適用 Vt 発見したクローンに対応する部分を履歴関係とする Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 14 提案手法の特徴 となりのバージョン同士でのつながり 任意の二点間の分析を行うのはコス トが大きい 計算量を極力抑える バージョン間の diff に対してのみク ローン分析を適用 Vt-1, Vt 全体に対して CCFinder を 適用するのはコストが大きい 各バージョンごとにクローン分析を適 用 正確なクローン分析 差分情報のみからクローン情報の分 析はしない 削除されたクローンは考慮しない 現在につながるクローンのみを考慮 有用な情報の抽出 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 15 PostgreSQL のクローン履歴分析 1. あるクローンに着目 • • 最新版だけでは抽出できないクローン関係の例 PostgreSQL のコア部分で行われたある変更に着目 2. クローン全体の履歴 • • PostgreSQL の開発工程におけるクローンの増加量を グラフ化 1998年7月から2005年7月の6年分を一月区切りで 解析 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 16 分析1 – 過去に関連のあったクローンセット pgsql/src/backend/commands/dbcommands.c 07/01 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple, 772 newtuple; ・・・ 790 791 newtuple = heap_copytuple(tuple); 792 datForm = (Form_pg_database) GETSTRUCT(newtuple); conversioncmds.c 793 aggregatecmds.c 794 /* 795 * If the new owner is the same as the existing owner, consider the 796 * command to have succeeded. This is to be consistent with other objects. 797 */ 798 if (datForm->datdba != newOwnerSysId) 799 { 800 /* changing owner's database for someone else: must be superuser */ opclasscmds.c operatorcmds.c 801 /* note that the someone else need not have any permissions */ 802 if (!superuser()) 803 ereport(ERROR, 804 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 805 errmsg("must be superuser to change owner"))); 806 807 /* change owner */ 808 datForm->datdba = newOwnerSysId; 809 simple_heap_update(rel, &newtuple->t_self, newtuple); functioncmds.c 810 CatalogUpdateIndexes(rel, newtuple); tablespace.c 811 } 812 813 systable_endscan(scan); 814 heap_close(rel, NoLock); 815 } pgsql/src/backend/commands/dbcommands.c 08/04 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple; 772 Relation rel; ・・・ 792 /* 793 * If the new owner is the same as the existing owner, consider the 794 * command to have succeeded. This is to be consistent with other objects. 795 */ pgsql/src/backend/commands/aggregatecmds.c 07/01 796 if (datForm->datdba != newOwnerSysId) aggregatecmds.c 291 /* 797 { 292 * Change aggregate owner 798 Datum repl_val[Natts_pg_database]; 293 */ 799 char repl_null[Natts_pg_database]; conversioncmds.c 294 void 800 char repl_repl[Natts_pg_database]; 295 AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) 801 Acl *newAcl; 296 { 802 Datum aclDatum; 297 803 Oid bool basetypeOid; isNull; 298 804 Oid procOid; opclasscmds.c HeapTuple newtuple; ・・・ 805 321 806 if (!HeapTupleIsValid(tup)) /* should not happen */ /* changing owner's database for someone else: must be superuser */ 322 807 elog(ERROR, failed forneed function %u",any procOid); /* note "cache that thelookup someone else not have permissions */ 323 808 procForm =if(Form_pg_proc) (!superuser()) GETSTRUCT(tup); opratorcmds.c 324 809 ereport(ERROR, 325 810 /* (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 326 811* If the new owner is the same as the existing owner, consider the errmsg("must be superuser to change owner"))); 327 812* command to have succeeded. This is for dump restoration purposes. tablecmds.c 328 813*/ memset(repl_null, ' ', sizeof(repl_null)); 329 814 if (procForm->proowner != newOwnerSysId) memset(repl_repl, ' ', sizeof(repl_repl)); 330 815 { 331 816 /* Otherwise, must be superuser to change object */ repl_repl[Anum_pg_database_datdba - 1] =ownership 'r'; functioncmds.c 332 817 if (!superuser()) repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId); 333 818 ereport(ERROR, 334 819 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), tablespace.c /* 335 820 errmsg("must be superuser to change owner"))); * Determine the modified ACL for the new owner. This is only 336 821 * necessary when the ACL is non-null. 337 822 /* Modify */ the owner --- okay to scribble on tup because it's a copy */ 338 823 procForm->proowner = newOwnerSysId; aclDatum = heap_getattr(tuple, 339 824 Anum_pg_database_datacl, schemacmds.c 340 825 simple_heap_update(rel, &tup->t_self, tup); RelationGetDescr(rel), 341 CatalogUpdateIndexes(rel, dbcommands.c tup); 342 } 343 344 heap_close(rel, NoLock); 345 heap_freetuple(tup); 346 } pgsql/src/backend/commands (SQL 文解釈・実行部の実装) Clone A Clone A Clone A Clone A Clone A Clone A schemacmds.c dbcommands.c Clone A Clone A 2005/08/04 Clone A Clone A Clone A Clone A Clone B Clone B Clone B Clone B Clone B 2004/07/01 2004/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 17 0.2 1800000 0.18 1600000 0.16 1400000 0.14 1200000 0.12 1000000 0.1 800000 0.08 600000 0.06 400000 0.04 200000 0.02 0 クローン含有率 2000000 その他-クローン その他-非クローン configure-クローン configure-非クローン contrib-クローン contrib-非クローン doc-クローン doc-非クローン src-クローン src-非クローン クローン含有率 0 19 9 19 8年 98 7月 年 19 11 99 月 19 年3 9 月 19 9年 99 7月 年 20 11 00 月 20 年3 0 月 20 0年 00 7月 年 20 11 01 月 20 年3 0 月 20 1年 01 7月 年 20 11 02 月 20 年3 0 月 20 2年 02 7月 年 20 11 03 月 20 年3 0 月 20 3年 03 7月 年 20 11 04 月 20 年3 0 月 20 4年 04 7月 年 20 11 05 月 年 3月 行数 分析2: PostgreSQL 全体のコード量 クローン含有率は開発工程全体をとおして安定 2005/08/04 src 以下が全体の8割を占めている Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 18 分析2: PostgreSQL コア部分のコード量 1200000 その他-クローン その他-非クローン src/backend/commands-クローン src/backend/commands-非クローン src/backend/access-クローン src/backend/access-非クローン src/backend/po-クローン src/backend/po-非クローン src/backend/utils-クローン src/backend/utils-非クローン 2000年11月、utils 以下のクローン含有率 1000000 800000 utils には文字コード変換用データの大量追加 600000 400000 200000 2005年4月 2005年1月 2004年10月 2004年7月 2004年4月 2004年1月 2003年10月 2003年7月 2003年4月 2003年1月 2002年10月 2002年7月 2002年4月 2002年1月 2001年10月 2001年7月 2001年4月 2001年1月 2000年10月 2000年7月 2000年4月 2000年1月 1999年10月 1999年7月 1999年4月 1999年1月 1998年10月 1998年7月 0 commands 以下のクローン率は徐々に上昇 0.2 0.18 0.16 0.14 その他 src/backend/commands src/backend/access src/backend/po src/backend/utils 0.12 0.1 0.08 0.06 0.04 0.02 02005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 19 考察 過去に関係のあったクローンの例 実際に関連性が高い 手動で履歴を探索していくのは手間がかかる 分析を行うための対話的ユーザインタフェースの作成 クローン量の変遷グラフ PostgreSQL の開発工程ではクローン含有率は安定 → 良好な開発パターン ただし src/backend/command 以下では上昇傾向 → 危険な傾向 危険なパターン、良好なパターンの列挙 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 20 関連研究 クローンの生存期間に着目した分析* (Kim ら) ある一定間隔ごとにクローン分析を行い、クローンの寿命を調査 クローンの生存期間によってクローンを分類 クローン分析にはCCFinderを用いる クローン履歴を利用したオリジン分析** (Godfrey ら) 関数が、過去のバージョンのどの関数に由来するものかを調べる 関数の統合、分割を半自動的に検出 クローン分析はメトリクスベース 対話的な分析 利用するメトリクスは分析者が決定 * M. Kim and D. Notkin: “Using a clone genealogy extractor for understanding and supporting evolution of code clones”, MSR 2005, Saint Louis, Missouri, pp. 17-21 (2005) ** M. W. Godfrey and L. Zou: “Using origin analysis to detect merging and splitting of source code entities”, IEEE Trans. Software Engineering, 31, 2, pp.166-181 (2005) 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 21 まとめ コードクローンの履歴を抽出する手法の提案 PostgreSQL から抽出した履歴の例の提示 課題 となりのバージョンだけで分析できないクローン履歴の抽 出 一度削除されてまた後で復活したクローン 活用方法の考察 分析用ユーザインタフェースの作成 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 22 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 23 クローン履歴 CloneB-3, B-4, B-5 が 編集されて別クローンに CloneB’-3 が削除 Clone B-5 Clone B’-3 Clone B’-2 Clone B-4 Clone B’-2 Clone B’-1 Clone B-3 Clone B’-1 Clone B-2 Clone B-2 Clone B-1 Clone B-2 Clone B-1 Clone B-1 Clone A-5 Clone A-3 追加 Clone A-4, A-5 追加 Clone A-4 Clone A-3 Clone A-3 Clone A-2 Clone A-2 Clone A-2 Clone A-1 Clone A-1 Clone A-1 Vt-2 Vt-1 Vt mogera huigara 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 24 クローン履歴 Clone A-3 追加 Clone A-1 Clone A-1 Clone B-1 Clone B-1 Clone A-3 Clone A-1 Clone B-1 Clone A-3 Clone A-4 Clone A-4, A-5 追加 Clone A-2 Clone B-2 Clone B-3 Clone A-2 Clone B-5 Clone B-4 Clone B-2 Clone B’-3 Clone A-2 Clone B’-2 Clone B’-1 Clone B-3, B-4, B-5 が編集 されて別クローンセットに Clone B’-2 Clone B-2 Clone B’-3 Clone A-5 Clone B’-1 Clone B’-3 追加 クローンの追加 クローンの編集 分岐 削除 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 25 クローンの履歴から見えてくるもの 過去に同じクローンセットだったク ローンを発見 Vtの時点では B と B’ は別クローン セット しかし, Vt-2 の時点では同じクローン セット クローンセットを発生時期で分類 CloneB-3, B-4, B-5 が 編集されて別クローンに Clone B-5 Clone B’-3 Clone B’-2 Clone B-4 Clone B’-2 Clone B’-1 Clone B-3 Clone B’-1 コード中に含まれるクローンの変化 を分析 コードクローン量の変化をグラフ化 コードクローンの割合をグラフ化 Clone B-2 Clone B-2 Clone B-1 VtにあるA-1, A-2, ... A-5 分割可能 最初からある A-1, A-2 後から追加された A-4, A-5 CloneB’-3 が削除 Clone B-2 Clone B-1 Clone B-1 Clone A-5 Clone A-3 追加 Clone A-4, A-5 追加 Clone A-4 Clone A-3 Clone A-3 Clone A-2 Clone A-2 Clone A-2 Clone A-1 Clone A-1 Clone A-1 Vt-2 Vt-1 Vt 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 26 行番号 ファイル1 25 31 ファイル1 Clone A クローン 関係 Clone A Clone A ファイル2 ファイル2 Clone A Clone A クローン 履歴関係 Clone B ファイル3 Clone B ファイル3 Clone B Clone B Vt-1 Vt 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 27 クローンの定義 コードクローン(あるいは単にク ローン) 類似文字列が存在するコード片 クローンの位置は (ファイル名、開 始行番号、終了行番号) で指定 クローンペア クローンA-1 とクローンA-2 が類似 文字列であるときに、これらをクロー ンペアとよぶ クローンセット Clone A-1 Clone A-3 Clone A-2 Clone B-2 Clone B-1 クローンペア関係において推移関 係が成り立つクローンの集合 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 28 CCFinder 字句比較に基づくクローン抽出手法 トークン区切り 言語依存 通常の英語文書にも対応 識別子の名前を無視する 変数名の名前を変えたコピー&ペーストにも対応できる 高いスケーラビリティ 大規模なソースコードに対する運用実績 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 29 版管理システム プロダクトの保管システム ex. CVS, subversion, Perforce, etc... さまざまなオープンソースプロジェクトで利用されている FreeBSD, Apache HTTP Server, ファイルが更新されるたびに、前回との差分を逐一記録 任意の時点でのソースコードを取り出すことが可能 これまでは必ずしも保障されていなかった 任意の時点でのクローン情報を知ることが可能 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 30 抽出アルゴリズム クローン ファイル1 ファイル1 挿入 Clone A クローン 履歴関係 Clone A Clone A Clone A ファイル2 Clone A ファイル2 Vt-1 Vt 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 31 行番号調整 Vt-1 Vt-1 挿入 8 15 18 削除 22 31 編集 Vt 8 36 31 18 22 25 18 29 15 34 8 8 18 25 29 34 39 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University Vt 32 行番号調整 追加(add) 削除(delete) 衝突(conflict) 2005/08/04 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 33 pgsql/src/backend/commands/dbcommands.c 08/04 765 /* 766 * ALTER DATABASE name OWNER TO newowner 767 */ 768 void 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 770 { 771 HeapTuple tuple; 772 Relation rel; ・・・ 792 /* 793 * If the new owner is the same as the existing owner, consider the 794 * command to have succeeded. This is to be consistent with other objects. 795 */ 796 if (datForm->datdba != newOwnerSysId) 797 { pgsql/src/backend/commands/dbcommands.c 07/01 798 Datum repl_val[Natts_pg_database]; 765 /* 799 char repl_null[Natts_pg_database]; 766 * ALTER DATABASE name OWNER TO newowner 800 char repl_repl[Natts_pg_database]; 767 */ 801 Acl *newAcl; 768 void 802 Datum aclDatum; 769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) 803 bool isNull; 770 { 804 HeapTuple tuple, newtuple; 771 HeapTuple 805 772 newtuple; 806 /* changing owner's database for someone else: must be superuser */ ・・・ 807 /* note that the someone else need not have any permissions */ 790 808 if (!superuser()) 791 newtuple = heap_copytuple(tuple); 809 ereport(ERROR, 792 datForm = (Form_pg_database) GETSTRUCT(newtuple); 810 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 793 811 errmsg("must be superuser to change owner"))); 794 /* 812 795 * If the new owner is the same as the existing owner, consider the 813 memset(repl_null, ' ', sizeof(repl_null)); 796 * command to have succeeded. This is to be consistent with other objects. 814 797 */ memset(repl_repl, ' ', sizeof(repl_repl)); 815 798 if (datForm->datdba != newOwnerSysId) 816 799 { repl_repl[Anum_pg_database_datdba - 1] = 'r'; 817 repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId); 800 /* changing owner's database for someone else: must be superuser */ 818 801 /* note that the someone else need not have any permissions */ 819 /*if (!superuser()) 802 820 * Determine the modified ACL for the new owner. This is only 803 ereport(ERROR, 821 * necessary when the ACL is non-null. 804 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 822 */ 805 errmsg("must be superuser to change owner"))); 823 aclDatum = heap_getattr(tuple, 806 824 807 /* change owner */ Anum_pg_database_datacl, 825 RelationGetDescr(rel), 808 datForm->datdba = newOwnerSysId; 分析1 pgsql/src/backend/commands/aggregatecmds.c 07/01 291 /* 292 * Change aggregate owner 293 */ 294 void 295 AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) 296 { 297 Oid basetypeOid; 298 Oid procOid; ・・・ 321 if (!HeapTupleIsValid(tup)) /* should not07/01 happen */ pgsql/src/backend/commands/aggregatecmds.c 322 291 /* elog(ERROR, "cache lookup failed for function %u", procOid); 323 292 procForm = (Form_pg_proc) GETSTRUCT(tup); * Change aggregate owner 324 293 */ 325 294 /* void 326 295 AlterAggregateOwner(List * If the new owner is the same as TypeName the existing*basetype, owner, consider the *name, AclId newOwnerSysId) 327 296 {* command to have succeeded. This is for dump restoration purposes. 328 297 */ Oid basetypeOid; 329 298 if (procForm->proowner != newOwnerSysId) Oid procOid; 330 ・・・ { 331 321 /* Otherwise, must be superuser to change object if (!HeapTupleIsValid(tup)) /* should not happen */ ownership */ 332 322 if (!superuser()) elog(ERROR, "cache lookup failed for function %u", procOid); 333 323 ereport(ERROR, procForm = (Form_pg_proc) GETSTRUCT(tup); 334 324 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 335 325 errmsg("must be superuser to change owner"))); /* 336 326 * If the new owner is the same as the existing owner, consider the 337 327 /** Modify thetoowner okay to scribble on tup because it's a copy */ command have --succeeded. This is for dump restoration purposes. 338 328 procForm->proowner = newOwnerSysId; */ 339 329 if (procForm->proowner != newOwnerSysId) 340 330 simple_heap_update(rel, &tup->t_self, tup); { 341 331 CatalogUpdateIndexes(rel, tup); /* Otherwise, must be superuser to change object ownership */ 342 332 } if (!superuser()) 343 333 ereport(ERROR, 344 334 heap_close(rel, NoLock); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), 345 335 heap_freetuple(tup); errmsg("must be superuser to change owner"))); 346 }336 337 /* Modify the owner --- okay to scribble on tup because it's a copy */ 338 procForm->proowner = newOwnerSysId; 339 340 simple_heap_update(rel, &tup->t_self, tup); 341 CatalogUpdateIndexes(rel, tup); 342 } 343 344 heap_close(rel, NoLock); 345 heap_freetuple(tup); 346 } Clone A Clone A Clone A Clone A Clone A Clone A Clone A Clone A 2005/08/04 2004/07/01 Clone A Clone A Clone A Clone A 2004/08/04 Clone B Clone B 809 810 811 812 813 814 815 } Clone B simple_heap_update(rel, &newtuple->t_self, newtuple); CatalogUpdateIndexes(rel, newtuple); } Clone B systable_endscan(scan); heap_close(rel, NoLock); Clone B Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 34
© Copyright 2024 ExpyDoc