<title>SQLite Result Codes</title>
<tcl>hd_keywords {result code} {result codes} {error code} {error codes}</tcl>
<h1 align="center">SQLite Result Codes</h1>

<p>
Many of the routines in the SQLite [C-language Interface] return
numeric result codes indicating either success or failure, and 
in the event of a failure, providing some idea of the cause of
the failure.  This document strives to explain what each
of those numeric result codes means.

<h2>Result Codes versus Error Codes</h2>

<p>
"Error codes" are a subset of "result codes" that indicate that
something has gone wrong.  There are only a few non-error result
codes:  [SQLITE_OK], [SQLITE_ROW], and [SQLITE_DONE].  The term
"error code" means any result code other than these three.

<tcl>hd_fragment pve {primary versus extended result codes}</tcl>
<h2>Primary Result Codes versus Extended Result Codes</h2>

<p>
Result codes are signed 32-bit integers.
The least significant 8 bits of the result code define a broad category
and are called the "primary result code".  More significant bits provide
more detailed information about the error and are called the
"extended result code"

<p>
Note that the primary result code is always a part of the extended
result code.  Given a full 32-bit extended result code, the application
can always find the corresponding primary result code merely by extracting
the least significant 8 bits of the extended result code.

<p>
All extended result codes are also error codes.  Hence the terms
"extended result code" and "extended error code" are interchangeable.

<p>
For historic compatibility, the C-language interfaces return
primary result codes by default.  
The extended result code for the most recent error can be
retrieved using the [sqlite3_extended_errcode()] interface.
The [sqlite3_extended_result_codes()] interface can be used to put
a [database connection] into a mode where it returns the
extended result codes instead of the primary result codes.

<h2>Definitions</h2>

<p>
All result codes are integers.
Symbolic names for all result codes are created using
"#define" macros in the sqlite3.h header file.
There are separate sections in the sqlite3.h header file for
the [result code definitions] and the [extended result code definitions].

<p>
Primary result code symbolic names are of the form "SQLITE_XXXXXX" where
XXXXXX is a sequence of uppercase alphabetic characters.  Extended
result code names are of the form "SQLITE_XXXXXX_YYYYYYY" where
the XXXXXX part is the corresponding primary result code and the
YYYYYYY is an extension that further classifies the result code.

<p>
The names and numeric values for existing result codes are fixed
and unchanging.  However, new result codes, and especially new extended
result codes, might appear in future releases of SQLite.

<tcl>
unset -nocomplain resdesc
unset -nocomplain resvalue
proc RESCODE {name value desc} {
  set ::resdesc($name) $desc
  set ::resvalue($name) $value
}

