/ Check-in [20382325]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The .dump output uses INSERT instead of COPY now. Expression syntax of the form "expr NOT NULL" is now supported. (CVS 276)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 20382325c7c8c6b11bd45b23060d0f7fdb4d8fd1
User & Date: drh 2001-10-01 14:29:23
Context
2001-10-02
13:01
Remove C++ comments from btree.c. (CVS 277) check-in: 4b7710e2 user: drh tags: trunk
2001-10-01
14:29
The .dump output uses INSERT instead of COPY now. Expression syntax of the form "expr NOT NULL" is now supported. (CVS 276) check-in: 20382325 user: drh tags: trunk
2001-09-28
23:15
Version 2.0.0 (CVS 470) check-in: c0a8a1fb user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to VERSION.

     1         -2.0.0
            1  +2.0.1

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.32 2001/09/27 15:11:54 drh Exp $
           17  +** @(#) $Id: parse.y,v 1.33 2001/10/01 14:29:23 drh Exp $
    18     18   */
    19     19   %token_prefix TK_
    20     20   %token_type {Token}
    21     21   %default_type {Token}
    22     22   %extra_argument {Parse *pParse}
    23     23   %syntax_error {
    24     24     sqliteSetString(&pParse->zErrMsg,"syntax error",0);
................................................................................
   367    367   expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
   368    368   expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
   369    369   expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
   370    370   expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
   371    371   expr(A) ::= expr(X) ISNULL(E). {
   372    372     A = sqliteExpr(TK_ISNULL, X, 0, 0);
   373    373     sqliteExprSpan(A,&X->span,&E);
          374  +}
          375  +expr(A) ::= expr(X) IS NULL(E). {
          376  +  A = sqliteExpr(TK_ISNULL, X, 0, 0);
          377  +  sqliteExprSpan(A,&X->span,&E);
   374    378   }
   375    379   expr(A) ::= expr(X) NOTNULL(E). {
   376    380     A = sqliteExpr(TK_NOTNULL, X, 0, 0);
   377    381     sqliteExprSpan(A,&X->span,&E);
          382  +}
          383  +expr(A) ::= expr(X) NOT NULL(E). {
          384  +  A = sqliteExpr(TK_NOTNULL, X, 0, 0);
          385  +  sqliteExprSpan(A,&X->span,&E);
   378    386   }
   379    387   expr(A) ::= NOT(B) expr(X). {
   380    388     A = sqliteExpr(TK_NOT, X, 0, 0);
   381    389     sqliteExprSpan(A,&B,&X->span);
   382    390   }
   383    391   expr(A) ::= MINUS(B) expr(X). [UMINUS] {
   384    392     A = sqliteExpr(TK_UMINUS, X, 0, 0);

Changes to src/shell.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code to implement the "sqlite" command line
    13     13   ** utility for accessing SQLite databases.
    14     14   **
    15         -** $Id: shell.c,v 1.34 2001/09/27 15:11:54 drh Exp $
           15  +** $Id: shell.c,v 1.35 2001/10/01 14:29:23 drh Exp $
    16     16   */
    17     17   #include <stdlib.h>
    18     18   #include <string.h>
    19     19   #include <stdio.h>
    20     20   #include "sqlite.h"
    21     21   #include <unistd.h>
    22     22   #include <ctype.h>
................................................................................
   123    123     sqlite *db;            /* The database */
   124    124     int echoOn;            /* True to echo input commands */
   125    125     int cnt;               /* Number of records displayed so far */
   126    126     FILE *out;             /* Write results here */
   127    127     int mode;              /* An output mode setting */
   128    128     int showHeader;        /* True to show column names in List or Column mode */
   129    129     int escape;            /* Escape this character when in MODE_List */
   130         -  char zDestTable[250];  /* Name of destination table when MODE_Insert */
          130  +  char *zDestTable;      /* Name of destination table when MODE_Insert */
   131    131     char separator[20];    /* Separator character for MODE_List */
   132    132     int colWidth[100];     /* Requested width of each column when in column mode*/
   133    133     int actualWidth[100];  /* Actual width of each column */
   134    134   };
   135    135   
   136    136   /*
   137    137   ** These are the allowed modes.
................................................................................
   349    349           output_html_string(p->out, azArg[i] ? azArg[i] : "");
   350    350           fprintf(p->out,"</TD>\n");
   351    351         }
   352    352         fprintf(p->out,"</TD></TR>\n");
   353    353         break;
   354    354       }
   355    355       case MODE_Insert: {
   356         -      fprintf(p->out,"INSERT INTO '%s' VALUES(",p->zDestTable);
          356  +      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
   357    357         for(i=0; i<nArg; i++){
   358    358           char *zSep = i>0 ? ",": "";
   359    359           if( azArg[i]==0 ){
   360    360             fprintf(p->out,"%sNULL",zSep);
   361    361           }else if( is_numeric(azArg[i]) ){
   362    362             fprintf(p->out,"%s%s",zSep, azArg[i]);
   363    363           }else{
................................................................................
   366    366           }
   367    367         }
   368    368         fprintf(p->out,");\n");
   369    369       }
   370    370     }      
   371    371     return 0;
   372    372   }
          373  +
          374  +/*
          375  +** Set the destination table field of the callback_data structure to
          376  +** the name of the table given.  Escape any quote characters in the
          377  +** table name.
          378  +*/
          379  +static void set_table_name(struct callback_data *p, const char *zName){
          380  +  int i, n;
          381  +  int needQuote;
          382  +  char *z;
          383  +
          384  +  if( p->zDestTable ){
          385  +    free(p->zDestTable);
          386  +    p->zDestTable = 0;
          387  +  }
          388  +  if( zName==0 ) return;
          389  +  needQuote = !isalpha(*zName) && *zName!='_';
          390  +  for(i=n=0; zName[i]; i++, n++){
          391  +    if( !isalnum(zName[i]) && zName[i]!='_' ){
          392  +      needQuote = 1;
          393  +      if( zName[i]=='\'' ) n++;
          394  +    }
          395  +  }
          396  +  if( needQuote ) n += 2;
          397  +  z = p->zDestTable = malloc( n+1 );
          398  +  if( z==0 ){
          399  +    fprintf(stderr,"Out of memory!\n");
          400  +    exit(1);
          401  +  }
          402  +  n = 0;
          403  +  if( needQuote ) z[n++] = '\'';
          404  +  for(i=0; zName[i]; i++){
          405  +    z[n++] = zName[i];
          406  +    if( zName[i]=='\'' ) z[n++] = '\'';
          407  +  }
          408  +  if( needQuote ) z[n++] = '\'';
          409  +  z[n] = 0;
          410  +}
   373    411   
   374    412   /*
   375    413   ** This is a different callback routine used for dumping the database.
   376    414   ** Each row received by this callback consists of a table name,
   377    415   ** the table type ("index" or "table") and SQL to create the table.
   378    416   ** This routine should print text sufficient to recreate the table.
   379    417   */
................................................................................
   380    418   static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
   381    419     struct callback_data *p = (struct callback_data *)pArg;
   382    420     if( nArg!=3 ) return 1;
   383    421     fprintf(p->out, "%s;\n", azArg[2]);
   384    422     if( strcmp(azArg[1],"table")==0 ){
   385    423       struct callback_data d2;
   386    424       d2 = *p;
   387         -    d2.mode = MODE_List;
   388         -    d2.escape = '\t';
   389         -    strcpy(d2.separator,"\t");
   390         -    fprintf(p->out, "COPY '%s' FROM STDIN;\n", azArg[0]);
          425  +    d2.mode = MODE_Insert;
          426  +    d2.zDestTable = 0;
          427  +    set_table_name(&d2, azArg[0]);
   391    428       sqlite_exec_printf(p->db, 
   392    429          "SELECT * FROM '%q'",
   393    430          callback, &d2, 0, azArg[0]
   394    431       );
   395         -    fprintf(p->out, "\\.\n");
          432  +    set_table_name(&d2, 0);
   396    433     }
   397         -  fprintf(p->out, "VACUUM '%s';\n", azArg[0]);
   398    434     return 0;
   399    435   }
   400    436   
   401    437   /*
   402    438   ** Text of a help message
   403    439   */
   404    440   static char zHelp[] = 
................................................................................
   458    494     /* Process the input line.
   459    495     */
   460    496     if( nArg==0 ) return;
   461    497     n = strlen(azArg[0]);
   462    498     c = azArg[0][0];
   463    499     if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
   464    500       char *zErrMsg = 0;
          501  +    fprintf(p->out, "BEGIN TRANSACTION;\n");
   465    502       if( nArg==1 ){
   466    503         sqlite_exec(db,
   467    504           "SELECT name, type, sql FROM sqlite_master "
   468         -        "WHERE type!='meta' "
          505  +        "WHERE type!='meta' AND sql NOT NULL "
   469    506           "ORDER BY tbl_name, type DESC, name",
   470    507           dump_callback, p, &zErrMsg
   471    508         );
   472    509       }else{
   473    510         int i;
   474    511         for(i=1; i<nArg && zErrMsg==0; i++){
   475    512           sqlite_exec_printf(db, 
   476    513             "SELECT name, type, sql FROM sqlite_master "
   477         -          "WHERE tbl_name LIKE '%q' AND type!='meta' "
          514  +          "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
   478    515             "ORDER BY type DESC, name",
   479    516             dump_callback, p, &zErrMsg, azArg[i]
   480    517           );
   481    518           
   482    519         }
   483    520       }
   484    521       if( zErrMsg ){
   485    522         fprintf(stderr,"Error: %s\n", zErrMsg);
   486    523         free(zErrMsg);
          524  +    }else{
          525  +      fprintf(p->out, "COMMIT;\n");
   487    526       }
   488    527     }else
   489    528   
   490    529     if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
   491    530       int j;
   492    531       char *z = azArg[1];
   493    532       int val = atoi(azArg[1]);
