Developer FAQ/es

== Cómo involucrarse con el Proyecto ==
=== ¿ Cómo me puedo involucrar en el desarrollo de PostgreSQL ? ===
Puede descargar el código y echarle un vistazo. Vea la pregunta siguiente.
Suscríbase y lea lista de correo pgsql-hackers (llamada comúnmente "hackers"). Es ahí donde los principales contribuidores y miembros principales del proyecto discuten el desarrollo.
=== ¿ Cómo descargo/actualizo el código fuente actual ? ===
Existen varias maneras de obtener el código fuente. Los desarrolladores ocasionales pueden obtener simplemente el código fuente más receiente desde ftp://ftp.postgresql.org/pub/snapshot/.
Los desarrolladores más involucrados pueden tomar ventaja del acceso anónimo a nuestro sistema de administración de código fuente. El código fuente se encuentra almacenado bajo CVS actualmente. Para mayores detalles sobre como obtener el código fuente desde el repositorio CVS vea http://developer.postgresql.org/docs/postgres/cvs.html.
También tenemos un mirror Git del repositorio CVS; vea http://git.postgresql.org/?p=postgresql.git
=== ¿ Que ambiente de desarrollo se requiere para desarrollar código? ===
PostgreSQL se encuentra desarrollado en lenguaje de programación C en su mayor parte. El código fuente esta orientado a las plataformas más populares en Unix y en ambientes Windows (Windows 2000, XP y posteriores).
La mayoría de los desarrolladores ejecutan un sistema operativo tipo Unix y utilizan herramientas de código abierto como GCC, GNU Make, GDB, Autoconf y demás. Si usted ha contribuido código libre abierto anteriormente, probablemente se encuentre familiarizado con esas herramientas. Los desarrolladores que utilizan herramientas para Windows pueden utilizar MinGW. Algunos desarrolladores utilizan compiladores de otros distribuidores con resultados variados.
La lista completa de software requerido para generar PostgreSQL se puede encontrar en las instrucciones de instalación. 
Los desarrolladores que reconstruyen constantemente el código fuente envían la bandera --enable-depend para configurar. El resultado es que si usted genera una modificación a un archivo de encabezamiento en C, todos los archivos que dependen de ese archivo también son reconstruidos.
El archivo src/Makefile.custom se puede utilizar para establecer variables del ambiente tales como CUSTOM_COPT, que son utilizadas para cada compilación.
=== ¿ Dónde puedo aprender más sobre el código ? ===
Además de la documentación que se encuentra en el mismo código fuente, puede encontrar alginos papeles/presentaciones que discuten el código en http://www.postgresql.org/developer. Una excelente presentación se puede encontrar en http://neilconway.org/talks/hacking/
=== ¿ Qué áreas necesitan ser trabajadas ? ===
Las principales características se encuentran detalladas en la lista de cosas por hacer
Puede aprender más acerca de esas características consultando los archivos, los estándares SQL y textos recomendados (véa Libros para desarrolladores).
=== ¿ Cómo me puedo involucrar en el desarrollo del sitio web de PostgreSQL ? ===
El desarrollo del sitio web de PostgreSQL se discute en la lista de correo pgsql-www. Existe una página para el proyecto donde se encuentra el código fuente disponible en http://pgweb.postgresql.org/.
== Herramientas de Desarrollo y Ayuda ==
=== ¿ Qué herramientas se encuentran disponibles para los desarrolladores ? ===
Primero, todos los archivos del directorio src/tools están diseñados para los desarrolladores.
 RELEASE_CHANGES son cambios que se han hecho para cada versión liberada (release)
 backend descripción/Diagrama de Flujo de los directorios de backend.
 ccsym encuentre defines estandar hechos por su compilador.
 copyright arreglos a los anuncios de copyright.
 
 entab convierte espacios en tabulaciones, utilizado por pgindent
 find_static encuentra funciones que pueden hechas estáticas
 find_typedef localiza typedefs en el código fuente
 find_badmacros encuentra macros que utilizan llaves incorrectamente
 fsync un escript que provee información sobre el costo de las
 llamadas del systema de sincronización del caché
 make_ctags genera un archivo 'tags' para vi en cada directorio
 make_diff genera archivos *.orig y *.diff del código fuente
 make_etags genera archivos 'etags' para emacs
 make_keywords genera una comparación entre nuestras palabras clave y el estándar SQL'92
 make_mkid genera archivos ID para mkid
 pgcvslog se utiliza para generar una lista de cambios para cada versión
 pginclude scripts para añadir/eliminar archivos include
 pgindent genera la indentación de los archivos de código fuente
 pgtest un sistema semi-automático de generación
 thread un script para pruebas de hilos (threads)
