[caracas-pm] Como verificar la sintaxis de una función plPerl en postgres

Monica Tahan monicatahan at gmail.com
Thu Aug 21 20:51:30 PDT 2014


Gracias Ernesto por tu respuesta...

Si efectivamente, la razón por la que recurrimos a usar pl/perlU, es por
sus bondades para el procesamiento de archivos de textos CSV, funcionalidad
que no iba a poder emplear en su máxima expresión en pl/perl sencillo o con
plpgsql, que es el que se debe emplear primero que cualquier otro como
mencionas. En este caso puntual estamos usando librerías externas para la
conversión de tipo de codificación del archivo y estructuras de validación
con expresiones regulares, de los datos del CSV origen.

El error de sintaxis estaba en las estructuras de los inserts, porque el
dato no se estaba guardando, sino estaba intentando insertar en hash (mala
mia), ya habíamos hecho el perl -c y la sintaxis de perl estaba OK, era
sintaxys SQL errada. Hoy resolvimos el problema, haciendo lo siguiente:

1. Tomamos la expresión que va después del like y la construimos en una
variable concatenándole la expresión regular para añadir los porcentajes.
2. Tomamos el dato empleando la expresión: my $dato_id =
$query_id->{rows}[0]->{id_columna};

Ya con eso, la función corrió correctamente y no hubo inconvenientes. Voy
tomar en cuenta tu recomendación respecto al uso de la familia SPI, pues me
interesa que el tiempo de ejecución sea imperceptible para el usuario.

Gracias a todos por sus respuestas, feliz noche...



El 21 de agosto de 2014, 22:41, Ernesto Hernández-Novich <emhnemhn at gmail.com
> escribió:

> On Tue, 2014-08-19 at 10:05 -0430, Monica Tahan wrote:
> [...]
> > Si, de hecho el script lo hicimos en pl/perlU.
>
> Antes que comentar sobre la función en PL/perlU es pertinente aclarar
> que la *única* razón para usar Perl como lenguaje almacenado en
> PostgreSQL, es porque la manipulación que se va a hacer de los datos
> requiere expresiones regulares *avanzadas* o alguna librería externa
> provista con Perl para algo que no se puede hacer con PL/pgSQL.
>
> PL/pgSQL tiene toda la funcionalidad necesaria para manipular datos,
> aplicar expresiones regulares, operar sobre cadenas y números, efectuar
> consultas estáticas o dinámicas paralelizables, y cuenta con las
> estructuras de control para expresar algoritmos generales, con un
> desempeño que ha de ser superior al de Perl porque se ahorra el paso de
> datos a una máquina virtual diferente. No es necesario que den más
> detalles sobre lo que intentan hacer con PL/perlU, pero reflexionen al
> respecto porque es posible que lo que traten de hacer salga mucho más
> fácil con PL/pgSQL.
>
> Al final, PL/pgSQL debe ser el primer lenguaje almacenado a usar en
> PostgreSQL, y PL/R el segundo, con cualquier otro en un *distante*
> tercero.
>
> >  Cuando corro la función desarrollada en pl/perlu me da error de
> > sintaxis cerda de "xxxx". Con lo que no estamos muy claros es con
> > spi_exec_query, me explico:
>
> > Estamos haciendo una función que consulta unas tablas, y el resultado
> > de la consulta devuelve un dato, es decir, no es un arreglo, sino un
> > valor, para ello coloqué algo así:
> >
> >
> > my $tabla_id = spi_exec_query("SELECT esquema.tabla.id from
> > esquema.tabla WHERE esquema.tabla.nombre LIKE '% $valor%'") or
> > elog(ERROR, qq{$tabla_id $!});
>
> Interpolar $valor no es buena idea, pues se presta a ataques de
> inyección de SQL. Es mejor usar quote_literal() o quote_ident() según el
> caso, aunque lo realmente correcto es usar la familia
>
> spi_prepare
> spi_query_prepared
> spi_exec_prepared
> spi_freeplan
>
> para que la consulta sea reutilizable. El código que presentan va a
> hacerle daño al caché de instrucciones de PostgreSQL porque cada
> invocación va a corresponder a una instrucción "diferente" cuando se
> podría tener un plan de ejecución único reutilizable.
>
> El error de sintaxis ocurre por usar 'or' como conector en una
> expresión, pues el 'or' es una *instrucción* y no un *operador*. Citando
> el manual 'perlop': Using "or" for assignment is unlikely to do what you
> want; see below. Y cuando uno 'sees below' comprende que
>
> my $variable = spi_exec_query(...) or elog(...)
>
> en realidad es interpretado como
>
> my ($variable = spi_exec_query(...)) or elog(...)
>
> que es un error de sintaxis. Cambien 'or' por '||' o '//'.
>
> > Deseo guardar en $tabla_id el valor que retorna el select, el cual no
> > es un conjunto de datos, sino un solo dato, para ello es correcta la
> > forma como está escrita la instrucción???
>
> No.
>
> > O debo hacer $datoquequiero = $tabla->{rows}; ????
>
> Tampoco.
>
> my $r = spi_exec_query(...)
>
> Revisar el manual de PL/perl para PostgreSQL revela que el resultado de
> spi_exec_query() es una referencia a un hash, una de cuyas claves es
>
> $r->{rows}
>
> que contiene todas las filas como un *arreglo de referencias a hashes*,
> de manera que si quiero la columna 'foo' de la fila 42
>
> $r->{rows}[42]->{foo}
>
> Incidentalmente, un debugger no habría servido de nada, porque el error
> fundamental aquí es de sintaxis, consecuencia de usar un 'or', así que
> nunca habría llegado a ejecutar ni una instrucción. Personalmente,
> hubiera seleccionado el trozo de Perl en mi editor (vim) e invocado
> 'perl -c' para confirmar la sintaxis, habría obtenido un
>
> Found = in conditional, should be == at foo.pl line ...
>
> y de allí se deduce el error que involucra el 'or'.
> --
> Ernesto Hernández-Novich - @iamemhn - Unix: Live free or die!
> Geek by nature, Linux by choice, Debian of course.
> If you can't aptitude it, it isn't useful or doesn't exist.
> GPG Key Fingerprint = 0064 ADF5 EB5C DE16 99C1 6C56 F2A3 86B5 A757 E5A1
>
> _______________________________________________
> caracas-pm mailing list
> caracas-pm at pm.org
> http://mail.pm.org/mailman/listinfo/caracas-pm
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/caracas-pm/attachments/20140821/bb7299d9/attachment.html>


More information about the caracas-pm mailing list