Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix various bugs. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | primary-keys |
Files: | files | file ages | folders |
SHA1: |
a70fb0629b2889c5ebe45ebd40b67b1b |
User & Date: | dan 2012-04-11 15:01:13.508 |
Context
2012-04-11
| ||
18:48 | Fix some problems with REPLACE and other conflict handling. check-in: ff493aaa41 user: dan tags: primary-keys | |
15:01 | Fix various bugs. check-in: a70fb0629b user: dan tags: primary-keys | |
2012-04-10
| ||
19:52 | Changes to support "real" user-defined primary keys. This is quite broken at present. check-in: 3841829752 user: dan tags: primary-keys | |
Changes
Changes to src/auth.c.
︙ | ︙ | |||
166 167 168 169 170 171 172 | } iCol = pExpr->iColumn; if( NEVER(pTab==0) ) return; if( iCol>=0 ){ assert( iCol<pTab->nCol ); zCol = pTab->aCol[iCol].zName; | < < < | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | } iCol = pExpr->iColumn; if( NEVER(pTab==0) ) return; if( iCol>=0 ){ assert( iCol<pTab->nCol ); zCol = pTab->aCol[iCol].zName; }else{ zCol = "ROWID"; } assert( iDb>=0 && iDb<db->nDb ); if( SQLITE_IGNORE==sqlite4AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
841 842 843 844 845 846 847 | if( pTable==0 ){ db->mallocFailed = 1; pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; } pTable->zName = zName; | < | 841 842 843 844 845 846 847 848 849 850 851 852 853 854 | if( pTable==0 ){ db->mallocFailed = 1; pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; } pTable->zName = zName; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; pTable->nRowEst = 1000000; assert( pParse->pNewTable==0 ); pParse->pNewTable = pTable; /* If this is the magic sqlite_sequence table used by autoincrement, |
︙ | ︙ |
Changes to src/delete.c.
︙ | ︙ | |||
680 681 682 683 684 685 686 | int nCol; nCol = pIdx->nColumn; regBase = sqlite4GetTempRange(pParse, nCol+1); sqlite4VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol); for(j=0; j<nCol; j++){ int idx = pIdx->aiColumn[j]; | | | 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | int nCol; nCol = pIdx->nColumn; regBase = sqlite4GetTempRange(pParse, nCol+1); sqlite4VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol); for(j=0; j<nCol; j++){ int idx = pIdx->aiColumn[j]; if( idx<0 ){ sqlite4VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j); }else{ sqlite4VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); sqlite4ColumnDefault(v, pTab, idx, -1); } } if( doMakeRec ){ |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
2146 2147 2148 2149 2150 2151 2152 | void sqlite4ExprCodeGetColumnOfTable( Vdbe *v, /* The VDBE under construction */ Table *pTab, /* The table containing the value */ int iTabCur, /* The cursor for this table */ int iCol, /* Index of the column to extract */ int regOut /* Extract the valud into this register */ ){ | | | 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 | void sqlite4ExprCodeGetColumnOfTable( Vdbe *v, /* The VDBE under construction */ Table *pTab, /* The table containing the value */ int iTabCur, /* The cursor for this table */ int iCol, /* Index of the column to extract */ int regOut /* Extract the valud into this register */ ){ if( iCol<0 ){ sqlite4VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); }else{ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; sqlite4VdbeAddOp3(v, op, iTabCur, iCol, regOut); } if( iCol>=0 ){ sqlite4ColumnDefault(v, pTab, iCol, regOut); |
︙ | ︙ | |||
2729 2730 2731 2732 2733 2734 2735 | ** p1==2 -> old.b p1==5 -> new.b */ Table *pTab = pExpr->pTab; int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; assert( pExpr->iTable==0 || pExpr->iTable==1 ); assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol ); | < | 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 | ** p1==2 -> old.b p1==5 -> new.b */ Table *pTab = pExpr->pTab; int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; assert( pExpr->iTable==0 || pExpr->iTable==1 ); assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol ); assert( p1>=0 && p1<(pTab->nCol*2+2) ); sqlite4VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "%s.%s -> $%d", (pExpr->iTable ? "new" : "old"), (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), target |
︙ | ︙ |
Changes to src/kvmem.c.
︙ | ︙ | |||
185 186 187 188 189 190 191 | */ static int kvmemKeyCompare( const KVByteArray *aK1, KVSize nK1, const KVByteArray *aK2, KVSize nK2 ){ int c; c = memcmp(aK1, aK2, nK1<nK2 ? nK1 : nK2); | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | */ static int kvmemKeyCompare( const KVByteArray *aK1, KVSize nK1, const KVByteArray *aK2, KVSize nK2 ){ int c; c = memcmp(aK1, aK2, nK1<nK2 ? nK1 : nK2); if( c==0 ) c = nK1 - nK2; return c; } /* ** Create a new KVMemData object */ static KVMemData *kvmemDataNew(const KVByteArray *aData, KVSize nData){ |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
216 217 218 219 220 221 222 | if( nameInUsingClause(pItem->pUsing, zCol) ) continue; } cnt++; pExpr->iTable = pItem->iCursor; pExpr->pTab = pTab; pMatch = pItem; pSchema = pTab->pSchema; | < | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | if( nameInUsingClause(pItem->pUsing, zCol) ) continue; } cnt++; pExpr->iTable = pItem->iCursor; pExpr->pTab = pTab; pMatch = pItem; pSchema = pTab->pSchema; pExpr->iColumn = (i16)j; break; } } } } #ifndef SQLITE_OMIT_TRIGGER |
︙ | ︙ | |||
247 248 249 250 251 252 253 | if( pTab ){ int iCol; pSchema = pTab->pSchema; cntTab++; for(iCol=0; iCol<pTab->nCol; iCol++){ Column *pCol = &pTab->aCol[iCol]; if( sqlite4StrICmp(pCol->zName, zCol)==0 ){ | < < < | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | if( pTab ){ int iCol; pSchema = pTab->pSchema; cntTab++; for(iCol=0; iCol<pTab->nCol; iCol++){ Column *pCol = &pTab->aCol[iCol]; if( sqlite4StrICmp(pCol->zName, zCol)==0 ){ break; } } if( iCol>=pTab->nCol && sqlite4IsRowid(zCol) ){ iCol = -1; /* IMP: R-44911-55124 */ } if( iCol<pTab->nCol ){ |
︙ | ︙ | |||
413 414 415 416 417 418 419 | */ Expr *sqlite4CreateColumnExpr(sqlite4 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite4ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ struct SrcList_item *pItem = &pSrc->a[iSrc]; p->pTab = pItem->pTab; p->iTable = pItem->iCursor; | < < < | | | | < | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | */ Expr *sqlite4CreateColumnExpr(sqlite4 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite4ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ struct SrcList_item *pItem = &pSrc->a[iSrc]; p->pTab = pItem->pTab; p->iTable = pItem->iCursor; p->iColumn = (ynVar)iCol; testcase( iCol==BMS ); testcase( iCol==BMS-1 ); pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); ExprSetProperty(p, EP_Resolved); } return p; } /* ** This routine is callback for sqlite4WalkExpr(). |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
1088 1089 1090 1091 1092 1093 1094 | sNC.pNext = pNC; sNC.pParse = pNC->pParse; zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); } }else if( ALWAYS(pTab->pSchema) ){ /* A real table */ assert( !pS ); | < | 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 | sNC.pNext = pNC; sNC.pParse = pNC->pParse; zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); } }else if( ALWAYS(pTab->pSchema) ){ /* A real table */ assert( !pS ); assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); if( iCol<0 ){ zType = "INTEGER"; zOriginCol = "rowid"; }else{ zType = pTab->aCol[iCol].zType; zOriginCol = pTab->aCol[iCol].zName; |
︙ | ︙ | |||
1212 1213 1214 1215 1216 1217 1218 | char *zCol; int iCol = p->iColumn; for(j=0; ALWAYS(j<pTabList->nSrc); j++){ if( pTabList->a[j].iCursor==p->iTable ) break; } assert( j<pTabList->nSrc ); pTab = pTabList->a[j].pTab; | < | 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 | char *zCol; int iCol = p->iColumn; for(j=0; ALWAYS(j<pTabList->nSrc); j++){ if( pTabList->a[j].iCursor==p->iTable ) break; } assert( j<pTabList->nSrc ); pTab = pTabList->a[j].pTab; assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); if( iCol<0 ){ zCol = "rowid"; }else{ zCol = pTab->aCol[iCol].zName; } sqlite4VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); |
︙ | ︙ | |||
1279 1280 1281 1282 1283 1284 1285 | pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; pTab = pColExpr->pTab; | < | 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 | pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; pTab = pColExpr->pTab; zName = sqlite4MPrintf(db, "%s", iCol>=0 ? pTab->aCol[iCol].zName : "rowid"); }else if( pColExpr->op==TK_ID ){ assert( !ExprHasProperty(pColExpr, EP_IntValue) ); zName = sqlite4MPrintf(db, "%s", pColExpr->u.zToken); }else{ /* Use the original text of the column expression as its name */ |
︙ | ︙ | |||
1391 1392 1393 1394 1395 1396 1397 | ** is disabled */ assert( db->lookaside.bEnabled==0 ); pTab->nRef = 1; pTab->zName = 0; pTab->nRowEst = 1000000; selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect); | < | 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 | ** is disabled */ assert( db->lookaside.bEnabled==0 ); pTab->nRef = 1; pTab->zName = 0; pTab->nRowEst = 1000000; selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect); if( db->mallocFailed ){ sqlite4DeleteTable(db, pTab); return 0; } return pTab; } |
︙ | ︙ | |||
3235 3236 3237 3238 3239 3240 3241 | sqlite4WalkSelect(pWalker, pSel); pFrom->pTab = pTab = sqlite4DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; pTab->zName = sqlite4MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); | < | 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 | sqlite4WalkSelect(pWalker, pSel); pFrom->pTab = pTab = sqlite4DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; pTab->zName = sqlite4MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); pTab->nRowEst = 1000000; pTab->tabFlags |= TF_Ephemeral; #endif }else{ /* An ordinary table or view name in the FROM clause */ assert( pFrom->pTab==0 ); pFrom->pTab = pTab = |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1291 1292 1293 1294 1295 1296 1297 | ** refers VDBE cursor number that holds the table open, not to the root ** page number. Transient tables are used to hold the results of a ** sub-query that appears instead of a real table name in the FROM clause ** of a SELECT statement. */ struct Table { char *zName; /* Name of the table or view */ | < < < < < | 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 | ** refers VDBE cursor number that holds the table open, not to the root ** page number. Transient tables are used to hold the results of a ** sub-query that appears instead of a real table name in the FROM clause ** of a SELECT statement. */ struct Table { char *zName; /* Name of the table or view */ int nCol; /* Number of columns in this table */ Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ u16 nRef; /* Number of pointers to this Table */ u8 tabFlags; /* Mask of TF_* values */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ #ifndef SQLITE_OMIT_CHECK Expr *pCheck; /* The AND of all CHECK constraints */ #endif #ifndef SQLITE_OMIT_ALTERTABLE int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | int regOld = 0; /* Content of OLD.* table in triggers */ int regKeySet = 0; /* Register containing KeySet object */ Index *pPk; /* The primary key index of this table */ int iPk; /* Offset of primary key in aRegIdx[] */ int bChngPk = 0; /* True if any PK columns are updated */ int bOpenAll = 0; /* True if all indexes were opened */ memset(&sContext, 0, sizeof(sContext)); db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto update_cleanup; } assert( pSrc->nSrc==1 ); /* Locate the table which we want to update. */ pTab = sqlite4SrcListLookup(pParse, pSrc); if( pTab==0 ) goto update_cleanup; iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema); pPk = sqlite4FindPrimaryKey(pTab, &iPk); /* Figure out if we have any triggers and if the table being ** updated is a view. */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite4TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); isView = pTab->pSelect!=0; | > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | int regOld = 0; /* Content of OLD.* table in triggers */ int regKeySet = 0; /* Register containing KeySet object */ Index *pPk; /* The primary key index of this table */ int iPk; /* Offset of primary key in aRegIdx[] */ int bChngPk = 0; /* True if any PK columns are updated */ int bOpenAll = 0; /* True if all indexes were opened */ int bImplicitPk; /* True if pTab has an implicit PK */ memset(&sContext, 0, sizeof(sContext)); db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto update_cleanup; } assert( pSrc->nSrc==1 ); /* Locate the table which we want to update. */ pTab = sqlite4SrcListLookup(pParse, pSrc); if( pTab==0 ) goto update_cleanup; iDb = sqlite4SchemaToIndex(pParse->db, pTab->pSchema); pPk = sqlite4FindPrimaryKey(pTab, &iPk); bImplicitPk = (pPk->aiColumn[0]<0); /* Figure out if we have any triggers and if the table being ** updated is a view. */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite4TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); isView = pTab->pSelect!=0; |
︙ | ︙ | |||
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | /* Allocate other required registers. */ regKeySet = ++pParse->nMem; regOldKey = ++pParse->nMem; if( pTrigger || hasFK ){ regOld = pParse->nMem + 1; pParse->nMem += pTab->nCol; } if( chngRowid || pTrigger || hasFK ){ regNewRowid = ++pParse->nMem; } regNew = pParse->nMem + 1; pParse->nMem += pTab->nCol; /* Start the view context. */ if( isView ){ sqlite4AuthContextPush(pParse, &sContext, pTab->zName); } | > > > | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | /* Allocate other required registers. */ regKeySet = ++pParse->nMem; regOldKey = ++pParse->nMem; if( pTrigger || hasFK ){ regOld = pParse->nMem + 1; pParse->nMem += pTab->nCol; } #if 0 if( chngRowid || pTrigger || hasFK ){ regNewRowid = ++pParse->nMem; } #endif if( bImplicitPk ) pParse->nMem++; regNew = pParse->nMem + 1; pParse->nMem += pTab->nCol; /* Start the view context. */ if( isView ){ sqlite4AuthContextPush(pParse, &sContext, pTab->zName); } |
︙ | ︙ | |||
436 437 438 439 440 441 442 443 444 445 446 447 448 449 | */ testcase( i==31 ); testcase( i==32 ); sqlite4VdbeAddOp3(v, OP_Column, iCur+iPk, i, regNew+i); sqlite4ColumnDefault(v, pTab, i, regNew+i); } } /* Fire any BEFORE UPDATE triggers. This happens before constraints are ** verified. One could argue that this is wrong. */ if( tmask&TRIGGER_BEFORE ){ sqlite4VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol); sqlite4TableAffinityStr(v, pTab); | > > > | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | */ testcase( i==31 ); testcase( i==32 ); sqlite4VdbeAddOp3(v, OP_Column, iCur+iPk, i, regNew+i); sqlite4ColumnDefault(v, pTab, i, regNew+i); } } if( bImplicitPk ){ sqlite4VdbeAddOp2(v, OP_Rowid, iCur+iPk, regNew-1); } /* Fire any BEFORE UPDATE triggers. This happens before constraints are ** verified. One could argue that this is wrong. */ if( tmask&TRIGGER_BEFORE ){ sqlite4VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol); sqlite4TableAffinityStr(v, pTab); |
︙ | ︙ | |||
460 461 462 463 464 465 466 | /* If it did not delete it, the row-trigger may still have modified ** some of the columns of the row being updated. Load the values for ** all columns not modified by the update statement into their ** registers in case this has happened. */ for(i=0; i<pTab->nCol; i++){ | | | | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | /* If it did not delete it, the row-trigger may still have modified ** some of the columns of the row being updated. Load the values for ** all columns not modified by the update statement into their ** registers in case this has happened. */ for(i=0; i<pTab->nCol; i++){ if( aXRef[i]<0 ){ sqlite4VdbeAddOp3(v, OP_Column, iCur, i, regNew+i); sqlite4ColumnDefault(v, pTab, i, regNew+i); } } } if( !isView ){ int j1; /* Address of jump instruction */ /* Do constraint checks. */ assert( bChngPk==0 || bImplicitPk==0 ); if( bChngPk==0 ) aRegIdx[iPk] = 0; sqlite4GenerateConstraintChecks( pParse, pTab, iCur, regNew, aRegIdx, 0, 1, onError, addr, 0 ); if( bChngPk==0 ) aRegIdx[iPk] = regOldKey; /* Do FK constraint checks. */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
3018 3019 3020 3021 3022 3023 3024 | rc = SQLITE_OK; pc = pOp->p2-1; }else if( rc==SQLITE_INEXACT ){ assert( nShort<pProbe->n ); rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey); if( rc==SQLITE_OK ){ if( nKey<nShort | | | 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 | rc = SQLITE_OK; pc = pOp->p2-1; }else if( rc==SQLITE_INEXACT ){ assert( nShort<pProbe->n ); rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey); if( rc==SQLITE_OK ){ if( nKey<nShort || memcmp(pProbe->z, aKey, nShort) || (nKey==pProbe->n && 0==memcmp(pProbe->z, aKey, nKey)) ){ pc = pOp->p2-1; } } } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
1650 1651 1652 1653 1654 1655 1656 | } pColl = sqlite4ExprCollSeq(pParse, pExpr); if( !pColl ){ pColl = db->pDfltColl; } if( pIdx->zName && i<pIdx->nColumn ){ iColumn = pIdx->aiColumn[i]; | < < < | 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 | } pColl = sqlite4ExprCollSeq(pParse, pExpr); if( !pColl ){ pColl = db->pDfltColl; } if( pIdx->zName && i<pIdx->nColumn ){ iColumn = pIdx->aiColumn[i]; iSortOrder = pIdx->aSortOrder[i]; zColl = pIdx->azColl[i]; }else{ iColumn = -1; iSortOrder = 0; zColl = pColl->zName; } |
︙ | ︙ |
Changes to test/simple.test.
︙ | ︙ | |||
242 243 244 245 246 247 248 | CREATE INDEX i1 ON t1(b); } do_execsql_test 10.2 { INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); } | | > > | > > | | < | | | > > | | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | CREATE INDEX i1 ON t1(b); } do_execsql_test 10.2 { INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); } do_execsql_test 10.3 { UPDATE t1 SET b = 10 WHERE a=3 } do_execsql_test 10.4 { SELECT * FROM t1 } {1 2 3 10} do_execsql_test 10.5 { PRAGMA integrity_check } {ok} #------------------------------------------------------------------------- reset_db do_execsql_test 11.1 { CREATE TABLE t1(a, b, c, UNIQUE(a)); INSERT INTO t1 VALUES(1,2,3); } do_catchsql_test 11.2 { INSERT INTO t1 VALUES(1,2,4) } {1 {column a is not unique}} finish_test #proc populate_t1 {} { # db eval { # INSERT INTO t1(a, b) VALUES(4, 'four'); # INSERT INTO t1(a, b) VALUES(9, 'nine'); |
︙ | ︙ |