En un escaneo de índice, el método de acceso al índice es responsable de regurgitar los TIDs de todas las tuplas de las que se le ha hablado que coinciden con las claves de escaneo (scan keys). El método de acceso no está involucrado en la recuperación real de esas tuplas de la tabla padre del índice, ni en la determinación de si pasan la prueba de visibilidad del escaneo u otras condiciones.
Una clave de escaneo es la representación interna de una cláusula WHERE de
la forma clave_de_índice operador
constante, donde la clave de índice es una de las columnas del
índice y el operador es uno de los miembros de la familia de operadores
asociada con esa columna de índice. Un escaneo de índice tiene cero o más claves
de escaneo, que están unidas implícitamente mediante AND — se espera que las tuplas devueltas
satisfagan todas las condiciones indicadas.
El método de acceso puede reportar que el índice es con pérdidas (lossy), o que requiere comprobaciones repetidas, para una consulta en particular. Esto implica que el escaneo del índice devolverá todas las entradas que pasan la clave de escaneo, más posiblemente entradas adicionales que no lo hacen. La maquinaria de escaneo de índices del sistema central aplicará entonces las condiciones del índice de nuevo a la tupla del montón para verificar si realmente debe ser seleccionada o no. Si no se especifica la opción de volver a comprobar, el escaneo del índice debe devolver exactamente el conjunto de entradas coincidentes.
Ten en cuenta que depende enteramente del método de acceso garantizar que
encuentra correctamente todas y solo las entradas que pasan todas las claves de escaneo dadas.
Además, el sistema central simplemente entregará todas las cláusulas WHERE
que coincidan con las claves del índice y las familias de operadores, sin ningún
análisis semántico para determinar si son redundantes o
contradictorias. Como ejemplo, dado
WHERE x > 4 AND x > 14 donde x es una columna indexada por
b-tree, se deja a la función amrescan de b-tree
darse cuenta de que la primera clave de escaneo es redundante y se puede descartar.
El alcance del preprocesamiento necesario durante amrescan
dependerá de la medida en que el método de acceso al índice necesite reducir
las claves de escaneo a una forma “normalizada”.
Algunos métodos de acceso devuelven las entradas del índice en un orden bien definido, otros no lo hacen. En realidad, hay dos formas diferentes en las que un método de acceso puede admitir salidas ordenadas:
Los métodos de acceso que siempre devuelven las entradas en el orden natural
de sus datos (como btree) deben establecer
amcanorder en verdadero.
Actualmente, tales métodos de acceso deben usar números de estrategia compatibles con btree
para sus operadores de igualdad y ordenación.
Los métodos de acceso que admiten operadores de ordenación deben establecer
amcanorderbyop en verdadero.
Esto indica que el índice es capaz de devolver entradas en
un orden que satisfaga ORDER BY clave_de_índice
operador constante. Los modificadores de escaneo
de esa forma se pueden pasar a amrescan como se describió
anteriormente.
La función amgettuple tiene un argumento direction,
que puede ser bien ForwardScanDirection (el caso normal)
o bien BackwardScanDirection. Si la primera llamada después de
amrescan especifica BackwardScanDirection, entonces el
conjunto de entradas de índice coincidentes debe escanearse de atrás hacia adelante en lugar de en la
dirección normal de adelante hacia atrás, por lo que amgettuple debe devolver
la última tupla coincidente en el índice, en lugar de la primera como lo
haría normalmente. (Esto solo ocurrirá para los métodos de acceso
que establecen amcanorder en verdadero). Después de la
primera llamada, amgettuple debe estar preparada para avanzar el escaneo en
cualquier dirección desde la entrada devuelta más recientemente. (Pero si
amcanbackward es falso, todas las llamadas subsiguientes
tendrán la misma dirección que la primera).
Los métodos de acceso que admiten escaneos ordenados deben admitir “marcar” una
posición en un escaneo y volver más tarde a la posición marcada. La misma
posición se puede restaurar varias veces. Sin embargo, solo se necesita recordar una posición
por escaneo; una nueva llamada a ammarkpos anula la
posición marcada anteriormente. Un método de acceso que no admite escaneos
ordenados no necesita proporcionar las funciones ammarkpos y amrestrpos
en IndexAmRoutine; en su lugar, establece esos punteros en NULL.
Tanto la posición del escaneo como la posición de la marca (si la hay) deben mantenerse de manera coherente frente a inserciones o eliminaciones concurrentes en el índice. Está bien si una entrada recién insertada no es devuelta por un escaneo que habría encontrado la entrada si hubiera existido cuando comenzó el escaneo, o que el escaneo devuelva dicha entrada al volver a escanear o al retroceder a pesar de que no se había devuelto la primera vez. Del mismo modo, una eliminación concurrente puede o no verse reflejada en los resultados de un escaneo. Lo que es importante es que las inserciones o eliminaciones no causen que el escaneo pierda o devuelva repetidamente entradas que no se estaban insertando o eliminando en sí mismas.
Si el índice almacena los valores de datos indexados originales (y no una representación con pérdidas de ellos), es útil admitir escaneos de solo índice, en los que el índice devuelve los datos reales y no solo el TID de la tupla del montón. Esto solo evitará E/S si el mapa de visibilidad muestra que el TID está en una página visible para todos (all-visible); de lo contrario, la tupla del montón debe ser visitada de todos modos para comprobar la visibilidad MVCC. Pero eso no es de incumbencia del método de acceso.
En lugar de usar amgettuple, se puede hacer un escaneo de índice con
amgetbitmap para recuperar todas las tuplas en una sola llamada. Esto puede ser
notablemente más eficiente que amgettuple porque permite
evitar ciclos de bloqueo/desbloqueo dentro del método de acceso. En principio,
amgetbitmap debería tener los mismos efectos que las llamadas repetidas a
amgettuple, pero imponemos varias restricciones para
simplificar las cosas. En primer lugar, amgetbitmap devuelve todas
las tuplas a la vez y no se admite marcar o restaurar posiciones de escaneo. En segundo lugar, las tuplas se devuelven en un mapa de bits que no
tiene ninguna ordenación específica, que es por lo que amgetbitmap no
toma un argumento direction. (Tampoco se suministrarán operadores de
ordenación para tal escaneo).
Además, no hay provisión para escaneos de solo índice con
amgetbitmap, ya que no hay forma de devolver el contenido de
las tuplas de índice.
Finalmente, amgetbitmap
no garantiza ningún bloqueo de las tuplas devueltas, con implicaciones
detalladas en Section 63.4.
Ten en cuenta que se permite que un método de acceso implemente solo
amgetbitmap y no amgettuple, o viceversa,
si su implementación interna no es adecuada para una API o la otra.