From: drh
Date: Mon, 1 Oct 2001 14:29:22 +0000 (+0000)
Subject: The .dump output uses INSERT instead of COPY now. Expression syntax
X-Git-Tag: version-3.6.10~5768
X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=33048c0b9273c4b608d9932f51b29fd9bb0b2c42;p=thirdparty%2Fsqlite.git
The .dump output uses INSERT instead of COPY now. Expression syntax
of the form "expr NOT NULL" is now supported. (CVS 276)
FossilOrigin-Name: 20382325c7c8c6b11bd45b23060d0f7fdb4d8fd1
---
diff --git a/VERSION b/VERSION
index 227cea2156..38f77a65b3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.0
+2.0.1
diff --git a/manifest b/manifest
index 59e64be5c3..1aeab0905d 100644
--- a/manifest
+++ b/manifest
@@ -1,9 +1,9 @@
-C Version\s2.0.0\s(CVS\s470)
-D 2001-09-28T23:15:00
+C The\s.dump\soutput\suses\sINSERT\sinstead\sof\sCOPY\snow.\s\sExpression\ssyntax\nof\sthe\sform\s"expr\sNOT\sNULL"\sis\snow\ssupported.\s(CVS\s276)
+D 2001-10-01T14:29:23
F Makefile.in 98d4627cb364537e4c3a29ee806171f3abf5211a
F Makefile.template 7179523fdf3d6e7933ec843e2352dcfc9785c700
F README 93d2977cc5c6595c448de16bdefc312b9d401533
-F VERSION 3861a21803fcd9eb92a403027b0da2bb7add4de1
+F VERSION 1fb7be12efaa1608dc63e784e33082ae0ac7919b
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
@@ -33,11 +33,11 @@ F src/os.c 45376582c41dc8829330816d56b8e9e6cd1b7972
F src/os.h 0f478e2fef5ec1612f94b59b163d4807d4c77d6d
F src/pager.c 0fe02b63a89d8eebb42ad30529d0c7cc918ecb94
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
-F src/parse.y 7a61488cb52da8b3da094aadb391b42d59a25602
+F src/parse.y 5ead6fe1e7c5f13220030f41ce68af155b54c6ab
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
F src/random.c 708a23f69f40d6f2ae5ce1a04e6a4055d4a6ecec
F src/select.c 7d90a6464906419fde96c0707a4cf4f3280db318
-F src/shell.c 977ec6b6479c8b8b6e05323d5026a6f4bd73aa54
+F src/shell.c cd2ae9f22dec5e4e5411e6253abfc3e240b4e030
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 08151912b382ded315b5c8fc6288d9d7a9332aa4
F src/sqliteInt.h 3ead85324704b79b2ae6799d6af3e5fd710756d9
@@ -100,7 +100,7 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb
F www/c_interface.tcl 8e8d9e66e8467c5751116c3427296bde77f474a6
-F www/changes.tcl 47619693c843174b57d41482fcd00e2e70d41fd0
+F www/changes.tcl d7169a77887928e83f8a0d2c22f6b60c212afd0b
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
F www/index.tcl 998f61fe69be9f1b04e403c8efb75bca92710e83
@@ -111,7 +111,7 @@ F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
-P 4b4bfc6290f05c6672338690911f68fd8bb418c9
-R 50ffde789836ed27912ab4a11f3cd02b
+P c0a8a1fb4224c63bcbb438cfd2ca0d4e0bb5b824
+R 56826905453f8d467277c7046d36715b
U drh
-Z a438430725f024febbccaf23542689eb
+Z a2a4bc82e41106d3d020ca0bfe23edb2
diff --git a/manifest.uuid b/manifest.uuid
index b461a99970..1b9974eed3 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-c0a8a1fb4224c63bcbb438cfd2ca0d4e0bb5b824
\ No newline at end of file
+20382325c7c8c6b11bd45b23060d0f7fdb4d8fd1
\ No newline at end of file
diff --git a/src/parse.y b/src/parse.y
index b5519895de..d64c56ba36 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.32 2001/09/27 15:11:54 drh Exp $
+** @(#) $Id: parse.y,v 1.33 2001/10/01 14:29:23 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
@@ -372,10 +372,18 @@ expr(A) ::= expr(X) ISNULL(E). {
A = sqliteExpr(TK_ISNULL, X, 0, 0);
sqliteExprSpan(A,&X->span,&E);
}
+expr(A) ::= expr(X) IS NULL(E). {
+ A = sqliteExpr(TK_ISNULL, X, 0, 0);
+ sqliteExprSpan(A,&X->span,&E);
+}
expr(A) ::= expr(X) NOTNULL(E). {
A = sqliteExpr(TK_NOTNULL, X, 0, 0);
sqliteExprSpan(A,&X->span,&E);
}
+expr(A) ::= expr(X) NOT NULL(E). {
+ A = sqliteExpr(TK_NOTNULL, X, 0, 0);
+ sqliteExprSpan(A,&X->span,&E);
+}
expr(A) ::= NOT(B) expr(X). {
A = sqliteExpr(TK_NOT, X, 0, 0);
sqliteExprSpan(A,&B,&X->span);
diff --git a/src/shell.c b/src/shell.c
index e93f284e47..a9f34e110f 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -12,7 +12,7 @@
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
-** $Id: shell.c,v 1.34 2001/09/27 15:11:54 drh Exp $
+** $Id: shell.c,v 1.35 2001/10/01 14:29:23 drh Exp $
*/
#include
#include
@@ -127,7 +127,7 @@ struct callback_data {
int mode; /* An output mode setting */
int showHeader; /* True to show column names in List or Column mode */
int escape; /* Escape this character when in MODE_List */
- char zDestTable[250]; /* Name of destination table when MODE_Insert */
+ char *zDestTable; /* Name of destination table when MODE_Insert */
char separator[20]; /* Separator character for MODE_List */
int colWidth[100]; /* Requested width of each column when in column mode*/
int actualWidth[100]; /* Actual width of each column */
@@ -353,7 +353,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
break;
}
case MODE_Insert: {
- fprintf(p->out,"INSERT INTO '%s' VALUES(",p->zDestTable);
+ fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
for(i=0; i0 ? ",": "";
if( azArg[i]==0 ){
@@ -371,6 +371,44 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
return 0;
}
+/*
+** Set the destination table field of the callback_data structure to
+** the name of the table given. Escape any quote characters in the
+** table name.
+*/
+static void set_table_name(struct callback_data *p, const char *zName){
+ int i, n;
+ int needQuote;
+ char *z;
+
+ if( p->zDestTable ){
+ free(p->zDestTable);
+ p->zDestTable = 0;
+ }
+ if( zName==0 ) return;
+ needQuote = !isalpha(*zName) && *zName!='_';
+ for(i=n=0; zName[i]; i++, n++){
+ if( !isalnum(zName[i]) && zName[i]!='_' ){
+ needQuote = 1;
+ if( zName[i]=='\'' ) n++;
+ }
+ }
+ if( needQuote ) n += 2;
+ z = p->zDestTable = malloc( n+1 );
+ if( z==0 ){
+ fprintf(stderr,"Out of memory!\n");
+ exit(1);
+ }
+ n = 0;
+ if( needQuote ) z[n++] = '\'';
+ for(i=0; zName[i]; i++){
+ z[n++] = zName[i];
+ if( zName[i]=='\'' ) z[n++] = '\'';
+ }
+ if( needQuote ) z[n++] = '\'';
+ z[n] = 0;
+}
+
/*
** This is a different callback routine used for dumping the database.
** Each row received by this callback consists of a table name,
@@ -384,17 +422,15 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
if( strcmp(azArg[1],"table")==0 ){
struct callback_data d2;
d2 = *p;
- d2.mode = MODE_List;
- d2.escape = '\t';
- strcpy(d2.separator,"\t");
- fprintf(p->out, "COPY '%s' FROM STDIN;\n", azArg[0]);
+ d2.mode = MODE_Insert;
+ d2.zDestTable = 0;
+ set_table_name(&d2, azArg[0]);
sqlite_exec_printf(p->db,
"SELECT * FROM '%q'",
callback, &d2, 0, azArg[0]
);
- fprintf(p->out, "\\.\n");
+ set_table_name(&d2, 0);
}
- fprintf(p->out, "VACUUM '%s';\n", azArg[0]);
return 0;
}
@@ -462,10 +498,11 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
c = azArg[0][0];
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
char *zErrMsg = 0;
+ fprintf(p->out, "BEGIN TRANSACTION;\n");
if( nArg==1 ){
sqlite_exec(db,
"SELECT name, type, sql FROM sqlite_master "
- "WHERE type!='meta' "
+ "WHERE type!='meta' AND sql NOT NULL "
"ORDER BY tbl_name, type DESC, name",
dump_callback, p, &zErrMsg
);
@@ -474,7 +511,7 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
for(i=1; iout, "COMMIT;\n");
}
}else
@@ -564,11 +603,13 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
}else if( strncmp(azArg[1],"html",n2)==0 ){
p->mode = MODE_Html;
}else if( strncmp(azArg[1],"insert",n2)==0 ){
+ char *zTab;
+ int k, n;
p->mode = MODE_Insert;
if( nArg>=3 ){
- sprintf(p->zDestTable,"%.*s", (int)(sizeof(p->zDestTable)-1), azArg[2]);
+ set_table_name(p, azArg[2]);
}else{
- sprintf(p->zDestTable,"table");
+ set_table_name(p, "table");
}
}else {
fprintf(stderr,"mode should be on of: column html insert line list\n");
@@ -658,14 +699,14 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
}else{
sqlite_exec_printf(db,
"SELECT sql FROM sqlite_master "
- "WHERE tbl_name LIKE '%q' AND type!='meta'"
+ "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOTNULL "
"ORDER BY type DESC, name",
callback, &data, &zErrMsg, azArg[1]);
}
}else{
sqlite_exec(db,
"SELECT sql FROM sqlite_master "
- "WHERE type!='meta' "
+ "WHERE type!='meta' AND sql NOTNULL "
"ORDER BY tbl_name, type DESC, name",
callback, &data, &zErrMsg
);
@@ -878,6 +919,7 @@ int main(int argc, char **argv){
process_input(&data, stdin);
}
}
+ set_table_name(&data, 0);
sqlite_close(db);
return 0;
}
diff --git a/www/changes.tcl b/www/changes.tcl
index 4eb9609708..5191cee745 100644
--- a/www/changes.tcl
+++ b/www/changes.tcl
@@ -17,6 +17,16 @@ proc chng {date desc} {
puts "
"
}
+chng {2001 Oct 1 (2.0.1)} {
+The ".dump" output from the shell does not work if there are embedded
+ newlines anywhere in the data. This is an old bug that was carried
+ forward from version 1.0. To fix it, the ".dump" output no longer
+ uses the COPY command. It instead generates INSERT statements.
+Extend the expression syntax to support "expr NOT NULL" (with a
+ space between the "NOT" and the "NULL") in addition to "expr NOTNULL"
+ (with no space).
+}
+
chng {2001 Sep 28 (2.0.0)} {
Automatically build binaries for Linux and Windows and put them on
the website.