38 OCIでのベクトル・データ型のサポート

この項では、ベクトル列値をフェッチおよび変更するためのOCI (Oracle Call Interface) APIの拡張機能について説明します。ベクトル列のバインドまたは定義に使用できる様々なCデータ型をリストします。また、ベクトル・メタデータにアクセスするための詳細も提供します。

トピック:

38.1 OCIVector記述子

この項では、OCIVector記述子を使用してOCI (Oracle Call Interface)でVECTORを表す方法について説明します。

OCIVector記述子は、記述子タイプOCI_DTYPE_VECTORによって識別されます。OCIVector記述子は、OCIDescriptorAlloc()およびOCIDescriptorFree()関数を使用してそれぞれ割当ておよび解放できます。OCIVector記述子のインスタンスは、サーバーとの間でVECTORコンテンツの読取り(OCIDefine*())および書込み(OCIBind*())に使用できます。OCIVectorFromTextまたはOCIVectorFromArray関数を使用して、ベクトル記述子を移入することもできます。OCIVector記述子に存在するベクトル・データは、OCIVectorToTextまたはOCIVectorToArray関数を使用してフェッチできます。

OCI記述子 説明 OCI記述子型定数
OCIVector * VECTOR記述子 OCI_DTYPE_VECTOR

38.2 OCIVector記述子の属性

この項では、OCIVector記述子の属性について説明します。

OCI_ATTR_VECTOR_DATA_FORMAT

モード
読取り専用
説明

この属性は、ベクトルの各次元が格納される形式を参照します。

次の入力形式がサポートされています:
  • IEEE FLOAT16
  • IEEE FLOAT32
  • IEEE FLOAT64
  • INT8

属性の対応する値を次に示します:

  • VECTOR_FORMAT_FLOAT16 (1)
  • VECTOR_FORMAT_FLOAT32 (2)
  • VECTOR_FORMAT_FLOAT64 (3)
  • VECTOR_FORMAT_INT8 (4)
属性のデータ型
ub1

OCI_ATTR_VECTOR_DIMENSION

モード
読取り専用
説明

ベクトルの次元。

属性のデータ型
ub4

OCI_ATTR_VECTOR_PROPERTY

モード
読取り専用
説明
ベクトルの追加の詳細。0x01ビット値は、ベクトルに柔軟な次元があるかどうかをチェックするOCI_ATTR_VECTOR_COL_PROPERTY_IS_FLEXフラグを表します。
属性のデータ型
ub4

OCI_ATTR_VECTOR_CHARSET_ID

モード
読取り専用
説明
文字セットのID。
属性のデータ型
ub2

OCI_ATTR_VECTOR_ERROR_POSITION

モード
読取り専用
説明
入力ベクトル・データ内のエラーの位置。
属性のデータ型
ub4

38.3 外部VECTORデータ型とOCI

この項では、SQLデータ型VECTORのOracle Call Interface(OCI)データ型定数について説明します。VECTORは、Oracle Databaseで認識されるデータ型です。

Oracle Databaseリリース23ai以降、OCIドライバではVECTORデータ型がサポートされます。OCIでは、VECTORデータ型は定数SQLT_VECを使用して表されます。つまり、クライアントは、データ型定数としてSQLT_VECを使用して、VECTOR記述子をwrite (OCI定義)およびread (OCIバインド)できます。
外部データ型 プログラム変数 SQL型定数
VECTOR OCIVector* SQLT_VEC

関連項目:

外部データ型

38.4 VECTOR SQLデータ型のサポートのバインドまたは定義

VECTORデータ型のバインドまたは定義をサポートするために、OCIでは、外部データ型定数SQLT_VEC (OCIVector*)を有効にして、バインドの目的にOCIVectorFromArrayを使用してdouble、floatまたはintegerの配列のネイティブ表現を設定できるようにします。OCIVector記述子には、定義時の正規表現があります。ユーザーは、OCIVectorToArray関数を使用してネイティブ表現の配列を取得できます。

