SQLite

Check-in [8443a272]
Login

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

Overview
Comment:Improved CLI error messages.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8443a2724f463bd2e14ea3aa337e8987104f63365767ca2b0993f3f3196cff95
User & Date: drh 2021-10-26 17:36:26
Context
2021-10-26
22:36
Enhance fuzzcheck so that if an argument is an ordinary disk file (not a database) it is read in and processed as a script. (check-in: 978dc89d user: drh tags: trunk)
17:36
Improved CLI error messages. (check-in: 8443a272 user: drh tags: trunk)
16:57
Add phase and error number to CLI error messages. (Closed-Leaf check-in: 7f87a298 user: larrybr tags: detail_cli_errors)
09:53
Fix the busy_timeout restriction on fuzzcheck so that it can deal with hexadecimal integer literals. (check-in: 4b41535b user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612


2613
2614
2615
2616

2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
                sqlite3_errmsg(p->db));
    if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
  }
  return rc;
}

/*
** Allocate space and save off current error string.
*/
static char *save_err_msg(
  sqlite3 *db            /* Database to query */


){
  int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
  char *zErrMsg = sqlite3_malloc64(nErrMsg);
  if( zErrMsg ){

    memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
  }
  return zErrMsg;
}

#ifdef __linux__
/*
** Attempt to display I/O stats on Linux using /proc/PID/io
*/
static void displayLinuxIoStats(FILE *out){







|


|
>
>

<
<
|
>
|
<
<







2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615


2616
2617
2618


2619
2620
2621
2622
2623
2624
2625
                sqlite3_errmsg(p->db));
    if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
  }
  return rc;
}

/*
** Allocate space and save off string indicating current error.
*/
static char *save_err_msg(
  sqlite3 *db,           /* Database to query */
  const char *zWhen,     /* Qualifier (format) wrapper */
  int rc                 /* Error code returned from API */
){


  if( zWhen==0 )
    zWhen = "%s (%d)";
  return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc);


}

#ifdef __linux__
/*
** Attempt to display I/O stats on Linux using /proc/PID/io
*/
static void displayLinuxIoStats(FILE *out){
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
#endif

  while( zSql[0] && (SQLITE_OK == rc) ){
    static const char *zStmtSql;
    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
    if( SQLITE_OK != rc ){
      if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db);
      }
    }else{
      if( !pStmt ){
        /* this happens for a comment or white-space */
        zSql = zLeftover;
        while( IsSpace(zSql[0]) ) zSql++;
        continue;







|







3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
#endif

  while( zSql[0] && (SQLITE_OK == rc) ){
    static const char *zStmtSql;
    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
    if( SQLITE_OK != rc ){
      if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)", rc);
      }
    }else{
      if( !pStmt ){
        /* this happens for a comment or white-space */
        zSql = zLeftover;
        while( IsSpace(zSql[0]) ) zSql++;
        continue;
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
      ** next statement to execute. */
      rc2 = sqlite3_finalize(pStmt);
      if( rc!=SQLITE_NOMEM ) rc = rc2;
      if( rc==SQLITE_OK ){
        zSql = zLeftover;
        while( IsSpace(zSql[0]) ) zSql++;
      }else if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db);
      }

      /* clear saved stmt handle */
      if( pArg ){
        pArg->pStmt = NULL;
      }
    }







|







3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
      ** next statement to execute. */
      rc2 = sqlite3_finalize(pStmt);
      if( rc!=SQLITE_NOMEM ) rc = rc2;
      if( rc==SQLITE_OK ){
        zSql = zLeftover;
        while( IsSpace(zSql[0]) ) zSql++;
      }else if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc);
      }

      /* clear saved stmt handle */
      if( pArg ){
        pArg->pStmt = NULL;
      }
    }

Changes to test/shell1.test.

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
do_test shell1-1.1.2 {
  catchcmd "test.db \"select+3\" \"select+4\"" ""
} {0 {3
4}}
# error on extra options
do_test shell1-1.1.3 {
  catchcmd "test.db FOO test.db BAD" ".quit"
} {1 {Error: near "FOO": syntax error}}

# -help
do_test shell1-1.2.1 {
  set res [catchcmd "-help test.db" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Usage} $res] \







|







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
do_test shell1-1.1.2 {
  catchcmd "test.db \"select+3\" \"select+4\"" ""
} {0 {3
4}}
# error on extra options
do_test shell1-1.1.3 {
  catchcmd "test.db FOO test.db BAD" ".quit"
} {1 {Error: in prepare, near "FOO": syntax error (1)}}

