Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Support for a future ALTER TABLE command to add columns with default values. (CVS 2367) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9d5abc1ddf6da37563c12d5a0401b89b |
User & Date: | danielk1977 2005-03-09 12:26:51.000 |
Context
2005-03-09
| ||
13:09 | Fix a file corruption bug in CREATE INDEX in auto-vacuum databases. (CVS 2368) (check-in: 64c4c717d3 user: danielk1977 tags: trunk) | |
12:26 | Support for a future ALTER TABLE command to add columns with default values. (CVS 2367) (check-in: 9d5abc1ddf user: danielk1977 tags: trunk) | |
2005-03-02
| ||
05:18 | Print an error message and quit if the regression tests are run as root. Ticket #1153. (CVS 2366) (check-in: 9b96078763 user: drh tags: trunk) | |
Changes
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 ** in order to generate code for 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 ** in order to generate code for DELETE FROM statements. ** ** $Id: delete.c,v 1.101 2005/03/09 12:26:51 danielk1977 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. |
︙ | ︙ | |||
432 433 434 435 436 437 438 439 440 441 442 443 | sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); for(j=0; j<pIdx->nColumn; j++){ int idx = pIdx->aiColumn[j]; if( idx==pTab->iPKey ){ sqlite3VdbeAddOp(v, OP_Dup, j, 0); }else{ sqlite3VdbeAddOp(v, OP_Column, iCur, idx); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); sqlite3IndexAffinityStr(v, pIdx); } | > | 432 433 434 435 436 437 438 439 440 441 442 443 444 | sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); for(j=0; j<pIdx->nColumn; j++){ int idx = pIdx->aiColumn[j]; if( idx==pTab->iPKey ){ sqlite3VdbeAddOp(v, OP_Dup, j, 0); }else{ sqlite3VdbeAddOp(v, OP_Column, iCur, idx); sqlite3ColumnDefault(v, pTab, idx); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); sqlite3IndexAffinityStr(v, pIdx); } |
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.195 2005/03/09 12:26:51 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
399 400 401 402 403 404 405 406 407 408 409 410 411 412 | assert( pNew->token.z==0 ); } pNew->span.z = 0; pNew->pLeft = sqlite3ExprDup(p->pLeft); pNew->pRight = sqlite3ExprDup(p->pRight); pNew->pList = sqlite3ExprListDup(p->pList); pNew->pSelect = sqlite3SelectDup(p->pSelect); return pNew; } void sqlite3TokenCopy(Token *pTo, Token *pFrom){ if( pTo->dyn ) sqliteFree((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; pTo->z = sqliteStrNDup(pFrom->z, pFrom->n); | > | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | assert( pNew->token.z==0 ); } pNew->span.z = 0; pNew->pLeft = sqlite3ExprDup(p->pLeft); pNew->pRight = sqlite3ExprDup(p->pRight); pNew->pList = sqlite3ExprListDup(p->pList); pNew->pSelect = sqlite3SelectDup(p->pSelect); pNew->pTab = p->pTab; return pNew; } void sqlite3TokenCopy(Token *pTo, Token *pFrom){ if( pTo->dyn ) sqliteFree((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; pTo->z = sqliteStrNDup(pFrom->z, pFrom->n); |
︙ | ︙ | |||
843 844 845 846 847 848 849 850 851 852 853 854 855 856 | cntTab++; for(j=0; j < pTab->nCol; j++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; pExpr->pColl = pTab->aCol[j].pColl; break; } } } } #endif /* !defined(SQLITE_OMIT_TRIGGER) */ | > | 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 | cntTab++; for(j=0; j < pTab->nCol; j++, pCol++) { if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ cnt++; pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; pExpr->pColl = pTab->aCol[j].pColl; pExpr->pTab = pTab; break; } } } } #endif /* !defined(SQLITE_OMIT_TRIGGER) */ |
︙ | ︙ | |||
954 955 956 957 958 959 960 961 962 963 964 965 966 967 | pExpr->pLeft = 0; sqlite3ExprDelete(pExpr->pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; if( cnt==1 ){ assert( pNC!=0 ); sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); } return cnt!=1; } /* ** pExpr is a node that defines a function of some kind. It might ** be a syntactic function like "count(x)" or it might be a function | > > > | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | pExpr->pLeft = 0; sqlite3ExprDelete(pExpr->pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; if( cnt==1 ){ assert( pNC!=0 ); sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); if( pMatch && !pMatch->pSelect ){ pExpr->pTab = pMatch->pTab; } } return cnt!=1; } /* ** pExpr is a node that defines a function of some kind. It might ** be a syntactic function like "count(x)" or it might be a function |
︙ | ︙ | |||
1381 1382 1383 1384 1385 1386 1387 | op = pExpr->op; switch( op ){ case TK_COLUMN: { if( !pParse->fillAgg && pExpr->iAgg>=0 ){ sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg); }else if( pExpr->iColumn>=0 ){ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); | < < | < < | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 | op = pExpr->op; switch( op ){ case TK_COLUMN: { if( !pParse->fillAgg && pExpr->iAgg>=0 ){ sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg); }else if( pExpr->iColumn>=0 ){ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn); }else{ sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0); } break; } case TK_INTEGER: { codeInteger(v, pExpr->token.z, pExpr->token.n); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.282 2005/03/09 12:26:51 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and |
︙ | ︙ | |||
254 255 256 257 258 259 260 | if( iDb==0 ){ db->file_format = meta[1]; if( db->file_format==0 ){ /* This happens if the database was initially empty */ db->file_format = 1; } | | > > | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | if( iDb==0 ){ db->file_format = meta[1]; if( db->file_format==0 ){ /* This happens if the database was initially empty */ db->file_format = 1; } if( db->file_format==2 || db->file_format==3 ){ /* File format 2 is treated exactly as file format 1. New ** databases are created with file format 1. */ db->file_format = 1; } } /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. ** file_format==3 Version 3.1.4. ** ** Version 3.0 can only use files with file_format==1. Version 3.1.3 ** can read and write files with file_format==1 or file_format==2. ** Version 3.1.4 can read and write file formats 1, 2 and 3. */ if( meta[1]>3 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); |
︙ | ︙ |
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.167 2005/03/09 12:26:51 danielk1977 Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { if( pParse->zErrMsg==0 ){ |
︙ | ︙ | |||
599 600 601 602 603 604 605 | Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &Z); Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); A = sqlite3Expr(TK_DOT, temp1, temp4, 0); } term(A) ::= INTEGER(X). {A = sqlite3Expr(@X, 0, 0, &X);} term(A) ::= FLOAT(X). {A = sqlite3Expr(@X, 0, 0, &X);} term(A) ::= STRING(X). {A = sqlite3Expr(@X, 0, 0, &X);} | | | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 | Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &Z); Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); A = sqlite3Expr(TK_DOT, temp1, temp4, 0); } term(A) ::= INTEGER(X). {A = sqlite3Expr(@X, 0, 0, &X);} term(A) ::= FLOAT(X). {A = sqlite3Expr(@X, 0, 0, &X);} term(A) ::= STRING(X). {A = sqlite3Expr(@X, 0, 0, &X);} term(A) ::= BLOB(X). {A = sqlite3Expr(@X, 0, 0, &X);} expr(A) ::= REGISTER(X). {A = sqlite3RegisterExpr(pParse, &X);} expr(A) ::= VARIABLE(X). { Token *pToken = &X; Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); sqlite3ExprAssignVarNumber(pParse, pExpr); } expr(A) ::= ID(X) LP exprlist(Y) RP(E). { |
︙ | ︙ |
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.372 2005/03/09 12:26:51 danielk1977 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 |
︙ | ︙ | |||
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | ** gives a different answer at different times during statement processing ** then iTable is the address of a subroutine that computes the subquery. ** ** The Expr.pSelect field points to a SELECT statement. The SELECT might ** be the right operand of an IN operator. Or, if a scalar SELECT appears ** in an expression the opcode is TK_SELECT and Expr.pSelect is the only ** operand. */ struct Expr { u8 op; /* Operation performed by this node */ char affinity; /* The affinity of the column or 0 if not a column */ u8 iDb; /* Database referenced by this expression */ u8 flags; /* Various flags. See below */ CollSeq *pColl; /* The collation type of the column or 0 */ Expr *pLeft, *pRight; /* Left and right subnodes */ ExprList *pList; /* A list of expressions used as function arguments ** or in "<expr> IN (<expr-list)" */ Token token; /* An operand token */ Token span; /* Complete text of the expression */ int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the ** iColumn-th field of the iTable-th table. */ int iAgg; /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull ** result from the iAgg-th element of the aggregator */ int iAggCtx; /* The value to pass as P1 of OP_AggGet. */ Select *pSelect; /* When the expression is a sub-select. Also the ** right side of "<expr> IN (<select>)" */ }; /* ** The following are the meanings of bits in the Expr.flags field. */ #define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ #define EP_Agg 0x0002 /* Contains one or more aggregate functions */ | > > > > > | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | ** gives a different answer at different times during statement processing ** then iTable is the address of a subroutine that computes the subquery. ** ** The Expr.pSelect field points to a SELECT statement. The SELECT might ** be the right operand of an IN operator. Or, if a scalar SELECT appears ** in an expression the opcode is TK_SELECT and Expr.pSelect is the only ** operand. ** ** If the Expr is of type OP_Column, and the table it is selecting from ** is a disk table or the "old.*" pseudo-table, then pTab points to the ** corresponding table definition. */ struct Expr { u8 op; /* Operation performed by this node */ char affinity; /* The affinity of the column or 0 if not a column */ u8 iDb; /* Database referenced by this expression */ u8 flags; /* Various flags. See below */ CollSeq *pColl; /* The collation type of the column or 0 */ Expr *pLeft, *pRight; /* Left and right subnodes */ ExprList *pList; /* A list of expressions used as function arguments ** or in "<expr> IN (<expr-list)" */ Token token; /* An operand token */ Token span; /* Complete text of the expression */ int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the ** iColumn-th field of the iTable-th table. */ int iAgg; /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull ** result from the iAgg-th element of the aggregator */ int iAggCtx; /* The value to pass as P1 of OP_AggGet. */ Select *pSelect; /* When the expression is a sub-select. Also the ** right side of "<expr> IN (<select>)" */ Table *pTab; /* Table for OP_Column expressions. */ }; /* ** The following are the meanings of bits in the Expr.flags field. */ #define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ #define EP_Agg 0x0002 /* Contains one or more aggregate functions */ |
︙ | ︙ | |||
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8); void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(); sqlite3_value *sqlite3GetTransientValue(sqlite3*db); extern const unsigned char sqlite3UpperToLower[]; void sqlite3RootPageMoved(Db*, int, int); void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3AlterFunctions(sqlite3*); void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); void sqlite3CodeSubselect(Parse *, Expr *); int sqlite3SelectResolve(Parse *, Select *, NameContext *); #endif | > > > | 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 | const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8); void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(); sqlite3_value *sqlite3GetTransientValue(sqlite3*db); int sqlite3ValueFromExpr(Expr *, u8, u8, sqlite3_value **); void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); extern const unsigned char sqlite3UpperToLower[]; void sqlite3RootPageMoved(Db*, int, int); void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3AlterFunctions(sqlite3*); void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); void sqlite3CodeSubselect(Parse *, Expr *); int sqlite3SelectResolve(Parse *, Select *, NameContext *); void sqlite3ColumnDefault(Vdbe *, Table *, int); #endif |
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 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | ** 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.105 2005/03/09 12:26:51 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The most recently coded instruction was an OP_Column to retrieve column ** 'i' of table pTab. This routine sets the P3 parameter of the ** OP_Column to the default value, if any. ** ** The default value of a column is specified by a DEFAULT clause in the ** column definition. This was either supplied by the user when the table ** was created, or added later to the table definition by an ALTER TABLE ** command. If the latter, then the row-records in the table btree on disk ** may not contain a value for the column and the default value, taken ** from the P3 parameter of the OP_Column instruction, is returned instead. ** If the former, then all row-records are guaranteed to include a value ** for the column and the P3 value is not required. ** ** Column definitions created by an ALTER TABLE command may only have ** literal default values specified: a number, null or a string. (If a more ** complicated default expression value was provided, it is evaluated ** when the ALTER TABLE is executed and one of the literal values written ** into the sqlite_master table.) ** ** Therefore, the P3 parameter is only required if the default value for ** the column is a literal number, string or null. The sqlite3ValueFromExpr() ** function is capable of transforming these types of expressions into ** sqlite3_value objects. */ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){ if( pTab && !pTab->pSelect ){ sqlite3_value *pValue; u8 enc = sqlite3VdbeDb(v)->enc; Column *pCol = &pTab->aCol[i]; sqlite3ValueFromExpr(pCol->pDflt, enc, pCol->affinity, &pValue); sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM); } } /* ** Process an UPDATE statement. ** ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; ** \_______/ \________/ \______/ \________________/ * onError pTabList pChanges pWhere |
︙ | ︙ | |||
290 291 292 293 294 295 296 297 298 299 300 301 302 303 | if( i==pTab->iPKey ){ sqlite3VdbeAddOp(v, OP_String8, 0, 0); continue; } j = aXRef[i]; if( j<0 ){ sqlite3VdbeAddOp(v, OP_Column, iCur, i); }else{ sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); if( !isView ){ sqlite3TableAffinityStr(v, pTab); | > | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | if( i==pTab->iPKey ){ sqlite3VdbeAddOp(v, OP_String8, 0, 0); continue; } j = aXRef[i]; if( j<0 ){ sqlite3VdbeAddOp(v, OP_Column, iCur, i); sqlite3ColumnDefault(v, pTab, i); }else{ sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); if( !isView ){ sqlite3TableAffinityStr(v, pTab); |
︙ | ︙ | |||
374 375 376 377 378 379 380 381 382 383 384 385 386 387 | if( i==pTab->iPKey ){ sqlite3VdbeAddOp(v, OP_String8, 0, 0); continue; } j = aXRef[i]; if( j<0 ){ sqlite3VdbeAddOp(v, OP_Column, iCur, i); }else{ sqlite3ExprCode(pParse, pChanges->a[j].pExpr); } } /* Do constraint checks */ | > | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | if( i==pTab->iPKey ){ sqlite3VdbeAddOp(v, OP_String8, 0, 0); continue; } j = aXRef[i]; if( j<0 ){ sqlite3VdbeAddOp(v, OP_Column, iCur, i); sqlite3ColumnDefault(v, pTab, i); }else{ sqlite3ExprCode(pParse, pChanges->a[j].pExpr); } } /* Do constraint checks */ |
︙ | ︙ |
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.457 2005/03/09 12:26:51 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
298 299 300 301 302 303 304 305 306 307 308 309 310 311 | if( ((double)pRec->i)==pRec->r ){ pRec->flags |= MEM_Int; } } } } } #ifdef SQLITE_DEBUG /* ** Write a nice string representation of the contents of cell pMem ** into buffer zBuf, length nBuf. */ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){ | > > > > > > > > | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | if( ((double)pRec->i)==pRec->r ){ pRec->flags |= MEM_Int; } } } } } /* ** Exported version of applyAffinity(). This one works on sqlite3_value*, ** not the internal Mem* type. */ void sqlite3ValueApplyAffinity(sqlite3_value *pVal, u8 affinity, u8 enc){ applyAffinity((Mem *)pVal, affinity, enc); } #ifdef SQLITE_DEBUG /* ** Write a nice string representation of the contents of cell pMem ** into buffer zBuf, length nBuf. */ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf){ |
︙ | ︙ | |||
1673 1674 1675 1676 1677 1678 1679 | if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){ rc = SQLITE_CORRUPT; goto abort_due_to_error; } break; } | | | 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 | if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){ rc = SQLITE_CORRUPT; goto abort_due_to_error; } break; } /* Opcode: Column P1 P2 P3 ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Push onto the stack the value ** of the P2-th column contained in the data. If there are less that (P2+1) ** values in the record, push a NULL onto the stack. ** |
︙ | ︙ | |||
1907 1908 1909 1910 1911 1912 1913 | goto op_column_out; } zData = sMem.z; } sqlite3VdbeSerialGet(zData, aType[p2], pTos); pTos->enc = db->enc; }else{ | > > > | > | 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 | goto op_column_out; } zData = sMem.z; } sqlite3VdbeSerialGet(zData, aType[p2], pTos); pTos->enc = db->enc; }else{ if( pOp->p3 ){ sqlite3VdbeMemShallowCopy(pTos, (Mem *)(pOp->p3), MEM_Static); }else{ pTos->flags = MEM_Null; } } /* If we dynamically allocated space to hold the data (in the ** sqlite3VdbeMemFromBtree() call above) then transfer control of that ** dynamically allocated space over to the pTos structure rather. ** This prevents a memory copy. */ |
︙ | ︙ |
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.93 2005/03/09 12:26:51 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P3_STATIC (-2) /* Pointer to a static string */ #define P3_POINTER (-3) /* P3 is a pointer to some structure or object */ #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #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 */ /* 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. | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P3_STATIC (-2) /* Pointer to a static string */ #define P3_POINTER (-3) /* P3 is a pointer to some structure or object */ #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #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 */ /* 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. |
︙ | ︙ | |||
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | int sqlite3VdbeCurrentAddr(Vdbe*); void sqlite3VdbeTrace(Vdbe*,FILE*); int sqlite3VdbeReset(Vdbe*); int sqliteVdbeSetVariables(Vdbe*,int,const char**); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X #else # define VdbeComment(X) #endif #endif | > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | int sqlite3VdbeCurrentAddr(Vdbe*); void sqlite3VdbeTrace(Vdbe*,FILE*); int sqlite3VdbeReset(Vdbe*); int sqliteVdbeSetVariables(Vdbe*,int,const char**); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X #else # define VdbeComment(X) #endif #endif |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 | sqliteFree(pOp->p3); } if( pOp->p3type==P3_VDBEFUNC ){ VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3; sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqliteFree(pVdbeFunc); } } sqliteFree(p->aOp); } releaseMemArray(p->aVar, p->nVar); sqliteFree(p->aLabel); sqliteFree(p->aStack); releaseMemArray(p->aColName, p->nResColumn*2); | > > > | 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | sqliteFree(pOp->p3); } if( pOp->p3type==P3_VDBEFUNC ){ VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3; sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqliteFree(pVdbeFunc); } if( pOp->p3type==P3_MEM ){ sqlite3ValueFree((sqlite3_value*)pOp->p3); } } sqliteFree(p->aOp); } releaseMemArray(p->aVar, p->nVar); sqliteFree(p->aLabel); sqliteFree(p->aStack); releaseMemArray(p->aColName, p->nResColumn*2); |
︙ | ︙ | |||
1843 1844 1845 1846 1847 1848 1849 | */ void sqlite3ExpirePreparedStatements(sqlite3 *db){ Vdbe *p; for(p = db->pVdbe; p; p=p->pNext){ p->expired = 1; } } | > > > > > > > | 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 | */ void sqlite3ExpirePreparedStatements(sqlite3 *db){ Vdbe *p; for(p = db->pVdbe; p; p=p->pNext){ p->expired = 1; } } /* ** Return the database associated with the Vdbe. */ sqlite3 *sqlite3VdbeDb(Vdbe *v){ return v->db; } |
Changes to src/vdbemem.c.
︙ | ︙ | |||
695 696 697 698 699 700 701 702 703 704 705 706 707 708 | Mem *p = sqliteMalloc(sizeof(*p)); if( p ){ p->flags = MEM_Null; p->type = SQLITE_NULL; } return p; } /* ** Change the string value of an sqlite3_value object */ void sqlite3ValueSetStr( sqlite3_value *v, int n, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 695 696 697 698 699 700 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 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 763 764 765 766 767 768 769 770 771 772 773 774 | Mem *p = sqliteMalloc(sizeof(*p)); if( p ){ p->flags = MEM_Null; p->type = SQLITE_NULL; } 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", "NULL", "'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( Expr *pExpr, u8 enc, u8 affinity, sqlite3_value **ppVal ){ int op; char *zVal = 0; sqlite3_value *pVal = 0; if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ zVal = sqliteStrNDup(pExpr->token.z, pExpr->token.n); pVal = sqlite3ValueNew(); if( !zVal || !pVal ) goto no_mem; sqlite3Dequote(zVal); sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3FreeX); if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc); }else{ sqlite3ValueApplyAffinity(pVal, affinity, enc); } }else if( op==TK_UMINUS ) { if( SQLITE_OK==sqlite3ValueFromExpr(pExpr->pLeft, enc, affinity, &pVal) ){ pVal->i = -1 * pVal->i; pVal->r = -1.0 * pVal->r; } } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ int nVal; pVal = sqlite3ValueNew(); zVal = sqliteStrNDup(pExpr->token.z+1, pExpr->token.n-1); if( !zVal || !pVal ) goto no_mem; sqlite3Dequote(zVal); nVal = strlen(zVal)/2; sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(zVal), nVal, 0, sqlite3FreeX); sqliteFree(zVal); } #endif *ppVal = pVal; return SQLITE_OK; no_mem: sqliteFree(zVal); sqlite3ValueFree(pVal); *ppVal = 0; return SQLITE_NOMEM; } /* ** Change the string value of an sqlite3_value object */ void sqlite3ValueSetStr( sqlite3_value *v, int n, |
︙ | ︙ |
Changes to test/alter2.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing that SQLite can handle a subtle # file format change that may be used in the future to implement # "ALTER TABLE ... ADD COLUMN". # | | | 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 script is testing that SQLite can handle a subtle # file format change that may be used in the future to implement # "ALTER TABLE ... ADD COLUMN". # # $Id: alter2.test,v 1.3 2005/03/09 12:26:51 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # We have to have pragmas in order to do this test ifcapable {!pragma} return |
︙ | ︙ | |||
53 54 55 56 57 58 59 | set bt [btree_open $fname 10 0] set meta [btree_get_meta $bt] btree_close $bt lindex $meta 2 } # This procedure sets the SQL statement stored for table $tbl in the | | > > | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | set bt [btree_open $fname 10 0] set meta [btree_get_meta $bt] btree_close $bt lindex $meta 2 } # This procedure sets the SQL statement stored for table $tbl in the # sqlite_master table of file 'test.db' to $sql. Also set the file format # to the supplied value. This is 2 if the added column has a default that is # NULL, or 3 otherwise. # proc alter_table {tbl sql {file_format 2}} { sqlite3 dbat test.db dbat eval { PRAGMA writable_schema = 1; UPDATE sqlite_master SET sql = $sql WHERE name = $tbl AND type = 'table'; PRAGMA writable_schema = 0; } dbat close |
︙ | ︙ | |||
218 219 220 221 222 223 224 | SELECT * FROM clog; } } {{} 2 {} 6 {} 10} } #--------------------------------------------------------------------- # Check that an error occurs if the database is upgraded to a file | | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | SELECT * FROM clog; } } {{} 2 {} 6 {} 10} } #--------------------------------------------------------------------- # Check that an error occurs if the database is upgraded to a file # format that SQLite does not support (in this case 4). Note: The # file format is checked each time the schema is read, so changing the # file format requires incrementing the schema cookie. # do_test alter2-4.1 { set_file_format 4 } {} do_test alter2-4.2 { catchsql { SELECT * FROM sqlite_master; } } {1 {unsupported file format}} do_test alter2-4.3 { |
︙ | ︙ | |||
286 287 288 289 290 291 292 293 294 | } {1} do_test alter2-6.3 { execsql { CREATE TABLE t1(a, b); } get_file_format } {2} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | } {1} do_test alter2-6.3 { execsql { CREATE TABLE t1(a, b); } get_file_format } {2} #--------------------------------------------------------------------- # Test that types and values for columns added with default values # other than NULL work with SELECT statements. # do_test alter2-7.1 { execsql { DROP TABLE t1; CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); INSERT INTO t1 VALUES(4); SELECT * FROM t1; } } {1 2 3 4} do_test alter2-7.2 { set sql {CREATE TABLE t1(a, b DEFAULT '123', c INTEGER DEFAULT '123')} alter_table t1 $sql 3 execsql { SELECT * FROM t1 LIMIT 1; } } {1 123 123} do_test alter2-7.3 { execsql { SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } } {1 integer 123 text 123 integer} do_test alter2-7.4 { execsql { SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } } {1 integer 123 text 123 integer} do_test alter2-7.5 { set sql {CREATE TABLE t1(a, b DEFAULT -123.0, c VARCHAR(10) default 5)} alter_table t1 $sql 3 execsql { SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } } {1 integer -123.0 real 5 text} #----------------------------------------------------------------------- # Test that UPDATE trigger tables work with default values, and that when # a row is updated the default values are correctly transfered to the # new row. # ifcapable trigger { db function set_val {set ::val} do_test alter2-8.1 { execsql { CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN SELECT set_val( old.b||' '||typeof(old.b)||' '||old.c||' '||typeof(old.c)||' '|| new.b||' '||typeof(new.b)||' '||new.c||' '||typeof(new.c) ); END; } list } {} } do_test alter2-8.2 { execsql { UPDATE t1 SET c = 10 WHERE a = 1; SELECT a, typeof(a), b, typeof(b), c, typeof(c) FROM t1 LIMIT 1; } } {1 integer -123.0 real 10 text} ifcapable trigger { do_test alter2-8.3 { set ::val } {-123 real 5 text -123 real 10 text} } #----------------------------------------------------------------------- # Test that DELETE trigger tables work with default values, and that when # a row is updated the default values are correctly transfered to the # new row. # ifcapable trigger { do_test alter2-9.1 { execsql { CREATE TRIGGER trig2 BEFORE DELETE ON t1 BEGIN SELECT set_val( old.b||' '||typeof(old.b)||' '||old.c||' '||typeof(old.c) ); END; } list } {} do_test alter2-9.2 { execsql { DELETE FROM t1 WHERE a = 2; } set ::val } {-123 real 5 text} } #----------------------------------------------------------------------- # Test creating an index on a column added with a default value. # do_test alter2-10.1 { execsql { CREATE TABLE t2(a); INSERT INTO t2 VALUES('a'); INSERT INTO t2 VALUES('b'); INSERT INTO t2 VALUES('c'); INSERT INTO t2 VALUES('d'); } alter_table t2 {CREATE TABLE t2(a, b DEFAULT X'ABCD', c DEFAULT NULL);} 3 catchsql { SELECT * FROM sqlite_master; } execsql { SELECT quote(a), quote(b), quote(c) FROM t2 LIMIT 1; } } {'a' X'ABCD' NULL} do_test alter2-10.2 { execsql { CREATE INDEX i1 ON t2(b); SELECT a FROM t2 WHERE b = X'ABCD'; } } {a b c d} do_test alter2-10.3 { execsql { DELETE FROM t2 WHERE a = 'c'; SELECT a FROM t2 WHERE b = X'ABCD'; } } {a b d} do_test alter2-10.4 { execsql { SELECT count(b) FROM t2 WHERE b = X'ABCD'; } } {3} finish_test |
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.31 2005/03/09 12:26:51 danielk1977 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. |
︙ | ︙ | |||
483 484 485 486 487 488 489 | if {![sqlite3 -has-codec]} { # Test what happens when the library encounters a newer file format. # Do this by updating the file format via the btree layer. do_test capi3-7.1 { set ::bt [btree_open test.db 10 0] btree_begin_transaction $::bt set meta [btree_get_meta $::bt] | | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | if {![sqlite3 -has-codec]} { # Test what happens when the library encounters a newer file format. # Do this by updating the file format via the btree layer. do_test capi3-7.1 { set ::bt [btree_open test.db 10 0] btree_begin_transaction $::bt set meta [btree_get_meta $::bt] lset meta 2 4 eval [concat btree_update_meta $::bt [lrange $meta 0 end]] btree_commit $::bt btree_close $::bt } {} do_test capi3-7.2 { sqlite3 db test.db catchsql { |
︙ | ︙ |
Changes to www/opcode.tcl.
1 2 3 | # # Run this Tcl script to generate the sqlite.html file. # | | > > > | > > | 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 43 44 45 46 47 | # # Run this Tcl script to generate the sqlite.html file. # set rcsid {$Id: opcode.tcl,v 1.15 2005/03/09 12:26:51 danielk1977 Exp $} source common.tcl header {SQLite Virtual Machine Opcodes} puts { <h2>SQLite Virtual Machine Opcodes</h2> } set fd [open [lindex $argv 0] r] set file [read $fd [file size [lindex $argv 0]]] close $fd set current_op {} foreach line [split $file \n] { set line [string trim $line] if {[string index $line 1]!="*"} { set current_op {} continue } if {[regexp {^/\* Opcode: } $line]} { set current_op [lindex $line 2] set txt [lrange $line 3 end] regsub -all {>} $txt {\>} txt regsub -all {<} $txt {\<} txt set Opcode($current_op:args) $txt lappend OpcodeList $current_op continue } if {$current_op==""} continue if {[regexp {^\*/} $line]} { set current_op {} continue } set line [string trim [string range $line 3 end]] if {$line==""} { append Opcode($current_op:text) \n<p> } else { regsub -all {>} $line {\>} line regsub -all {<} $line {\<} line append Opcode($current_op:text) \n$line } } unset file puts { <h3>Introduction</h3> |
︙ | ︙ |