** The implementation of dot-command ".lint fkey-indexes". */
| 21633 | ** The implementation of dot-command ".lint fkey-indexes". |
| 21634 | */ |
| 21635 | static int lintFkeyIndexes( |
| 21636 | ShellState *pState, /* Current shell tool state */ |
| 21637 | char **azArg, /* Array of arguments passed to dot command */ |
| 21638 | int nArg /* Number of entries in azArg[] */ |
| 21639 | ){ |
| 21640 | sqlite3 *db = pState->db; /* Database handle to query "main" db of */ |
| 21641 | FILE *out = pState->out; /* Stream to write non-error output to */ |
| 21642 | int bVerbose = 0; /* If -verbose is present */ |
| 21643 | int bGroupByParent = 0; /* If -groupbyparent is present */ |
| 21644 | int i; /* To iterate through azArg[] */ |
| 21645 | const char *zIndent = ""; /* How much to indent CREATE INDEX by */ |
| 21646 | int rc; /* Return code */ |
| 21647 | sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ |
| 21648 | |
| 21649 | /* |
| 21650 | ** This SELECT statement returns one row for each foreign key constraint |
| 21651 | ** in the schema of the main database. The column values are: |
| 21652 | ** |
| 21653 | ** 0. The text of an SQL statement similar to: |
| 21654 | ** |
| 21655 | ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?" |
| 21656 | ** |
| 21657 | ** This SELECT is similar to the one that the foreign keys implementation |
| 21658 | ** needs to run internally on child tables. If there is an index that can |
| 21659 | ** be used to optimize this query, then it can also be used by the FK |
| 21660 | ** implementation to optimize DELETE or UPDATE statements on the parent |
| 21661 | ** table. |
| 21662 | ** |
| 21663 | ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by |
| 21664 | ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema |
| 21665 | ** contains an index that can be used to optimize the query. |
| 21666 | ** |
| 21667 | ** 2. Human readable text that describes the child table and columns. e.g. |
| 21668 | ** |
| 21669 | ** "child_table(child_key1, child_key2)" |
| 21670 | ** |
| 21671 | ** 3. Human readable text that describes the parent table and columns. e.g. |
| 21672 | ** |
| 21673 | ** "parent_table(parent_key1, parent_key2)" |
| 21674 | ** |
| 21675 | ** 4. A full CREATE INDEX statement for an index that could be used to |
| 21676 | ** optimize DELETE or UPDATE statements on the parent table. e.g. |
| 21677 | ** |
| 21678 | ** "CREATE INDEX child_table_child_key ON child_table(child_key)" |
| 21679 | ** |
| 21680 | ** 5. The name of the parent table. |
| 21681 | ** |
| 21682 | ** These six values are used by the C logic below to generate the report. |
| 21683 | */ |
| 21684 | const char *zSql = |
| 21685 | "SELECT " |
| 21686 | " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '" |
| 21687 | " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " |
| 21688 | " || fkey_collate_clause(" |
| 21689 | " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" |
| 21690 | ", " |
| 21691 | " 'SEARCH ' || s.name || ' USING COVERING INDEX*('" |
| 21692 | " || group_concat('*=?', ' AND ') || ')'" |
no test coverage detected