O cenário
Dois sistemas (não servidor) rodando PHP e PostgreSQL com as seguintes versões
Fedora 15:
PHP
PHP 5.3.13 (cli) (criado: 9 de maio de 2012 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) Version 9.0.7
Módulo versão 1.0.2
PostgreSQLName
PostgreSQL 9.1.4
Com extensão CITEXT habilitada.ArchLinux:
PHP
PHP 5.4.6 (cli) (criado: 16 de agosto de 2012 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) Version 9.1.4
Módulo versão 1.0.2
PostgreSQLName
PostgreSQL 9.1.4
Com extensão CITEXT habilitada.
quando uma consulta simples, como
select column1 from schema1.table1 where column1= ?
Onde coluna1 é do tipo CITEXT, é executado via PHP PDO
- No Fedora com PHP 5.3.13, libpq 9.0.7, a consulta é executada como esperado com CITEXT (ocorre uma pesquisa que não diferencia maiúsculas de minúsculas ).
- No ArchLinux com PHP 5.4.6,libpq 9.1.4, a consulta não é executada como esperado com CITEXT (ocorre uma pesquisa que diferencia maiúsculas de minúsculas ).
Eu estou supondo que a versão mais recente das bibliotecas PHP PDO está fazendo algo semelhante a isto:
select column1 from schema1.table1 where column1= 'value'::text;
durante a encadernação.
- Estou certo?
- Existe uma solução alternativa? Caso contrário, o uso de CITEXT como um tipo de dados de coluna para obter a vantagem da pesquisa que não diferencia maiúsculas de minúsculas é inútil ao usar versões mais recentes do PDO.
Atualizar
Depois de ativar o log de nível de instrução, no ArchLinux com 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
onde o valor real da coluna column1
é VALUE
.
Ainda volta com 0 elementos.
quando a declaração
select column1 from schema1.table1 where column1 = 'value';
é executado diretamente no PSQL
prompt e retorna com uma única linha.
column1
---------
VALUE
(1 row)
Portanto, o casting de tipo não ocorre! Ainda não consigo entender o comportamento de PDO
/ postgresql
.
Atualização 2012-08-27 16:15:43.669142+00 (UMT + 0)
Depois de tentar executar diretamente uma consulta sem preparar uma instrução.
Aqui está o código que foi usado para testar:
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.
}
Eu recebo o erro:
object(PDOException)#10 (8) { ["message":protected]=> string(211) "SQLSTATE[42704]: \
Undefined object: 7 ERROR: type "citext" does not exist LINE 1: ...
Não entendo porque citext
não está sendo detectado! Quando a instrução é executada diretamente no PSQL
prompt, tudo funciona bem conforme mencionado acima.
Localize o namespace dentro do qual o
citext
tipo reside:Anexe esse namespace (normalmente, 'público', mas pode ser diferente no seu caso e pode explicar o problema) ao elenco para
citext
:Se isso resolver o problema, mas de uma forma que você considera deselegante, você pode reconsiderar como está usando esquemas e
search_path
: certifique-se de que todos os seus tipos personalizados estejam acessíveis, não importa o que aconteça.