Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem in the schemalint code that comes up when a sub-query uses one or more of the same tables as its parent. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | schemalint |
Files: | files | file ages | folders |
SHA1: |
fc18cc9293fb0080b7152c16baac49f4 |
User & Date: | dan 2016-03-09 08:07:31.577 |
Context
2016-03-09
| ||
08:08 | Merge latest trunk changes with this branch. (check-in: 59caca4387 user: dan tags: schemalint) | |
08:07 | Fix a problem in the schemalint code that comes up when a sub-query uses one or more of the same tables as its parent. (check-in: fc18cc9293 user: dan tags: schemalint) | |
2016-02-22
| ||
19:51 | Add test script shell6.test, containing tests for schemalint. (check-in: 0b73406595 user: dan tags: schemalint) | |
Changes
Changes to src/shell_indexes.c.
︙ | ︙ | |||
409 410 411 412 413 414 415 | }else{ sqlite3_free(pNew); } return rc; } | < > > > > > > > > > > > > > > > > | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | }else{ sqlite3_free(pNew); } return rc; } static int idxCreateTables( sqlite3 *db, /* User database */ sqlite3 *dbm, /* In-memory database to create tables in */ IdxScan *pScan, /* List of scans */ char **pzErrmsg /* OUT: Error message */ ){ int rc = SQLITE_OK; IdxScan *pIter; for(pIter=pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){ rc = idxGetTableInfo(db, pIter, pzErrmsg); /* Test if table has already been created. If so, jump to the next ** iteration of the loop. */ if( rc==SQLITE_OK ){ sqlite3_stmt *pSql = 0; rc = idxPrintfPrepareStmt(dbm, &pSql, pzErrmsg, "SELECT 1 FROM sqlite_master WHERE tbl_name = %Q", pIter->zTable ); if( rc==SQLITE_OK ){ int bSkip = 0; if( sqlite3_step(pSql)==SQLITE_ROW ) bSkip = 1; rc = sqlite3_finalize(pSql); if( bSkip ) continue; } } if( rc==SQLITE_OK ){ int rc2; sqlite3_stmt *pSql = 0; rc = idxPrintfPrepareStmt(db, &pSql, pzErrmsg, "SELECT sql FROM sqlite_master WHERE tbl_name = %Q", pIter->zTable ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ |
︙ | ︙ | |||
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | void (*xOut)(void*, const char*), /* Output callback */ void *pOutCtx, /* Context for xOut() */ char **pzErr /* OUT: Error message (sqlite3_malloc) */ ){ sqlite3 *dbm = pCtx->dbm; sqlite3_stmt *pExplain = 0; sqlite3_stmt *pSelect = 0; int rc, rc2; int bFound = 0; rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,"EXPLAIN QUERY PLAN %s",zSql); if( rc==SQLITE_OK ){ rc = idxPrepareStmt(dbm, &pSelect, pzErr, "SELECT rowid, sql FROM sqlite_master WHERE name = ?" ); } while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ int i; const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); int nDetail = strlen(zDetail); | > > > > > > | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | void (*xOut)(void*, const char*), /* Output callback */ void *pOutCtx, /* Context for xOut() */ char **pzErr /* OUT: Error message (sqlite3_malloc) */ ){ sqlite3 *dbm = pCtx->dbm; sqlite3_stmt *pExplain = 0; sqlite3_stmt *pSelect = 0; sqlite3_stmt *pInsert = 0; int rc, rc2; int bFound = 0; rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,"EXPLAIN QUERY PLAN %s",zSql); if( rc==SQLITE_OK ){ rc = idxPrepareStmt(dbm, &pSelect, pzErr, "SELECT rowid, sql FROM sqlite_master WHERE name = ?" ); } if( rc==SQLITE_OK ){ rc = idxPrepareStmt(dbm, &pInsert, pzErr, "INSERT OR IGNORE INTO aux.indexes VALUES(?)" ); } while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ int i; const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); int nDetail = strlen(zDetail); |
︙ | ︙ | |||
827 828 829 830 831 832 833 | nIdx++; } sqlite3_bind_text(pSelect, 1, zIdx, nIdx, SQLITE_STATIC); if( SQLITE_ROW==sqlite3_step(pSelect) ){ i64 iRowid = sqlite3_column_int64(pSelect, 0); const char *zSql = (const char*)sqlite3_column_text(pSelect, 1); if( iRowid>=pCtx->iIdxRowid ){ | | > | > > > > > > > > > > > | | > | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 | nIdx++; } sqlite3_bind_text(pSelect, 1, zIdx, nIdx, SQLITE_STATIC); if( SQLITE_ROW==sqlite3_step(pSelect) ){ i64 iRowid = sqlite3_column_int64(pSelect, 0); const char *zSql = (const char*)sqlite3_column_text(pSelect, 1); if( iRowid>=pCtx->iIdxRowid ){ sqlite3_bind_text(pInsert, 1, zSql, -1, SQLITE_STATIC); sqlite3_step(pInsert); rc = sqlite3_reset(pInsert); if( rc ) goto find_indexes_out; } } rc = sqlite3_reset(pSelect); break; } } } rc2 = sqlite3_reset(pExplain); if( rc==SQLITE_OK ) rc = rc2; if( rc==SQLITE_OK ){ sqlite3_stmt *pLoop = 0; rc = idxPrepareStmt(dbm, &pLoop, pzErr, "SELECT name FROM aux.indexes"); if( rc==SQLITE_OK ){ while( SQLITE_ROW==sqlite3_step(pLoop) ){ bFound = 1; xOut(pOutCtx, sqlite3_column_text(pLoop, 0)); } rc = sqlite3_finalize(pLoop); } if( rc==SQLITE_OK ){ if( bFound==0 ) xOut(pOutCtx, "(no new indexes)"); xOut(pOutCtx, ""); } } while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ int iSelectid = sqlite3_column_int(pExplain, 0); int iOrder = sqlite3_column_int(pExplain, 1); int iFrom = sqlite3_column_int(pExplain, 2); const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); |
︙ | ︙ | |||
863 864 865 866 867 868 869 870 871 872 873 874 875 876 | } } find_indexes_out: rc2 = sqlite3_finalize(pExplain); if( rc==SQLITE_OK ) rc = rc2; rc2 = sqlite3_finalize(pSelect); if( rc==SQLITE_OK ) rc = rc2; return rc; } /* ** The xOut callback is invoked to return command output to the user. The | > > | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 | } } find_indexes_out: rc2 = sqlite3_finalize(pExplain); if( rc==SQLITE_OK ) rc = rc2; rc2 = sqlite3_finalize(pSelect); if( rc==SQLITE_OK ) rc = rc2; rc2 = sqlite3_finalize(pInsert); if( rc==SQLITE_OK ) rc = rc2; return rc; } /* ** The xOut callback is invoked to return command output to the user. The |
︙ | ︙ | |||
907 908 909 910 911 912 913 | , 0, 0, pzErrmsg ); } /* Prepare an INSERT statement for writing to aux.depmask */ if( rc==SQLITE_OK ){ rc = idxPrepareStmt(dbm, &ctx.pInsertMask, pzErrmsg, | | | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 | , 0, 0, pzErrmsg ); } /* Prepare an INSERT statement for writing to aux.depmask */ if( rc==SQLITE_OK ){ rc = idxPrepareStmt(dbm, &ctx.pInsertMask, pzErrmsg, "INSERT OR IGNORE INTO aux.depmask SELECT mask | ?1 FROM aux.depmask;" ); } /* Analyze the SELECT statement in zSql. */ if( rc==SQLITE_OK ){ ctx.dbm = dbm; sqlite3_db_config(db, SQLITE_DBCONFIG_WHEREINFO, idxWhereInfo, (void*)&ctx); |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
3986 3987 3988 3989 3990 3991 3992 | /* ORDER BY callbacks */ if( p->pOrderBy ){ int i; int bFirst = 1; for(i=0; i<p->pOrderBy->nExpr; i++){ Expr *pExpr = p->pOrderBy->a[i].pExpr; CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); | < | 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 | /* ORDER BY callbacks */ if( p->pOrderBy ){ int i; int bFirst = 1; for(i=0; i<p->pOrderBy->nExpr; i++){ Expr *pExpr = p->pOrderBy->a[i].pExpr; CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); pExpr = sqlite3ExprSkipCollate(pExpr); if( pExpr->op==TK_COLUMN && pExpr->iTable==pItem->iCursor ){ int iCol = pExpr->iColumn; if( pColl && iCol>=0 ){ int bDesc = p->pOrderBy->a[i].sortOrder; x(pCtx, SQLITE_WHEREINFO_ORDERBY, pColl->zName, iCol, bDesc); } |
︙ | ︙ |
Deleted test/schemalint.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to test/shell6.test.
︙ | ︙ | |||
178 179 180 181 182 183 184 | # do_setup_rec_test 10.1 { CREATE TABLE t5(a, b); CREATE TABLE t6(c, d); } { SELECT * FROM t5, t6 WHERE a=? AND b=c AND c=? } { | < > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | # do_setup_rec_test 10.1 { CREATE TABLE t5(a, b); CREATE TABLE t6(c, d); } { SELECT * FROM t5, t6 WHERE a=? AND b=c AND c=? } { CREATE INDEX t5_idx_000123a7 ON t5(a, b) CREATE INDEX t6_idx_00000063 ON t6(c) 0|0|1|SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?) 0|1|0|SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?) } finish_test |