jsonb operadores existenciales con consultas parametrizadas

… o la pregunta del signo de interrogación.

Actualmente estoy implementando la funcionalidad de búsqueda para una base de datos postgres, en php, que usa el nuevo tipo jsonb.

Para lograr esto estoy ejecutando declaraciones preparadas con marcadores de posición con nombre.

Sin embargo, me he encontrado con un problema interesante al tratar de usar algunos de los nuevos operadores de contención y existencia JSON postgres junto con marcadores de posición nombrados.

¿La base del problema es que los propios operadores usan el signo de interrogación ? como parte de su syntax. es decir

? ¿Existe la cadena clave / elemento dentro del valor JSON?

?| ¿Alguna de estas cadenas de teclas / elementos existe?

?& ¿Existen todas estas cadenas de teclas / elementos?

Esto significa que tengo declaraciones que se ven así en PHP.

 $sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ? :value"); $sth->bindValue(1, $value, PDO::PARAM_STR); $sth->execute(); 

Esto falla porque el signo de interrogación se interpreta como marcador de posición. Para evitar esto, he tratado de hacer que el operador sea un parámetro nombrado como tal.

 $sth = $dbh->prepare("SELECT * FROM stuff WHERE meta :operator :value"); $sth->bindValue(1, $operator, PDO::PARAM_STR); $sth->bindValue(2, $value, PDO::PARAM_STR); $sth->execute(); 

Sin embargo, esto arroja el mismo error que usar el operador desnudo, es decir,

ERROR: syntax error at or near \"$1\"1

¿Alguien más se ha encontrado con este problema o alguien puede pensar en una buena solución?

¿Hay alguna manera de escapar o pasar el signo de interrogación para que uno pueda usar los operadores de contención y existencia de postgres jsonb con consultas parametrizadas con PDO?

puede usar funciones correspondientes en lugar de operadores (jsonb_exists, jsonb_exists_any, jsonb_exists_all). por ejemplo ejecutar \do+ "?" en psql para ver el nombre de la función de? operador.

o define tu propio operador sin “?” símbolo en su lugar.

Por ejemplo:

 CREATE OPERATOR ~@ (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists) CREATE OPERATOR ~@| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any) CREATE OPERATOR ~@& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all) 

Para que uno pueda usar ~@ , ~@| y ~@& en lugar de ? , ?| y ?& respectivamente. p.ej

 $sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ~@ :value"); $sth->bindValue(1, $value, PDO::PARAM_STR); $sth->execute();