1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

2.0.3 (CVS 287)

FossilOrigin-Name: 75e90cf09b64ee1fcb39a711fc9ac6d3d2b849a5
This commit is contained in:
drh
2001-10-13 02:59:08 +00:00
parent 99fcd718e1
commit bf4133cba1
15 changed files with 350 additions and 116 deletions

View File

@ -1 +1 @@
2.0.2 2.0.3

View File

@ -1,9 +1,9 @@
C Remove\sthe\sP3\sand\slabel\sarguments\sfrom\sthe\sinternal\ssqliteVdbeAddOp()\nfunction.\s\sThis\smakes\sthe\scode\seasier\sto\sread\sand\sperhaps\ssmaller\sas\nwell.\s(CVS\s286) C 2.0.3\s(CVS\s287)
D 2001-10-13T01:06:48 D 2001-10-13T02:59:09
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b
F README 93d2977cc5c6595c448de16bdefc312b9d401533 F README 93d2977cc5c6595c448de16bdefc312b9d401533
F VERSION 73e5f5e088b67ed1629b08ca531b81c778ab8695 F VERSION f993f873300343a57c72ba514c06e41d922e43c1
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588 F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914 F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
@ -21,9 +21,9 @@ F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7 F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
F src/build.c 191f9ec9dd53d7b7767e6fe36d84c524eca9b731 F src/build.c 9c3e3634b20c358e538f33f5ae125667e65447b2
F src/delete.c bed54503368e0976aa2e8487d8914e7b7fb63aae F src/delete.c bed54503368e0976aa2e8487d8914e7b7fb63aae
F src/expr.c 5aa5db4d426e71b7a51edcef5d75969bc377d8f6 F src/expr.c c1381b8229a5573b0928ede962e45c1c49d067af
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75 F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
F src/insert.c ae283e85a301bb3cd6af955f62bde1ca4ba4b56d F src/insert.c ae283e85a301bb3cd6af955f62bde1ca4ba4b56d
@ -33,24 +33,24 @@ F src/os.c cece4ac6cabc9d377ef0a4ab4c16f6f0f6c84377
F src/os.h bed702c9e3b768bc3cb1b12c90b83d099c1546be F src/os.h bed702c9e3b768bc3cb1b12c90b83d099c1546be
F src/pager.c e2e189a15e230c60e811f5e2ab25e68ae41c90be F src/pager.c e2e189a15e230c60e811f5e2ab25e68ae41c90be
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
F src/parse.y 2275a832b544e8b57c422880a0d9badd4976d042 F src/parse.y 148e4cd134d3cbd816dcb0df50e49e498faa6ba4
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9 F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
F src/select.c ff4dc2271bb6de7a94f22e651be4d29b4f24ff3f F src/select.c ff4dc2271bb6de7a94f22e651be4d29b4f24ff3f
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76 F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11 F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
F src/sqliteInt.h 141b57b9eee7e8c937ac603f6cb7ecca77c1dd77 F src/sqliteInt.h 5d6a79c70bdd9f993958c9c4a7970079fda495dd
F src/table.c abd0adbe0fee39d995287b3bcccd908d174dfcac F src/table.c abd0adbe0fee39d995287b3bcccd908d174dfcac
F src/tclsqlite.c 765599686c19ed777ac379928d732c8bfc63ebac F src/tclsqlite.c 765599686c19ed777ac379928d732c8bfc63ebac
F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49 F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321 F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96 F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
F src/tokenize.c 15d349b68d9dc5722956bd7549752ace62034787 F src/tokenize.c c3fcb76a41a22803b6060bddb5fbadc80bbe309c
F src/update.c 0b287faf0cc1d2bfa437f8a54061dd12ae6df91d F src/update.c 0b287faf0cc1d2bfa437f8a54061dd12ae6df91d
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387 F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
F src/vdbe.c e26521af3d0f12426bd8567f4236d6b61eed2a00 F src/vdbe.c dd65cd51bd5540edd8126723701f6ede6cb5f90c
F src/vdbe.h 21e4aede55ccc9d81c88cae4772310c6debbe6df F src/vdbe.h 86fc2ef42f48024c9a2e1b7fb01eda22b65a5295
F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86 F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0 F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
@ -58,15 +58,15 @@ F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
F test/btree2.test 20ce47ab804f15b6563736528bdd38aabe5193dc F test/btree2.test 20ce47ab804f15b6563736528bdd38aabe5193dc
F test/copy.test 768e6f1701a07d08090e1ca7f7dcce0a7a72b43e F test/copy.test 768e6f1701a07d08090e1ca7f7dcce0a7a72b43e
F test/delete.test 5ebb114582457428b3e0e30b21b477fedcb85609 F test/delete.test 5ebb114582457428b3e0e30b21b477fedcb85609
F test/expr.test b3475005ea19d53bf8c4573fb6e4a4498be5b434 F test/expr.test b4171c84b767f7b7e94dbce4824ba8e981a1c72f
F test/func.test dfee65686b8ba06071c2f007243a25c96ce82cf2 F test/func.test fb0f44de6d8487359a4455accbae120bde267772
F test/in.test 9323681388be301dc73f370b4cd62c5a33f79d1e F test/in.test 9323681388be301dc73f370b4cd62c5a33f79d1e
F test/index.test 6076f29d09a4f26a2efa38b03b8cc338b8662f0e F test/index.test 6076f29d09a4f26a2efa38b03b8cc338b8662f0e
F test/insert.test a5c122aa726f1cef6f07d6767e8fd6f220994c11 F test/insert.test a5c122aa726f1cef6f07d6767e8fd6f220994c11
F test/insert2.test 252d7130d8cc20f649b31a4f503cd87e660abda8 F test/insert2.test 252d7130d8cc20f649b31a4f503cd87e660abda8
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1 F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1
F test/main.test 085ece17913a487caacbc0a392638c958c83a75d F test/main.test 1626345b5f630c5398eede500d9354813b76b0fd
F test/malloc.test f1400a8d002eb96f1ca0a34abe56d2ab3e324740 F test/malloc.test f1400a8d002eb96f1ca0a34abe56d2ab3e324740
F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6 F test/misc1.test 50a5ca3481fc1f3cd6b978bcd6ed04c06f26a1e6
F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077 F test/pager.test 59bbc4e3d489529ed33db6e15595789e51056077
@ -102,19 +102,19 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4 F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb
F www/c_interface.tcl a59ee0835d1b33fcddab7d4fd65cf9e50f7d2dc7 F www/c_interface.tcl a59ee0835d1b33fcddab7d4fd65cf9e50f7d2dc7
F www/changes.tcl 4c722e1271b9c25477f2483dad1a96681ce73380 F www/changes.tcl 7078c2b8a93c723babef5883e29ae629924d9378
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60 F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
F www/index.tcl 68c815d64b35b2dcc4d4f6845827df71c6869f9f F www/index.tcl 68c815d64b35b2dcc4d4f6845827df71c6869f9f
F www/lang.tcl 3a7900e3f80cab50f322d925e573bd9f0acd57e1 F www/lang.tcl 8cf5de0e7b5d038506cd0b8fd26567ba43777b16
F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60 F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
F www/opcode.tcl 4365ad9798872491dbd7d3071510ebe461785ac3 F www/opcode.tcl 4365ad9798872491dbd7d3071510ebe461785ac3
F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44 F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
P 0a7848b6190981cb7eb673bbe68cb217694daf2e P 288ef1247b94c6c933451d120cdc78e471efc14e
R d882e44ee7d8a71c7c53e113bfd46069 R 8da9c9836a4f886cd81b2c8f2ff58fcd
U drh U drh
Z dbd2803044813be5011e55726d60bdc8 Z ed5e48602a3cb4f7e24daba213a3911c