Oracleデータベースでは、charncharvarchar2nvarchar2CLOBおよびNCLOBからVECTORデータ型への暗黙的な変換が可能であり、その逆も可能です。したがって、ユーザーはこれらの外部データ型を使用できます。Oracle Databaseはバインドのために暗黙的な変換を処理し、クライアントは定義のために暗黙的な変換を処理します。VECTORをバインド型または定義型として指定できない古いクライアントの場合、サポートされる唯一のバインド型または定義型は、charchar varchar2nvarchar2CLOBおよびNCLOBに対応する文字列型バインドまたは定義のみです。

ベクトル列型を持つ表の記述情報は、OCIDescribeAny()を介して公開されます。

PL/SQL OUTバインド用に新しい外部データ型SQLT_VECが導入されました。この外部データ型は、VECTORデータ型の列に対してバインドまたは定義を行うためにオーバーロードされます。

38.5 OCIベクトル・サポート関数

OCIベクトル・サポート関数は、ネイティブなC配列とOCIVector記述子との間の変換のために提供されています。また、charncharvarchar2nvarchar2CLOBおよびNCLOB外部データ型をベクトル列のバインドまたは定義に使用できます。

表38-1 OCIベクトル・サポート関数

関数 用途
OCIVectorFromText ベクトルのテキスト表現をベクトル形式に変換します。
OCIVectorFromArray ベクトルの配列表現をベクトル形式に変換します。
OCIVectorToText ベクトルをテキスト形式に変換します。
OCIVectorToArray ベクトルを配列形式に変換します。

38.5.1 OCIVectorFromText

ベクトルのテキスト表現をベクトル形式に変換します。

用途

ベクトルのテキスト表現をベクトル形式に変換します。入力テキストを記述子に格納されるベクトルに変換するには、OCIVectorDescriptor、エラー・ハンドル、ベクトル形式、ベクトル・テキスト、テキスト長および様々なベクトル・フラグを使用します。

構文

sword OCIVectorFromText(OCIVector *vectord, OCIError *errhp, ub1 vformat, ub4 vdim
                        const OraText *vtext, ub4 vtextlen, ub4 mode);

パラメータ

パラメータ 用途
OCIVector *vectord (IN/OUT) ベクトルに関連付けられたOCIVector記述子を指定します。入力テキストのベクトル表現を格納します。
OCIError *errhp 変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。
ub1 vformat テキストに存在する要素の形式(OCI_ATTR_VECTOR_FORMAT_*値)を指定します。
ub4 vdim ベクトル・テキスト内の次元数を指定します。
const OraText * vtext ベクトルに変換する入力テキストを指定します。
ub4 vtextlen 入力テキストの長さを指定します。
ub4 mode 将来役立つ可能性のあるフラグを指定します。

現在のデフォルト・フラグはOCI_DEFAULTです。

戻り値

OCI_SUCCESS (正常に実行された場合)。

OCI_ERROR (エラーが返された場合)。

38.5.2 OCIVectorFromArray

ベクトルの配列表現をベクトル形式に変換します。

用途

OCIVectorFromArray関数は、入力配列を記述子に格納されるベクトルに変換するために、OCIVectorDescriptor、エラー・ハンドル、ベクトル形式、ベクトル次元、ベクトル配列およびその他の様々なベクトル・フラグを使用します。

構文

sword OCIVectorFromArray(OCIVector *vectord, OCIError *errhp, ub1 vformat,
                         ub4 vdim, void *vecarray, ub4 mode);

表38-2 パラメータ

パラメータ 用途
OCIVector *vectord (IN/OUT) 入力テキストのベクトル表現を格納するOCIVector記述子を指定します。
OCIError *errhp 変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。
ub1 vformat 配列に存在する要素の形式(OCI_ATTR_VECTOR_FORMAT_*値)を指定します。次のように値を使用します:
  • OCI_ATTR_VECTOR_FORMAT_FLEX 0
  • OCI_ATTR_VECTOR_FORMAT_FLOAT16 1
  • OCI_ATTR_VECTOR_FORMAT_FLOAT32 2
  • OCI_ATTR_VECTOR_FORMAT_FLOAT64 3
  • OCI_ATTR_VECTOR_FORMAT_INT8 4
