Información sobre la indexación de tabla virtual
struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Número de entradas en aConstraint */ struct sqlite3_index_constraint { int iColumn; /* Columna en el lado izquierdo de la restricción */ unsigned char op; /* Operador de restricción */ unsigned char usable; /* Verdadero si esta restricción se puede utilizar */ int iTermOffset; /* Usado internamente - xBestIndex debe ignorarlo */ } *aConstraint; /* Tabla de las restricciones de la cláusula WHERE */ int nOrderBy; /* Número de términos en la cláusula ORDER BY */ struct sqlite3_index_orderby { int iColumn; /* Número de columna */ unsigned char desc; /* Verdadero para DESC. Falso para ASC. */ } *aOrderBy; /* Cláusula ORDER BY */ /* Outputs */ struct sqlite3_index_constraint_usage { int argvIndex; /* Si >0, la restricción es parte de argv para xFilter */ unsigned char omit; /* No codificar una prueba para esta restricción */ } *aConstraintUsage; int idxNum; /* Número usado para identificar el índice */ char *idxStr; /* Cadena, posiblemente obtenida desde sqlite3_malloc */ int needToFreeIdxStr; /* Liberar idxStr usando sqlite3_free() si es verdadero */ int orderByConsumed; /* Verdadero si la salida ya está ordenada */ double estimatedCost; /* Coste estimado de usar este índice */ };
La estructura sqlite3_index_info y sus subestructuras se usa como parte del interfaz de la tabla virtual para pasar información y recibir la respuesta desde el método xBestIndex de un módulo de tabla virtual. Los campos debajo de **Inputs** se usan como entradas para xBestIndex y son de sólo lectura. xBestIndex inserta sus resultados dentro de los campos **Outputs**.
El array aConstraint[] almacena las restricciones de la cláusula WHERE en el formato:
column OP expr
Donde OP es =, <, <=, >, o >=. El operador concreto se almacena en aConstraint[].op usando uno de los valores SQLITE_INDEX_CONSTRAINT_. El índice de la columna se almacena en aConstraint[].iColumn. aConstraint[].usable es verdadero si expr en el lado derecho puede ser evaluada (y por lo tanto la restricción utilizable) y falso si no.
El optimizador invierte automáticamente los términos en la forma "expr OP column" y hace otras simplificaciones en la cláusila WHERE en un intento de obtener tantos términos de cláusula WHERE en el formato mostrado antes como sea posible. El array aConstraint[] sólo informa sobre términos de la cláusula WHERE que sean relevantes para la tabla virtual en particular que está siendo consultada.
La información sobre la cláusula ORDER BY se almacena en aOrderBy[]. Cada término de aOrderBy almacena una columna de la cláusula ORDER BY.
El método xBestIndex debe rellenar aConstraintUsage[] con información sobre que parámetros pasar a xFilter. Si argvIndex>0 entonces se evalúa el lado derecho del correspondiente aConstraint[] y se convierte en la entrada número argvIndex de argv. Si aConstraintUsage[].omit es verdadera, entonces se supone que la restricción está manejada por completo por la tabla virtual y no se comprueba de nuevo por SQLite.
Los valores idxNum y idxPtr se registran y se pasan en el método xFilter. sqlite3_free() se usa para liberar idxPtr si y sólo si needToFreeIdxPtr es verdadero.
El orderByConsumed significa que la salida de xFilter/xNext se produce en el orden correcto para satisfacer la cláusula ORDER BY de modo que no se necesita ningún paso de ordenamiento separado.
El valor estimatedCost es una estimación del coste de hacer la búsqueda en particular. Un recorrido completo de una tabla con N entradas tendrá un consto de N. Una búsqueda binaria de una tabla con N entradas debe tener un costo aproximado de log(N).