En src/include/catalg:
 unused_oids un script que busca OIDs sin utilizar para utilizarlos en los catálogos del sistema
 duplicate_oids localiza OIDs duplicados en las definiciones de los catálogos del sistema
Si abre en su navegador de internet el archivo tools/backend/index.html, usted puede ver algunos programas que describen el flujo de datos, los componentes del backend en un diagrama de flujo y una descripción del área de memoria compartida. Puede hacer click en cualquier parte del diagrama de flujo para ver su descripción. Si hace click en el nombre del directorio, será llevado a ese directorio en el código fuente, para navegar en el código fuente que se encuentra actualmente en él. Tambien tenemos varios archivos LEEME (README) en algunos directorios del código fuente para describir la función del módulo. El navegador mostrará esto cuando acceda a cada directorio. El directorio tools/backend tambiens e encuentra contenido en nuestra página web con el título __Como Procesa PostgreSQL una consulta__.
En segundo lugar sería importante que usted cuenta con un editor que pueda manejar etiquetas (tags), para que pueda etiquetar cualquier llamada a una función y ver la definición de la función. La mayoría de los editores soportan esto via archivos de etiquetas (tags o etags).
En tercer lugar, usted necesitará obtener los id-utils desde ftp://ftp.gnu.org/gnu/id-utils/
Ejecutando tools/make_mkid, se crea un archivo de símbolos para el código fuente que puede ser rápidamente consultado.
Algunos desarrolladores hacen uso de cscope, este puede ser encontrado en http://cscope.sf.net/. Otros utilizan glimpse, que se puede encontrar en http://webglimpse.net/.
El archivo tools/make_diff contiene herramientas para crear archivos con parches diff que pueden ser aplicados a la distribución. Esto produce archivos diffs para el contexto, que es nuestro formato preferido.
Nuestro estándar es el formato BSD, con cada nivel de código indentado con una tabulación, en donde cada tabulador equivale a cuatro espacios. Usted necesitará configurar su editor o visor de archivos para mostrar las tabulaciones como cuatro estpacios:
 vi in ~/.exrv:
 set tabstop=4
 set shiftwidth=4
 set noexpandtab
 more:
 more -x4
 less:
 less -x4
