シナリオ
次のバージョンの PHP と PostgreSQL を実行する 2 つのシステム (サーバーではない)
フェドーラ 15:
PHP
PHP 5.3.13 (cli) (ビルド: 2012 年 5 月 9 日 14:38:35)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0、Copyright (c) 1998-2012 Zend Technologies
pdo_pgsql
PostgreSQL(libpq) バージョン9.0.7
モジュールバージョン 1.0.2
PostgreSQL
CITEXT 拡張機能が有効になっているPostgreSQL 9.1.4 。アーチリナックス:
PHP
PHP 5.4.6 (cli) (ビルド: 2012 年 8 月 16 日 12:50:09)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0、Copyright (c) 1998-2012 Zend Technologies
pdo_pgsql
PostgreSQL(libpq) バージョン9.1.4
モジュールバージョン 1.0.2
PostgreSQL
CITEXT 拡張機能が有効になっているPostgreSQL 9.1.4 。
次のような単純なクエリの場合
select column1 from schema1.table1 where column1= ?
column1 は CITEXT 型で、PHP PDO を介して実行されます
- PHP 5.3.13、libpq 9.0.7 を使用する Fedora では、クエリは CITEXT で期待どおりに実行されます (大文字と小文字を区別しない検索が発生します)。
- PHP 5.4.6、libpq 9.1.4 を使用する ArchLinux では、クエリが CITEXT で期待どおりに実行されません (大文字と小文字を区別する検索が発生します)。
PHP PDO ライブラリの新しいバージョンは、次のようなことをしていると思います。
select column1 from schema1.table1 where column1= 'value'::text;
バインディング中。
- 私は正しいですか?
- 回避策はありますか? それ以外の場合、大文字と小文字を区別しない検索の利点を得るために列のデータ型として CITEXT を使用しても、新しいバージョンの PDO を使用する場合は役に立ちません。
アップデート
ArchLinux で PHP 5.4.6,libpq 9.1.4 を使用して、ステートメント レベルのログ記録をオンにした後:
LOG: execute pdo_stmt_00000001: select column1 from schema1.table1 where column1 = $1
DETAIL: parameters: $1 = 'value'
LOG: statement: DEALLOCATE pdo_stmt_00000001
列の実際の値column1
は ですVALUE
。
まだ0要素で戻ってきます。
声明のとき
select column1 from schema1.table1 where column1 = 'value';
プロンプトで直接実行されPSQL
、単一の行が返されます。
column1
---------
VALUE
(1 row)
したがって、型キャストは行われません! PDO
/の動作はまだ理解できませんpostgresql
。
更新 2012-08-27 16:15:43.669142+00 (UMT + 0)
ステートメントを準備せずにクエリを直接実行しようとした後。
テストに使用したコードは次のとおりです。
try {
$db = new PDO('pgsql:dbname=database1;user=user;password=pass;host=localhost');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT column1 from schema1.column1 where column1 = 'value'::citext ";
$retval=$db->query($sql);
foreach ($retval as $row) {
print $row['uname'] . '<br>';
}
}catch (PDOException $PDOerr) {
echo 'An error occured : <br>';
var_dump($PDOerr);
exit;
//some thing went wrong while performing the action on db.
}
エラーが発生します:
object(PDOException)#10 (8) { ["message":protected]=> string(211) "SQLSTATE[42704]: \
Undefined object: 7 ERROR: type "citext" does not exist LINE 1: ...
citext
が検出されない理由がわかりません。PSQL
ステートメントがプロンプトで直接実行されると、上記のようにすべてが正常に機能します。
最終更新
ログインしようとしていたユーザーの検索パスの問題でした。他のスキーマに対してセッション単位で実行したときにユーザーを作成しset search_path
、デフォルトの '"$user",public' の代わりに他のスキーマに設定したと推測しています。ユーザーには、パブリック スキーマへのアクセス権がまったくありませんでした。Daniel Vérité
私を正しい方向に向けてくれてありがとう。
ところで、ALTER ROLE user SET search_path TO "$user",public;
検索パスを設定するために使用されます。ただし、現在のユーザーにちなんで名付けられたスキーマがないため、 $user は役に立ちません。