Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Floating point and 64-bit integer constants store in the virtual machine opcodes in binary, not as text. Performance improvement. Ticket #2733. (CVS 4507) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7e30fd6a09899842c922b044714dc667 |
User & Date: | drh 2007-10-23 15:39:45.000 |
Context
2007-10-23
| ||
15:51 | Make sure the _LARGEFILE_SOURCE macro occurs before any system includes. Ticket #2739. (CVS 4508) (check-in: 36465aeb1f user: drh tags: trunk) | |
15:39 | Floating point and 64-bit integer constants store in the virtual machine opcodes in binary, not as text. Performance improvement. Ticket #2733. (CVS 4507) (check-in: 7e30fd6a09 user: drh tags: trunk) | |
14:55 | Fix limit assertions in vdbe.c. Ticket #2740. (CVS 4506) (check-in: 27f846d089 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.314 2007/10/23 15:39:45 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 | if( testAddr ){ sqlite3VdbeJumpHere(v, testAddr); } return; } #endif /* SQLITE_OMIT_SUBQUERY */ /* ** Generate an instruction that will put the integer describe by ** text z[0..n-1] on the stack. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > > > > | | | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 | if( testAddr ){ sqlite3VdbeJumpHere(v, testAddr); } return; } #endif /* SQLITE_OMIT_SUBQUERY */ /* ** Duplicate an 8-byte value */ static char *dup8bytes(Vdbe *v, const char *in){ char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8); if( out ){ memcpy(out, in, 8); } return out; } /* ** Generate an instruction that will put the floating point ** value described by z[0..n-1] on the stack. */ static void codeReal(Vdbe *v, const char *z, int n, int negateFlag){ assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed ); if( z ){ double value; char *zV; sqlite3AtoF(z, &value); if( negateFlag ) value = -value; zV = dup8bytes(v, (char*)&value); sqlite3VdbeOp3(v, OP_Real, 0, 0, zV, P3_REAL); } } /* ** Generate an instruction that will put the integer describe by ** text z[0..n-1] on the stack. */ static void codeInteger(Vdbe *v, const char *z, int n, int negateFlag){ assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed ); if( z ){ int i; if( sqlite3GetInt32(z, &i) ){ if( negateFlag ) i = -i; sqlite3VdbeAddOp(v, OP_Integer, i, 0); }else if( sqlite3FitsIn64Bits(z, negateFlag) ){ i64 value; char *zV; sqlite3Atoi64(z, &value); if( negateFlag ) value = -value; zV = dup8bytes(v, (char*)&value); sqlite3VdbeOp3(v, OP_Int64, 0, 0, zV, P3_INT64); }else{ codeReal(v, z, n, negateFlag); } } } /* ** Generate code that will extract the iColumn-th column from |
︙ | ︙ | |||
1765 1766 1767 1768 1769 1770 1771 | sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else{ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable); } break; } case TK_INTEGER: { | | | > > > < < | | 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 | sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else{ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable); } break; } case TK_INTEGER: { codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0); break; } case TK_FLOAT: { codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0); break; } case TK_STRING: { sqlite3DequoteExpr(pParse->db, pExpr); sqlite3VdbeOp3(v,OP_String8, 0, 0, (char*)pExpr->token.z, pExpr->token.n); break; } case TK_NULL: { sqlite3VdbeAddOp(v, OP_Null, 0, 0); break; } #ifndef SQLITE_OMIT_BLOB_LITERAL |
︙ | ︙ | |||
1875 1876 1877 1878 1879 1880 1881 | break; } case TK_UMINUS: { Expr *pLeft = pExpr->pLeft; assert( pLeft ); if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; | < | | < | 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 | break; } case TK_UMINUS: { Expr *pLeft = pExpr->pLeft; assert( pLeft ); if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; if( pLeft->op==TK_FLOAT ){ codeReal(v, (char*)p->z, p->n, 1); }else{ codeInteger(v, (char*)p->z, p->n, 1); } break; } /* Fall through into TK_NOT */ } case TK_BITNOT: case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.615 2007/10/23 15:39:45 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "sqliteLimit.h" /* ** For testing purposes, the various size limit constants are really |
︙ | ︙ | |||
1779 1780 1781 1782 1783 1784 1785 | int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3AtoF(const char *z, double*); char *sqlite3_snprintf(int,char*,const char*,...); int sqlite3GetInt32(const char *, int*); | | | 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 | int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3AtoF(const char *z, double*); char *sqlite3_snprintf(int,char*,const char*,...); int sqlite3GetInt32(const char *, int*); int sqlite3FitsIn64Bits(const char *, int); int sqlite3Utf16ByteLen(const void *pData, int nChar); int sqlite3Utf8CharLen(const char *pData, int nByte); int sqlite3Utf8Read(const u8*, const u8*, const u8**); int sqlite3PutVarint(unsigned char *, u64); int sqlite3GetVarint(const unsigned char *, u64 *); int sqlite3GetVarint32(const unsigned char *, u32 *); int sqlite3VarintLen(u64 v); |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.279 2007/10/23 15:39:45 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* |
︙ | ︙ | |||
1127 1128 1129 1130 1131 1132 1133 | } /* ** If zNum represents an integer that will fit in 64-bits, then set ** *pValue to that integer and return true. Otherwise return false. */ static int sqlite3GetInt64(const char *zNum, i64 *pValue){ | | | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | } /* ** If zNum represents an integer that will fit in 64-bits, then set ** *pValue to that integer and return true. Otherwise return false. */ static int sqlite3GetInt64(const char *zNum, i64 *pValue){ if( sqlite3FitsIn64Bits(zNum, 0) ){ sqlite3Atoi64(zNum, pValue); return 1; } return 0; } /* |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.213 2007/10/23 15:39:45 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* |
︙ | ︙ | |||
372 373 374 375 376 377 378 | ** 64-bit signed integer, return TRUE. Otherwise return FALSE. ** ** This routine returns FALSE for the string -9223372036854775808 even that ** that number will, in theory fit in a 64-bit integer. Positive ** 9223373036854775808 will not fit in 64 bits. So it seems safer to return ** false. */ | | > | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | ** 64-bit signed integer, return TRUE. Otherwise return FALSE. ** ** This routine returns FALSE for the string -9223372036854775808 even that ** that number will, in theory fit in a 64-bit integer. Positive ** 9223373036854775808 will not fit in 64 bits. So it seems safer to return ** false. */ int sqlite3FitsIn64Bits(const char *zNum, int negFlag){ int i, c; int neg = 0; if( *zNum=='-' ){ neg = 1; zNum++; }else if( *zNum=='+' ){ zNum++; } if( negFlag ) neg = 1-neg; while( *zNum=='0' ){ zNum++; /* Skip leading zeros. Ticket #2454 */ } for(i=0; (c=zNum[i])>='0' && c<='9'; i++){} if( i<19 ){ /* Guaranteed to fit if less than 19 digits */ return 1; |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.653 2007/10/23 15:39:45 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
701 702 703 704 705 706 707 | pTos->flags = MEM_Int; pTos->u.i = pOp->p1; break; } /* Opcode: Int64 * * P3 ** | | | | | < < < < > | | | < < < < < | 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | pTos->flags = MEM_Int; pTos->u.i = pOp->p1; break; } /* Opcode: Int64 * * P3 ** ** P3 is a pointer to a 64-bit integer value. ** Push that value onto the stack. */ case OP_Int64: { pTos++; assert( pOp->p3!=0 ); pTos->flags = MEM_Int; memcpy(&pTos->u.i, pOp->p3, 8); break; } /* Opcode: Real * * P3 ** ** P3 is a pointer to a 64-bit floating point value. Push that value ** onto the stack. */ case OP_Real: { /* same as TK_FLOAT, */ pTos++; pTos->flags = MEM_Real; memcpy(&pTos->r, pOp->p3, 8); break; } /* Opcode: String8 * * P3 ** ** P3 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time. |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.114 2007/10/23 15:39:45 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ #define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ #define P3_MPRINTF (-11) /* P3 is a string obtained from sqlite3_mprintf() */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. | > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ #define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ #define P3_MPRINTF (-11) /* P3 is a string obtained from sqlite3_mprintf() */ #define P3_REAL (-12) /* P3 is a 64-bit floating point value */ #define P3_INT64 (-13) /* P3 is a 64-bit signed integer */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
428 429 430 431 432 433 434 435 436 437 | /* ** Delete a P3 value if necessary. */ static void freeP3(int p3type, void *p3){ if( p3 ){ switch( p3type ){ case P3_DYNAMIC: case P3_KEYINFO: case P3_KEYINFO_HANDOFF: { | > > > < < < < | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | /* ** Delete a P3 value if necessary. */ static void freeP3(int p3type, void *p3){ if( p3 ){ switch( p3type ){ case P3_REAL: case P3_INT64: case P3_MPRINTF: case P3_DYNAMIC: case P3_KEYINFO: case P3_KEYINFO_HANDOFF: { sqlite3_free(p3); break; } case P3_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p3; freeEphemeralFunction(pVdbeFunc->pFunc); sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); |
︙ | ︙ | |||
626 627 628 629 630 631 632 633 634 635 636 637 638 639 | break; } case P3_FUNCDEF: { FuncDef *pDef = (FuncDef*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); zP3 = zTemp; break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P3_VTAB: { sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule); zP3 = zTemp; break; | > > > > > > > > > > | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | break; } case P3_FUNCDEF: { FuncDef *pDef = (FuncDef*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); zP3 = zTemp; break; } case P3_INT64: { sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3); zP3 = zTemp; break; } case P3_REAL: { sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3); zP3 = zTemp; break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P3_VTAB: { sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule); zP3 = zTemp; break; |
︙ | ︙ |
Changes to test/alter.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2004 November 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the ALTER TABLE statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2004 November 10 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the ALTER TABLE statement. # # $Id: alter.test,v 1.27 2007/10/23 15:39:46 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # If SQLITE_OMIT_ALTERTABLE is defined, omit this file. ifcapable !altertable { |
︙ | ︙ | |||
634 635 636 637 638 639 640 | # that includes a COLLATE clause. # do_test alter-7.1 { execsql { CREATE TABLE t1(a TEXT COLLATE BINARY); ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE; INSERT INTO t1 VALUES(1,'-2'); | | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | # that includes a COLLATE clause. # do_test alter-7.1 { execsql { CREATE TABLE t1(a TEXT COLLATE BINARY); ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE; INSERT INTO t1 VALUES(1,'-2'); INSERT INTO t1 VALUES(5.4e-08,'5.4e-08'); SELECT typeof(a), a, typeof(b), b FROM t1; } } {text 1 integer -2 text 5.4e-08 real 5.4e-08} # Make sure that when a column is added by ALTER TABLE ADD COLUMN and has # a default value that the default value is used by aggregate functions. # do_test alter-8.1 { execsql { CREATE TABLE t2(a INTEGER); |
︙ | ︙ |