/ Check-in [f98c8ac8]
Login

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

Overview
Comment:Back out the "--raw" option on ".read" in the command-line shell. Instead, fix the command-line shell so that if EOF is reached without seeing a final semicolon, it goes ahead and passes the accumulated SQL text to SQLite.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f98c8ac8c485098f163400d3a92d6afb4008adbe
User & Date: drh 2016-11-11 14:54:22
Context
2016-11-11
15:49
Handle some obscure "row value misused" cases that could cause segfaults or assertion failures. check-in: fba5fddb user: dan tags: trunk
14:54
Back out the "--raw" option on ".read" in the command-line shell. Instead, fix the command-line shell so that if EOF is reached without seeing a final semicolon, it goes ahead and passes the accumulated SQL text to SQLite. check-in: f98c8ac8 user: drh tags: trunk
09:51
Add extra tests for the xBestIndex() virtual table method. check-in: 642a8fba user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/shell.c.

  4201   4201   
  4202   4202     if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
  4203   4203       rc = 2;
  4204   4204     }else
  4205   4205   
  4206   4206     if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
  4207   4207       FILE *alt;
  4208         -    char *zFile;
  4209         -    int rawMode = 0;
  4210         -    if( nArg!=2 && nArg!=3 ){
  4211         -      raw_printf(stderr, "Usage: .read [--raw] FILE\n");
         4208  +    if( nArg!=2 ){
         4209  +      raw_printf(stderr, "Usage: .read FILE\n");
  4212   4210         rc = 1;
  4213   4211         goto meta_command_exit;
  4214   4212       }
  4215         -    if( nArg==3 ){
  4216         -      const char *z = azArg[1];
  4217         -      while( z[0]=='-' ) z++;
  4218         -      if( strcmp(z,"raw")==0 ){
  4219         -        rawMode = 1;
  4220         -      }
  4221         -      else{
  4222         -        raw_printf(stderr, "unknown option: \"%s\"\n", azArg[1]);
  4223         -        rc = 1;
  4224         -        goto meta_command_exit;
  4225         -      }
  4226         -    }
  4227         -    zFile = azArg[nArg-1];
  4228         -    if( rawMode ){
  4229         -      char *z = readFile(zFile);
  4230         -      if( z==0 ){
  4231         -        utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
  4232         -        rc = 1;
  4233         -      }else{
  4234         -        char *zErr = 0;
  4235         -        open_db(p, 1);
  4236         -        rc = sqlite3_exec(p->db, z, callback, p, &zErr);
  4237         -        sqlite3_free(z);
  4238         -        if( zErr ){
  4239         -          utf8_printf(stdout, "%s", zErr);
  4240         -          sqlite3_free(zErr);
  4241         -        }
  4242         -      }
  4243         -    }else{
  4244         -      alt = fopen(zFile, "rb");
         4213  +    alt = fopen(azArg[1], "rb");
  4245   4214         if( alt==0 ){
  4246   4215           utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
  4247   4216           rc = 1;
  4248   4217         }else{
  4249   4218           rc = process_input(p, alt);
  4250   4219           fclose(alt);
  4251   4220         }
  4252         -    }
  4253   4221     }else
  4254   4222   
  4255   4223     if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
  4256   4224       const char *zSrcFile;
  4257   4225       const char *zDb;
  4258   4226       sqlite3 *pSrc;
  4259   4227       sqlite3_backup *pBackup;