ub4 vdim 配列内の要素の数を指定します。
void *vecarray ベクトルに変換する配列を指定します。
ub4 mode 将来役立つ可能性のあるフラグを指定します。

現在のデフォルト・フラグはOCI_DEFAULTです。

戻り値

OCI_SUCCESS (正常に実行された場合)。

OCI_ERROR (エラーが返された場合)。

38.5.3 OCIVectorToText

ベクトルをテキスト形式に変換します。

用途

OCIVectorToText関数は、記述子に格納されるベクトルをテキスト形式に変換するために、OCIVectorDescriptor、エラー・ハンドル、テキスト・ポインタ、テキスト長ポインタ、その他様々なベクトル・フラグを使用します。

構文

sword OCIVectorToText(OCIVector *vectord, OCIError *errhp, text *vtext,
                      ub4 *vtextlen, ub4 mode);

表38-3 パラメータ

パラメータ 用途
OCIVector *vectord データのベクトル表現を格納するOCIVector記述子を指定します。
OCIError *errhp 変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。
OraText *vtext ベクトルのテキスト表現に使用されるバッファへのポインタを指定します。この関数のコール元がこのメモリーを割り当てる必要があります。
ub4 *vtextlen 関数に渡されるテキスト・バッファの長さへのポインタを指定します

ノート:

バッファ・サイズが小さい場合、エラー51810が返され、データが切り捨てられます。

ノート:

エラー51810、「VECTORからCHARまたはVARCHARへの変換を行うにはバッファ・サイズが不十分です。」

バッファ・サイズが不十分であり、VECTOR列を指定されたCHARまたはVARCHAR形式に変換できないため、前述のエラー・メッセージが返されます。

これを解決するには、指定されたCHARまたはVARCHARバッファ・サイズが、変換されたVECTOR列値を格納するのに十分であることを確認します。関数LENGTH(FROM_VECTOR(<vector>))は、適切なバッファ・サイズを決定するために使用されます。
ub4 mode 将来役立つ可能性のあるフラグを指定します。

現在のデフォルト・フラグはOCI_DEFAULTです。

戻り値

  • OCI_SUCCESS (正常に実行された場合)。
  • OCI_ERROR (エラーが返された場合)。ベクトルを保持するための十分な割当てメモリーが入力バッファにない場合、OCI_ERRORが返されます。

38.5.4 OCIVectorToArray

ベクトルを配列形式に変換します。

用途

OCIVectorToArray関数は、記述子に格納されているベクトルを配列形式に変換するために、OCIVectorDescriptor、エラー・ハンドル、ベクトル形式、ベクトル次元へのポインタ、配列へのポインタ、その他様々なベクトル・フラグを使用します。

構文

sword OCIVectorToArray(OCIVector *vectord, OCIError *errhp, ub1 vformat,
                      ub4 *vdim, void *vecarray, ub4 mode);

表38-4 パラメータ

パラメータ 用途
OCIVector *vectord データのベクトル表現を格納するOCIVector記述子を指定します。
OCIError *errhp 変換に関連付けられたハンドル・エラーに渡されるエラー・ハンドルを指定します。
ub1 vformat 記述子に格納されるベクトルの形式(OCI_ATTR_VECTOR_FORMAT_*値)を指定します。
ub4 *vdim 配列バッファ内の次元数へのポインタを指定します。出力値はベクトル内の実際のディメンション数です。
void *vecarray ベクトル配列へのポインタを指定します。この関数のコール元は、ベクトルの次元数に対応するためにこのメモリーを割り当てる必要があります。これは、vformatパラメータを使用して指定されたベクトル形式のサイズを乗算したvdimパラメータを使用して指定されます。
ub4 mode 将来役立つ可能性のあるフラグを指定します。

現在のデフォルト・フラグはOCI_DEFAULTです。