El directorio tools/editors de los últimos códigos fuente contiene parámetros de ejemplo que pueden ser utilizados con los editores emacs, xemacs y vim que se utilizan para ayudar a mantener los estándares de codificación de PostgreSQL.
pgindent formateará el código especificando banderas (flags) a la utilería de indentación de su sistema operativo. Este artículo describe el valor de un estilo de codificación consistente.
pgindent se ejecuta sobre todos los archivos de código fuente justo antes de cada período de pruebas beta. Formatea automáticamente todos los archivos de código fuente para hacerlos consistentes. Los bloques de comentarios que necesitan saltos de línea específicos deberán ser formateados como bloques de comentarios, en donde el comentario comienza como /*------. Esos comentarios no serán reformatados de manera alguna.
pginclude contiene scripts utilizados para agregar todos los #include necesarios en los archivos include, y eliminar los #inlcude innecesarios.
Cuando se agregan objetos interconstruidos tales como tipo (types) o funciones (functions), usted necesitará asignarles OIDs. Nuestra convención es que todos los OIDs asignados de manera manual tienen valores distintos en un rango de 1-9999. (Funcionaría mecánicamente para estos el ser unicos dentro de catálogos de sistema individuales, pero por claridad requerimos que sean únicos en todo el sistema.) Existe un script llamado unused_oids en src/include/catalog que muestra los OIDs que no se encuentran en uso actualmente. Para asignar un nuevo OID, seleccione uno que se encuentre libre de acuerdo a unused_oids, y para obtener puntos adicionales seleccione uno que se encuentre cerca de objetos que esten relacionados actualmente. Vea también el script duplciate_oids, que le alertará si se ha equivocado.
=== ¿ Que libros son buenos para los Desarrolladores ? ===
Existen cinco libros buenos:
* An Introduction to Database Systems, de C.J. Date, Addison, Wesley
* A Guide to the SQL Standard, de C.J. Date, et. al, Addison, Wesley
* Fundamentals of Database Systems, de Elmasri and Navathe
* Transaction Processing, de Jim Gray, Morgan, Kaufmann
* Transactional Information Systems de Gerhard Weikum, Kaufmann
=== ¿ De que se trata todo esto de configure ? ===
Los archivos configure y configure.in son parte del paquete autoconf de GNU. La herramienta configure nos permite realizar pruebas de varias de las capacidades del Sistema Operativo, y establecer variables que pueden ser probadas en programas en C y archivos Make (Makefiles). Autoconf se encuentra instalado en el servidor principal de PostgreSQL. Para agregar opciones a configure, edite el archivo configure.in, y luego ejecute autoconf para generar el archivo configure.
Cuando la utilería configure es ejecutada por el usuario, realiza pruebas de varias de las capacidades del Sistema Operativo, almacena estas en los archivos config.status y config.cache, y modifica una serie de archivos *.in. Por ejemplo, si existe un archivo Makefile.in, la herramienta configure genera un archivo Makefile que contiene reemplazos para todos los parámetros @var@ encontrados por la herramienta configure.
Cuando necesite editar archivos, asegúrese de que no pierde tiempo modificando archivos generados por la herramienta configure, Edite el archivo *.in, y vuelva a ejecutar la herramienta configure para recrear el archivo necesario. Si usted ejecuta distclean desde el directorio superior del código fuente, todos los archivos derivados por la herramienta configure son eliminados, asi que usted solo verá el archivo contenido en el código fuente de la distribución.
=== ¿ Cómo añado un nuevo port ? ===
Existen una gran variedad de lugares que necesitan ser modificados para añadir un nuevo port. Primero, comience en el directorio src/template. Agregue la entrada apropiada para su Sistema Operativo. También, utilice el archivo src/config.guess para agregar su Sistema Operativo a src/template/.similar. No deberá hacer que la versión de su Sistema Operativo concuerde exactamente. Las pruebas de la herramienta configure buscarán por el número exacto de versión de su Sistema Operativo, y en caso de no encontrarlo, buscarán el que coincida sin el número de versión. Edite src/configure.in para añadir su nuevo Sistema Operativo. (Vea la herramienta configure descrita anteriormente.)
Luego revise src/include/port y añada su archivo para el nuevo Sistema Operativo, con los valores apropiados. Con suerte ya existe código de bloqueo en src/include/storage/s_lock.h para su CPU. Tambien se encuentra el directorio src/makefiles para manejos específicos del archivo Makefile. Ahí existe un directorio backend/port si usted necesita archivos especiales para su sistema operativo.
=== ¿ Por que no utilizar hilos (threads), dispositivos raw, async-IO <inserte aqui su carácterística favorita> ? ===
Siempre existe la tentación de utilizar las características más novedosas de los Sistemas Operativos tan pronto como aparecen. Nosotros resistimos esa tentación.
Primero, soportamos más de 15 Sistemas Operativos, asi que cualquier nueva característica debe estar bien establecida antes de que la consideremos. Segundo, las características más nuevas no proveen mejoras dramáticas. Tercero, usualmente tienen algún inconveniente, como estabilidad reducida o código adicional requerido. Por lo tanto, no nos apresuramos a utilizar nuevas características, en lugar de esto, esperamos a que la característica se establezca, entonces solicitamos pruebas para demostrar que una mejora medible es posible.
Como ejemplo, los hilos (threads) no son utilizados actualmente en el backend debido a que:
* Históricamente, los hilos (threads) no eran soportados y contenían muchos errores.
* Un error en un backend puede corromper otros backends.
* Las mejoras en velocidad utilizando hilos (threads) son pequeñas comparas con el tiempo restante para el arranque del backend.
* El código del backend tendría que ser más complejo.
Asi que, no descnocemos las nuevas características. Simplemente somo cautelosos sobre su adopción. el listado de cosas por hacer (TODO list) contiene vínculos a discusiones que muestran nuestro razonamiento en esas áreas.
=== ¿ Cómo son administradas las ramas del CVS ? ===
Vea Manejo de Ramas (en inglés).
=== ¿ Dónde puedo obtener una copia de los estándares SQL ? ===
Se supone que los debe adquirir de ISO o ANSI. Busque por ISO/ANSI 9075. La oferta de ANSI es menos cara, pero el contenido de los documentos de ambas organizaciones es el mismo.
Siendo que comprar una gopia de la guía oficial para el estándar es algo cara, la mayoría de los desarrolladores dependen de varios borradores disponibles en Internet.
Algunos de estos son:
* SQL-92 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
* SQL:1999 http://www.cse.iitb.ac.in/dbms/Data/Papers-Other/SQL1999/ansi-iso-9075-2-1999.pdf
* SQL:2003 http://www.wiscorp.com/sql_2003_standard.zip
* SQL:2008 (preliminar) http://www.wiscorp.com/sql200n.zip
La documentación de PostgreSQL contiene información sobre PostgreSQL y la adherencia al estándar SQL.
Algunas páginas web acerca del estándar son:
* http://troels.arvin.dk/db/rdbms/links/#standards
* http://www.wiscorp.com/SQLStandards.html
* http://www.contrib.andrew.cmu.edu/~shadow/sql.html#syntax (SQL-92)
* http://dbs.uni-leipzig.de/en/lokal/standards.pdf (papel)
Tenga en cuenta que tener acceso a una copia del estándar SQL no es necesario para volverse un contribuidor valioso al desarrollo de PostgreSQL. Interpretar el estándar es algo difícil y requiere de años de experiencia. Y de cualquier manera la mayoría de las características en PostgreSQL no se encuentran especificadas en el estándar.
=== ¿ Dónde puedo obtener asistencia Técnica ? ===
Muchas de las preguntas técnicas hechos por todos aquellos nuevos en el código fuente pueden ser respondidas en la lista de correo pgsql-hackers - los archivos de la cual se pueden encontrar en http://archives.postgresql.org/pgsql-hackers/.
Si no puede encontrar una discusión en particular o relativa a su pregunta, siéntase libre de colocarla en la lista.
La mayoría de la gente que contribuye también responde preguntas técnicas, incluyendo preguntas acerca del desarrollo de nuevas características, en IRC en irc.freenode.net en el canal #postgresql.
== Proceso de Desarrollo ==
=== ¿ Qué hago después de seleccionar algún artículo para trabajar ? ===
Envíe un correo a pgsql-hackers con una propuesta para lo que usted desea hacer (asumiendo que su contribución no es trivial). Trabajar aislado no es recomendable debido a que otros pueden estar trabajando en el mismo artículo, o usted puede comprender incorrectamente el artículo. En el correo, discuta tanto el método de implementación interno que planea utilizar, como cualquier cambio que será visible al usuario (nueva sintaxis, etc). Para parches complejos es importante obtener retroalimentación de la comunidad para su propuesta antes de comenzar a trabajar. Fallar al hacerlo puede significar que su parche sea rechazado. Si su trabajo esta siendo patrocinado por alguna compañía, lea este artículo para tener algunos tips sobre como ser más efectivo.
Un sitio web es mantenido para los parches que están en espera de revisión, http://momjian.postgresql.org/cgi-bin/pgpatches, y para aquellos que son almacenados para la siguiente versión, http://momjian.postgresql.org/cgi-bin/pgpatches_hold.
=== He desarrollado un parche, ¿ Qué sigue ? ===
Usted va a necesitar enviar el parche a pgsql-patches@postgresql.org. Será revisado por otros contribuyentes del proyecto y entonces será aceptado o devuelto para realizar más trabajo. Para ayudarlo a asegurar que su parche es revisado y enviado a tiempo, por favor intente asegurarse de que su envío cumple con los siguientes puntos:
# Asegúrese que su parche es generado contra la versión más reciente del código fuente, que para los desarrolladores es CVS HEAD. Para más acerca de las ramas en PostgreSQL véa como son administradas las ramas.
# Intente generar un parche que sea tan legible como sea posible siguiendo las convenciones de formato. Esto hace facilita las cosas para quien revisa, y no hay razón en tratar de hacer cosas distintas a pgindent. También evite espacios en blanco innecesarios debido a que solo distraerán a quien revisa, y los cambios en formato serán eliminados por la siguiente ejecución de pgindent.
# El parche deberá ser generado en formato diff contextual (diff -c y deberá ser aplicable desde el directorio raíz. Si usted no está familiarizado con esto, puede encontrar informativo el script en src/tools/make_diff/difforig. Los diffs unificados solo son preferibles si los cambios en el archivo son de una sola línea y no dependen de las líneas que los rodean.)
# PostgreSQL se encuentra bajo licencia BSD. Al publicar un parche en las listas de correo de PostgreSQL, usted esta cediendo derechos irrevocables al PosgreSQL Global Development Group para distribuir su parches bajo la licencia BSD.
# Confirme que su parches supere las pruebas de regresión. Si sus cambios son para un port específico, por favor liste los ports en los que lo ha probado.
# Si esta agregando una nueva característica, confirme que esta ha sido perfectamente probada. Intente probar la característica en todos los escenarios posibles.
# Los parches con nuevas características deberán ser acompañados por parches para la documentación. Si necesita ayuda revisando el estándar SQL, vea esta pregunta.
# Provea un resúmen general de la implementación, preferentemente con comentarios en el código. Seguir el estilo para comentarios en código es usualmente una buena forma de hacerlo. También vea este artículo en developerWorks.
# Si se trata de un parche enfocado al rendimiento, por favor provea los resultados que confirmen el beneficio de su parche. Esta bien publicar parches sin esta información, aunque el parche no será aplicado hasta que alguien lo haya probado y encuentre un aumento significativo en el rendimiento.
Aún si supera todos los puntos anteriores, el parche aún puede ser rechazado por otras razones. Por favor, preparese a escuchar comentarios y hacer modificaciones.
Usted será notificado via email cuando el parche sea aplicado, y su nombre puede aparecer en las notas de la siguiente versión.
=== ¿ Cómo es revisado un parche ? ===
Quienes revisan los parches revisar varias cosas antes de aplicarlos:
* El parche sigue el estándar SQL o la comunidad está de acuerdo con el comportamiento del mismo.
* El estilo se integra correctamente con el del código que lo rodea
* Utiliza correctamente todos los subsistemas de PostgreSQL
* Contiene suficientes comentarios
* Contiene código que funciona en todos los sistemas operativos soportados
* Tiene la documentación adecuada
* Supera las pruebas de regresión, y de ser necesario, añade nuevas pruebas
* Se comporta de la manera esperada, aún bajo circunstancias inusuales
* No contiene riesgos para la estabilidad del sistema
* No complica más el código fuente
* Si esta relacionado con el rendimiento, contiene una mejora medible
* Es de suficiente uso para el usuario promedio de PostgreSQL
* Sigue los procedimientos de codificación estándar de PostgreSQL
=== ¿ Como realizo pruebas de mis cambios ? ===
==== Sistema de pruebas básico ====
La manera más sencilla de probar el código es asegurarse de que se construye en base a la última versión del código y que no se generan alertas del compilador.
Se recomienda que se envíe --enable-cassert para relizar la configuración. Esto activará las verificaciones en el fuente las cuales en algunas ocasiones mostrarán errores (bugs) debido a que causan corrupciones de datos o violaciones de segmentos. Esto generalmente hace que la depuración sea más sencilla.
Luego, se pueden realizar las pruebas a través de psql.
==== Suite de pruebas de Regresión ====
El siguiente paso es probar los cambios contra la suite de pruebas de regresión existente. Para hacer esto, ejecute "make check" en el directorio raíz del código fuente. Si alguna prueba falla, investigue.
Si ha cambiado de manera deliberada alguna conducta existente, este cambio puede causar una falla en la prueba de regresión pero no de regresión actual. Si es así, deberá parchar también la suite de pruebas de regresión.
==== Otras pruebas en tiempo de ejecución ====
Algunos desarrolladores utilizan herramientas tales como valgrind (http://valgrind.kde.org) para realizar pruebas de memoria, gprof (que viene con la suite GNU binutils) y oprofile (http://oprofile.sourceforge.net/) para realizar el profiling y algunas otras herramientas relacionadas.
==== Que hay de las pruebas unitarias, análisis estáticos, revisipones de modelo... ? ====
Han habido algunas discusiones acerca de otros frameworks de pruebas y algunos desarrolladores estan explorando esas ideas.
Tenga en mente que los Makefiles no tienen las dependencias adecuadas para los archivos include. Tiene que realizar un make clean y luego generar otro make. Si está utilizando GCC pude utilizar la opción --enable-depend de configure para hace que el compilador calcule las dependencias de manera automática.
== Preguntas Técnicas ==
=== ¿ Cómo acceso de manera eficiente la información en los catálogos del systema desde el código del backend ? ===
Primero necesitará localizar las tuplas (registros) en los cuales está interesado. Existen dos maneras de hacer esto. La primera, la función SearchSysCache() y otras relacionadas le permiten hacer consultas a los catálogos del sistema utilizando índices predefinidos en los catálogos. Esta es la manera preferida para acceder a las tablas del sistema, debido a que la primera llamada al caché carga los registros necesarios, y peticiones futuras pueden devolver los resultados sin acceder a las tablas. Una lista de los cachés disponibles se encuentra en src/backend/utils/cache/syscache.c. usr/backend/utils/cache/lsyscache.c contiene funciones específicas para búsquedas por columna en caché.
Los registros devueltos son versiones propiedad del caché de la pila de registros. Por lo tanto, no debe modificar o eliminar la tupla devuelta por SearchSysCache(). Lo que debe hacer es liberarla con ReleaseSysCache() cuando ya no la utilice; esto le informa al caché que puede deshacerse de la tupla si es necesario. Si usted se reusa a llamar ReleaseSysCache(), entonces la entrada del caché permanecerá bloqueada en el caché hasta el final de la transacción, lo que es tolerable durante el desarrollo pero considerado inaceptable para código incluido en una versión.
Si no puede utilizar el caché del sistema, necesitará extraer los datos directamente de la tabla, utilizando el buffer del caché que se encuentra compartido por todos los backends. El backend automáticamente se ocupa de cargar los registros dentro del buffer de caché. Para hacer esto, abra la tala con heap_open(). Puede comenzar el barrido de una tabla con heap_beginscan(), luego utilizar heap_getnext() y continuar mientras HeapTupleIsValid() devuelva verdadero. Entonces debe acer un heap_endscan(). Se pueden asignar llaves al barrido. No se utilizan índices, asi que todos los registros serán comparados a las llaves, y solamente los que sean válidos serán devueltos.
También puede utilizar heap_fetch() para obtener todos los registros por número de bloque/offset. Mientras los barridos bloquean y desbloquean automaticamente los registros del buffer del caché, con heap_fetch(), usted debe enviar un apuntador de buffer y hacer un ReleaseBuffer() cuando haya terminado.
Una vez que cuenta con el registro, puede obtener los datos que son comúnes para todas las tuplas, como son t_self y t_oid, accesando simplemente las entradas de la estructura HeapTuple. Si necesita una columna específica de alguna tabla, deberá tomar el puntero de HeapTuple, y utilizar la macro GETSTRUCT() para acceder el inicio especifico en la tabla para la tupla. Puede hacer una conversión del puntero, por ejemplo a Form_pg_proc si esta accediendo a la tabla pg_proc, o Form_pg_type si está accediendo a pg_type. Entonces puede acceder a los campos de la tupla utilizando la estructura del puntero:
((Form_pg_class) GETSTRUCT(tupla))->relnatts
Observe sinembargo que esto solamente funcioa para las columnas de ancho fijo y nunca para las nulas, y solamente cuando columnas previas son de ancho fijo y nunca nulas. De otra manera la ubicación de la columna es variable y deberá utilizar heap_getattr() o alguna función relacionada para extraerlo de la tupla.
También evite realizar almacenamientos en campos de estructura para hacer cambios en tuplas vivas. La mejor manera es utilizar heap_modifytuple() y enviar la tupla original, además de los valores que se desea modificar. Esto devuelve una tupla palloc, que se envia a heap_update(). Puede eliminar tuplas enviando el t_self de la tupla a heap_delete(). Puede utilizar también el t_self para heap_update(). Recuerde, las tuplas pueden ser también copias de la caché del sistema, las cuales pueden desaparecer despues de llamar ReleaseSysCache(), o leer directamente desde los buffers del disco, los cuales desaparecen cuando ejecuta heap_getnext(), heap_endscan o ReleaseBuffer(), en el caso de heap_fetch(). O puede ser también una tupla palloc, para la que debe ejecutar pfree() una vez que haya terminado.
=== ¿ Por qué algunas veces los nombres de tablas, columnas, tipos, funciones o vistas son referidos como Name o NameData, y algunas veces como char * ? ===
Los nombres de tablas, columnas, tipos, funciones y vistas son almacenados en las tablas del sistema en columnas de tipo Name, Name un tipo de dato de ancho fijo, con terminación nula de NAMEDATALEN bytes. (El valor por defecto para NAMEDATALEN es de 64 bytes.)
 typedef struct nameData
 {
 char data[NAMEDATALEN];
 } NameData;
 typedef NameData *Name;
Los nombres de tablas, columnas, tipos, funciones y vistas que vienen dentro del backend via consultas de usuarios son almacenados como cadenas de ancho variable con terminación nula.
Muchas funciones son llamadas con ambos tipos de nombres, por ejemplo heap_open(). Debido a que Name es un tipo con caracter nulo de terminación, es seguro enviarlo a una función que espera un tipo char *, Debido a que existen muchos casos donde los nombres en disco (Name) son comparados contra los nombres proporcionados por los usuarios (char *), existen muchos casos donde Name y char * son utilizados indistintamente.
=== ¿ Por qué utilizamos Node y List para generar estructuras de datos ? ===
Hacemos esto debido a que nos permite de manera consistente enviar datos hacia el backend en una forma flexible. Cada nodo contiene una propiedad NodeTag que especifica que tipo de dato se encuentra dentro del Nodo. Las listas son grupos de nodos encadenados como una lista transmitida. El ordenamiento de los elementos en la lista puede o no ser significativo, dependiendo del uso de la lista en particular.
Aquí hay algunos comandos para manipulación de Listas:
;lfirst(i)
;lfirst_int(i)
;lfirst_oid(i)
:devuelve los datos (un puntero, entero o un OID respectivamente) de la celda i en la lista.
;lnext(i)
:devuelve la siguiente celda en la lista después de i.
;foreach(i, list)
:hace un ciclo a través de la lista, asignando cada celda de la lista a i.
Es importante observar que i es un ListCell *, no los datos en la celda de la Lista. Necesita utilizar una de las variantes de lfirst para obtener los datos de la celda.
Aqui se encuentran algunos trozos de código típicos que hacen un ciclo a través de una Lista que contiene elementos Var * y procesos:
 List *list;
 ListCell *i;
 ...
 foreach(i, list)
 {
 Var *var = (Var *) lfirst(i);
 ...
 /* procesar var aquí */
 }