................................................................................
  5203   5171     if( zSql==0 ) return 1;
  5204   5172     zSql[nSql] = ';';
  5205   5173     zSql[nSql+1] = 0;
  5206   5174     rc = sqlite3_complete(zSql);
  5207   5175     zSql[nSql] = 0;
  5208   5176     return rc;
  5209   5177   }
         5178  +
         5179  +/*
         5180  +** Run a single line of SQL
         5181  +*/
         5182  +static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
         5183  +  int rc;
         5184  +  char *zErrMsg = 0;
         5185  +
         5186  +  open_db(p, 0);
         5187  +  if( p->backslashOn ) resolve_backslashes(zSql);
         5188  +  BEGIN_TIMER;
         5189  +  rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
         5190  +  END_TIMER;
         5191  +  if( rc || zErrMsg ){
         5192  +    char zPrefix[100];
         5193  +    if( in!=0 || !stdin_is_interactive ){
         5194  +      sqlite3_snprintf(sizeof(zPrefix), zPrefix,
         5195  +                       "Error: near line %d:", startline);
         5196  +    }else{
         5197  +      sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
         5198  +    }
         5199  +    if( zErrMsg!=0 ){
         5200  +      utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
         5201  +      sqlite3_free(zErrMsg);
         5202  +      zErrMsg = 0;
         5203  +    }else{
         5204  +      utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
         5205  +    }
         5206  +    return 1;
         5207  +  }else if( p->countChanges ){
         5208  +    raw_printf(p->out, "changes: %3d   total_changes: %d\n",
         5209  +            sqlite3_changes(p->db), sqlite3_total_changes(p->db));
         5210  +  }
         5211  +  return 0;
         5212  +}
         5213  +
  5210   5214   
  5211   5215   /*
  5212   5216   ** Read input from *in and process it.  If *in==0 then input
  5213   5217   ** is interactive - the user is typing it it.  Otherwise, input
  5214   5218   ** is coming from a file or device.  A prompt is issued and history
  5215   5219   ** is saved only if input is interactive.  An interrupt signal will
  5216   5220   ** cause this routine to exit immediately, unless input is interactive.
................................................................................
  5220   5224   static int process_input(ShellState *p, FILE *in){
  5221   5225     char *zLine = 0;          /* A single input line */
  5222   5226     char *zSql = 0;           /* Accumulated SQL text */
  5223   5227     int nLine;                /* Length of current line */
  5224   5228     int nSql = 0;             /* Bytes of zSql[] used */
  5225   5229     int nAlloc = 0;           /* Allocated zSql[] space */
  5226   5230     int nSqlPrior = 0;        /* Bytes of zSql[] used by prior line */
  5227         -  char *zErrMsg;            /* Error message returned */
  5228   5231     int rc;                   /* Error code */
  5229   5232     int errCnt = 0;           /* Number of errors seen */
  5230   5233     int lineno = 0;           /* Current line number */
  5231   5234     int startline = 0;        /* Line number for start of current input */
  5232   5235   
  5233   5236     while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
  5234   5237       fflush(p->out);
................................................................................
  5280   5283       }else{
  5281   5284         zSql[nSql++] = '\n';
  5282   5285         memcpy(zSql+nSql, zLine, nLine+1);
  5283   5286         nSql += nLine;
  5284   5287       }
  5285   5288       if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
  5286   5289                   && sqlite3_complete(zSql) ){
  5287         -      p->cnt = 0;
  5288         -      open_db(p, 0);
  5289         -      if( p->backslashOn ) resolve_backslashes(zSql);
  5290         -      BEGIN_TIMER;
  5291         -      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
  5292         -      END_TIMER;
  5293         -      if( rc || zErrMsg ){
  5294         -        char zPrefix[100];
  5295         -        if( in!=0 || !stdin_is_interactive ){
  5296         -          sqlite3_snprintf(sizeof(zPrefix), zPrefix,
  5297         -                           "Error: near line %d:", startline);
  5298         -        }else{
  5299         -          sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
  5300         -        }
  5301         -        if( zErrMsg!=0 ){
  5302         -          utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
  5303         -          sqlite3_free(zErrMsg);
  5304         -          zErrMsg = 0;
  5305         -        }else{
  5306         -          utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
  5307         -        }
  5308         -        errCnt++;
  5309         -      }else if( p->countChanges ){
  5310         -        raw_printf(p->out, "changes: %3d   total_changes: %d\n",
  5311         -                sqlite3_changes(p->db), sqlite3_total_changes(p->db));
  5312         -      }
         5290  +      errCnt += runOneSqlLine(p, zSql, in, startline);
  5313   5291         nSql = 0;
  5314   5292         if( p->outCount ){
  5315   5293           output_reset(p);
  5316   5294           p->outCount = 0;
  5317   5295         }
  5318   5296       }else if( nSql && _all_whitespace(zSql) ){
  5319   5297         if( p->echoOn ) printf("%s\n", zSql);
  5320   5298         nSql = 0;
  5321   5299       }
  5322   5300     }
  5323         -  if( nSql ){
  5324         -    if( !_all_whitespace(zSql) ){
  5325         -      utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
  5326         -      errCnt++;
  5327         -    }
         5301  +  if( nSql && !_all_whitespace(zSql) ){
         5302  +    runOneSqlLine(p, zSql, in, startline);
  5328   5303     }
  5329   5304     free(zSql);
  5330   5305     free(zLine);
  5331   5306     return errCnt>0;
  5332   5307   }
  5333   5308   
  5334   5309   /*

Changes to test/shell3.test.

    92     92     catchcmd "foo.db" "CREATE TABLE t1(a); DROP TABLE t1;"
    93     93   } {0 {}}
    94     94   do_test shell3-2.6 {
    95     95     catchcmd "foo.db" ".tables"
    96     96   } {0 {}}
    97     97   do_test shell3-2.7 {
    98     98     catchcmd "foo.db" "CREATE TABLE"
    99         -} {1 {Error: incomplete SQL: CREATE TABLE}}
           99  +} {1 {Error: near line 1: near "TABLE": syntax error}}
   100    100   
   101    101   finish_test