Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Changes to lemon to generate additional comments in the output file and to remove unreachable code. Additional test cases for improved test coverage. (CVS 4736) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2a0bc1e186532a0bfe36ca18fda74a5e |
User & Date: | drh 2008-01-22 01:48:06 |
Context
2008-01-22
| ||
11:50 | Move the test (sqlite3_simulate_device) functionality out of the main code and into a test vfs. (CVS 4737) (check-in: 17e7bd6c user: danielk1977 tags: trunk) | |
01:48 | Changes to lemon to generate additional comments in the output file and to remove unreachable code. Additional test cases for improved test coverage. (CVS 4736) (check-in: 2a0bc1e1 user: drh tags: trunk) | |
2008-01-21
| ||
16:47 | Additional test cases for the RTRIM collation. (CVS 4735) (check-in: 51452d20 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.469 2008/01/22 01:48:06 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
134 135 136 137 138 139 140 141 142 143 144 145 146 147 | void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; db = pParse->db; if( db->mallocFailed ) return; if( pParse->nested ) return; if( !pParse->pVdbe ){ if( pParse->rc==SQLITE_OK && pParse->nErr ){ pParse->rc = SQLITE_ERROR; return; } } | > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; db = pParse->db; if( db->mallocFailed ) return; if( pParse->nested ) return; if( pParse->nErr ) return; if( !pParse->pVdbe ){ if( pParse->rc==SQLITE_OK && pParse->nErr ){ pParse->rc = SQLITE_ERROR; return; } } |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.238 2008/01/22 01:48:06 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ // The type of the data attached to each token is Token. This is also the // default type for non-terminals. |
︙ | ︙ | |||
967 968 969 970 971 972 973 | trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z) trigger_time(C) trigger_event(D) ON fullname(E) foreach_clause when_clause(G). { sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR); A = (Z.n==0?B:Z); } | | | 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 | trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z) trigger_time(C) trigger_event(D) ON fullname(E) foreach_clause when_clause(G). { sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR); A = (Z.n==0?B:Z); } %type trigger_time {int} trigger_time(A) ::= BEFORE. { A = TK_BEFORE; } trigger_time(A) ::= AFTER. { A = TK_AFTER; } trigger_time(A) ::= INSTEAD OF. { A = TK_INSTEAD;} trigger_time(A) ::= . { A = TK_BEFORE; } %type trigger_event {struct TrigEvent} %destructor trigger_event {sqlite3IdListDelete($$.b);} |
︙ | ︙ | |||
1060 1061 1062 1063 1064 1065 1066 | cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). { sqlite3Attach(pParse, F, D, K); } cmd ::= DETACH database_kw_opt expr(D). { sqlite3Detach(pParse, D); } | | | 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). { sqlite3Attach(pParse, F, D, K); } cmd ::= DETACH database_kw_opt expr(D). { sqlite3Detach(pParse, D); } %type key_opt {Expr*} %destructor key_opt {sqlite3ExprDelete($$);} key_opt(A) ::= . { A = 0; } key_opt(A) ::= KEY expr(X). { A = X; } database_kw_opt ::= DATABASE. database_kw_opt ::= . %endif SQLITE_OMIT_ATTACH |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** 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 contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** 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 contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.169 2008/01/22 01:48:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) |
︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | const char *zState = "unknown"; int j; if( db->aDb[i].zName==0 ) continue; sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC); pBt = db->aDb[i].pBt; if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ zState = "closed"; | | | 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 | const char *zState = "unknown"; int j; if( db->aDb[i].zName==0 ) continue; sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC); pBt = db->aDb[i].pBt; if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ zState = "closed"; }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ zState = azLockName[j]; } sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } }else |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** | | | 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. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** ** $Id: prepare.c,v 1.72 2008/01/22 01:48:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. |
︙ | ︙ | |||
640 641 642 643 644 645 646 | int rc; sqlite3_stmt *pNew; const char *zSql; sqlite3 *db; assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); zSql = sqlite3_sql((sqlite3_stmt *)p); | | < < | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 | int rc; sqlite3_stmt *pNew; const char *zSql; sqlite3 *db; assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); zSql = sqlite3_sql((sqlite3_stmt *)p); assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ db = sqlite3VdbeDb(p); assert( sqlite3_mutex_held(db->mutex) ); rc = sqlite3LockAndPrepare(db, zSql, -1, 0, &pNew, 0); if( rc ){ if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; } |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
659 660 661 662 663 664 665 666 667 668 669 670 671 | } case P4_REAL: { sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal); break; } case P4_MEM: { Mem *pMem = pOp->p4.pMem; if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); | > < < | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | } case P4_REAL: { sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal); break; } case P4_MEM: { Mem *pMem = pOp->p4.pMem; assert( (pMem->flags & MEM_Null)==0 ); if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); } break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { sqlite3_vtab *pVtab = pOp->p4.pVtab; sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule); |
︙ | ︙ | |||
2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 | /* ** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero ** or positive integer if {nKey1, pKey1} is less than, equal to or ** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings ** composed by the OP_MakeRecord opcode of the VDBE. */ int sqlite3VdbeRecordCompare( void *userData, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ KeyInfo *pKeyInfo = (KeyInfo*)userData; | > > > | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 | /* ** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero ** or positive integer if {nKey1, pKey1} is less than, equal to or ** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings ** composed by the OP_MakeRecord opcode of the VDBE. ** ** Key1 and Key2 do not have to contain the same number of fields. ** But if the lengths differ, Key2 must be the shorter of the two. */ int sqlite3VdbeRecordCompare( void *userData, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ KeyInfo *pKeyInfo = (KeyInfo*)userData; |
︙ | ︙ | |||
2172 2173 2174 2175 2176 2177 2178 | if( rc==0 ){ if( pKeyInfo->incrKey ){ rc = -1; }else if( !pKeyInfo->prefixIsEqual ){ if( d1<nKey1 ){ rc = 1; }else if( d2<nKey2 ){ | | | 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 | if( rc==0 ){ if( pKeyInfo->incrKey ){ rc = -1; }else if( !pKeyInfo->prefixIsEqual ){ if( d1<nKey1 ){ rc = 1; }else if( d2<nKey2 ){ rc = -1; /* Only occurs on a corrupt database file */ } } }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){ rc = -rc; } |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
940 941 942 943 944 945 946 | return p; } /* ** Create a new sqlite3_value object, containing the value of pExpr. ** ** This only works for very simple expressions that consist of one constant | | | 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | return p; } /* ** Create a new sqlite3_value object, containing the value of pExpr. ** ** This only works for very simple expressions that consist of one constant ** token (i.e. "5", "5.1", "'a string'"). If the expression can ** be converted directly into a value, then the value is allocated and ** a pointer written to *ppVal. The caller is responsible for deallocating ** the value by passing it to sqlite3ValueFree() later on. If the expression ** cannot be converted to a value, then *ppVal is set to NULL. */ int sqlite3ValueFromExpr( sqlite3 *db, /* The database connection */ |
︙ | ︙ |
Changes to test/capi3.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 January 29 # # 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 testing the callback-free C/C++ API. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2003 January 29 # # 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 testing the callback-free C/C++ API. # # $Id: capi3.test,v 1.58 2008/01/22 01:48:09 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the UTF-16 representation of the supplied UTF-8 string $str. # If $nt is true, append two 0x00 bytes as a nul terminator. |
︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 1115 1116 | do_test capi3-17.2 { sqlite3_reset $STMT sqlite3_column_int $STMT 0 } {0} do_test capi3-17.3 { sqlite3_finalize $STMT } {SQLITE_OK} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 | do_test capi3-17.2 { sqlite3_reset $STMT sqlite3_column_int $STMT 0 } {0} do_test capi3-17.3 { sqlite3_finalize $STMT } {SQLITE_OK} # Verify that sqlite3_step() fails with an SQLITE_SCHEMA error # when the statement is prepared with sqlite3_prepare() (not # sqlite3_prepare_v2()) and the schema has changed. # do_test capi3-18.1 { set STMT [sqlite3_prepare db {SELECT * FROM t2} -1 TAIL] sqlite3 db2 test.db db2 eval {CREATE TABLE t3(x)} db2 close breakpoint sqlite3_step $STMT } {SQLITE_ERROR} do_test capi3-18.2 { sqlite3_reset $STMT sqlite3_errcode db } {SQLITE_SCHEMA} do_test capi3-18.3 { sqlite3_errmsg db } {database schema has changed} # The error persist on retry when sqlite3_prepare() has been used. do_test capi3-18.4 { sqlite3_step $STMT } {SQLITE_ERROR} do_test capi3-18.5 { sqlite3_reset $STMT sqlite3_errcode db } {SQLITE_SCHEMA} do_test capi3-18.6 { sqlite3_errmsg db } {database schema has changed} sqlite3_finalize $STMT finish_test |
Changes to test/enc3.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # The focus of this file is testing of the proper handling of conversions # to the native text representation. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # The focus of this file is testing of the proper handling of conversions # to the native text representation. # # $Id: enc3.test,v 1.8 2008/01/22 01:48:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {utf16} { do_test enc3-1.1 { execsql { |
︙ | ︙ | |||
75 76 77 78 79 80 81 | SELECT rowid FROM t2 WHERE a LIKE x'610062002500'; } } {1} } # Try to attach a database with a different encoding. # | | > > > > | > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | SELECT rowid FROM t2 WHERE a LIKE x'610062002500'; } } {1} } # Try to attach a database with a different encoding. # ifcapable {utf16 && shared_cache} { db close file delete -force test8.db test8.db-journal set ::enable_shared_cache [sqlite3_enable_shared_cache 1] sqlite3 dbaux test8.db sqlite3 db test.db db eval {SELECT 1 FROM sqlite_master LIMIT 1} do_test enc3-3.1 { dbaux eval { PRAGMA encoding='utf8'; CREATE TABLE t1(x); PRAGMA encoding } } {UTF-8} do_test enc3-3.2 { catchsql { ATTACH 'test.db' AS utf16; SELECT 1 FROM utf16.sqlite_master LIMIT 1; } dbaux } {1 {attached databases must use the same text encoding as main database}} dbaux close file delete -force test8.db test8.db-journal sqlite3_enable_shared_cache $::enable_shared_cache } finish_test |
Changes to test/expr.test.
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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # | | | 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # # $Id: expr.test,v 1.62 2008/01/22 01:48:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a table to work with. # execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)} |
︙ | ︙ | |||
168 169 170 171 172 173 174 175 176 177 178 179 180 181 | test_expr expr-2.20 {r1=2.34, r2=2.34} {r2<>r1} 0 test_expr expr-2.21 {r1=2.34, r2=2.34} {r2==r1} 1 test_expr expr-2.22 {r1=1.23, r2=2.34} {min(r1,r2,r1+r2,r1-r2)} {-1.11} test_expr expr-2.23 {r1=1.23, r2=2.34} {max(r1,r2,r1+r2,r1-r2)} {3.57} test_expr expr-2.24 {r1=25.0, r2=11.0} {r1%r2} 3.0 test_expr expr-2.25 {r1=1.23, r2=NULL} {coalesce(r1+r2,99.0)} 99.0 test_expr expr-2.26 {r1=1e300, r2=1e300} {coalesce((r1*r2)*0.0,99.0)} 99.0 test_expr expr-2.27 {r1=1.1, r2=0.0} {r1/r2} {{}} test_expr expr-2.28 {r1=1.1, r2=0.0} {r1%r2} {{}} test_expr expr-3.1 {t1='abc', t2='xyz'} {t1<t2} 1 test_expr expr-3.2 {t1='xyz', t2='abc'} {t1<t2} 0 test_expr expr-3.3 {t1='abc', t2='abc'} {t1<t2} 0 test_expr expr-3.4 {t1='abc', t2='xyz'} {t1<=t2} 1 | > | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | test_expr expr-2.20 {r1=2.34, r2=2.34} {r2<>r1} 0 test_expr expr-2.21 {r1=2.34, r2=2.34} {r2==r1} 1 test_expr expr-2.22 {r1=1.23, r2=2.34} {min(r1,r2,r1+r2,r1-r2)} {-1.11} test_expr expr-2.23 {r1=1.23, r2=2.34} {max(r1,r2,r1+r2,r1-r2)} {3.57} test_expr expr-2.24 {r1=25.0, r2=11.0} {r1%r2} 3.0 test_expr expr-2.25 {r1=1.23, r2=NULL} {coalesce(r1+r2,99.0)} 99.0 test_expr expr-2.26 {r1=1e300, r2=1e300} {coalesce((r1*r2)*0.0,99.0)} 99.0 test_expr expr-2.26b {r1=1e300, r2=-1e300} {coalesce((r1*r2)*0.0,99.0)} 99.0 test_expr expr-2.27 {r1=1.1, r2=0.0} {r1/r2} {{}} test_expr expr-2.28 {r1=1.1, r2=0.0} {r1%r2} {{}} test_expr expr-3.1 {t1='abc', t2='xyz'} {t1<t2} 1 test_expr expr-3.2 {t1='xyz', t2='abc'} {t1<t2} 0 test_expr expr-3.3 {t1='abc', t2='abc'} {t1<t2} 0 test_expr expr-3.4 {t1='abc', t2='xyz'} {t1<=t2} 1 |
︙ | ︙ |
Changes to test/mallocF.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This test script checks that tickets #2794, #2795, #2796, and #2797 # have been fixed. # | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This test script checks that tickets #2794, #2795, #2796, and #2797 # have been fixed. # # $Id: mallocF.test,v 1.3 2008/01/22 01:48:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { puts "Skipping mallocF tests: not compiled with -DSQLITE_MEMDEBUG..." finish_test return } source $testdir/malloc_common.tcl # tickets #2794 and #2795 and #2797 # |
︙ | ︙ |
Added test/mallocG.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | # 2007 Aug 29 # # 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 test script checks malloc failures in various obscure operations. # # $Id: mallocG.test,v 1.1 2008/01/22 01:48:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # ifcapable !memdebug { puts "Skipping mallocG tests: not compiled with -DSQLITE_MEMDEBUG..." finish_test return } source $testdir/malloc_common.tcl # Malloc failures while opening a database connection. # do_malloc_test malloeG-1 -tclbody { db close sqlite3 db test.db } do_malloc_test mallocG-2 -sqlprep { CREATE TABLE t1(x, y); CREATE TABLE t2(x INTEGER PRIMARY KEY); } -sqlbody { SELECT y FROM t1 WHERE x IN t2; } finish_test |
Changes to test/sqllimits1.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains tests to verify that the limits defined in # sqlite source file limits.h are enforced. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file contains tests to verify that the limits defined in # sqlite source file limits.h are enforced. # # $Id: sqllimits1.test,v 1.23 2008/01/22 01:48:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Test organization: # # sqllimits-1.*: SQLITE_MAX_LENGTH |
︙ | ︙ | |||
183 184 185 186 187 188 189 190 191 192 193 194 195 196 | append sql [string repeat $tail $N] catchsql $sql } {1 {String or BLOB exceeded size limit}} do_test sqllimits-2.2 { set ::SQLITE_MAX_SQL_LENGTH 0 catchsql $sql } {0 1} #-------------------------------------------------------------------- # Test cases sqllimits-3.* test that the limit set using the # max_page_count pragma. # do_test sqllimits-3.1 { execsql { | > > > > > > > > > > > > > > > > > | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | append sql [string repeat $tail $N] catchsql $sql } {1 {String or BLOB exceeded size limit}} do_test sqllimits-2.2 { set ::SQLITE_MAX_SQL_LENGTH 0 catchsql $sql } {0 1} do_test sqllimits-2.3 { set ::SQLITE_MAX_SQL_LENGTH 50000 set sql "SELECT 1 WHERE 1==1" set tail " /* A comment to take up space in order to make the string\ longer without increasing the expression depth */\ AND 1 == 1" set N [expr {($::SQLITE_MAX_SQL_LENGTH / [string length $tail])+1}] append sql [string repeat $tail $N] set nbytes [string length $sql] append sql { AND 0} set rc [catch {sqlite3_prepare $DB $sql $nbytes TAIL} STMT] lappend rc $STMT } {1 {(18) statement too long}} do_test sqllimits-2.4 { sqlite3_errmsg $DB } {statement too long} #-------------------------------------------------------------------- # Test cases sqllimits-3.* test that the limit set using the # max_page_count pragma. # do_test sqllimits-3.1 { execsql { |
︙ | ︙ |
Changes to tool/lemon.c.
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 | LEFT, RIGHT, NONE, UNK } assoc; /* Associativity if predecence is defined */ char *firstset; /* First-set for all rules of this symbol */ Boolean lambda; /* True if NT and can generate an empty string */ char *destructor; /* Code which executes whenever this symbol is ** popped from the stack during error processing */ int destructorln; /* Line number of destructor code */ char *datatype; /* The data type of information held by this ** object. Only used if type==NONTERMINAL */ int dtnum; /* The data type number. In the parser, the value ** stack is a union. The .yy%d element of this | > | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | LEFT, RIGHT, NONE, UNK } assoc; /* Associativity if predecence is defined */ char *firstset; /* First-set for all rules of this symbol */ Boolean lambda; /* True if NT and can generate an empty string */ int useCnt; /* Number of times used */ char *destructor; /* Code which executes whenever this symbol is ** popped from the stack during error processing */ int destructorln; /* Line number of destructor code */ char *datatype; /* The data type of information held by this ** object. Only used if type==NONTERMINAL */ int dtnum; /* The data type number. In the parser, the value ** stack is a union. The .yy%d element of this |
︙ | ︙ | |||
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 | Symbol_init(); State_init(); lem.argv0 = argv[0]; lem.filename = OptArg(0); lem.basisflag = basisflag; Symbol_new("$"); lem.errsym = Symbol_new("error"); /* Parse the input file */ Parse(&lem); if( lem.errorcnt ) exit(lem.errorcnt); if( lem.nrule==0 ){ fprintf(stderr,"Empty grammar.\n"); exit(1); | > | 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 | Symbol_init(); State_init(); lem.argv0 = argv[0]; lem.filename = OptArg(0); lem.basisflag = basisflag; Symbol_new("$"); lem.errsym = Symbol_new("error"); lem.errsym->useCnt = 0; /* Parse the input file */ Parse(&lem); if( lem.errorcnt ) exit(lem.errorcnt); if( lem.nrule==0 ){ fprintf(stderr,"Empty grammar.\n"); exit(1); |
︙ | ︙ | |||
2132 2133 2134 2135 2136 2137 2138 | } psp->prevrule = rp; } psp->state = WAITING_FOR_DECL_OR_RULE; }else if( isalpha(x[0]) ){ if( psp->nrhs>=MAXRHS ){ ErrorMsg(psp->filename,psp->tokenlineno, | | | 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 | } psp->prevrule = rp; } psp->state = WAITING_FOR_DECL_OR_RULE; }else if( isalpha(x[0]) ){ if( psp->nrhs>=MAXRHS ){ ErrorMsg(psp->filename,psp->tokenlineno, "Too many symbols on RHS of rule beginning at \"%s\".", x); psp->errorcnt++; psp->state = RESYNC_AFTER_RULE_ERROR; }else{ psp->rhs[psp->nrhs] = Symbol_new(x); psp->alias[psp->nrhs] = 0; psp->nrhs++; |
︙ | ︙ | |||
3426 3427 3428 3429 3430 3431 3432 | fprintf(out,"typedef union {\n"); lineno++; fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; for(i=0; i<arraysize; i++){ if( types[i]==0 ) continue; fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; free(types[i]); } | > | > | 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 | fprintf(out,"typedef union {\n"); lineno++; fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++; for(i=0; i<arraysize; i++){ if( types[i]==0 ) continue; fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; free(types[i]); } if( lemp->errsym->useCnt ){ fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; } free(stddt); free(types); fprintf(out,"} YYMINORTYPE;\n"); lineno++; *plineno = lineno; } /* |
︙ | ︙ | |||
3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 | ** Compare to axset structures for sorting purposes */ static int axset_compare(const void *a, const void *b){ struct axset *p1 = (struct axset*)a; struct axset *p2 = (struct axset*)b; return p2->nAction - p1->nAction; } /* Generate C source code for the parser */ void ReportTable(lemp, mhflag) struct lemon *lemp; int mhflag; /* Output in makeheaders format if true */ { FILE *out, *in; | > > > > > > > > > > > > > > > > > > > | 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 | ** Compare to axset structures for sorting purposes */ static int axset_compare(const void *a, const void *b){ struct axset *p1 = (struct axset*)a; struct axset *p2 = (struct axset*)b; return p2->nAction - p1->nAction; } /* ** Write text on "out" that describes the rule "rp". */ static void writeRuleText(FILE *out, struct rule *rp){ int j; fprintf(out,"%s ::=", rp->lhs->name); for(j=0; j<rp->nrhs; j++){ struct symbol *sp = rp->rhs[j]; fprintf(out," %s", sp->name); if( sp->type==MULTITERMINAL ){ int k; for(k=1; k<sp->nsubsym; k++){ fprintf(out,"|%s",sp->subsym[k]->name); } } } } /* Generate C source code for the parser */ void ReportTable(lemp, mhflag) struct lemon *lemp; int mhflag; /* Output in makeheaders format if true */ { FILE *out, *in; |
︙ | ︙ | |||
3571 3572 3573 3574 3575 3576 3577 | fprintf(out,"#define %sARG_STORE\n",name); lineno++; } if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; | > | | > | 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 | fprintf(out,"#define %sARG_STORE\n",name); lineno++; } if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; if( lemp->errsym->useCnt ){ fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; } if( lemp->has_fallback ){ fprintf(out,"#define YYFALLBACK 1\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); /* Generate the action table and its associates: ** |
︙ | ︙ | |||
3771 3772 3773 3774 3775 3776 3777 | /* Generate a table containing a text string that describes every ** rule in the rule set of the grammer. This information is used ** when tracing REDUCE actions. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ assert( rp->index==i ); | | < < | < < < < < < < | > | > | > | > | 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 | /* Generate a table containing a text string that describes every ** rule in the rule set of the grammer. This information is used ** when tracing REDUCE actions. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ assert( rp->index==i ); fprintf(out," /* %3d */ \"", i); writeRuleText(out, rp); fprintf(out,"\",\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); /* Generate code which executes every time a symbol is popped from ** the stack while processing errors or while destroying the parser. ** (In other words, generate the %destructor actions) */ if( lemp->tokendest ){ for(i=0; i<lemp->nsymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type!=TERMINAL ) continue; fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; } for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++); if( i<lemp->nsymbol ){ emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); fprintf(out," break;\n"); lineno++; } } if( lemp->vardest ){ struct symbol *dflt_sp = 0; for(i=0; i<lemp->nsymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->index<=0 || sp->destructor!=0 ) continue; fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; dflt_sp = sp; } if( dflt_sp!=0 ){ emit_destructor_code(out,dflt_sp,lemp,&lineno); fprintf(out," break;\n"); lineno++; } } for(i=0; i<lemp->nsymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; /* Combine duplicate destructors into a single case */ for(j=i+1; j<lemp->nsymbol; j++){ struct symbol *sp2 = lemp->symbols[j]; if( sp2 && sp2->type!=TERMINAL && sp2->destructor && sp2->dtnum==sp->dtnum && strcmp(sp->destructor,sp2->destructor)==0 ){ fprintf(out," case %d: /* %s */\n", sp2->index, sp2->name); lineno++; sp2->destructor = 0; } } emit_destructor_code(out,lemp->symbols[i],lemp,&lineno); fprintf(out," break;\n"); lineno++; } |
︙ | ︙ | |||
3858 3859 3860 3861 3862 3863 3864 | /* Generate code which execution during each REDUCE action */ for(rp=lemp->rule; rp; rp=rp->next){ translate_code(lemp, rp); } for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; if( rp->code==0 ) continue; | | > > | > > | 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 | /* Generate code which execution during each REDUCE action */ for(rp=lemp->rule; rp; rp=rp->next){ translate_code(lemp, rp); } for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; if( rp->code==0 ) continue; fprintf(out," case %d: /* ", rp->index); writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ if( rp2->code==rp->code ){ fprintf(out," case %d: /* ", rp2->index); writeRuleText(out, rp2); fprintf(out," */\n"); lineno++; rp2->code = 0; } } emit_code(out,rp,lemp,&lineno); fprintf(out," break;\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); |
︙ | ︙ | |||
4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 | sp->fallback = 0; sp->prec = -1; sp->assoc = UNK; sp->firstset = 0; sp->lambda = LEMON_FALSE; sp->destructor = 0; sp->datatype = 0; Symbol_insert(sp,sp->name); } return sp; } /* Compare two symbols for working purposes ** ** Symbols that begin with upper case letters (terminals or tokens) ** must sort before symbols that begin with lower case letters | > > | 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 | sp->fallback = 0; sp->prec = -1; sp->assoc = UNK; sp->firstset = 0; sp->lambda = LEMON_FALSE; sp->destructor = 0; sp->datatype = 0; sp->useCnt = 0; Symbol_insert(sp,sp->name); } sp->useCnt++; return sp; } /* Compare two symbols for working purposes ** ** Symbols that begin with upper case letters (terminals or tokens) ** must sort before symbols that begin with lower case letters |
︙ | ︙ |
Changes to tool/lempar.c.
︙ | ︙ | |||
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | int yymajor, /* The major token code number */ ParseTOKENTYPE yyminor /* The value for the token */ ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; int yyact; /* The parser action. */ int yyendofinput; /* True if we are at the end of input */ int yyerrorhit = 0; /* True if yymajor has invoked an error */ yyParser *yypParser; /* The parser */ /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; if( yypParser->yyidx<0 ){ #if YYSTACKDEPTH<=0 if( yypParser->yystksz <=0 ){ | > > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 | int yymajor, /* The major token code number */ ParseTOKENTYPE yyminor /* The value for the token */ ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; int yyact; /* The parser action. */ int yyendofinput; /* True if we are at the end of input */ #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif yyParser *yypParser; /* The parser */ /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; if( yypParser->yyidx<0 ){ #if YYSTACKDEPTH<=0 if( yypParser->yystksz <=0 ){ |
︙ | ︙ | |||
683 684 685 686 687 688 689 | if( yyendofinput && yypParser->yyidx>=0 ){ yymajor = 0; }else{ yymajor = YYNOCODE; } }else if( yyact < YYNSTATE + YYNRULE ){ yy_reduce(yypParser,yyact-YYNSTATE); | > | > > | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | if( yyendofinput && yypParser->yyidx>=0 ){ yymajor = 0; }else{ yymajor = YYNOCODE; } }else if( yyact < YYNSTATE + YYNRULE ){ yy_reduce(yypParser,yyact-YYNSTATE); }else{ assert( yyact == YY_ERROR_ACTION ); #ifdef YYERRORSYMBOL int yymx; #endif #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); } #endif #ifdef YYERRORSYMBOL /* A syntax error has occurred. |
︙ | ︙ | |||
765 766 767 768 769 770 771 | yypParser->yyerrcnt = 3; yy_destructor(yymajor,&yyminorunion); if( yyendofinput ){ yy_parse_failed(yypParser); } yymajor = YYNOCODE; #endif | < < < | 770 771 772 773 774 775 776 777 778 779 780 | yypParser->yyerrcnt = 3; yy_destructor(yymajor,&yyminorunion); if( yyendofinput ){ yy_parse_failed(yypParser); } yymajor = YYNOCODE; #endif } }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); return; } |