戻り値

  • OCI_SUCCESS (正常に実行された場合)。
  • OCI_ERROR (エラーが返された場合)。ベクトルを保持するための十分な割当てメモリーが入力バッファにない場合、OCI_ERRORが返されます。

38.5.5 OCIVectorFromSparseArray

要素のSPARSE配列表現をOCIVector記述子に変換します。

用途

OCIVectorFromSparseArray関数は、要素のSPARSE配列表現をOCIVector記述子に変換します。この記述子を使用すると、DMLのプレースホルダをバインドしたり、記述子属性操作で使用できます。

構文

TBD

表38-5 パラメータ

パラメータ 説明
vectord (IN/OUT) ベクトル記述子へのポインタを指定します。
errhp (IN/OUT) エラー・ハンドルを指定します。
vformat (IN) ベクトルの形式を指定します。サポートされている形式値:
  • OCI_ATTR_VECTOR_FORMAT_INT8
  • OCI_ATTR_VECTOR_FORMAT_FLOAT32
  • OCI_ATTR_VECTOR_FORMAT_FLOAT64
  • OCI_ATTR_VECTOR_FORMAT_BINARY
vdim (IN) SPARSEベクトルの合計次元数を指定します。
indices (IN) 索引配列の次元数を指定します。
indarray (IN) ゼロ以外の次元索引位置値を含む配列へのポインタを指定します。
vecarray (IN) SPARSEベクトルのvformat値の要素の配列へのポインタを指定します。
mode (IN) 操作モードを指定します。

戻り値

  • OCI_ERROR: エラーが返された場合。
  • OCI_SUCCESS: 関数が正常に実行された場合。
  • OCI_INVALID_HANDLE: 記述子またはエラー・ハンドルが無効な場合。

ノート:

indarrayの入力には、ゼロ以外の次元の索引が含まれています。vecarrayの入力には、これらの索引のvformatの要素の配列が含まれています。索引は1ベースで、索引配列の最初の要素は0ではなく1です。

例38-1

密配列[0, 1.0, 0, 1.0, 0]の入力は次のようになります:

vdim = 5、indices = 2、indarray = [2,4]、vecarray = [1.0, 1.0]

38.5.6 OCIVectorToSparseArray

OCIVector記述子の内容を、要素のSPARSE配列表現に変換します。

用途

OCIVectorToSparseArray関数は、OCIVector記述子の内容を要素のSPARSE配列表現に変換します。この配列表現を使用すると、DMLのプレースホルダをバインドしたり、記述子属性操作で使用できます。

構文

未定

表38-6 パラメータ

パラメータ 説明
vectord (IN/OUT) ベクトル記述子へのポインタを指定します。
errhp (IN/OUT) エラー・ハンドルを指定します。
vformat (IN) ベクトルの形式を指定します。OCI_ATTR_VECTOR_FORMAT_*を参照してください
vdim (IN/OUT) indarrayのサイズを含むポインタを指定します。出力値には、SPARSEベクトルの合計次元数が含まれています。
indices (OUT) indarrayの次元数が移入されるポインタを指定します。
indarray (OUT) ゼロ以外のSPARSEベクトルの次元の索引が移入されるバッファへのポインタを指定します。
vecarray (OUT) SPARSEベクトルのvformat要素の配列が移入されるバッファへのポインタを指定します
mode (IN) 操作モードを指定します。

戻り値

  • OCI_ERROR: エラーが発生して、エラーが返された場合。
  • OCI_SUCCESS: 関数が正常に実行された場合。
  • OCI_INVALID_HANDLE: 記述子またはエラー・ハンドルが無効な場合。

ノート:

indarrayの出力には、ゼロ以外の次元の索引が含まれています。vecarrayの出力には、これらの索引のvformat要素の配列が含まれています。索引は1ベースで、索引配列の最初の要素は0ではなく1です。

たとえば、密配列[0, 1.0, 0, 1.0, 0]の場合、次の出力が返されます:

vdim = 5、indices = 2、indarray = [2,4]、vecarray = [1.0, 1.0]

38.6 OCIVectorのバインドと定義 *

