背景
OCIファンクションを作成し、Oracle NoSQL Database Python SDK(borneo
)を使用してデータを取得する際、PrepareRequest
を利用してSQLにプレースホルダをバインドする実装を行いました。
しかし、主キーがUUID型のカラムに対してプレースホルダを使用すると、PREPARE: Illegal Argument: Invalid UUID string
というエラーが発生しました。
環境とテーブル定義
以下のようなテーブルを作成します。
SQL
CREATE TABLE test (
userId STRING AS UUID,
userName STRING,
uuidStr STRING AS UUID,
PRIMARY KEY(userId)
)
このテーブルに以下のデータを登録します。
JSON
{
"userId": "10000000-0000-4000-8000-000000000000",
"userName": "taro",
"uuidStr": "20000000-0000-4000-8000-000000000000"
}
実装と発生した問題
エラーが発生したコードは以下の通りです。
Python
import io
import os
import logging
from borneo import NoSQLHandle, NoSQLHandleConfig, Regions, QueryRequest, PrepareRequest
from borneo.iam import SignatureProvider
def handler(ctx, data: io.BytesIO = None):
try:
compartmentId = os.getenv('COMPARTMENT_OCID')
provider = SignatureProvider.create_with_resource_principal()
config = NoSQLHandleConfig(Regions.AP_TOKYO_1, provider).set_default_compartment(compartmentId)
handle = NoSQLHandle(config)
userId = "10000000-0000-4000-8000-000000000000"
sqlText = 'DECLARE $userId STRING; SELECT userId, userName FROM test WHERE userId = $userId'
prepareRequest = PrepareRequest().set_statement(sqlText)
prepareResult = handle.prepare(prepareRequest)
prepareStatement = prepareResult.get_prepared_statement()
prepareStatement.set_variable('$userId', userId)
queryRequest = QueryRequest().set_prepared_statement(prepareStatement)
queryResult = handle.query_iterable(queryRequest)
except Exception as ex:
logging.getLogger().info(str(ex))
このコードを実行すると、以下のエラーが発生しました。
PREPARE: Illegal Argument: Invalid UUID string:
Traceback (most recent call last):
File "/function/testsql.py", line 27, in handler
prepareResult = handle.prepare(prepareRequest)
...
borneo.exception.IllegalArgumentException: PREPARE: Illegal Argument: Invalid UUID string:
一方で、主キーではないUUID型カラム uuidStr に対してプレースホルダを使用すると、エラーは発生しません。
Python
uuidStr = "10000000-0000-4000-8000-000000000000"
sqlText = 'DECLARE $uuidStr STRING; SELECT userId, userName FROM test WHERE uuidStr = $uuidStr'
prepareRequest = PrepareRequest().set_statement(sqlText)
prepareResult = handle.prepare(prepareRequest)
prepareStatement = prepareResult.get_prepared_statement()
prepareStatement.set_variable('$uuidStr', uuidStr)
queryRequest = QueryRequest().set_prepared_statement(prepareStatement)
queryResult = handle.query_iterable(queryRequest)
問い合わせと対応状況
この件について、Oracle サポートに問い合わせたところ、開発チームもこの問題を認識しており、修正対応中であるとの回答を得ました。
およそ10営業日後、この問題が解消されたと連絡があり、同現象が再現しないことを確認しました。
まとめ
この問題は、UUID型の主キーに対してプレースホルダを使用すると発生するバグでした。
開発チームによる修正が行われたため、現在は正常に動作します。
OCIのサポートも的確に問題を把握し、迅速に対応してくれた点は非常に評価できます。