9 演算子の定義

演算子を定義し、それを索引タイプを指定して、または指定せずに使用できます。

9.1 ユーザー定義演算子

ユーザー定義演算子は最上位のスキーマ・オブジェクトです。ユーザー定義演算子は、多くの点で、組込み演算子(<、>、=など)と同様に機能します。たとえば、組込み演算子とまったく同じ状況で呼び出すことができます。SQL文を簡素化し、それらをより短く理解しやすくすることで、使いやすさを促進できます。

ユーザー定義演算子の特徴は次のとおりです。

  • 表、ビュー、型およびスタンドアロン・ファンクションと同じネームスペースにあって名前で識別されます。

  • 指定のコンテキストにおける演算子の動作を定義するファンクションにバインドされます。

  • 各演算子を使用できる状況を示す権限により制御されます。

  • 通常は、データベースに組み込まれていない索引の定義に使用できる索引タイプに関連付けられています。

関連項目:

構文および権限の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

9.1.1 演算子バインディング

演算子バインディングにより、演算子をその実装に使用するファンクションのシグネチャに関連付けます。シグネチャは、ファンクションの引数のデータ型、出現順序およびファンクションの戻り型のリストで構成されています。演算子バインディングにより、Oracleに対して演算子の起動時に実行するファンクションを指示します。各ファンクションのシグネチャが異なる場合は、1つの演算子を複数のファンクションにバインドできます。ファンクションが異なるものとみなされるには、各ファンクションの引数リストが異なっている必要があります。戻り値のデータ型が一致しなくても引数リストが一致しているファンクションは、異なるものとはみなされず、同じ演算子にはバインドできません。

演算子に可能なバインド先は、次のとおりです。

  • スタンドアロン・ファンクション

  • パッケージ・ファンクション

  • ユーザー定義型のメンバー・メソッド

演算子は、アクセス可能な任意のスキーマ内でファンクションおよびスキーマにバインドできます。各演算子の作成時に、バインディングを1つ以上指定する必要があります。一意でない演算子バインディングを指定すると、Oracleサーバーでエラーになります。

9.1.2 演算子の権限

演算子と演算子バインディングを作成するには、次の権限が必要です。

  • CREATE OPERATORまたはCREATE ANY OPERATOR権限

  • 参照されるファンクション、演算子、パッケージまたは型に対するEXECUTE権限

ユーザー定義演算子を削除するには、その演算子の所有者であるか、またはDROP ANY OPERATOR権限が必要です。

ユーザー定義演算子を式で起動するには、その演算子の所有者であるか、またはそれに対するEXECUTE権限が必要です。

9.1.3 演算子の作成

演算子を作成するには、CREATE OPERATOR文で演算子名とバインディングを指定します。例9-1では、演算子Contains()を作成し、テキスト・ドメインと空間ドメイン内で実装を提供するファンクションにバインドします。

例9-1 演算子の作成

CREATE OPERATOR Contains
BINDING
(VARCHAR2, VARCHAR2) RETURN NUMBER USING text.contains,
(Spatial.Geo, Spatial.Geo) RETURN NUMBER USING Spatial.contains;

9.1.4 演算子の削除

演算子とすべてのバインディングを削除するには、DROP OPERATOR文で演算子名を指定します。例9-2では、演算子Contains()を削除します。

デフォルトのDROP動作はDROP RESTRICTです。つまり、演算子バインディングのいずれかに依存索引タイプまたは補助演算子が存在する場合、DROP操作は禁止されます。

デフォルト動作をオーバーライドするには、FORCEオプションを使用します。例9-3では、演算子とすべてのバインディングを削除し、依存索引タイプ・オブジェクトと依存補助演算子に無効マークを付けます。

例9-2 演算子の削除(RESTRICTオプション)

DROP OPERATOR Contains;

例9-3 演算子の削除(FORCEオプション)

DROP OPERATOR Contains FORCE;

9.1.5 演算子の変更

ALTER OPERATOR文を使用すると、既存の演算子についてバインディングを追加または削除できます。例9-4では、演算子Contains()にバインディングを追加します。

例9-4 演算子へのバインディングの追加

ALTER OPERATOR Contains
  ADD BINDING (music.artist, music.artist) RETURN NUMBER
  USING music.contains;
9.1.5.1 ALTER OPERATORに必要な権限