................................................................................
   560    599       }else if( strncmp(azArg[1],"column",n2)==0 ){
   561    600         p->mode = MODE_Column;
   562    601       }else if( strncmp(azArg[1],"list",n2)==0 ){
   563    602         p->mode = MODE_List;
   564    603       }else if( strncmp(azArg[1],"html",n2)==0 ){
   565    604         p->mode = MODE_Html;
   566    605       }else if( strncmp(azArg[1],"insert",n2)==0 ){
          606  +      char *zTab;
          607  +      int k, n;
   567    608         p->mode = MODE_Insert;
   568    609         if( nArg>=3 ){
   569         -        sprintf(p->zDestTable,"%.*s", (int)(sizeof(p->zDestTable)-1), azArg[2]);
          610  +        set_table_name(p, azArg[2]);
   570    611         }else{
   571         -        sprintf(p->zDestTable,"table");
          612  +        set_table_name(p, "table");
   572    613         }
   573    614       }else {
   574    615         fprintf(stderr,"mode should be on of: column html insert line list\n");
   575    616       }
   576    617     }else
   577    618   
   578    619     if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
................................................................................
   654    695           new_argv[1] = 0;
   655    696           new_colv[0] = "sql";
   656    697           new_colv[1] = 0;
   657    698           callback(&data, 1, new_argv, new_colv);
   658    699         }else{
   659    700           sqlite_exec_printf(db,
   660    701             "SELECT sql FROM sqlite_master "
   661         -          "WHERE tbl_name LIKE '%q' AND type!='meta'"
          702  +          "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOTNULL "
   662    703             "ORDER BY type DESC, name",
   663    704             callback, &data, &zErrMsg, azArg[1]);
   664    705         }
   665    706       }else{
   666    707         sqlite_exec(db,
   667    708            "SELECT sql FROM sqlite_master "
   668         -         "WHERE type!='meta' "
          709  +         "WHERE type!='meta' AND sql NOTNULL "
   669    710            "ORDER BY tbl_name, type DESC, name",
   670    711            callback, &data, &zErrMsg
   671    712         );
   672    713       }
   673    714       if( zErrMsg ){
   674    715         fprintf(stderr,"Error: %s\n", zErrMsg);
   675    716         free(zErrMsg);
................................................................................
   874    915           sqlite_version
   875    916         );
   876    917         process_input(&data, 0);
   877    918       }else{
   878    919         process_input(&data, stdin);
   879    920       }
   880    921     }
          922  +  set_table_name(&data, 0);
   881    923     sqlite_close(db);
   882    924     return 0;
   883    925   }

Changes to www/changes.tcl.

    12     12   }
    13     13   
    14     14   
    15     15   proc chng {date desc} {
    16     16     puts "<DT><B>$date</B></DT>"
    17     17     puts "<DD><P><UL>$desc</UL></P></DD>"
    18     18   }
           19  +
           20  +chng {2001 Oct 1 (2.0.1)} {
           21  +<li>The ".dump" output from the shell does not work if there are embedded
           22  +    newlines anywhere in the data.  This is an old bug that was carried
           23  +    forward from version 1.0.  To fix it, the ".dump" output no longer
           24  +    uses the COPY command.  It instead generates INSERT statements.</li>
           25  +<li>Extend the expression syntax to support "expr NOT NULL" (with a
           26  +    space between the "NOT" and the "NULL") in addition to "expr NOTNULL"
           27  +    (with no space).</li>
           28  +}
    19     29   
    20     30   chng {2001 Sep 28 (2.0.0)} {
    21     31   <li>Automatically build binaries for Linux and Windows and put them on
    22     32       the website.</li>
    23     33   }
    24     34   
    25     35   chng {2001 Sep 28 (2.0-alpha-4)} {