RESCODE SQLITE_OK 0 {
  The SQLITE_OK result code means that the operation was successful and
  that there were no errors.  Most other result codes indicate an error.
}
RESCODE SQLITE_ERROR 1 {
  The SQLITE_ERROR result code is a generic error code that is used when
  no other more specific error code is available.
}
RESCODE SQLITE_INTERNAL     2  {
  The SQLITE_INTERNAL result code indicates an internal malfunction.
  In a working version of SQLite, an application should never see this
  result code.  If application does encounter this result code, it shows
  that there is a bug in the database engine.
  <p>
  Actually, SQLite does not currently generate this result code under
  any circumstances.  However, [application-defined SQL functions] or
  [virtual tables], or [VFSes], or other extensions might cause this 
  result code to be returned.
}
RESCODE SQLITE_PERM         3  {
  The SQLITE_PERM result code indicates a file-system permissions problem.
  Currently, on the unix VFS generates this result code.
}
RESCODE SQLITE_ABORT        4  {
  The SQLITE_ABORT result code indicates that an operation was aborted
  prior to completion, usually be application request.
  <p>
  If the callback function to [sqlite3_exec()] returns non-zero, then
  sqlite3_exec() will return SQLITE_ABORT.
  <p>
  In addition to being a result code,
  the SQLITE_ABORT value is also used as a [conflict resolution mode]
  returned from the [sqlite3_vtab_on_conflict()] interface.
}
RESCODE SQLITE_BUSY         5  {
}
RESCODE SQLITE_LOCKED       6  {}
RESCODE SQLITE_NOMEM        7   {
  The SQLITE_NOMEM result code indicates that SQLite was unable to allocate
  all the memory it needed to complete the operation.  In other words, an
  internal call to [sqlite3_malloc()] or [sqlite3_realloc()] has failed in
  a case where the memory being allocated was required in order to continue
  the operation.
}
RESCODE SQLITE_READONLY     8   {
  The SQLITE_READONLY result code is returned when an attempt is made to 
  alter some data for which the current database connection does not have
  write permission.
}
RESCODE SQLITE_INTERRUPT    9   {
  The SQLITE_INTERRUPT result code indicates that an operation was
  interrupted by the [sqlite3_interrupt()] interface.
}
RESCODE SQLITE_IOERR       10   {
  The SQLITE_IOERR result code says that the operation could not finish
  because the operating system reported an I/O error.  This could mean
  a hardware malfunction.  Or perhaps a removable storage device such as
  a USB thumb drive on which the database file is stored was removed in
  the middle of a write operation.
  <p>
  A full disk drive will normally give an SQLITE_FULL error rather than
  an SQLITE_IOERR error.
  <p>
  There are many different extended result codes for I/O errors that
  identify the specific I/O operation that failed.
}
RESCODE SQLITE_CORRUPT     11   {
  The SQLITE_CORRUPT result code indicates that the database file has
  been corrupted.  See the [How To Corrupt Your Database Files] for
  further discussion on how corruption can occur.
}
RESCODE SQLITE_NOTFOUND    12   {}
RESCODE SQLITE_FULL        13   {
  The SQLITE_FULL result code indicates that a write could not complete
  because the disk is full.  Note that this error can occur when trying
  to write information into the main database file, or into a temporary 
  file.  Sometimes users encounter this error when they are using large
  temporary files (for example to do large sorts) but have very little
  space available in the partition used by temporary files.
}
RESCODE SQLITE_CANTOPEN    14   {}
RESCODE SQLITE_PROTOCOL    15   {}
RESCODE SQLITE_EMPTY       16   {}
RESCODE SQLITE_SCHEMA      17   {
  The SQLITE_SCHEMA result code indicates that the database schema
  has changed.  This result code can be returned from [sqlite3_step()] for
  a [prepared statement] that was generated using [sqlite3_prepare()] or
  [sqlite3_prepare16()].  If the database schema was changed by some other
  process in between the time that the statement was prepared and the time
  the statement was run, this error can result.
  <p>
  If a [prepared statement] is generated from [sqlite3_prepare_v2()] then
  the statement is automatically re-prepared if the schema changes, up to
  [SQLITE_MAX_SCHEMA_RETRY] times (default: 50).  The [sqlite3_step()]
  interface will only return SQLITE_SCHEMA back to the application if 
  the failure persists after these many retries.
}
RESCODE SQLITE_TOOBIG      18   {}
RESCODE SQLITE_CONSTRAINT  19   {}
RESCODE SQLITE_MISMATCH    20   {}
RESCODE SQLITE_MISUSE      21   {
  The SQLITE_MISUSE return code might be returned if the application uses
  any SQLite interface in a way that is undefined or unsupported.  For
  example, using a [prepared statement] after that prepared statement has
  been [sqlite3_finalize|finalized] might result in an SQLITE_MISUSE error.
  <p>
  SQLite tries to detect misuse and report the misuse using this result code.
  However, there is no guarantee that the detection of misuse will be
  successful.  The misuse detection is probablistic.  Applications should
  never depend on an SQLITE_MISUSE return value.
  <p>
  If SQLite ever returns SQLITE_MISUSE from any interface, that means that
  the application is incorrectly coded and needs to be fixed.
}
RESCODE SQLITE_NOLFS       22   {
  The SQLITE_NOLFS error can be returned on systems that do not support
  large files when the database grows to be larger than what the filesystem
  can handle.  "NOLFS" stands for "NO Large File Support".
}
RESCODE SQLITE_AUTH        23   {}
RESCODE SQLITE_FORMAT      24   {}
RESCODE SQLITE_RANGE       25   {}
RESCODE SQLITE_NOTADB      26   {}
RESCODE SQLITE_NOTICE      27   {}
RESCODE SQLITE_WARNING     28   {}
RESCODE SQLITE_ROW         100  {}
RESCODE SQLITE_DONE        101  {}
RESCODE SQLITE_IOERR_READ              {SQLITE_IOERR | (1<<8)} {}
RESCODE SQLITE_IOERR_SHORT_READ        {SQLITE_IOERR | (2<<8)} {}
RESCODE SQLITE_IOERR_WRITE             {SQLITE_IOERR | (3<<8)} {}
RESCODE SQLITE_IOERR_FSYNC             {SQLITE_IOERR | (4<<8)} {}
RESCODE SQLITE_IOERR_DIR_FSYNC         {SQLITE_IOERR | (5<<8)} {}
RESCODE SQLITE_IOERR_TRUNCATE          {SQLITE_IOERR | (6<<8)} {}
RESCODE SQLITE_IOERR_FSTAT             {SQLITE_IOERR | (7<<8)} {}
RESCODE SQLITE_IOERR_UNLOCK            {SQLITE_IOERR | (8<<8)} {}
RESCODE SQLITE_IOERR_RDLOCK            {SQLITE_IOERR | (9<<8)} {}
RESCODE SQLITE_IOERR_DELETE            {SQLITE_IOERR | (10<<8)} {}
RESCODE SQLITE_IOERR_BLOCKED           {SQLITE_IOERR | (11<<8)} {}
RESCODE SQLITE_IOERR_NOMEM             {SQLITE_IOERR | (12<<8)} {}
RESCODE SQLITE_IOERR_ACCESS            {SQLITE_IOERR | (13<<8)} {}
RESCODE SQLITE_IOERR_CHECKRESERVEDLOCK {SQLITE_IOERR | (14<<8)} {}
RESCODE SQLITE_IOERR_LOCK              {SQLITE_IOERR | (15<<8)} {}
RESCODE SQLITE_IOERR_CLOSE             {SQLITE_IOERR | (16<<8)} {}
RESCODE SQLITE_IOERR_DIR_CLOSE         {SQLITE_IOERR | (17<<8)} {}
RESCODE SQLITE_IOERR_SHMOPEN           {SQLITE_IOERR | (18<<8)} {}
RESCODE SQLITE_IOERR_SHMSIZE           {SQLITE_IOERR | (19<<8)} {}
RESCODE SQLITE_IOERR_SHMLOCK           {SQLITE_IOERR | (20<<8)} {}
RESCODE SQLITE_IOERR_SHMMAP            {SQLITE_IOERR | (21<<8)} {}
RESCODE SQLITE_IOERR_SEEK              {SQLITE_IOERR | (22<<8)} {}
RESCODE SQLITE_IOERR_DELETE_NOENT      {SQLITE_IOERR | (23<<8)} {}
RESCODE SQLITE_IOERR_MMAP              {SQLITE_IOERR | (24<<8)} {}
RESCODE SQLITE_IOERR_GETTEMPPATH       {SQLITE_IOERR | (25<<8)} {}
RESCODE SQLITE_IOERR_CONVPATH          {SQLITE_IOERR | (26<<8)} {}
RESCODE SQLITE_LOCKED_SHAREDCACHE      {SQLITE_LOCKED |  (1<<8)} {}
RESCODE SQLITE_BUSY_RECOVERY           {SQLITE_BUSY   |  (1<<8)} {}
RESCODE SQLITE_BUSY_SNAPSHOT           {SQLITE_BUSY   |  (2<<8)} {}
RESCODE SQLITE_CANTOPEN_NOTEMPDIR      {SQLITE_CANTOPEN | (1<<8)} {}
RESCODE SQLITE_CANTOPEN_ISDIR          {SQLITE_CANTOPEN | (2<<8)} {}
RESCODE SQLITE_CANTOPEN_FULLPATH       {SQLITE_CANTOPEN | (3<<8)} {}
RESCODE SQLITE_CANTOPEN_CONVPATH       {SQLITE_CANTOPEN | (4<<8)} {}
RESCODE SQLITE_CORRUPT_VTAB            {SQLITE_CORRUPT | (1<<8)} {}
RESCODE SQLITE_READONLY_RECOVERY       {SQLITE_READONLY | (1<<8)} {}
RESCODE SQLITE_READONLY_CANTLOCK       {SQLITE_READONLY | (2<<8)} {}
RESCODE SQLITE_READONLY_ROLLBACK       {SQLITE_READONLY | (3<<8)} {}
RESCODE SQLITE_READONLY_DBMOVED        {SQLITE_READONLY | (4<<8)} {}
RESCODE SQLITE_ABORT_ROLLBACK          {SQLITE_ABORT | (2<<8)} {}
RESCODE SQLITE_CONSTRAINT_CHECK        {SQLITE_CONSTRAINT | (1<<8)} {}
RESCODE SQLITE_CONSTRAINT_COMMITHOOK   {SQLITE_CONSTRAINT | (2<<8)} {}
RESCODE SQLITE_CONSTRAINT_FOREIGNKEY   {SQLITE_CONSTRAINT | (3<<8)} {}
RESCODE SQLITE_CONSTRAINT_FUNCTION     {SQLITE_CONSTRAINT | (4<<8)} {}
RESCODE SQLITE_CONSTRAINT_NOTNULL      {SQLITE_CONSTRAINT | (5<<8)} {}
RESCODE SQLITE_CONSTRAINT_PRIMARYKEY   {SQLITE_CONSTRAINT | (6<<8)} {}
RESCODE SQLITE_CONSTRAINT_TRIGGER      {SQLITE_CONSTRAINT | (7<<8)} {}
RESCODE SQLITE_CONSTRAINT_UNIQUE       {SQLITE_CONSTRAINT | (8<<8)} {}
RESCODE SQLITE_CONSTRAINT_VTAB         {SQLITE_CONSTRAINT | (9<<8)} {}
RESCODE SQLITE_CONSTRAINT_ROWID        {SQLITE_CONSTRAINT |(10<<8)} {}
RESCODE SQLITE_NOTICE_RECOVER_WAL      {SQLITE_NOTICE | (1<<8)} {}
RESCODE SQLITE_NOTICE_RECOVER_ROLLBACK {SQLITE_NOTICE | (2<<8)} {}
RESCODE SQLITE_WARNING_AUTOINDEX       {SQLITE_WARNING | (1<<8)} {}

