Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improved estimates of the relative speed of index scans based on declared datatypes of columns in the table. Add "r" column to PRAGMA index_info, showing the estimated relative scan rate. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | index-scan-rate |
Files: | files | file ages | folders |
SHA1: |
07462bb6059f023c22a6c84a4a02afbd |
User & Date: | drh 2013-10-04 15:30:21.142 |
Context
2013-10-04
| ||
15:58 | Fix test cases so that they work when the query planner uses index size estimates to determine whether or not to try an covering index scan. (check-in: 2f394de88f user: drh tags: index-scan-rate) | |
15:30 | Improved estimates of the relative speed of index scans based on declared datatypes of columns in the table. Add "r" column to PRAGMA index_info, showing the estimated relative scan rate. (check-in: 07462bb605 user: drh tags: index-scan-rate) | |
02:36 | Progress toward using the iScanRatio information on indices. Many tests are still failing. (check-in: 6c352edbba user: drh tags: index-scan-rate) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | pCol->zName = z; /* If there is no type specified, columns have the default affinity ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will ** be called next to set pCol->affinity correctly. */ pCol->affinity = SQLITE_AFF_NONE; p->nCol++; } /* ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. A "NOT NULL" constraint has ** been seen on a column. This routine sets the notNull flag on | > | 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | pCol->zName = z; /* If there is no type specified, columns have the default affinity ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will ** be called next to set pCol->affinity correctly. */ pCol->affinity = SQLITE_AFF_NONE; pCol->szEst = 1; p->nCol++; } /* ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. A "NOT NULL" constraint has ** been seen on a column. This routine sets the notNull flag on |
︙ | ︙ | |||
1063 1064 1065 1066 1067 1068 1069 | ** 'REAL' | SQLITE_AFF_REAL ** 'FLOA' | SQLITE_AFF_REAL ** 'DOUB' | SQLITE_AFF_REAL ** ** If none of the substrings in the above table are found, ** SQLITE_AFF_NUMERIC is returned. */ | | > > | | > | 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 | ** 'REAL' | SQLITE_AFF_REAL ** 'FLOA' | SQLITE_AFF_REAL ** 'DOUB' | SQLITE_AFF_REAL ** ** If none of the substrings in the above table are found, ** SQLITE_AFF_NUMERIC is returned. */ char sqlite3AffinityType(const char *zIn, u8 *pszEst){ u32 h = 0; char aff = SQLITE_AFF_NUMERIC; const char *zChar; if( zIn==0 ) return aff; while( zIn[0] ){ h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; zIn++; if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ aff = SQLITE_AFF_TEXT; zChar = zIn; }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ aff = SQLITE_AFF_TEXT; }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ aff = SQLITE_AFF_TEXT; }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ aff = SQLITE_AFF_NONE; |
︙ | ︙ | |||
1095 1096 1097 1098 1099 1100 1101 | aff = SQLITE_AFF_REAL; #endif }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ aff = SQLITE_AFF_INTEGER; break; } } | > > > > > > > > > > > > | > > > > > > | 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 | aff = SQLITE_AFF_REAL; #endif }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ aff = SQLITE_AFF_INTEGER; break; } } if( pszEst ){ if( aff>=SQLITE_AFF_NUMERIC ){ *pszEst = 1; }else if( zChar ){ *pszEst = 1; while( zChar[0] ){ int v; if( sqlite3Isdigit(zChar[0]) && sqlite3GetInt32(zChar, &v) ){ v = v/4 + 1; if( v>255 ) v = 255; *pszEst = v; break; } zChar++; } }else{ *pszEst = 3; } } return aff; } /* ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. The pFirst token is the first ** token in the sequence of tokens that describe the type of the |
︙ | ︙ | |||
1117 1118 1119 1120 1121 1122 1123 | Column *pCol; p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; pCol = &p->aCol[p->nCol-1]; assert( pCol->zType==0 ); pCol->zType = sqlite3NameFromToken(pParse->db, pType); | | | 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 | Column *pCol; p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; pCol = &p->aCol[p->nCol-1]; assert( pCol->zType==0 ); pCol->zType = sqlite3NameFromToken(pParse->db, pType); pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst); } /* ** The expression is the default value for the most recently added column ** of the table currently under construction. ** ** Default value expressions must be constant. Raise an exception if this |
︙ | ︙ | |||
1465 1466 1467 1468 1469 1470 1471 | testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); zType = azType[pCol->affinity - SQLITE_AFF_TEXT]; len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_NONE | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); zType = azType[pCol->affinity - SQLITE_AFF_TEXT]; len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_NONE || pCol->affinity==sqlite3AffinityType(zType, 0) ); memcpy(&zStmt[k], zType, len); k += len; assert( k<=n ); } sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); return zStmt; } /* ** Estimate the total row width for a table. */ static unsigned estimatedTableWidth(const Table *pTab){ unsigned wTable = 0; const Column *pTabCol; int i; for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){ wTable += pTabCol->szEst; } if( pTab->iPKey<0 ) wTable++; return wTable; } /* ** Set the iScanRatio for an index based on estimates of the average ** table row width and average index row width. Estimates are derived ** from the declared datatypes of the various columns. */ static void setIndexScanRatio(Index *pIdx, unsigned wTable){ unsigned wIndex = 1; int i; const Column *aCol = pIdx->pTable->aCol; for(i=0; i<pIdx->nColumn; i++){ assert( pIdx->aiColumn[i]>=0 && pIdx->aiColumn[i]<pIdx->pTable->nCol ); wIndex += aCol[pIdx->aiColumn[i]].szEst; } assert( 100*wIndex/wTable <= 255 ); pIdx->iScanRatio = (u8)(128*wIndex/wTable); /* printf("%s: wIndex=%d wTable=%d ratio=%d\n", ** pIdx->zName, wIndex, wTable, (100*pIdx->iScanRatio)/128); */ } /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. ** ** The table structure that other action routines have been building ** is added to the internal hash tables, assuming no errors have |
︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 | */ void sqlite3EndTable( Parse *pParse, /* Parse context */ Token *pCons, /* The ',' token after the last column defn. */ Token *pEnd, /* The final ')' token in the CREATE TABLE */ Select *pSelect /* Select from a "CREATE ... AS SELECT" */ ){ | | | | > > > > > > > > | 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 | */ void sqlite3EndTable( Parse *pParse, /* Parse context */ Token *pCons, /* The ',' token after the last column defn. */ Token *pEnd, /* The final ')' token in the CREATE TABLE */ Select *pSelect /* Select from a "CREATE ... AS SELECT" */ ){ Table *p; /* The new table */ sqlite3 *db = pParse->db; /* The database connection */ int iDb; /* Database in which the table lives */ Index *pIdx; /* An implied index of the table */ unsigned wTable; /* Estimated average width of a row in the table */ if( (pEnd==0 && pSelect==0) || db->mallocFailed ){ return; } p = pParse->pNewTable; if( p==0 ) return; assert( !db->init.busy || !pSelect ); iDb = sqlite3SchemaToIndex(db, p->pSchema); #ifndef SQLITE_OMIT_CHECK /* Resolve names in all CHECK constraint expressions. */ if( p->pCheck ){ sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); } #endif /* !defined(SQLITE_OMIT_CHECK) */ /* Compute the iScanRatio of implied indices */ wTable = estimatedTableWidth(p); for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ setIndexScanRatio(pIdx, wTable); } /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" or "sqlite_temp_master" table on the disk. ** So do not write to the disk again. Extract the root page number ** for the table from the db->init.newTnum field. (The page number ** should have been put there by the sqliteOpenCb routine.) */ |
︙ | ︙ | |||
2438 2439 2440 2441 2442 2443 2444 | sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_Close, iTab); sqlite3VdbeAddOp1(v, OP_Close, iIdx); sqlite3VdbeAddOp1(v, OP_Close, iSorter); } | < < < < < < < < < | 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 | sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_Close, iTab); sqlite3VdbeAddOp1(v, OP_Close, iIdx); sqlite3VdbeAddOp1(v, OP_Close, iSorter); } /* ** Create a new index for an SQL table. pName1.pName2 is the name of the index ** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is ** currently being constructed by a CREATE TABLE statement. |
︙ | ︙ | |||
2489 2490 2491 2492 2493 2494 2495 | DbFixer sFix; /* For assigning database names to pTable */ int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ sqlite3 *db = pParse->db; Db *pDb; /* The specific table containing the indexed database */ int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ | < < | 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 | DbFixer sFix; /* For assigning database names to pTable */ int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ sqlite3 *db = pParse->db; Db *pDb; /* The specific table containing the indexed database */ int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ const Column *pTabCol; /* A column in the table */ int nCol; /* Number of columns */ int nExtra = 0; /* Space allocated for zExtra[] */ char *zExtra; /* Extra space after the Index object */ assert( pParse->nErr==0 ); /* Never called with prior errors */ if( db->mallocFailed || IN_DECLARE_VTAB ){ |
︙ | ︙ | |||
2734 2735 2736 2737 2738 2739 2740 | if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); pParse->checkSchema = 1; goto exit_create_index; } pIndex->aiColumn[i] = j; | < | 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 | if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); pParse->checkSchema = 1; goto exit_create_index; } pIndex->aiColumn[i] = j; if( pListItem->pExpr ){ int nColl; assert( pListItem->pExpr->op==TK_COLLATE ); zColl = pListItem->pExpr->u.zToken; nColl = sqlite3Strlen30(zColl) + 1; assert( nExtra>=nColl ); memcpy(zExtra, zColl, nColl); |
︙ | ︙ | |||
2758 2759 2760 2761 2762 2763 2764 | } pIndex->azColl[i] = zColl; requestedSortOrder = pListItem->sortOrder & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0; } sqlite3DefaultRowEst(pIndex); | | | < < | 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 | } pIndex->azColl[i] = zColl; requestedSortOrder = pListItem->sortOrder & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0; } sqlite3DefaultRowEst(pIndex); if( pParse->pNewTable==0 ){ setIndexScanRatio(pIndex, estimatedTableWidth(pTab)); } if( pTab==pParse->pNewTable ){ /* This routine has been called to create an automatic index as a ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or ** a PRIMARY KEY or UNIQUE clause following the column definitions. ** i.e. one of: ** |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 | if( op==TK_SELECT ){ assert( pExpr->flags&EP_xIsSelect ); return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); } #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | if( op==TK_SELECT ){ assert( pExpr->flags&EP_xIsSelect ); return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); } #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) && pExpr->pTab!=0 ){ /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ |
︙ | ︙ | |||
2457 2458 2459 2460 2461 2462 2463 | } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ int aff, to_op; inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); assert( !ExprHasProperty(pExpr, EP_IntValue) ); | | | 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 | } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ int aff, to_op; inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); assert( !ExprHasProperty(pExpr, EP_IntValue) ); aff = sqlite3AffinityType(pExpr->u.zToken, 0); to_op = aff - SQLITE_AFF_TEXT + OP_ToText; assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); testcase( to_op==OP_ToText ); |
︙ | ︙ | |||
3124 3125 3126 3127 3128 3129 3130 | sqlite3ExplainExpr(pOut, pExpr->pLeft); break; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ const char *zAff = "unk"; | | | 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 | sqlite3ExplainExpr(pOut, pExpr->pLeft); break; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ const char *zAff = "unk"; switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){ case SQLITE_AFF_TEXT: zAff = "TEXT"; break; case SQLITE_AFF_NONE: zAff = "NONE"; break; case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break; case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break; case SQLITE_AFF_REAL: zAff = "REAL"; break; } sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff); |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
1451 1452 1453 1454 1455 1456 1457 | Table *pTab; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); pIdx = pTab->pIndex; if( pIdx ){ int i = 0; | | | > > | | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 | Table *pTab; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); pIdx = pTab->pIndex; if( pIdx ){ int i = 0; sqlite3VdbeSetNumCols(v, 4); pParse->nMem = 4; sqlite3CodeVerifySchema(pParse, iDb); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "r", SQLITE_STATIC); while(pIdx){ sqlite3VdbeAddOp2(v, OP_Integer, i, 1); sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->iScanRatio*100/128, 4); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); ++i; pIdx = pIdx->pNext; } } } } break; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1193 1194 1195 1196 1197 1198 1199 | char *zName; /* Name of this column */ Expr *pDflt; /* Default value of this column */ char *zDflt; /* Original text of the default value */ char *zType; /* Data type for this column */ char *zColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ char affinity; /* One of the SQLITE_AFF_... values */ | > | | 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 | char *zName; /* Name of this column */ Expr *pDflt; /* Default value of this column */ char *zDflt; /* Original text of the default value */ char *zType; /* Data type for this column */ char *zColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ char affinity; /* One of the SQLITE_AFF_... values */ u8 szEst; /* Estimated size of this column. INT==1 */ u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; /* Allowed values for Column.colFlags: */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ |
︙ | ︙ | |||
3078 3079 3080 3081 3082 3083 3084 | void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); | | | 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 | void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); char sqlite3AffinityType(const char*, u8*); void sqlite3Analyze(Parse*, Token*, Token*); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); int sqlite3FindDbName(sqlite3 *, const char *); int sqlite3AnalysisLoad(sqlite3*,int iDB); void sqlite3DeleteIndexSamples(sqlite3*,Index*); void sqlite3DefaultRowEst(Index*); |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
570 571 572 573 574 575 576 | pragma foreign_key_list(t5); } } {} do_test pragma-6.4 { execsql { pragma index_list(t3); } | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | pragma foreign_key_list(t5); } } {} do_test pragma-6.4 { execsql { pragma index_list(t3); } } {/0 sqlite_autoindex_t3_1 1 \d+/} } ifcapable {!foreignkey} { execsql {CREATE TABLE t3(a,b UNIQUE)} } do_test pragma-6.5.1 { execsql { CREATE INDEX t3i1 ON t3(a,b); |
︙ | ︙ | |||
643 644 645 646 647 648 649 | do_test pragma-7.1.1 { # Make sure a pragma knows to read the schema if it needs to db close sqlite3 db test.db execsql { pragma index_list(t3); } | | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | do_test pragma-7.1.1 { # Make sure a pragma knows to read the schema if it needs to db close sqlite3 db test.db execsql { pragma index_list(t3); } } {/0 t3i1 0 \d+ 1 sqlite_autoindex_t3_1 1 \d+/} do_test pragma-7.1.2 { execsql { pragma index_list(t3_bogus); } } {} } ;# ifcapable schema_pragmas ifcapable {utf16} { |
︙ | ︙ | |||
1657 1658 1659 1660 1661 1662 1663 | db2 eval {PRAGMA index_info(i2)} } {0 2 c 1 3 d 2 1 b} do_test 23.3 { db eval { CREATE INDEX i3 ON t1(d,b,c); } db2 eval {PRAGMA index_list(t1)} | | | 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 | db2 eval {PRAGMA index_info(i2)} } {0 2 c 1 3 d 2 1 b} do_test 23.3 { db eval { CREATE INDEX i3 ON t1(d,b,c); } db2 eval {PRAGMA index_list(t1)} } {/0 i3 0 \d+ 1 i2 0 \d+ 2 i1 0 \d+/} do_test 23.4 { db eval { ALTER TABLE t1 ADD COLUMN e; } db2 eval { PRAGMA table_info(t1); } |
︙ | ︙ |