演算子を変更するには、その演算子が自分のスキーマ内に存在するか、ALTER ANY OPERATOR権限を持っている必要があります。また、参照される演算子とファンクションに対するEXECUTE権限が必要です。

9.1.5.2 ALTER OPERATORの制限事項

ALTER OPERATOR文には、次の制限が適用されます。

  • 発行できるのは、既存の演算子に関連するALTER OPERATOR文のみです。

  • ALTER OPERATOR文で追加または削除できるバインディングは1つのみです。

  • ALTER OPERATORを使用して、演算子の唯一のバインディングを削除することはできません。演算子を削除するには、DROP OPERATOR文を使用します。演算子にはバインディングが必要です。

  • 索引タイプに関連付けられている演算子にバインディングを追加する場合は、ALTER INDEXTYPE ADD OPERATOR文も発行しなければ、バインディングは索引タイプに関連付けられません。

9.1.6 演算子へのコメントの付加

演算子にコメント・テキストを追加するには、COMMENT文で名前とテキストを指定します。例9-5では、Contains()演算子に関する情報を提供します。

演算子に関するコメントは、次のビューを介してデータ・ディクショナリ内で使用できます。

  • USER_OPERATOR_COMMENTS

  • ALL_OPERATOR_COMMENTS

  • DBA_OPERATOR_COMMENTS

COMMENT ANY OPERATOR権限がない場合、コメント付けできるのは自分のスキーマ内にある演算子のみです。

例9-5 演算子へのコメントの追加

COMMENT ON OPERATOR
Contains IS 'a number that indicates if the text contains the key';

9.1.7 演算子の起動について

組込み演算子と同様に、ユーザー定義演算子は式を使用できる場所であればどこでも起動できます。たとえば、ユーザー定義演算子を次の場所で使用できます。

  • SELECTコマンドのSELECT構文のリスト

  • WHERE句の条件

  • ORDER BY句およびGROUP BY

演算子が起動されると、Oracleはバインドされているファンクションを実行して演算子を評価します。演算子に複数のファンクションがバインドされている場合は、引数のデータ型が起動のデータ型と(暗黙的な型の変換後に)一致しているファンクションが実行されます。起動された演算子の引数リストが、その演算子にバインドされているファンクションのシグネチャと一致しない場合は、エラーが発生します。ユーザー定義演算子には複数のバインディングを指定できるため、オーバーロードされるファンクションとして使用できます。

例9-6では、演算子Contains()を作成するとします。

例9-7Contains()が使用される場合、ファンクションのシグネチャが演算子の引数のデータ型と一致しているため、演算子の起動Contains(resume, 'Oracle')により、ファンクションtext.contains(resume, 'Oracle')が実行されます。同様に、演算子の起動Contains(location, :bay_area)により、ファンクションspatial.contains(location, :bay_area)が実行されます。

例9-8の文を実行すると、引数のデータ型と一致する演算子バインディングがないため、エラーになります。

9.1.7.1 Contains()演算子の作成

例9-6 Contains()演算子の作成

CREATE OPERATOR Contains
BINDING 
(VARCHAR2, VARCHAR2) RETURN NUMBER 
USING text.contains, 
(spatial.geo, spatial.geo) RETURN NUMBER 
USING spatial.contains;
9.1.7.2 Contains()演算子の問合せ時の使用

例9-7 演算子Contains()の問合せ時の使用

SELECT * FROM MyEmployees
WHERE Contains(resume, 'Oracle')=1 AND Contains(location, :bay_area)=1;
9.1.7.3 Contains()演算子の間違った使用

例9-8 演算子Contains()の間違った使用

SELECT * FROM MyEmployees
WHERE Contains(address, employee_addr_type('123 Main Street', 'Anytown', 'CA',
  '90001'))=1; 

9.2 演算子と索引タイプ

通常、演算子は索引タイプに関連付けて定義されます。ファンクション実装を指定して演算子を作成した後、索引スキャンによるこれらの演算子の評価をサポートする索引タイプを作成できます。

WHERE句の外にある演算子は、実際にはそれを実装するファンクションの代替であり、この種の演算子の意味はファンクション実装により決定されます。WHERE句の中にある演算子は、ファンクション実装を使用して評価される場合と、索引スキャンにより評価される場合があります。

9.2.1 WHERE句の中にある演算子