#############################################################################
# Code to process the RESCODE values
#
# Convert formula RESCODE values into numerics
set nResCode 0
set nPrimCode 0
set nExtCode 0
set nNonError 3
unset -nocomplain prim_rc
unset -nocomplain ext_rc
foreach name [array names resvalue] {
  set val $resvalue($name)
  if {[regexp {^(SQLITE_[^ ]+) *\| *\((\d+)<<8\)$} $val all basename hival]} {
    set val [expr {$resvalue($basename)+($hival<<8)}]
    set resvalue($name) $val
  }
  set valtoname($val) $name
  incr nResCode
  if {$val<256} {
    incr nPrimCode
    set prim_rc($name) $val
  } else {
    incr nExtCode
    set ext_rc($name) $val
  }
}

hd_puts "<h2>Primary Result Code List</h2>\n"
hd_puts "<p>The $nPrimCode result codes"
</tcl>
  are [result code definitions|defined in sqlite3.h] and are
  listed in alphabetical order below:
  <table border=0 width="100%" cellpadding=10>
  <tr><td valign="top" align="left"><ul>
<tcl>
set nrow [expr {($nPrimCode+2)/3}]
set i 0
foreach name [lsort [array names prim_rc]] {
  if {$i==$nrow} {
    hd_puts "</ul></td><td valign=\"top\" align=\"left\"><ul>\n"
    set i 0
  }
  incr i
  hd_resolve "<li> \[$name\] ($prim_rc($name))\n"
}
hd_puts "</td></td></table>\n\n"

