SQLite Forum

Why is the return code 17 (and not 1)?
Login

Why is the return code 17 (and not 1)?

(1.1) By Aask (AAsk1902) on 2022-11-09 19:04:51 edited from 1.0 [link] [source]

The error code is in round brackets i.e. (17) in the CLI; my application reports the same error code.

SQLite version 3.39.4 2022-09-29 15:55:41
Enter ".help" for usage hints.
sqlite> .open ./db/chinook.db
sqlite> select form employees;
Parse error: no such column: form (17)
  select form employees;
         ^--- error here
sqlite>

The documentation: (17) SQLITE_SCHEMA The SQLITE_SCHEMA result code indicates that the database schema has changed.

I am using a free-standing laptop with no other application using SQLite: how can the schema change?

The SQL is badly constructed: I would expect a return code of 1.

(2) By Simon Slavin (slavin) on 2022-11-10 00:49:17 in reply to 1.1 [link] [source]

Interesting. If you don't open a database you get

SQLite version 3.39.4 2022-09-29 16:56:49
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> select form employees;
Parse error: no such column: form
  select form employees;
         ^--- error here
sqlite> 

Are we sure that the "17" means SQLite error 17, and not, for example, that the error is found at the 17th character in the command, or something like that ?

(3) By Aask (AAsk1902) on 2022-11-10 06:19:24 in reply to 2 [link] [source]

Are we sure that the "17" means SQLite error 17..

Absolutely sure. In my application I capture the return code and it is definitely 17.

no such column (is logical) ought to be a return code 1 ,generic error (but 17 SQLite_SCHEMA is not , perhaps!).

(4) By Gunter Hick (gunter_hick) on 2022-11-10 06:50:33 in reply to 1.1 [link] [source]

According to the syntax, the SELECT token is followed by a listof result columns, optionally followed by FROM and one or more tables.

Since you misspelled FROM as form, it is looking for a column named form and has nowhere to look.

"no such column" is therefore the appropriate response.

If you had succeeded in writing SELECT FROM employees; you would have encountered a syntax error instead.

(5) By Rowan Worth (sqweek) on 2022-11-10 07:07:07 in reply to 4 [link] [source]

I don't think you understood the question, which has nothing to do with the error text and everything to do with the return code and why we are seeing:

#define SQLITE_SCHEMA      17   /* The database schema changed */

and not:

#define SQLITE_ERROR        1   /* SQL error or missing database */

which is the normal code for SQL errors.

(I don't have the answer, just wanted to affirm the OP that it's a legitimate question)

(6) By Gunter Hick (gunter_hick) on 2022-11-10 07:21:37 in reply to 2 [link] [source]

Not being able to resolve a name may be caused by

a) the name not being defined in the call to sqlite3_prepare()
b) the schema having changed between the calls to sqlite3_prepare() and sqlite3_step()

When a name is not resolvable, the lookupName() function sets the checkSchema flag; subsequently, the schemaIsValid() function retrieves the database file cookie  and compares it to the cookie saved in the connection, returning SQLITE_SCHEMA if they do not match.

Maybe the cookie saved in the connection has not yet been set, as it is the first statement to be prepared and it fails to do so before SQLite has any reason (valid table reference) to go fetch the database file cookie yet.

(7) By Gunter Hick (gunter_hick) on 2022-11-10 07:36:19 in reply to 5 [link] [source]

See https://sqlite.org/forum/forumpost/062749765b768431 for the explanation of why SQLITE_SCHEMA is returned. It does have everything to do with the fact that SQLite is expecting a column name and fails to find it, as opposed to a syntax error because the result column list is empty.

(8) By Aask (AAsk1902) on 2022-11-10 08:31:36 in reply to 7 [link] [source]

The parse error is

Parse error: no such column: form

To me that is

SQLITE_ERROR 1 /* SQL error */

and as sqweek said just wanted to affirm the OP that it's a legitimate question

However, getting SQLITE_SCHEMA instead of SQLITE_ERROR is not earth shattering but confusing nonetheless.

(9) By Dan Kennedy (dan) on 2022-11-10 10:50:54 in reply to 8 [link] [source]

I don't get the problem with the program below. Can you post your patch to shell.c so we can try to reproduce that way?

Dan.

#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){
  const char *zDb = "";
  sqlite3 *db = 0;
  sqlite3_stmt *pStmt = 0;
  int rc = 0;

  if( argc>1 ){
    zDb = argv[1];
  }

  rc = sqlite3_open(zDb, &db);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "error in open\n");
    exit(-1);
  }

  rc = sqlite3_prepare_v2(db, "SELECT form employee", -1, &pStmt, 0);
  printf("error: (rc=%d), (sqlite3_errcode=%d), (sqlite3_errmsg=%s)\n",
    rc, sqlite3_errcode(db), sqlite3_errmsg(db)
  );
  return 0;
}

(10) By Gunter Hick (gunter_hick) on 2022-11-10 11:37:51 in reply to 9 [link] [source]

FWIW I actually could reproduce the SQLITE_SCHEMA return value with our custom build of SQLite 3.24 like this:

- run the shell with --init /dev/null x.db
- create table test (id integer primary key, val text);
- exit the shell

now the x.db file exists and has a nonzero schem cookie value

- run the shell with --init /dev/null x.db in gdb
- interrupt the process while at the command prompt
- set a breakpoint on sqlite3LockAndPrepare
- set a breakpoint on schemaIsValid
- continue

select missing from test;

- in sqlite3LockAndPrepare, the db->aDb[0].pSchema->schema_cookie is still zero
- the rc is SQLITE_ERROR
- the stored cookie is still zero after return
- schemaIsValid is never called

select form test;

- the stored cookie is still zero
- schemaIsValid is called
- sqlite3BtreeGetMeta returns the correct cookie value
- this differs from the stored cookie value
- the rc is SQLITE_SCHEMA

select * from test;

- at some time, the stored cookie value is updated

(11) By ddevienne on 2022-11-10 12:36:23 in reply to 10 [source]

FWIW, I can also repro using same DB the OP used (I think), using draft 3.40:

E:\oss\sqlite\sqlite-snapshot-202211061719.tar\sqlite-snapshot-202211061719>sqlite3-40.exe
SQLite version 3.40.0 2022-11-06 17:19:34
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> select form employees;
Parse error: no such column: form
  select form employees;
         ^--- error here
sqlite> .exit

E:\oss\sqlite\sqlite-snapshot-202211061719.tar\sqlite-snapshot-202211061719>sqlite3-40.exe
SQLite version 3.40.0 2022-11-06 17:19:34
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open Chinook_Sqlite.sqlite
sqlite> select form employees;
Parse error: no such column: form (17)
  select form employees;
         ^--- error here