Small. Fast. Reliable.
Choose any three.
*** 5,18 ****
  You can get the codes like this assuming res contains a result:
  
    #define RESULT_CODE(res)             ((res)&0xff)
!   #define EXTENDED_RESULT_CODE(res)    ((res)&~0xff)
! 
  
  The symbolic name for an extended result code always contains a related primary result code as a prefix. Primary result codes contain a single "_" character. Extended result codes contain two or more "_" characters. The numeric value of an extended result code can be converted to its corresponding primary result code by masking off the lower 8 bits.
  
  A complete list of available extended result codes and details about the meaning of the various extended result codes can be found by consulting the C code, especially the sqlite3.h header file and its antecedent sqlite.h.in.
  
! As of 3.3.8, this is the list:
  
    #define SQLITE_IOERR_READ          (SQLITE_IOERR | (1<<8))
    #define SQLITE_IOERR_SHORT_READ    (SQLITE_IOERR | (2<<8))
--- 5,17 ----
  You can get the codes like this assuming res contains a result:
  
    #define RESULT_CODE(res)             ((res)&0xff)
!   #define EXTENDED_RESULT_CODE(res)    (res)
  
  The symbolic name for an extended result code always contains a related primary result code as a prefix. Primary result codes contain a single "_" character. Extended result codes contain two or more "_" characters. The numeric value of an extended result code can be converted to its corresponding primary result code by masking off the lower 8 bits.
  
  A complete list of available extended result codes and details about the meaning of the various extended result codes can be found by consulting the C code, especially the sqlite3.h header file and its antecedent sqlite.h.in.
  
! As of 3.3.8, this is the list.  Note how SQLITE_IOERR is the standard result code (in the low byte) with the upper bytes containing more detail.
  
    #define SQLITE_IOERR_READ          (SQLITE_IOERR | (1<<8))
    #define SQLITE_IOERR_SHORT_READ    (SQLITE_IOERR | (2<<8))