Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch sort-column-opcodes Excluding Merge-Ins
This is equivalent to a diff from 49181427 to c1adf959
2017-02-20
| ||
14:30 | Small grammar simplification. (check-in: 0d8a868a user: drh tags: trunk) | |
13:11 | Merge fixes from trunk. (check-in: ff213f2e user: drh tags: auto-analyze) | |
2017-02-18
| ||
20:05 | Add an optimization to OP_Column to speed up sequential OP_Column instructions that read earlier fields from the same cursor. Attempt to reorder OP_Column opcodes so as to take advantage of this. (Leaf check-in: c1adf959 user: dan tags: sort-column-opcodes) | |
13:47 | Add the SQLITE_BUG_COMPATIBLE_20160819 compile-time option to omit the error message when an unrecognized argument is provided to the VACUUM command. (check-in: 49181427 user: drh tags: trunk) | |
2017-02-17
| ||
23:52 | Fix the #endif location for an #ifndef SQLITE_UNTESTABLE macro in the command-line shell. (check-in: 8cc9d74c user: drh tags: trunk) | |
Changes to src/expr.c.
︙ | |||
4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 | 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | assert( target>0 ); assert( pExpr->op!=TK_REGISTER ); sqlite3ExprCode(pParse, pExpr, target); iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, target, iMem); exprToRegister(pExpr, iMem); } /* ** Return the value of (*p1) - (*p2), as defined by the sort order described ** in the comment above reorderColumnFetch(). */ static int compareOpCode(VdbeOp *p1, VdbeOp *p2){ int res; assert( p1->opcode==OP_Column || p1->opcode==OP_VColumn || p1->opcode==OP_Copy || p1->opcode==OP_SCopy || p1->opcode==OP_Rowid || p1->opcode==OP_RealAffinity ); assert( p2->opcode==OP_Column || p2->opcode==OP_VColumn || p2->opcode==OP_Copy || p2->opcode==OP_SCopy || p2->opcode==OP_Rowid || p2->opcode==OP_RealAffinity ); assert( OP_VColumn>OP_Column && OP_Rowid>OP_Column ); assert( OP_Column>OP_RealAffinity ); assert( OP_RealAffinity>OP_Copy && OP_RealAffinity>OP_SCopy ); res = (int)(p2->opcode) - (int)(p1->opcode); if( res==0 ){ res = p1->p1 - p2->p1; if( res==0 ){ res = p2->p2 - p1->p2; } } return res; } /* ** The VM instructions from iFirst to the current address were generated ** in order to populate an array of registers with the results of a series ** of TK_COLUMN expressions. This guarantees that the specified range ** contains opcodes of the following types only: ** ** Rowid ** Column ** VColumn ** RealAffinity ** Copy ** SCopy ** ** This function sorts the opcodes so all of the OP_Column appear in a ** contiguous block, sorted by (p1, p2 DESC). The VDBE layer processes ** OP_Column instructions in this order more efficiently. ** ** In practice, the array is sorted so that all instructions of each type ** of opcode are arranged into a contiguous group. Given the following, ** this is a safe re-ordering: ** ** * All Rowid, VColumn and Column instructions appear before all ** RealAffinity instructions (that might operate on the result of ** a VColumn or Column), and ** ** * All RealAffinity instructions occur before all Copy and SCopy ** instructions (which might read a column-cache entry populated ** by a prior Column+RealAffinity). */ static void reorderColumnFetch(sqlite3 *db, Vdbe *v, int iFirst){ int iEnd = sqlite3VdbeCurrentAddr(v); int nOp = iEnd-iFirst; if( nOp>1 ){ VdbeOp *aSpace = (VdbeOp*)sqlite3StackAllocRaw(db, sizeof(VdbeOp) * nOp); if( aSpace ){ int sz; VdbeOp *aOp = sqlite3VdbeGetOp(v, iFirst); VdbeOp *a1 = aOp; VdbeOp *a2 = aSpace; for(sz=1; sz<nOp; sz=sz*2){ int i; for(i=0; i<nOp; i+=(sz*2)){ /* Merge the two lists of sz elements each starting at a1[i] and ** a1[i+sz] into a sz element list at a2[i]. */ int e1 = MIN(i+sz, nOp); int e2 = MIN(i+sz*2, nOp); int i2 = i+sz; int i1 = i; int iOut = i; while( i1<e1 || i2<e2 ){ if( i1>=e1 || (i2<e2 && compareOpCode(&a1[i2], &a1[i1])<0) ){ a2[iOut++] = a1[i2++]; }else{ a2[iOut++] = a1[i1++]; } } } SWAP(VdbeOp*, a1, a2); } if( a1!=aOp ){ memcpy(aOp, a1, sizeof(VdbeOp)*nOp); } sqlite3StackFree(db, aSpace); } } } /* ** Generate code that pushes the value of every element of the given ** expression list into a sequence of registers beginning at target. ** ** Return the number of elements evaluated. ** |
︙ | |||
4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 | 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 | + + + + + + + + + | ExprList *pList, /* The expression list to be coded */ int target, /* Where to write results */ int srcReg, /* Source registers if SQLITE_ECEL_REF */ u8 flags /* SQLITE_ECEL_* flags */ ){ struct ExprList_item *pItem; int i, j, n; int iFirst = -1; u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; Vdbe *v = pParse->pVdbe; assert( pList!=0 ); assert( target>0 ); assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ n = pList->nExpr; if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; for(pItem=pList->a, i=0; i<n; i++, pItem++){ Expr *pExpr = pItem->pExpr; if( iFirst>0 ){ if( pExpr->op!=TK_COLUMN ){ reorderColumnFetch(pParse->db, v, iFirst); iFirst = -1; } }else{ if( pExpr->op==TK_COLUMN ) iFirst = sqlite3VdbeCurrentAddr(v); } if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ if( flags & SQLITE_ECEL_OMITREF ){ i--; n--; }else{ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } |
︙ | |||
4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 | 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 | + | pOp->p3++; }else{ sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); } } } } if( iFirst>0 ) reorderColumnFetch(pParse->db, v, iFirst); return n; } /* ** Generate code for a BETWEEN operator. ** ** x BETWEEN y AND z |
︙ |
Changes to src/select.c.
︙ | |||
1270 1271 1272 1273 1274 1275 1276 | 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 | + - + - - - + + + + - - + + + + + + - - + + + | bSeq = 0; }else{ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); iSortTab = iTab; bSeq = 1; } iCol = nKey+bSeq; |
︙ |
Changes to src/sqliteInt.h.
︙ | |||
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 | 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 | + + | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_CONTINUE 0x01 /* * Each trigger present in the database schema is stored as an instance of * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. * 1. In the "trigHash" hash table (part of the sqlite3* that represents the |
︙ |
Changes to src/update.c.
︙ | |||
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | + + + + | ** the database after the BEFORE triggers are fired anyway (as the trigger ** may have modified them). So not loading those that are not going to ** be used eliminates some redundant opcodes. */ newmask = sqlite3TriggerColmask( pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError ); #if 1 for(i=pTab->nCol-1; i>=0; i--){ #else for(i=0; i<pTab->nCol; i++){ #endif if( i==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); }else{ j = aXRef[i]; if( j>=0 ){ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ |
︙ |
Changes to src/vdbe.c.
︙ | |||
549 550 551 552 553 554 555 | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 | - | return out2PrereleaseWithClear(pOut); }else{ pOut->flags = MEM_Int; return pOut; } } |
︙ | |||
2623 2624 2625 2626 2627 2628 2629 | 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 | + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | if( VdbeMemDynamic(pDest) ){ sqlite3VdbeMemSetNull(pDest); } assert( t==pC->aType[p2] ); if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ while( 1 ){ |
︙ |
Changes to src/vdbe.h.
︙ | |||
222 223 224 225 226 227 228 229 230 231 232 233 234 235 | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | + | void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); void sqlite3VdbeSwap(Vdbe*,Vdbe*); VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); void sqlite3VdbeSetVarmask(Vdbe*, int); void sqlite3VdbeUsesAltMap(Vdbe*); #ifndef SQLITE_OMIT_TRACE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
︙ |
Changes to src/vdbeInt.h.
︙ | |||
386 387 388 389 390 391 392 393 394 395 396 397 398 399 | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | + | bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ bft isPrepareV2:1; /* True if prepared with prepare_v2() */ bft usesAltMap:1; /* True if uses VdbeCursor.aAltMap[] */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ char *zSql; /* Text of the SQL statement that generated this */ void *pFree; /* Free this when deleting the vdbe */ VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ |
︙ |
Changes to src/vdbeaux.c.
︙ | |||
614 615 616 617 618 619 620 621 622 623 624 625 626 627 | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | + + + + + + + | if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){ assert( ADDR(pOp->p2)<pParse->nLabel ); pOp->p2 = aLabel[ADDR(pOp->p2)]; } } if( pOp==p->aOp ) break; pOp--; if( p->usesAltMap==0 && pOp[0].opcode==OP_Column && pOp[1].opcode==OP_Column && pOp[0].p1==pOp[1].p1 && pOp[0].p2>=pOp[1].p2 ){ pOp->p5 |= OPFLAG_CONTINUE; } } sqlite3DbFree(p->db, pParse->aLabel); pParse->aLabel = 0; pParse->nLabel = 0; *pMaxFuncArgs = nMaxArgs; assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); } |
︙ | |||
4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 | 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 | + + + + + + | if( iVar>32 ){ v->expmask = 0xffffffff; }else{ v->expmask |= ((u32)1 << (iVar-1)); } } /* ** Set the "uses-alt-map" flag. */ void sqlite3VdbeUsesAltMap(Vdbe *v){ v->usesAltMap = 1; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored ** in memory obtained from sqlite3DbMalloc). */ void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ |
︙ |
Changes to src/wherecode.c.
︙ | |||
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 | 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | + | ai[0] = pTab->nCol; for(i=0; i<pIdx->nColumn-1; i++){ assert( pIdx->aiColumn[i]<pTab->nCol ); if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1; } sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); } sqlite3VdbeUsesAltMap(v); } } /* ** If the expression passed as the second argument is a vector, generate ** code to write the first nReg elements of the vector into an array ** of registers starting with iReg. |
︙ |