Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Create table now works with sqlite3NestedParse. This changed uncovered a latent bug in xprintf which is also fixed. (CVS 2069) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b0506bdd701339d63166ada065445776 |
User & Date: | drh 2004-11-05 17:17:50.000 |
Context
2004-11-05
| ||
20:58 | Use sqlite3NestedParse to implement CREATE INDEX. (CVS 2070) (check-in: 47d8ebdaad user: drh tags: trunk) | |
17:17 | Create table now works with sqlite3NestedParse. This changed uncovered a latent bug in xprintf which is also fixed. (CVS 2069) (check-in: b0506bdd70 user: drh tags: trunk) | |
16:37 | Do not truncate a database file until after fsync() has been called on the journal. (CVS 2068) (check-in: cfee7f4a00 user: danielk1977 tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** <<<<<<< build.c | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** <<<<<<< build.c ** $Id: build.c,v 1.268 2004/11/05 17:17:50 drh Exp $ ======= ** $Id: build.c,v 1.268 2004/11/05 17:17:50 drh Exp $ >>>>>>> 1.262 */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to |
︙ | ︙ | |||
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 | pTable->nCol = 0; pTable->aCol = 0; pTable->iPKey = -1; pTable->pIndex = 0; pTable->iDb = iDb; if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; /* Begin generating the code that will insert the table record into ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause ** indices to be created and the table record must come before the ** indices. Hence, the record number for the table must be allocated ** now. */ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3BeginWriteOperation(pParse, 0, iDb); /* Every time a new table is created the file-format ** and encoding meta-values are set in the database, in ** case this is the first table created. */ sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); sqlite3OpenMasterTable(v, iDb); sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); } } | > > > > > > > > > > > > > > > | 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 | pTable->nCol = 0; pTable->aCol = 0; pTable->iPKey = -1; pTable->pIndex = 0; pTable->iDb = iDb; if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; /* If this is the magic sqlite_sequence table used by autoincrement, ** then record a pointer to this table in the main database structure ** so that INSERT can find the table easily. */ #ifndef SQLITE_OMIT_AUTOINCREMENT if( strcmp(zName, "sqlite_sequence")==0 ){ assert( db->aDb[iDb].pSeqTab==0 ); db->aDb[iDb].pSeqTab = pTable; } #endif /* Begin generating the code that will insert the table record into ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause ** indices to be created and the table record must come before the ** indices. Hence, the record number for the table must be allocated ** now. */ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3BeginWriteOperation(pParse, 0, iDb); /* Every time a new table is created the file-format ** and encoding meta-values are set in the database, in ** case this is the first table created. */ sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); /* This just creates a place-holder record in the sqlite_master table. ** The record created does not contain anything yet. It will be replaced ** by the real entry in code generated at sqlite3EndTable(). */ sqlite3OpenMasterTable(v, iDb); sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); } } |
︙ | ︙ | |||
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 | zType = pTab->aCol[iCol].zType; } if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){ pTab->iPKey = iCol; pTab->keyConf = onError; pTab->autoInc = autoInc; }else if( autoInc ){ sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " "INTEGER PRIMARY KEY"); }else{ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0); pList = 0; } primary_key_exit: sqlite3ExprListDelete(pList); | > > | 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 | zType = pTab->aCol[iCol].zType; } if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){ pTab->iPKey = iCol; pTab->keyConf = onError; pTab->autoInc = autoInc; }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " "INTEGER PRIMARY KEY"); #endif }else{ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0); pList = 0; } primary_key_exit: sqlite3ExprListDelete(pList); |
︙ | ︙ | |||
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 | ** ** If this is a TEMPORARY table, write the entry into the auxiliary ** file instead of into the main database file. */ if( !db->init.busy ){ int n; Vdbe *v; v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( p->pSelect==0 ){ /* A regular table */ sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); }else{ /* A view */ sqlite3VdbeAddOp(v, OP_Integer, 0, 0); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT ** statement to populate the new table. The root-page number for the ** new table is on the top of the vdbe stack. | > > > > > > > > > > > | 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 | ** ** If this is a TEMPORARY table, write the entry into the auxiliary ** file instead of into the main database file. */ if( !db->init.busy ){ int n; Vdbe *v; char *zType; /* "view" or "table" */ char *zType2; /* "VIEW" or "TABLE" */ char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ v = sqlite3GetVdbe(pParse); if( v==0 ) return; /* Create the rootpage for the new table and push it onto the stack. ** A view has no rootpage, so just push a zero onto the stack for ** views. Initialize zType at the same time. */ if( p->pSelect==0 ){ /* A regular table */ sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); zType = "table"; zType2 = "TABLE"; }else{ /* A view */ sqlite3VdbeAddOp(v, OP_Integer, 0, 0); zType = "view"; zType2 = "VIEW"; } sqlite3VdbeAddOp(v, OP_Close, 0, 0); /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT ** statement to populate the new table. The root-page number for the ** new table is on the top of the vdbe stack. |
︙ | ︙ | |||
1387 1388 1389 1390 1391 1392 1393 | p->nCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; sqlite3DeleteTable(0, pSelTab); } } | | > | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 | p->nCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; sqlite3DeleteTable(0, pSelTab); } } #if 0 sqlite3OpenMasterTable(v, p->iDb); sqlite3VdbeOp3(v, OP_String8, 0, 0, p->pSelect==0?"table":"view",P3_STATIC); sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0); sqlite3VdbeAddOp(v, OP_Pull, 3, 0); |
︙ | ︙ | |||
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 | sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat, 0, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); sqlite3ChangeCookie(db, v, p->iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0, sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); } /* Add the table to the in-memory representation of the database. */ if( db->init.busy && pParse->nErr==0 ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1446 1447 1448 1449 1450 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 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 | sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); sqlite3VdbeAddOp(v, OP_Concat, 0, 0); } sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); sqlite3ChangeCookie(db, v, p->iDb); sqlite3VdbeAddOp(v, OP_Close, 0, 0); #endif /* Compute the complete text of the CREATE statement */ if( pSelect ){ zStmt = createTableStmt(p); }else{ n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z); } /* A slot for the record has already been allocated in the ** SQLITE_MASTER table. We just need to update that slot with all ** the information we've collected. The rowid for the preallocated ** slot is the 2nd item on the stack. The top of the stack is the ** root page for the new table (or a 0 if this is a view). */ sqlite3NestedParse(pParse, "UPDATE %Q.%s " "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q " "WHERE rowid=#1", db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb), zType, p->zName, p->zName, zStmt ); sqliteFree(zStmt); /* Reparse everything to update our internal data structures */ sqlite3ChangeCookie(db, v, p->iDb); sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0, sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); } /* Add the table to the in-memory representation of the database. */ if( db->init.busy && pParse->nErr==0 ){ |
︙ | ︙ | |||
1644 1645 1646 1647 1648 1649 1650 | ** location iTable. The following code modifis the sqlite_master table to ** reflect this. ** ** The "#0" in the SQL is a special constant that means whatever value ** is on the top of the stack. See sqlite3RegisterExpr(). */ sqlite3NestedParse(pParse, | | | 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 | ** location iTable. The following code modifis the sqlite_master table to ** reflect this. ** ** The "#0" in the SQL is a special constant that means whatever value ** is on the top of the stack. See sqlite3RegisterExpr(). */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0", pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable); #endif } /* ** Write VDBE code to erase table pTab and all associated indices on disk. ** Code to update the sqlite_master tables and internal schema definitions |
︙ | ︙ | |||
1789 1790 1791 1792 1793 1794 1795 | ** table. The program name loops through the master table and deletes ** every row that refers to a table of the same name as the one being ** dropped. Triggers are handled seperately because a trigger can be ** created in the temp database that refers to a table in another ** database. */ sqlite3NestedParse(pParse, | | | 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 | ** table. The program name loops through the master table and deletes ** every row that refers to a table of the same name as the one being ** dropped. Triggers are handled seperately because a trigger can be ** created in the temp database that refers to a table in another ** database. */ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", db->aDb[pTab->iDb].zName, SCHEMA_TABLE(pTab->iDb), pTab->zName); if( !isView ){ destroyTable(pParse, pTab); } sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0); } sqliteViewResetAll(db, iDb); |
︙ | ︙ |
Changes to src/delete.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 C code routines that are called by the parser ** to handle DELETE FROM statements. ** | | | 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 C code routines that are called by the parser ** to handle DELETE FROM statements. ** ** $Id: delete.c,v 1.88 2004/11/05 17:17:50 drh Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
166 167 168 169 170 171 172 | /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ){ goto delete_from_cleanup; } | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ){ goto delete_from_cleanup; } if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, row_triggers_exist, pTab->iDb); /* If we are trying to delete from a view, construct that view into ** a temporary table. */ if( isView ){ Select *pView = sqlite3SelectDup(pTab->pSelect); |
︙ | ︙ | |||
291 292 293 294 295 296 297 | /* This is the beginning of the delete loop when there are no ** row triggers */ if( !row_triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); } /* Delete the row */ | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | /* This is the beginning of the delete loop when there are no ** row triggers */ if( !row_triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); } /* Delete the row */ sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); } /* If there are row triggers, close all cursors then invoke ** the AFTER triggers */ if( row_triggers_exist ){ if( !isView ){ |
︙ | ︙ |
Changes to src/insert.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 C code routines that are called by the parser ** to handle INSERT statements 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 C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.123 2004/11/05 17:17:50 drh Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity ** string for index pIdx. A column affinity string has one character ** for each column in the table, according to the affinity of the column: |
︙ | ︙ | |||
258 259 260 261 262 263 264 | } } /* Allocate a VDBE */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | } } /* Allocate a VDBE */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); /* if there are row triggers, allocate a temp table for new.* references. */ if( row_triggers_exist ){ newIdx = pParse->nTab++; } |
︙ | ︙ | |||
995 996 997 998 999 1000 1001 | sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); sqlite3TableAffinityStr(v, pTab); if( newIdx>=0 ){ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); } | > > > | > | 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); sqlite3TableAffinityStr(v, pTab); if( newIdx>=0 ){ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); } if( pParse->nested ){ pik_flags = 0; }else{ pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); } sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags); if( isUpdate && recnoChng ){ sqlite3VdbeAddOp(v, OP_Pop, 1, 0); } } |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | } et_info; /* ** Allowed values for et_info.flags */ #define FLAG_SIGNED 1 /* True if the value to convert is signed */ #define FLAG_INTERN 2 /* True if for internal use only */ /* ** The following table is searched linearly, so it is good to put the ** most frequently used conversion types first. */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, | > | | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | } et_info; /* ** Allowed values for et_info.flags */ #define FLAG_SIGNED 1 /* True if the value to convert is signed */ #define FLAG_INTERN 2 /* True if for internal use only */ #define FLAG_STRING 4 /* Allow infinity precision */ /* ** The following table is searched linearly, so it is good to put the ** most frequently used conversion types first. */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, { 'z', 0, 6, etDYNSTRING, 0, 0 }, { 'q', 0, 4, etSQLESCAPE, 0, 0 }, { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etRADIX, 0, 0 }, { 'x', 16, 0, etRADIX, 16, 1 }, { 'X', 16, 0, etRADIX, 0, 4 }, { 'f', 0, 1, etFLOAT, 0, 0 }, { 'e', 0, 1, etEXP, 30, 0 }, |
︙ | ︙ | |||
292 293 294 295 296 297 298 | c = *++fmt; }else{ while( c>='0' && c<='9' ){ precision = precision*10 + c - '0'; c = *++fmt; } } | < < | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | c = *++fmt; }else{ while( c>='0' && c<='9' ){ precision = precision*10 + c - '0'; c = *++fmt; } } }else{ precision = -1; } /* Get the conversion type modifier */ if( c=='l' ){ flag_long = 1; c = *++fmt; |
︙ | ︙ | |||
323 324 325 326 327 328 329 330 331 332 333 334 335 336 | if( useExtended || (infop->flags & FLAG_INTERN)==0 ){ xtype = infop->type; } break; } } zExtra = 0; /* ** At this point, variables are initialized as follows: ** ** flag_alternateform TRUE if a '#' is present. ** flag_plussign TRUE if a '+' is present. ** flag_leftjustify TRUE if a '-' is present or if the | > > > > > | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | if( useExtended || (infop->flags & FLAG_INTERN)==0 ){ xtype = infop->type; } break; } } zExtra = 0; /* Limit the precision to prevent overflowing buf[] during conversion */ if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){ precision = etBUFSIZE-40; } /* ** At this point, variables are initialized as follows: ** ** flag_alternateform TRUE if a '#' is present. ** flag_plussign TRUE if a '+' is present. ** flag_leftjustify TRUE if a '-' is present or if the |
︙ | ︙ | |||
559 560 561 562 563 564 565 566 567 568 569 570 571 | length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; case etSQLESCAPE: case etSQLESCAPE2: { int i, j, n, c, isnull; char *arg = va_arg(ap,char*); isnull = arg==0; if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); for(i=n=0; (c=arg[i])!=0; i++){ if( c=='\'' ) n++; } | > | > | | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 | length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; case etSQLESCAPE: case etSQLESCAPE2: { int i, j, n, c, isnull; int needQuote; char *arg = va_arg(ap,char*); isnull = arg==0; if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); for(i=n=0; (c=arg[i])!=0; i++){ if( c=='\'' ) n++; } needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ bufpt = zExtra = sqliteMalloc( n ); if( bufpt==0 ) return -1; }else{ bufpt = buf; } j = 0; if( needQuote ) bufpt[j++] = '\''; for(i=0; (c=arg[i])!=0; i++){ bufpt[j++] = c; if( c=='\'' ) bufpt[j++] = c; } if( needQuote ) bufpt[j++] = '\''; bufpt[j] = 0; length = j; if( precision>=0 && precision<length ) length = precision; } break; case etTOKEN: { Token *pToken = va_arg(ap, Token*); |
︙ | ︙ |
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.334 2004/11/05 17:17:50 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** These #defines should enable >2GB file support on Posix if the ** underlying operating system supports it. If the OS lacks |
︙ | ︙ | |||
320 321 322 323 324 325 326 | Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ Hash aFKey; /* Foreign keys indexed by to-table */ u16 flags; /* Flags associated with this database */ u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u8 safety_level; /* How aggressive at synching data to disk */ int cache_size; /* Number of pages to use in the cache */ | > | | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ Hash aFKey; /* Foreign keys indexed by to-table */ u16 flags; /* Flags associated with this database */ u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u8 safety_level; /* How aggressive at synching data to disk */ int cache_size; /* Number of pages to use in the cache */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ void *pAux; /* Auxiliary data. Usually NULL */ void (*xFreeAux)(void*); /* Routine to free pAux */ }; /* ** These macros can be used to test, set, or clear bits in the ** Db.flags field. */ |
︙ | ︙ |
Changes to src/update.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 C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 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 C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.94 2004/11/05 17:17:50 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. ** ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; |
︙ | ︙ | |||
216 217 218 219 220 221 222 | sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, 1, pTab->iDb); /* If we are trying to update a view, construct that view into ** a temporary table. */ if( isView ){ Select *pView; |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1802 1803 1804 1805 1806 1807 1808 | db->nTotalChange += nChange; } /* ** Set a flag in the vdbe to update the change counter when it is finalised ** or reset. */ | | | | 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 | db->nTotalChange += nChange; } /* ** Set a flag in the vdbe to update the change counter when it is finalised ** or reset. */ void sqlite3VdbeCountChanges(Vdbe *v){ v->changeCntOn = 1; } |