]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The .dump output uses INSERT instead of COPY now. Expression syntax
authordrh <drh@noemail.net>
Mon, 1 Oct 2001 14:29:22 +0000 (14:29 +0000)
committerdrh <drh@noemail.net>
Mon, 1 Oct 2001 14:29:22 +0000 (14:29 +0000)
of the form "expr NOT NULL" is now supported. (CVS 276)

FossilOrigin-Name: 20382325c7c8c6b11bd45b23060d0f7fdb4d8fd1

VERSION
manifest
manifest.uuid
src/parse.y
src/shell.c
www/changes.tcl

diff --git a/VERSION b/VERSION
index 227cea215648b1af34a87c9acf5b707fe02d2072..38f77a65b3015cb4dc42eebe91514e49b47b8597 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.0
+2.0.1
index 59e64be5c3e561ebef91b260a8178167877a8bb8..1aeab0905dba34a76a4aee14729f57f778114bd4 100644 (file)
--- 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
index b461a9997031e51d09ca6bb4adb613fc656456e4..1b9974eed35965668f1a5e3e201445c089274cfd 100644 (file)
@@ -1 +1 @@
-c0a8a1fb4224c63bcbb438cfd2ca0d4e0bb5b824
\ No newline at end of file
+20382325c7c8c6b11bd45b23060d0f7fdb4d8fd1
\ No newline at end of file
index b5519895de7c5d736148643fc8edf3c88e725abb..d64c56ba36c8bb99a7ebbde339c52a7564910f24 100644 (file)
@@ -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);
index e93f284e476291c677b4fe5e7fad604a918d17ca..a9f34e110f6a68fa873b32541be15ba2e30d058d 100644 (file)
@@ -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 <stdlib.h>
 #include <string.h>
@@ -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; i<nArg; i++){
         char *zSep = i>0 ? ",": "";
         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; i<nArg && zErrMsg==0; i++){
         sqlite_exec_printf(db, 
           "SELECT name, type, sql FROM sqlite_master "
-          "WHERE tbl_name LIKE '%q' AND type!='meta' "
+          "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
           "ORDER BY type DESC, name",
           dump_callback, p, &zErrMsg, azArg[i]
         );
@@ -484,6 +521,8 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
     if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);
       free(zErrMsg);
+    }else{
+      fprintf(p->out, "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;
 }
index 4eb96097086a9e85393f4484550300a49725f8c1..5191cee74517647c69e3931a7fd17c26021aea5f 100644 (file)
@@ -17,6 +17,16 @@ proc chng {date desc} {
   puts "<DD><P><UL>$desc</UL></P></DD>"
 }
 
+chng {2001 Oct 1 (2.0.1)} {
+<li>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.</li>
+<li>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).</li>
+}
+
 chng {2001 Sep 28 (2.0.0)} {
 <li>Automatically build binaries for Linux and Windows and put them on
     the website.</li>