View File

@ -1 +1 @@
288ef1247b94c6c933451d120cdc78e471efc14e 75e90cf09b64ee1fcb39a711fc9ac6d3d2b849a5

View File

@ -25,7 +25,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** PRAGMA
** **
** $Id: build.c,v 1.48 2001/10/13 01:06:48 drh Exp $ ** $Id: build.c,v 1.49 2001/10/13 02:59:09 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@ -1081,12 +1081,14 @@ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
return pList; return pList;
} }
} }
i = pList->nExpr++; if( pExpr ){
pList->a[i].pExpr = pExpr; i = pList->nExpr++;
pList->a[i].zName = 0; pList->a[i].pExpr = pExpr;
if( pName ){ pList->a[i].zName = 0;
sqliteSetNString(&pList->a[i].zName, pName->z, pName->n, 0); if( pName ){
sqliteDequote(pList->a[i].zName); sqliteSetNString(&pList->a[i].zName, pName->z, pName->n, 0);
sqliteDequote(pList->a[i].zName);
}
} }
return pList; return pList;
} }

View File

@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and ** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite. ** for generating VDBE code that evaluates expressions in SQLite.
** **
** $Id: expr.c,v 1.30 2001/10/13 01:06:48 drh Exp $ ** $Id: expr.c,v 1.31 2001/10/13 02:59:09 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -335,14 +335,16 @@ int sqliteFuncId(Token *pToken){
int len; int len;
int id; int id;
} aFunc[] = { } aFunc[] = {
{ "count", 5, FN_Count }, { "count", 5, FN_Count },
{ "min", 3, FN_Min }, { "min", 3, FN_Min },
{ "max", 3, FN_Max }, { "max", 3, FN_Max },
{ "sum", 3, FN_Sum }, { "sum", 3, FN_Sum },
{ "avg", 3, FN_Avg }, { "avg", 3, FN_Avg },
{ "fcnt", 4, FN_Fcnt }, /* Used for testing only */ { "fcnt", 4, FN_Fcnt }, /* Used for testing only */
{ "length", 6, FN_Length}, { "length", 6, FN_Length },
{ "substr", 6, FN_Substr}, { "substr", 6, FN_Substr },
{ "abs", 3, FN_Abs },
{ "round", 5, FN_Round },
}; };
int i; int i;
for(i=0; i<ArraySize(aFunc); i++){ for(i=0; i<ArraySize(aFunc); i++){
@ -401,17 +403,23 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
is_agg = 1; is_agg = 1;
break; break;
} }
case FN_Abs:
case FN_Length: { case FN_Length: {
too_few_args = n<1; too_few_args = n<1;
too_many_args = n>1; too_many_args = n>1;
break; break;
} }
case FN_Round: {
too_few_args = n<1;
too_many_args = n>2;
break;
}
case FN_Substr: { case FN_Substr: {
too_few_args = n<3; too_few_args = n<3;
too_many_args = n>3; too_many_args = n>3;
break; break;
} }
/* The "fcnt(*)" function always returns the number of fetch /* The "fcnt(*)" function always returns the number of OP_MoveTo
** operations that have occurred so far while processing the ** operations that have occurred so far while processing the
** SQL statement. This information can be used by test procedures ** SQL statement. This information can be used by test procedures
** to verify that indices are being used properly to minimize ** to verify that indices are being used properly to minimize
@ -496,6 +504,12 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
case TK_NOTNULL: op = OP_NotNull; break; case TK_NOTNULL: op = OP_NotNull; break;
case TK_NOT: op = OP_Not; break; case TK_NOT: op = OP_Not; break;
case TK_UMINUS: op = OP_Negative; break; case TK_UMINUS: op = OP_Negative; break;
case TK_BITAND: op = OP_BitAnd; break;
case TK_BITOR: op = OP_BitOr; break;
case TK_BITNOT: op = OP_BitNot; break;
case TK_LSHIFT: op = OP_ShiftLeft; break;
case TK_RSHIFT: op = OP_ShiftRight; break;
case TK_REM: op = OP_Remainder; break;
default: break; default: break;
} }
switch( pExpr->op ){ switch( pExpr->op ){
@ -534,12 +548,22 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
case TK_PLUS: case TK_PLUS:
case TK_STAR: case TK_STAR:
case TK_MINUS: case TK_MINUS:
case TK_REM:
case TK_BITAND:
case TK_BITOR:
case TK_SLASH: { case TK_SLASH: {
sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pLeft);
sqliteExprCode(pParse, pExpr->pRight); sqliteExprCode(pParse, pExpr->pRight);
sqliteVdbeAddOp(v, op, 0, 0); sqliteVdbeAddOp(v, op, 0, 0);
break; break;
} }
case TK_LSHIFT:
case TK_RSHIFT: {
sqliteExprCode(pParse, pExpr->pRight);
sqliteExprCode(pParse, pExpr->pLeft);
sqliteVdbeAddOp(v, op, 0, 0);
break;
}
case TK_CONCAT: { case TK_CONCAT: {
sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pLeft);
sqliteExprCode(pParse, pExpr->pRight); sqliteExprCode(pParse, pExpr->pRight);
@ -580,6 +604,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
} }
/* Fall through into TK_NOT */ /* Fall through into TK_NOT */
} }
case TK_BITNOT:
case TK_NOT: { case TK_NOT: {
sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pLeft);
sqliteVdbeAddOp(v, op, 0, 0); sqliteVdbeAddOp(v, op, 0, 0);
@ -625,6 +650,21 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
} }
break; break;
} }
case FN_Abs: {
sqliteExprCode(pParse, pList->a[0].pExpr);
sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
break;
}
case FN_Round: {
if( pList->nExpr==2 ){
sqliteExprCode(pParse, pList->a[1].pExpr);
}else{
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
}
sqliteExprCode(pParse, pList->a[0].pExpr);
sqliteVdbeAddOp(v, OP_Precision, 0, 0);
break;
}
case FN_Length: { case FN_Length: {
sqliteExprCode(pParse, pList->a[0].pExpr); sqliteExprCode(pParse, pList->a[0].pExpr);
sqliteVdbeAddOp(v, OP_Strlen, 0, 0); sqliteVdbeAddOp(v, OP_Strlen, 0, 0);

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** numeric codes for all of the tokens.
** **
** @(#) $Id: parse.y,v 1.36 2001/10/12 17:30:05 drh Exp $ ** @(#) $Id: parse.y,v 1.37 2001/10/13 02:59:09 drh Exp $
*/ */
%token_prefix TK_ %token_prefix TK_
%token_type {Token} %token_type {Token}
@ -331,7 +331,7 @@ inscollist(A) ::= ids(Y). {A = sqliteIdListAppend(0,&Y);}
%left GT GE LT LE. %left GT GE LT LE.
%left BITAND BITOR LSHIFT RSHIFT. %left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS. %left PLUS MINUS.
%left STAR SLASH MOD. %left STAR SLASH REM.
%left CONCAT. %left CONCAT.
%right UMINUS BITNOT. %right UMINUS BITNOT.
@ -385,7 +385,7 @@ expr(A) ::= expr(X) PLUS expr(Y). {A = sqliteExpr(TK_PLUS, X, Y, 0);}
expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);} expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
expr(A) ::= expr(X) STAR expr(Y). {A = sqliteExpr(TK_STAR, X, Y, 0);} expr(A) ::= expr(X) STAR expr(Y). {A = sqliteExpr(TK_STAR, X, Y, 0);}
expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);} expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
expr(A) ::= expr(X) MOD expr(Y). {A = sqliteExpr(TK_MOD, X, Y, 0);} expr(A) ::= expr(X) REM expr(Y). {A = sqliteExpr(TK_REM, X, Y, 0);}
expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);} expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
expr(A) ::= expr(X) ISNULL(E). { expr(A) ::= expr(X) ISNULL(E). {
A = sqliteExpr(TK_ISNULL, X, 0, 0); A = sqliteExpr(TK_ISNULL, X, 0, 0);

View File

@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.60 2001/10/12 17:30:05 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.61 2001/10/13 02:59:09 drh Exp $
*/ */
#include "sqlite.h" #include "sqlite.h"
#include "hash.h" #include "hash.h"
@ -117,21 +117,8 @@ extern int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */
#define FN_Fcnt 6 #define FN_Fcnt 6
#define FN_Length 7 #define FN_Length 7
#define FN_Substr 8 #define FN_Substr 8
#if 0
#define FN_Abs 9 #define FN_Abs 9
#define FN_Ceil 10 #define FN_Round 10
#define FN_Floor 11
#define FN_Frac 12
#define FN_Sin 13
#define FN_Cos 14
#define FN_Tan 15
#define FN_Asin 16
#define FN_Acos 17
#define FN_Atan 18
#define FN_Exp 19
#define FN_Ln 20
#define FN_Pow 21
#endif
/* /*
** Forward references to structures ** Forward references to structures

View File

@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the ** individual tokens and sends those tokens one-by-one over to the
** parser for analysis. ** parser for analysis.
** **
** $Id: tokenize.c,v 1.26 2001/10/09 04:19:47 drh Exp $ ** $Id: tokenize.c,v 1.27 2001/10/13 02:59:09 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@ -185,6 +185,10 @@ int sqliteGetToken(const char *z, int *tokenType){
*tokenType = TK_SLASH; *tokenType = TK_SLASH;
return 1; return 1;
} }
case '%': {
*tokenType = TK_REM;
return 1;
}
case '=': { case '=': {
*tokenType = TK_EQ; *tokenType = TK_EQ;
return 1 + (z[1]=='='); return 1 + (z[1]=='=');
@ -196,6 +200,9 @@ int sqliteGetToken(const char *z, int *tokenType){
}else if( z[1]=='>' ){ }else if( z[1]=='>' ){
*tokenType = TK_NE; *tokenType = TK_NE;
return 2; return 2;
}else if( z[1]=='<' ){
*tokenType = TK_LSHIFT;
return 2;
}else{ }else{
*tokenType = TK_LT; *tokenType = TK_LT;
return 1; return 1;
@ -205,6 +212,9 @@ int sqliteGetToken(const char *z, int *tokenType){
if( z[1]=='=' ){ if( z[1]=='=' ){
*tokenType = TK_GE; *tokenType = TK_GE;
return 2; return 2;
}else if( z[1]=='>' ){
*tokenType = TK_RSHIFT;
return 2;
}else{ }else{
*tokenType = TK_GT; *tokenType = TK_GT;
return 1; return 1;
@ -221,7 +231,7 @@ int sqliteGetToken(const char *z, int *tokenType){
} }
case '|': { case '|': {
if( z[1]!='|' ){ if( z[1]!='|' ){
*tokenType = TK_ILLEGAL; *tokenType = TK_BITOR;
return 1; return 1;
}else{ }else{
*tokenType = TK_CONCAT; *tokenType = TK_CONCAT;
@ -232,6 +242,14 @@ int sqliteGetToken(const char *z, int *tokenType){
*tokenType = TK_COMMA; *tokenType = TK_COMMA;
return 1; return 1;
} }
case '&': {
*tokenType = TK_BITAND;
return 1;
}
case '~': {
*tokenType = TK_BITNOT;
return 1;
}
case '\'': case '"': { case '\'': case '"': {
int delim = z[0]; int delim = z[0];
for(i=1; z[i]; i++){ for(i=1; z[i]; i++){

View File

@ -30,7 +30,7 @@
** But other routines are also provided to help in building up ** But other routines are also provided to help in building up
** a program instruction by instruction. ** a program instruction by instruction.
** **
** $Id: vdbe.c,v 1.83 2001/10/13 01:06:48 drh Exp $ ** $Id: vdbe.c,v 1.84 2001/10/13 02:59:09 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@ -814,7 +814,9 @@ static char *zOpName[] = { 0,
"ColumnName", "Callback", "Integer", "String", "ColumnName", "Callback", "Integer", "String",
"Null", "Pop", "Dup", "Pull", "Null", "Pop", "Dup", "Pull",
"Add", "AddImm", "Subtract", "Multiply", "Add", "AddImm", "Subtract", "Multiply",
"Divide", "Min", "Max", "Like", "Divide", "Remainder", "BitAnd", "BitOr",
"BitNot", "ShiftLeft", "ShiftRight", "AbsValue",
"Precision", "Min", "Max", "Like",
"Glob", "Eq", "Ne", "Lt", "Glob", "Eq", "Ne", "Lt",
"Le", "Gt", "Ge", "IsNull", "Le", "Gt", "Ge", "IsNull",
"NotNull", "Negative", "And", "Or", "NotNull", "Negative", "And", "Or",
@ -1322,10 +1324,20 @@ case OP_Concat: {
** is a string then it is converted to a double using the atof() ** is a string then it is converted to a double using the atof()
** function before the division. Division by zero returns NULL. ** function before the division. Division by zero returns NULL.
*/ */
/* Opcode: Remainder * * *
**
** Pop the top two elements from the stack, divide the
** first (what was on top of the stack) from the second (the
** next on stack)
** and push the remainder after division onto the stack. If either element
** is a string then it is converted to a double using the atof()
** function before the division. Division by zero returns NULL.
*/
case OP_Add: case OP_Add:
case OP_Subtract: case OP_Subtract:
case OP_Multiply: case OP_Multiply:
case OP_Divide: { case OP_Divide:
case OP_Remainder: {
int tos = p->tos; int tos = p->tos;
int nos = tos - 1; int nos = tos - 1;
VERIFY( if( nos<0 ) goto not_enough_stack; ) VERIFY( if( nos<0 ) goto not_enough_stack; )
@ -1337,11 +1349,16 @@ case OP_Divide: {
case OP_Add: b += a; break; case OP_Add: b += a; break;
case OP_Subtract: b -= a; break; case OP_Subtract: b -= a; break;
case OP_Multiply: b *= a; break; case OP_Multiply: b *= a; break;
default: { case OP_Divide: {
if( a==0 ) goto divide_by_zero; if( a==0 ) goto divide_by_zero;
b /= a; b /= a;
break; break;
} }
default: {
if( a==0 ) goto divide_by_zero;
b %= a;
break;
}
} }
POPSTACK; POPSTACK;
Release(p, nos); Release(p, nos);
@ -1357,11 +1374,18 @@ case OP_Divide: {
case OP_Add: b += a; break; case OP_Add: b += a; break;
case OP_Subtract: b -= a; break; case OP_Subtract: b -= a; break;
case OP_Multiply: b *= a; break; case OP_Multiply: b *= a; break;
default: { case OP_Divide: {
if( a==0.0 ) goto divide_by_zero; if( a==0.0 ) goto divide_by_zero;
b /= a; b /= a;
break; break;
} }
default: {
int ia = a;
int ib = b;
if( ia==0.0 ) goto divide_by_zero;
b = ib % ia;
break;
}
} }
POPSTACK; POPSTACK;
Release(p, nos); Release(p, nos);
@ -1377,6 +1401,37 @@ divide_by_zero:
break; break;
} }
/*
** Opcode: Precision * * *
**
** The top of stack is a floating-point number and the next on stack is
** an integer. Truncate the floating-point number to a number of digits
** specified by the integer and push the floating-point number back onto
** the stack.
*/
case OP_Precision: {
int tos = p->tos;
int nos = tos - 1;
int nDigit;
double v;
char zBuf[100];
VERIFY( if( nos<0 ) goto not_enough_stack; )
Realify(p, tos);
Integerify(p, nos);
nDigit = aStack[nos].i;
if( nDigit<0 ) nDigit = 0;
if( nDigit>30 ) nDigit = 30;
v = aStack[tos].r;
sprintf(zBuf, "%.*f", nDigit, v);
POPSTACK;
Release(p, nos);
zStack[nos] = sqliteStrDup(zBuf);
aStack[nos].n = strlen(zStack[tos]) + 1;
aStack[nos].flags = STK_Str | STK_Dyn;
break;
}
/* Opcode: Max * * * /* Opcode: Max * * *
** **
** Pop the top two elements from the stack then push back the ** Pop the top two elements from the stack then push back the
@ -1455,6 +1510,56 @@ case OP_Min: {
break; break;
} }
/* Opcode: BitAnd * * *
**
** Pop the top two elements from the stack. Convert both elements
** to integers. Push back onto the stack the bit-wise AND of the
** two elements.
*/
/* Opcode: BitOr * * *
**
** Pop the top two elements from the stack. Convert both elements
** to integers. Push back onto the stack the bit-wise OR of the
** two elements.
*/
/* Opcode: ShiftLeft * * *
**
** Pop the top two elements from the stack. Convert both elements
** to integers. Push back onto the stack the top element shifted
** left by N bits where N is the second element on the stack.
*/
/* Opcode: ShiftRight * * *
**
** Pop the top two elements from the stack. Convert both elements
** to integers. Push back onto the stack the top element shifted
** right by N bits where N is the second element on the stack.
*/
case OP_BitAnd:
case OP_BitOr:
case OP_ShiftLeft:
case OP_ShiftRight: {
int tos = p->tos;
int nos = tos - 1;
int a, b;
VERIFY( if( nos<0 ) goto not_enough_stack; )
Integerify(p, tos);
Integerify(p, nos);
a = aStack[tos].i;
b = aStack[nos].i;
switch( pOp->opcode ){
case OP_BitAnd: a &= b; break;
case OP_BitOr: a |= b; break;
case OP_ShiftLeft: a <<= b; break;
case OP_ShiftRight: a >>= b; break;
default: /* CANT HAPPEN */ break;
}
POPSTACK;
Release(p, nos);
aStack[nos].i = a;
aStack[nos].flags = STK_Int;
break;
}
/* Opcode: AddImm P1 * * /* Opcode: AddImm P1 * *
** **
** Add the value P1 to whatever is on top of the stack. ** Add the value P1 to whatever is on top of the stack.
@ -1633,21 +1738,33 @@ case OP_Or: {
** Treat the top of the stack as a numeric quantity. Replace it ** Treat the top of the stack as a numeric quantity. Replace it
** with its additive inverse. ** with its additive inverse.
*/ */
case OP_Negative: { /* Opcode: AbsValue * * *
**
** Treat the top of the stack as a numeric quantity. Replace it
** with its absolute value.
*/
case OP_Negative:
case OP_AbsValue: {
int tos = p->tos; int tos = p->tos;
VERIFY( if( tos<0 ) goto not_enough_stack; ) VERIFY( if( tos<0 ) goto not_enough_stack; )
if( aStack[tos].flags & STK_Real ){ if( aStack[tos].flags & STK_Real ){
Release(p, tos); Release(p, tos);
aStack[tos].r = -aStack[tos].r; if( pOp->opcode==OP_Negative || aStack[tos].r<0.0 ){
aStack[tos].r = -aStack[tos].r;
}
aStack[tos].flags = STK_Real; aStack[tos].flags = STK_Real;
}else if( aStack[tos].flags & STK_Int ){ }else if( aStack[tos].flags & STK_Int ){
Release(p, tos); Release(p, tos);
aStack[tos].i = -aStack[tos].i; if( pOp->opcode==OP_Negative || aStack[tos].i<0 ){
aStack[tos].i = -aStack[tos].i;
}
aStack[tos].flags = STK_Int; aStack[tos].flags = STK_Int;
}else{ }else{
Realify(p, tos); Realify(p, tos);
Release(p, tos); Release(p, tos);
aStack[tos].r = -aStack[tos].r; if( pOp->opcode==OP_Negative || aStack[tos].r<0.0 ){
aStack[tos].r = -aStack[tos].r;
}
aStack[tos].flags = STK_Real; aStack[tos].flags = STK_Real;
} }
break; break;
@ -1668,6 +1785,21 @@ case OP_Not: {
break; break;
} }
/* Opcode: * * *
**
** Interpret the top of the stack as an value. Replace it
** with its ones-complement.
*/
case OP_BitNot: {
int tos = p->tos;
VERIFY( if( p->tos<0 ) goto not_enough_stack; )
Integerify(p, tos);
Release(p, tos);
aStack[tos].i = ~aStack[tos].i;
aStack[tos].flags = STK_Int;
break;
}
/* Opcode: Noop * * * /* Opcode: Noop * * *
** **
** Do nothing. This instruction is often useful as a jump ** Do nothing. This instruction is often useful as a jump

View File

@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a ** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database. ** simple program to access and modify the underlying database.
** **
** $Id: vdbe.h,v 1.28 2001/10/13 01:06:49 drh Exp $ ** $Id: vdbe.h,v 1.29 2001/10/13 02:59:09 drh Exp $
*/ */
#ifndef _SQLITE_VDBE_H_ #ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_
@ -168,38 +168,37 @@ typedef struct VdbeOp VdbeOp;
#define OP_Subtract 83 #define OP_Subtract 83
#define OP_Multiply 84 #define OP_Multiply 84
#define OP_Divide 85 #define OP_Divide 85
#define OP_Remainder #define OP_Remainder 86
#define OP_BitAnd #define OP_BitAnd 87
#define OP_BitOr #define OP_BitOr 88
#define OP_BitNot #define OP_BitNot 89
#define OP_ShiftLeft #define OP_ShiftLeft 90
#define OP_ShiftRight #define OP_ShiftRight 91
#define OP_Power #define OP_AbsValue 92
#define OP_Exp #define OP_Precision 93
#define OP_Log #define OP_Min 94
#define OP_Min 86 #define OP_Max 95
#define OP_Max 87 #define OP_Like 96
#define OP_Like 88 #define OP_Glob 97
#define OP_Glob 89 #define OP_Eq 98
#define OP_Eq 90 #define OP_Ne 99
#define OP_Ne 91 #define OP_Lt 100
#define OP_Lt 92 #define OP_Le 101
#define OP_Le 93 #define OP_Gt 102
#define OP_Gt 94 #define OP_Ge 103
#define OP_Ge 95 #define OP_IsNull 104
#define OP_IsNull 96 #define OP_NotNull 105
#define OP_NotNull 97 #define OP_Negative 106
#define OP_Negative 98 #define OP_And 107
#define OP_And 99 #define OP_Or 108
#define OP_Or 100 #define OP_Not 109
#define OP_Not 101 #define OP_Concat 110
#define OP_Concat 102 #define OP_Noop 111
#define OP_Noop 103
#define OP_Strlen 104 #define OP_Strlen 112
#define OP_Substr 105 #define OP_Substr 113
#define OP_MAX 105 #define OP_MAX 113
/* /*
** Prototypes for the VDBE interface. See comments on the implementation ** Prototypes for the VDBE interface. See comments on the implementation

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is testing expressions. # focus of this file is testing expressions.
# #
# $Id: expr.test,v 1.15 2001/09/16 00:13:28 drh Exp $ # $Id: expr.test,v 1.16 2001/10/13 02:59:09 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -68,6 +68,11 @@ test_expr expr-1.38 {i1=1} {-i1} {-1}
test_expr expr-1.39 {i1=1} {+i1} {1} test_expr expr-1.39 {i1=1} {+i1} {1}
test_expr expr-1.40 {i1=1, i2=2} {+(i2+i1)} {3} test_expr expr-1.40 {i1=1, i2=2} {+(i2+i1)} {3}
test_expr expr-1.41 {i1=1, i2=2} {-(i2+i1)} {-3} test_expr expr-1.41 {i1=1, i2=2} {-(i2+i1)} {-3}
test_expr expr-1.42 {i1=1, i2=2} {i1|i2} {3}
test_expr expr-1.43 {i1=1, i2=2} {i1&i2} {0}
test_expr expr-1.44 {i1=1} {~i1} {-2}
test_expr expr-1.45 {i1=1, i2=3} {i1<<i2} {8}
test_expr expr-1.46 {i1=32, i2=3} {i1>>i2} {4}
test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is testing built-in functions. # focus of this file is testing built-in functions.
# #
# $Id: func.test,v 1.4 2001/09/16 00:13:28 drh Exp $ # $Id: func.test,v 1.5 2001/10/13 02:59:09 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -121,4 +121,44 @@ do_test func-3.10 {
} ;# End [sqlite -encoding]==UTF-8 and \u1234!=u1234 } ;# End [sqlite -encoding]==UTF-8 and \u1234!=u1234
# Test the abs() and round() functions.
#
do_test func-4.1 {
execsql {
CREATE TABLE t1(a,b,c);
INSERT INTO t1 VALUES(1,2,3);
INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
INSERT INTO t1 VALUES(3,-2,-5);
}
catchsql {SELECT abs(a,b) FROM t1}
} {1 {too many arguments to function abs()}}
do_test func-4.2 {
catchsql {SELECT abs() FROM t1}
} {1 {too few arguments to function abs()}}
do_test func-4.3 {
catchsql {SELECT abs(b) FROM t1 ORDER BY a}
} {0 {2 1.2345678901234 2}}
do_test func-4.4 {
catchsql {SELECT abs(c) FROM t1 ORDER BY a}
} {0 {3 12345.6789 5}}
do_test func-4.5 {
catchsql {SELECT round(a,b,c) FROM t1}
} {1 {too many arguments to function round()}}
do_test func-4.6 {
catchsql {SELECT round(b,2) FROM t1}
} {0 {2.00 1.23 -2.00}}
do_test func-4.7 {
catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
} {0 {2 1 -2}}
do_test func-4.8 {
catchsql {SELECT round(c) FROM t1 ORDER BY a}
} {0 {3 -12346 -5}}
do_test func-4.9 {
catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
} {0 {3.0 -12345.68 -5.000}}
do_test func-4.10 {
catchsql {SELECT round() FROM t1 ORDER BY a}
} {1 {too few arguments to function round()}}
finish_test finish_test

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is exercising the code in main.c. # focus of this file is exercising the code in main.c.
# #
# $Id: main.test,v 1.8 2001/09/16 00:13:28 drh Exp $ # $Id: main.test,v 1.9 2001/10/13 02:59:09 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -98,17 +98,9 @@ do_test main-3.2 {
foreach f [glob -nocomplain testdb/*] {file delete -force $f} foreach f [glob -nocomplain testdb/*] {file delete -force $f}
file delete -force testdb file delete -force testdb
sqlite db testdb sqlite db testdb
set v [catch {execsql {SELECT * from T1 where ~x}} msg] set v [catch {execsql {SELECT * from T1 where @x}} msg]
lappend v $msg lappend v $msg
} {1 {unrecognized token: "~"}} } {1 {unrecognized token: "@"}}
do_test main-3.3 {
catch {db close}
foreach f [glob -nocomplain testdb/*] {file delete -force $f}
file delete -force testdb
sqlite db testdb
set v [catch {execsql {SELECT a|b from T1 where x}} msg]
lappend v $msg
} {1 {unrecognized token: "|"}}
do_test main-3.3 { do_test main-3.3 {
catch {db close} catch {db close}

View File

@ -17,12 +17,16 @@ proc chng {date desc} {
puts "<DD><P><UL>$desc</UL></P></DD>" puts "<DD><P><UL>$desc</UL></P></DD>"
} }
chng {2001 Oct ? (2.0.3)} { chng {2001 Oct 13 (2.0.3)} {
<li>Bug fix: the <b>sqlite_busy_timeout()</b> function was delaying 1000 <li>Bug fix: the <b>sqlite_busy_timeout()</b> function was delaying 1000
times too long before failing.</li> times too long before failing.</li>
<li>Bug fix: an assertion was failing if the disk holding the database <li>Bug fix: an assertion was failing if the disk holding the database
file became full or stopped accepting writes for some other reason. file became full or stopped accepting writes for some other reason.
New tests were added to detect similar problems in the future.</li> New tests were added to detect similar problems in the future.</li>
<li>Added new operators: <b>&amp;</b> (bitwise-and)
<b>|</b> (bitwise-or), <b>~</b> (ones-complement),
<b>&lt;&lt;</b> (shift left), <b>&gt;&gt;</b> (shift right).</li>
<li>Added new functions: <b>round()</b> and <b>abs()</b>.</li>
} }
chng {2001 Oct 9 (2.0.2)} { chng {2001 Oct 9 (2.0.2)} {

View File

@ -1,7 +1,7 @@
# #
# Run this Tcl script to generate the sqlite.html file. # Run this Tcl script to generate the sqlite.html file.
# #
set rcsid {$Id: lang.tcl,v 1.11 2001/10/08 13:22:33 drh Exp $} set rcsid {$Id: lang.tcl,v 1.12 2001/10/13 02:59:10 drh Exp $}
puts {<html> puts {<html>
<head> <head>
@ -357,14 +357,21 @@ subcomponent of most other commands.</p>
highest to lowest precedence:</p> highest to lowest precedence:</p>
<blockquote><pre> <blockquote><pre>
<font color="#2c2cf0"><big>* / <font color="#2c2cf0"><big>* / %
+ - + -
&lt;&lt; &gt;&gt; &amp; |
&lt; &lt;= &gt; &gt;= &lt; &lt;= &gt; &gt;=
= == != &lt;&gt; </big>IN = == != &lt;&gt; </big>IN
AND AND
OR</font> OR</font>
</pre></blockquote> </pre></blockquote>
<p>Supported unary operaters are these:</p>
<blockquote><pre>
<font color="#2c2cf0"><big>- + ! ~</big></font>
</pre></blockquote>
<p>Any SQLite value can be used as part of an expression. <p>Any SQLite value can be used as part of an expression.
For arithmetic operations, integers are treated as integers. For arithmetic operations, integers are treated as integers.
Strings are first converted to real numbers using <b>atof()</b>. Strings are first converted to real numbers using <b>atof()</b>.
@ -437,7 +444,7 @@ functions:</p>
<blockquote><pre> <blockquote><pre>
<font color="#2c2cf0"><big>count min max sum <font color="#2c2cf0"><big>count min max sum
avg length substr</big></font> avg length substr abs round</big></font>
</pre></blockquote> </pre></blockquote>
<p> <p>
@ -445,12 +452,20 @@ The functions <b>count</b>, <b>sum</b>, and <b>avg</b> and the functions
<b>min</b> and <b>max</b> used with only one argument are all aggregate <b>min</b> and <b>max</b> used with only one argument are all aggregate
functions. This means that they are computed across all rows of the result. functions. This means that they are computed across all rows of the result.
The functions <b>min</b> and <b>max</b> The functions <b>min</b> and <b>max</b>
with two or more arguments and the with two or more arguments and all other functions
functions <b>length</b> and <b>substr</b>
are non-aggregates. Non-aggregate functions are non-aggregates. Non-aggregate functions
are computed separately for each row of the result. are computed separately for each row of the result.
</p> </p>
<p>
The <b>round</b> function can take either 1 or 2 arguments. The
first argument is the floating point value that is rounded. The
second argument is the number of digits to the right of the
decimal point to preserve. If the second argument is omitted,
zero is assumed. So round(1.23456,2) is 1.23 and
round(12.34,0) and round(12.34) both evaluate to 12.
</p>
<p> <p>
The "<b>count(*)</b>" syntax is supported but The "<b>count(*)</b>" syntax is supported but
"<b>count(distinct</b> <i>COLUMN-NAME</i><b>)</b>" is not. "<b>count(distinct</b> <i>COLUMN-NAME</i><b>)</b>" is not.