# -help
do_test shell1-1.2.1 {
  set res [catchcmd "-help test.db" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Usage} $res] \
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  catchcmd "-init FOO test.db" ""
} {0 {}}
do_test shell1-1.3.2 {
  catchcmd "-init FOO test.db .quit BAD" ""
} {0 {}}
do_test shell1-1.3.3 {
  catchcmd "-init FOO test.db BAD .quit" ""
} {1 {Error: near "BAD": syntax error}}

# -echo                print commands before execution
do_test shell1-1.4.1 {
  catchcmd "-echo test.db" ""
} {0 {}}

# -[no]header          turn headers on or off







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  catchcmd "-init FOO test.db" ""
} {0 {}}
do_test shell1-1.3.2 {
  catchcmd "-init FOO test.db .quit BAD" ""
} {0 {}}
do_test shell1-1.3.3 {
  catchcmd "-init FOO test.db BAD .quit" ""
} {1 {Error: in prepare, near "BAD": syntax error (1)}}

# -echo                print commands before execution
do_test shell1-1.4.1 {
  catchcmd "-echo test.db" ""
} {0 {}}

# -[no]header          turn headers on or off

Changes to test/shell2.test.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    INSERT INTO t5 VALUES(1, 2, 3);
    CREATE TRIGGER au_tble AFTER UPDATE ON t5 BEGIN
      UPDATE OR IGNORE t5 SET a = new.a, c = 10;
    END;

    UPDATE OR REPLACE t5 SET a = 4 WHERE a = 1;
  }
} {1 {Error: near line 9: too many levels of trigger recursion}}



# Shell not echoing all commands with echo on.
# Ticket [eb620916be].

# Test with echo off







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    INSERT INTO t5 VALUES(1, 2, 3);
    CREATE TRIGGER au_tble AFTER UPDATE ON t5 BEGIN
      UPDATE OR IGNORE t5 SET a = new.a, c = 10;
    END;

    UPDATE OR REPLACE t5 SET a = 4 WHERE a = 1;
  }
} {1 {Error: near line 9: stepping, too many levels of trigger recursion (1)}}



# Shell not echoing all commands with echo on.
# Ticket [eb620916be].

# Test with echo off

Changes to test/shell3.test.

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  catchcmd "foo.db \"CREATE TABLE t1(a); DROP TABLE t1;\""
} {0 {}}
do_test shell3-1.6 {
  catchcmd "foo.db" ".tables"
} {0 {}}
do_test shell3-1.7 {
  catchcmd "foo.db \"CREATE TABLE\""
} {1 {Error: incomplete input}}

#----------------------------------------------------------------------------
#   shell3-2.*: Basic tests for running SQL file from command line.
#

# Run SQL file from command line
do_test shell3-2.1 {







|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  catchcmd "foo.db \"CREATE TABLE t1(a); DROP TABLE t1;\""
} {0 {}}
do_test shell3-1.6 {
  catchcmd "foo.db" ".tables"
} {0 {}}
do_test shell3-1.7 {
  catchcmd "foo.db \"CREATE TABLE\""
} {1 {Error: in prepare, incomplete input (1)}}

#----------------------------------------------------------------------------
#   shell3-2.*: Basic tests for running SQL file from command line.
#

# Run SQL file from command line
do_test shell3-2.1 {
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  catchcmd "foo.db" "CREATE TABLE t1(a); DROP TABLE t1;"
} {0 {}}
do_test shell3-2.6 {
  catchcmd "foo.db" ".tables"
} {0 {}}
do_test shell3-2.7 {
  catchcmd "foo.db" "CREATE TABLE"
} {1 {Error: near line 1: incomplete input}}


#----------------------------------------------------------------------------
#   shell3-3.*: Basic tests for processing odd SQL constructs.
#

# Run combinations of odd identifiers, comments, semicolon placement







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  catchcmd "foo.db" "CREATE TABLE t1(a); DROP TABLE t1;"
} {0 {}}
do_test shell3-2.6 {
  catchcmd "foo.db" ".tables"
} {0 {}}
do_test shell3-2.7 {
  catchcmd "foo.db" "CREATE TABLE"
} {1 {Error: near line 1: in prepare, incomplete input (1)}}


#----------------------------------------------------------------------------
#   shell3-3.*: Basic tests for processing odd SQL constructs.
#

# Run combinations of odd identifiers, comments, semicolon placement