hd_fragment extrc {extended result code} {extended result codes} \
                  {extended error code} {extended error codes}
hd_puts "<h2>Extended Result Code List</h2>\n"
hd_puts "<p>The $nExtCode extended result codes"
</tcl>
  are [extended result code definitions|defined in sqlite3.h] and are
  listed in alphabetical order below:
  <table border=0 width="100%" cellpadding=10>
  <tr><td valign="top" align="left"><ul>
<tcl>
set nrow [expr {($nExtCode+1)/2}]
set i 0
foreach name [lsort [array names ext_rc]] {
  if {$i==$nrow} {
    hd_puts "</ul></td><td valign=\"top\" align=\"left\"><ul>\n"
    set i 0
  }
  incr i
  hd_resolve "<li> \[$name\] ($ext_rc($name))\n"
}
hd_puts "</td></td></table>\n\n"

hd_puts "
<h2>Result Code Meanings</h2>
<p>
The meanings for all $nResCode result code values are shown below,
in numeric order.
"

# Generate the table of result codes
#
foreach val [lsort -int [array names valtoname]] {
  set name $valtoname($val)
  regsub {sqlite_} [string tolower $name] {} tag
  hd_puts "<!--------------------------------------------------------------->\n"
  hd_fragment $tag --override $name
  hd_puts "<h3>($val) $valtoname($val)</h3>\n"
  hd_resolve $resdesc($name)\n\n
}

</tcl>
