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 "

    $desc

" } +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.