WHERE句の中にある演算子は、索引タイプにより指定されたスキャン方法を使用し、索引スキャンで効果的に評価できます。この処理には、次のステップが必要です。

  1. 演算子の評価をサポートする索引タイプの作成

  2. 特定の書式による演算子述語の認識

  3. ドメイン索引の選択

  4. 適切な索引スキャンの設定

  5. 索引スキャン・メソッドの実行

9.2.1.1 演算子述語の使用

索引タイプでは、演算子の戻り値の上限と下限の範囲で表すことのできる演算子述語の効率的な評価がサポートされています。特に、例9-9にリストされている形式の述語は、索引スキャン・ベースの評価に使用できます。

例9-9の書式のいずれかにOracleで内部的に変換できる演算子述語でも、索引スキャン・ベースの評価を使用できます。

op(...) + 2 = 3のように、演算子を式に使用すると、索引スキャン・ベースの評価が除外されます。

op() is NULL形式の述語はファンクション実装を使用して評価されます。

例9-9 演算子述語

op(...) LIKE value_expression
op(...) relop value_expression

   value_expressionは、ドメイン索引キーとして使用できる定数(列ではない)に評価される必要があります。relopは、<<==>=または>のいずれかです。

9.2.1.2 Contains()演算子を使用した問合せ結果の解決

演算子を索引スキャン・ベースで評価できるのは、演算子が索引タイプにより索引付けされた列またはオブジェクトの属性に適用される場合のみです。オプティマイザは、問合せ実行計画の生成中に選択性とコストを考慮して、索引付けされた実装とファンクション実装の間で最終決定を行います。

例9-10の問合せを考えてみます。

オプティマイザは、次の場合にはContains()演算子の評価にドメイン索引を使用するように選択できます。

  • resume列に索引が定義されている場合

  • 索引がTextIndexTypeタイプの場合

  • TextIndexTypeで適切なContains()演算子がサポートされている場合

前述の条件のいずれかが保持されない場合は、MyEmployees表のフルスキャンが実行され、Contains()のファンクション実装がポストフィルタとして適用されます。ただし、前述の条件がすべて満たされている場合、オプティマイザは選択性およびコストのファンクションを使用し、索引ベース評価のコストを全表スキャンと比較して、適切な実行計画を生成します。

例9-11で、少し異なる問合せを考えてみます。

ここでは、MyEmployees表にアクセスするために、id列の索引、resume列の索引、またはこれら2つのビットマップ・マージを使用できます。オプティマイザは、これら3つの計画のコストを見積り、最もコストの低いバリエーション、つまりidの索引を使用して、結果の行にContains()演算子を適用する方法を選択します。その場合、Oracleはドメイン索引ではなくContains()のファンクション実装を使用します。

例9-10 Contains()演算子の単純な問合せ時の使用

SELECT * FROM MyEmployees WHERE Contains(resume, 'Oracle') = 1;

例9-11 Contains()演算子の複雑な問合せ時の使用

SELECT * FROM MyEmployees WHERE Contains(resume, 'Oracle') =1 AND id =100;
9.2.1.3 索引スキャンの設定

演算子述語の評価用にドメイン索引が選択された場合は、索引スキャンが設定されます。索引スキャンは、対応する索引タイプ実装の一部として指定されたスキャン・メソッド(ODCIIndexStart()ODCIIndexFetch()ODCIIndexClose())により実行されます。ODCIIndexStart()メソッドは、名前、引数および述語を記述する上限と下限などの演算子関連情報を使用して起動されます。ODCIIndexStart()コール後に、一連のフェッチが実行されて述語を満たす行のROWIDが取得され、最後にSQLカーソルが破棄されるときにODCIIndexClose()がコールされます。

9.2.1.4 索引スキャン・メソッドの実行モデル

索引スキャン・ルーチンを実装するには、その起動方法と複数の起動セットの結合方法を理解する必要があります。

例として、例9-12の問合せを考えてみます。

オプティマイザが両方の表のresume列のドメイン索引を使用するように選択した場合は、索引タイプ・ルーチンを例9-13で示されている順序で起動できます。