OCIユーザーは、OCIVector*型の記述子を割り当て、これにinteger、floatまたはdoubleコンテンツの配列を割り当てて、SQLデータ型がVECTORであるデータベース表の列の書き込みに使用することができます。バインドおよび定義用の入力データ型は、SQLT_VECである必要があります。

また、OCIアプリケーションでは、次のSQLデータ型を使用してバインドおよび定義することもできます:
  • SQLT_CHR: 文字列
  • SQLT_CLOB: 文字LOB
  • SQLT_STR: NULLで終了する文字列
  • SQLT_LNG: 長い文字列
  • SQLT_LVC: より長い文字列
  • SQLT_AFC: ANSI固定文字列
  • SQLT_AVC: ANSI可変文字列
  • SQLT_VCS: 可変文字列

38.7 OCIDescribeAnyの拡張機能

この項では、新しいVECTOR列タイプの表またはビューに関する説明をサポートするために、OCIDescribeAnyに含まれる機能拡張について説明します。

OCIには、データベース・オブジェクト(表など)を明示的に記述してメタデータを取得する機能があります。また、OCIは、問合せ実行への応答の一部として選択されている列のメタデータを暗黙的に受信します。明示的記述と暗黙的記述の両方の場合、列メタデータは、OCIParam *型のパラメータ・ハンドルまたはベクトル記述子を介してアクセスされます。新しく導入されたOCIParamハンドル属性OCI_ATTR_VECTOR_DIMENSIONOCI_ATTR_VECTOR_DATA_FORMATおよびOCI_ATTR_VECTOR_PROPERTYは、ベクトル次元、ベクトル・データ形式およびベクトル・プロパティにそれぞれアクセスするために使用されます。

次のコールは、指定された列パラメータ・ハンドルのベクトル次元を返し、列が柔軟な次元を持ち、固定されていない場合は0を返します。vector_dimensionの長さがub4に固定されているため、Vector_dimension_lenは移入されません。
OCIAttrGet((dvoid*) colParamHandle, (ub4) OCI_DTYPE_PARAM, 
           (dvoid*) &vector_dimension, (ub4 *) &vector_dimension_len,
           (ub4) OCI_ATTR_VECTOR DIMENSION, 
           (OCIError *) errhp)

次のコールは、指定された列パラメータ・ハンドルのベクトルのデータ形式へのポインタを返し、ベクトルにデータ形式を含めることができる場合は0を返します。vector_data_typeの長さがub1に固定されているため、Vector_data_format_lenは返されません。
OCIAttrGet((dvoid*) colParamHandle, (ub4) OCI_DTYPE_PARAM, 
           (dvoid*) &vector_data_format, (ub4 *) &vector_data_format_len,
           (ub4) OCI_ATTR_VECTOR_DATA_FORMAT, 
           (OCIError *) errhp) 

次のコールは、指定された列パラメータ・ハンドルのベクトルのプロパティを返し、列に関連付けられたプロパティがない場合は0を返します。現在、実装されている唯一のプロパティはOCI_ATTR_VECTOR_COL_PROPERTY_IS_FLEXです。

OCIAttrGet((dvoid*) colParamHandle, (ub4) OCI_DTYPE_PARAM, 
           (dvoid*) &vector_property, (ub4 *) &vector_property_len,
           (ub4) OCI_ATTR_VECTOR_PROPERTY, 
           (OCIError *) errhp) 

属性OCI_ATTR_VECTOR_DIMENSIONOCI_ATTR_VECTOR_DATA_FORMATおよびOCI_ATTR_VECTOR_PROPERTYは、実表の列、ビュー列、およびベクトルが関連付けられているSELECTリスト内のすべての要素に対して適用する必要があります。