;lcons(node, list)
:agregar un nodo al frente de la lista, o crear una nueva lsita con nodo si la lista es NIL.
;lappend(list, node)
:agregar un nodo al final de la lista.
;list_concat(list1, list2)
:Concatenar list2 al final de list1.
;list_length(list)
:devuelve el largo de la lista.
;list_nth(list, i)
:devuelve el elemento i de la lista, contando desde cero.
;lcons_int, ...
:Existen versiones enterasd de estos: lcons_int, lappend_int, etc. Tambien hay versiones para listas de OIDS: lcons_oid, lappend_oid, etc.
Puede imprimir facilmente esos nodos dentro de gdb. Primero, para deshabilitar el truncado de la salida al utilizar el comando print en gdb:
(gdb) set print elements 0
En lugar de imprimir los valores en fomrato gdb, puede utilizar los siguientes dos comandos para imprimir la Lista, Nodo y contenido de la estructura en un formato detallado que es más sencillo de interpretar. Las listas se encuentran sin desenrrollar dentro de los nodos, y los nodos son impresos en detalle. La primera instrucción imprime en formato recortado, y la segunda en formato largo:
 (gdb) call print(any_pointer)
 (gdb) call pprint(any_pointer)
La salida aparece en el archivo de bitácora del servidor, o en la pantalla si esta ejecutando directamente el backend sin el postmaster.
=== He agregado un campo a la estructura. ¿ Qué más debo hacer ? ===
Las estructuras son enviadas a un analizador, reescritor, optimizador y ejecutor que requiere un poco de soporte. La mayoría de las estructuras tienen rutinas de soporte en src/backend/nodes utilizadas para crear, copiar, leer y dar salida a esas estructuras -- en particular, la mayoría de los tipos de nodos necesitan soporte en los archivos copyfuncs.c y equalfuncs.c, y alfunos necesitan soporte en outfuncs.c y posiblemente en readfuncs.c. Asegurese de agregar soporte para su nuevo campo en esos archivos. Localice cualquier otro lugar de la estructura que pueda necesitar código para su nuevo campo -- buscando referencias a los campos existentes de la estructura es una buena manera de hacerlo. mkid es útil para esto. (vea las herramientas disponibles).
Category:FAQ
Category:Español