この例では、単一の索引タイプ・ルーチンがContains()演算子のインスタンスごとに複数回起動されます。同じ索引タイプ・ルーチンを介して同時に多数の演算子を評価できます。必要な情報をすべてパラメータを介して取得するCREATEルーチンなどのルーチンは、コール間で状態を維持しないため、同時に複数の演算子を評価しても問題はありません。コール間で状態を維持する必要のあるFETCHルーチンなどの他のルーチンは、次に戻される行を知る必要があります。これらのルーチンは、各コールで渡されるSELFパラメータで状態情報を維持する必要があります。SELFパラメータ(実装タイプのインスタンス)を使用すると、状態全体(大きすぎる場合は状態を格納するカーソル時間メモリーへのハンドル)を格納できます。

9.2.1.5 Contains()演算子を使用した複数の表での問合せのフィルタ処理

例9-12 Contains()演算子の複数の表での問合せ時の使用

SELECT * FROM MyEmployees1, MyEmployees2 
WHERE 
  Contains(MyEmployees1.resume, 'Oracle') =1 AND 
  Contains(MyEmployees2.resume, 'UNIX') =1 AND 
  MyEmployees1.employee_id = MyEmployees2.employee_id;
9.2.1.6 Contains()演算子に対する索引タイプ・ルーチンの起動

例9-13 Contains()演算子問合せに対する索引タイプ・ルーチンの起動