次のコード・スニペットに示すように、ベクトル記述子でOCIAttrGetをコールして属性を取得することもできます:
  • OCIAttrGet((dvoid *)vectorDescriptor, OCI_DTYPE_VECTOR, (void *)&vectdim, (ub4*) 0, OCI_ATTR_VECTOR_DIMENSION, (OCIError *)errhp);
  • OCIAttrGet((dvoid *)vectorDescriptor, OCI_DTYPE_VECTOR, (void *)&vectformat, (ub4*) 0, OCI_ATTR_VECTOR_FORMAT, (OCIError *)errhp);
  • OCIAttrGet((dvoid *)vectorDescriptor, OCI_DTYPE_VECTOR, (void *)&vectprop, (ub4*) 0, OCI_ATTR_VECTOR_PROPERTY, (OCIError *)errhp);

38.8 ベクトル用のコード・スニペットの例

SELECT文

OCIStmt  *ociStmt = (OCIStmt *)NULL;
  	OCIDefine *defnhp1 = NULL;
  	OCIVector *vecp = NULL;
  	OraText *selstmt = "SELECT embedding FROM test ORDER BY id";
  
 	 sb2 ind1 = 0;

 	OCIHandleAlloc(ociEnv, (void*) &ociStmt, OCI_HTYPE_STMT, 0, 0);
        OCIStmtPrepare2(ociSvcCtx, ociStmt, ociError, selstmt, (ub4)sizeof((selstmt) - 1),
                         (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
        OCIDescriptorAlloc(ociEnv, (void**) &vecp, OCI_DTYPE_VECTOR, 0, 0);
        OCIDefineByPos(ociStmt, &defnhp1, ociError,1, &vecp, 0, SQLT_VEC, &ind1, NULL, 0, OCI_DEFAULT);
        OCIStmtExecute(ociSvcCtx, ociStmt, ociError, 0, 0, 0, 0, OCI_DEFAULT);
リテラルを含むINSERT文
OraText *insStmt = "INSERT INTO test VALUES(%d, '[%d.1, %d.2, %d.3]')";

OCIHandleAlloc(ociEnv, (void*) &insStmt, OCI_HTYPE_STMT, 0, 0);
  	OCIStmtPrepare2(ociSvcCtx, ociStmt, ociError, insStmt, (ub4)stmtlen,
                         (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
  	OCIStmtExecute(ociSvcCtx, ociStmt, ociError, 0, 0, 0, 0, OCI_DEFAULT);
BINDを含むINSERT文
OCIStmt * ociStmt = (OCIStmt *)NULL;
OCIBind * ociBind1 = (OCIBind *)NULL;
OCIBind * ociBind2 = (OCIBind *)NULL;
OraText *insstmtbnd = "INSERT INTO test VALUES(:1, :2)";
signed int bnd1 = 500;
OCIVector *vecp = NULL;
sb2 ind1 = 0;
sb2 ind2 = 0;
OCIHandleAlloc(ociEnv, (void*) &ociStmt, OCI_HTYPE_STMT, 0, 0);
OCIStmtPrepare2(ociSvcCtx, ociStmt, ociError, insstmtbnd, (ub4)(sizeof(insstmtbnd) - 1),
                   (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
OCIDescriptorAlloc(ociEnv, (void**) &vecp, OCI_DTYPE_VECTOR, 0, 0);
OCIBindByPos(ociStmt, &ociBind1, ociError,                       
                1, &bnd1, sizeof(signed int), SQLT_INT,                       
				&ind1, NULL, NULL, 0, NULL, OCI_DEFAULT);
OCIBindByPos(ociStmt, &ociBind2, ociError,2, &vecp, 0, SQLT_VEC, &ind2, NULL, NULL, 0, NULL,                                          
OCI_DEFAULT);

OCIVector API

ub2   vformat = LVECTOR_IEEE_FLOAT32;
ub4   vdim = 3;
float vfarr[3];
text vtext[UB2MAXVAL];
OCIError *errhp = (OCIError *) NULL;
OCIVector *vecp = NULL;
ub4   indx;

OCIVectorToText(vecp, errhp, &vtext[0], &vtextl, OCI_DEFAULT);
for (indx=0; indx++; indx < vdim)
     vfarr[idx] = indx + indx * 3.1427;
OCIVectorFromArray(vecp, errhp, vformat, vdim,
                               (void *)&vfarr[0], OCI_DEFAULT);