start(ctx1, ...); /* corr. to Contains(MyEmployees1.resume, 'Oracle') */
start(ctx2, ...); /* corr. to Contains(MyEmployees2.resume, 'UNIX');
fetch(ctx1, ...);
fetch(ctx2, ...);
fetch(ctx1, ...);
...
close(ctx1);
close(ctx2);

9.2.2 WHERE句の外にある演算子の使用

WHERE句の外で使用される演算子は、ファンクション実装を使用して評価されます。例9-14の文を実行する場合、OracleはMyEmployees表をスキャンし、resumeのインスタンスごとにContains()のファンクション実装を起動し、現在行のresumeの実際値(テキスト・データ)を渡します。このファンクションでは、resume列に作成されたドメイン索引が使用されないことに注意してください。

ファンクション実装ではドメイン索引を使用できるため、ドメイン索引を使用するファンクションの作成方法と、システムによる起動方法について考えます。

例9-14 WHERE句の外にある演算子の使用

SELECT Contains(resume, 'Oracle') FROM MyEmployees;
9.2.2.1 索引ベースのファンクション実装の作成

Contains()など、多数のドメイン固有演算子の場合、ファンクション実装には次の2つのオプションがあります。

  • 演算子がドメイン索引を持つ列またはOBJECT属性を対象とする場合、ファンクションでは実引数の値ではなく索引データを調べて演算子を評価できます。

    たとえば、MyEmployees表の特定の行でContains(resume, 'Oracle')が起動される場合、ファンクションではresume列に定義されているテキスト・ドメイン索引を調べ、resumeを含む行のROWIDに基づいて演算子を評価する方が、resumeテキスト・データ引数を処理するよりも容易です。

  • 演算子が適切なドメイン索引の定義されていない列を対象とする場合や、リテラル値(列以外)を使用して起動される場合、ファンクション実装では引数の値に基づいて演算子が評価されます。これは、すべての演算子バインディングに対するデフォルト動作です。

演算子で両方のオプションを処理させるには、演算子にオリジナルの引数のみでなく次の3つの引数を持つファンクション実装を提供します。

  • 索引コンテキスト: ドメイン索引情報と、演算子が評価される行のROWID。

  • スキャン・コンテキスト: 表の他の行を対象とする同じ演算子の以降の起動と状態を共有するためのコンテキスト値。

  • スキャン・フラグ: 現行のコールがすべてのクリーン・アップ操作を実行する必要のある最後の起動かどうかを示します。

例9-15のファンクションTextContains()は、Contains()演算子の索引ベースのファンクション実装を提供します。

Contains()演算子は、例9-16に示されているように、ファンクション実装に次のようにバインドされます。

WITH INDEX CONTEXT句は、ファンクション実装がアプリケーション・ドメイン索引を使用できることを指定します。SCAN CONTEXTは、スキャン・コンテキスト引数のデータ型を指定します。このデータ型は、この演算子をサポートする索引タイプの実装型と同じである必要があります。

9.2.2.2 索引ベースのファンクションでのContains()演算子の実装

例9-15 索引ベースのファンクションでのContains()演算子の実装

CREATE FUNCTION TextContains (Text IN VARCHAR2, Key IN VARCHAR2,
indexctx IN ODCIIndexCtx, scanctx IN OUT TextIndexMethods, scanflg IN NUMBER)
RETURN NUMBER AS
BEGIN
.......
END TextContains;
9.2.2.3 Contains()演算子のファンクション実装へのバインド

例9-16 Contains()演算子のファンクション実装へのバインド

CREATE OPERATOR Contains
BINDING (VARCHAR2, VARCHAR2) RETURN NUMBER 
WITH INDEX CONTEXT, SCAN CONTEXT TextIndexMethods
USING TextContains;
9.2.2.4 演算子の解決

演算子がWHERE句の外にある場合、Oracleは演算子のファンクション実装を起動します。ファンクション実装が索引ベースであるか、索引タイプを使用するように定義されている場合は、演算子の最初の引数が適切な索引タイプのドメイン索引が定義されている列またはオブジェクト属性である場合にのみ、追加の索引情報が引数として渡されます。

たとえば、問合せSELECT Contains(resume, 'Oracle & Unix') FROM MyEmployeesでは、Oracleは索引ベースのファンクション実装を使用し、resumeデータのかわりにresume列のドメイン索引に関する索引情報を渡して、Contains()演算子を評価します。

9.2.2.5 演算子の実行

索引ベースのファンクション実装を実行するために、Oracleは引数を次の方法で設定します。

  • 引数の初期セットは、演算子のユーザーが指定したセットと同じです。

  • 最初の引数が列でない場合は、ODCIIndexCtx属性がNULLに設定されます。

  • 最初の引数が列の場合は、ODCIIndexCtx属性が次のように設定されます。

    • 適用可能なドメイン索引が存在する場合、ODCIIndexInfo属性にはその情報が含まれ、それ以外の場合はNULLに設定されます。

    • rowid属性には、操作される行のROWIDが保持されます。

  • 演算子の初回起動時にスキャン・コンテキストがNULLに設定されます。これはIN/OUTパラメータであるため、初回起動からの戻り値が第2の起動に渡されます。

  • 演算子のすべての正常起動についてスキャン・フラグがRegularCallに設定されます。最後の起動後に、ファンクション実装がもう一度起動され、その時点で必要なクリーン・アップ・アクションを実行できます。このコール時に、スキャン・フラグがCleanupCallに設定され、スキャン・コンテキスト以外の引数がすべてNULLに設定されます。

索引情報が渡されると、実装ではROWIDをキーとして使用し、ドメイン索引検索により演算子の値を計算できます。ドメイン索引に関連付けられている索引構造は、索引メタデータを使用して識別されます。通常は、スキャン・コンテキストを使用して、同じ演算子の以降の起動と状態が共有されます。

演算子をサポートしている索引タイプがない場合、または列のドメイン索引が演算子に最初の引数として渡されない場合、索引コンテキスト引数はNULLになります。ただし、スキャン・コンテキスト引数は引き続き使用できます。このため、索引が問合せで使用されていない場合でも、演算子は呼出し間で状態を保持できます。

9.2.3 補助データを戻す演算子

WHERE句内の演算子は、行をフィルタリングするのみでなく、補助データを戻す必要がある場合があります。補助データは、それぞれが次のような1つ以上の演算子としてモデル化されます。

  • 対応する主演算子に結合する1つのリテラル数値引数

  • 主演算子の索引スキャン・ベース実装により生成された状態にアクセスするファンクション実装

例9-17の問合せでは、主演算子Contains()は、条件を満たす行を判別し各行のスコア値を計算する索引スキャンを使用して評価できます。Score演算子のファンクション実装は、索引スキャンにより生成された状態にアクセスして、ROWIDで識別された特定の行のスコアを取得します。リテラル引数1は、補助演算子Scoreを、補助データを生成する主演算子Contains()に関連付けます。

補助演算子のファンクション実装では、ドメイン索引または主演算子により生成された状態を使用できます。ファンクション実装には、起動時にさらに3つの引数が渡されます。

  • 索引コンテキスト(ドメイン索引情報を含む)

  • スキャン・コンテキスト(主演算子により生成された状態へのアクセスを提供)

  • スキャン・フラグ(ファンクション実装が最後に起動されるかどうかを示す)

補助データをモデル化する演算子の定義および起動方法を考えます。

例9-17 Contains()演算子を使用した補助データへのアクセス

SELECT Score(1) FROM MyEmployees 
WHERE Contains(resume, 'OCI & UNIX', 1) =1;
9.2.3.1 補助データを計算する演算子バインディング

補助データを計算する演算子バインディングは、主バインディングと呼ばれます。例9-18では、演算子Contains()に主バインディングを定義します。

この定義により、Contains()について次の2つのバインディングが登録されます。

  • CONTAINS(VARCHAR2, VARCHAR2)このバインディングは、補助データが不要な場合に使用されます。

  • CONTAINS(VARCHAR2, VARCHAR2, NUMBER)。このバインディングは、補助データが必要な場合に使用されます(NUMBER引数により、このバインディングが補助演算子バインディングに関連付けられます)。

これら2つのバインディングには、例9-19に示す単一のファンクション実装があります。

例9-18 Contains()演算子を使用した補助データの比較

CREATE OPERATOR Contains
BINDING (VARCHAR2, VARCHAR2) RETURN NUMBER
WITH INDEX CONTEXT, SCAN CONTEXT TextIndexMethods COMPUTE ANCILLARY DATA
USING TextContains;

例9-19 計算のバインディングの実装

TextContains(VARCHAR2, VARCHAR2, ODCIIndexCtx, TextIndexMethods, NUMBER).
9.2.3.2 補助データをモデル化する演算子バインディング

補助データをモデル化する演算子バインディングは、補助バインディングと呼ばれます。補助データ演算子のファンクション実装は、索引ベースのファンクション実装に似ています。ファンクションを定義したら、追加のANCILLARY TO属性を使用してそのファンクションを演算子にバインドすることで、ファンクション実装がその状態を主演算子バインディングと共有する必要があることを示します。

補助演算子バインディングのファンクション実装には、主演算子バインディングのファンクション実装と同じシグネチャを使用する必要があることに注意してください。

例9-20に、TextScore()ファンクション内の補助演算子の評価方法を示します。

TextScore()定義を使用して、例9-21に示されているような補助バインディングを作成できます。

ANCILLARY TO句には、Scoreと主演算子バインディングCONTAINS(VARCHAR2, VARCHAR2)が状態を共有するように指定します。

補助演算子バインディングは、Score(1)、Score(2)など、1つのリテラル数値引数を使用して起動されます。

例9-20 補助演算子の評価

CREATE FUNCTION TextScore (Text IN VARCHAR2, Key IN VARCHAR2,
  indexctx IN ODCIIndexCtx, scanctx IN OUT TextIndexMethods, scanflg IN NUMBER)
RETURN NUMBER AS
BEGIN
.......
END TextScore;

例9-21 補助演算子バインディングの作成

CREATE OPERATOR Score
BINDING (NUMBER) RETURN NUMBER
ANCILLARY TO Contains(VARCHAR2, VARCHAR2) 
USING TextScore;
9.2.3.3 演算子の解決

補助データに対応する演算子は、ユーザーが1つの数値引数を使用して起動します。この数値引数は補助操作と主演算子の起動時の両方でリテラルである必要があるため、演算子の関連付けは問合せのコンパイル時に実行できます。

対応する主演算子を判別するために、Oracleは補助演算子に渡された数値を主演算子の最後の引数として渡された数値と照合します。一致する主演算子の起動が見つからない場合、または複数が検出される場合はエラーになります。一致する主演算子の起動が検出されると、次のようになります。

  • 主演算子の引数が補助演算子でオペランドになります。

  • 補助演算子と主演算子の実行に同じスキャン・コンテキストが渡されます。

たとえば、例9-17の問合せでは、Scoreの起動は数値引数1に基づいてContains()の補助として判別され、Scoreのファンクション実装はオペランド(resume, 'Oracle&Unix', indexctx, scanctx, scanflg)を取得します。scanctxは、Contains()の起動と共有されます。

9.2.3.4 演算子の実行

演算子の実行では、索引スキャンを使用してContains()演算子を処理します。索引スキャンのfetch()コールで返される各行に対してScoreのファンクション実装が起動され、ODCIIndexCtx引数(索引情報、ROWIDおよび索引スキャン状態へのハンドルを含む)が渡されます。ファンクション実装は、索引スキャン状態へのハンドルを使用して、スコアを計算できます。