# page_content

c2: Atomic Commit In SQLite
c5: atomiccommit.html
c4:
1.  Introduction

An important feature of transactional databases like SQLite
is "atomic commit".  
Atomic commit means that either all database changes within a single 
transaction occur or none of them occur.  With atomic commit, it
is as if many different writes to different sections of the database
file occur instantaneously and simultaneously.
Real hardware serializes writes to mass storage, and writing
a single sector takes a finite amount of time.
So it is impossible to truly write many different sectors of a 
database file simultaneously and/or instantaneously.
But the atomic commit logic within
SQLite makes it appear as if the changes for a transaction
are all written instantaneously and simultaneously.

SQLite has the important property that transactions appear
to be atomic even if the transaction is interrupted by an
operating system crash or power failure.

This article describes the techniques used by SQLite to create the
illusion of atomic commit.

The information in this article applies only when SQLite is operating
in "rollback mode", or in other words when SQLite is not 
using a write-ahead log.  SQLite still supports atomic commit when
write-ahead logging is enabled, but it accomplishes atomic commit by
a different mechanism from the one described in this article.  See
the write-ahead log documentation for additional information on how
SQLite supports atomic commit in that context.



2.  Hardware Assumptions

Throughout this article, we will call the mass storage device "disk"
even though the mass storage device might really be flash memory.

We assume that disk is written in chunks which we call a "sector".
It is not possible to modify any part of the disk smaller than a sector.
To change a part of the disk smaller than a sector, you have to read in
the full sector that contains the part you want to change, make the
change, then write back out the complete sector.

On a traditional spinning disk, a sector is the minimum unit of transfer
in both directions, both reading and writing.  On flash memory, however,
the minimum size of a read is typically much smaller than a minimum write.
SQLite is only concerned with the minimum write amount and so for the
purposes of this article, when we say "sector" we mean the minimum amount
of data that can be written to mass storage in a single go.


  Prior to SQLite version 3.3.14, a sector size of 512 bytes was
  assumed in all cases.  There was a compile-time option to change
  this but the code had never been tested with a larger value.  The
  512 byte sector assumption seemed reasonable since until very recently
  all disk drives used a 512 byte sector internally.  However, there
  has recently been a push to increase the sector size of disks to
  4096 bytes.  Also the sector size
  for flash memory is usually larger than 512 bytes.  For these reasons,
  versions of SQLite beginning with 3.3.14 have a method in the OS
  interface layer that interrogates the underlying filesystem to find
  the true sector size.  As currently implemented (version 3.5.0) this
  method still returns a hard-coded value of 512 bytes, since there
  is no standard way of discovering the true sector size on either
  Unix or Windows.  But the method is available for embedded device
  manufacturers to tweak according to their own needs.  And we have
  left open the possibility of filling in a more meaningful implementation
  on Unix and Windows in the future.

SQLite has traditionally assumed that a sector write is not atomic.
However, SQLite does always assume that a sector write is linear.  By "linear"
we mean that SQLite assumes that when writing a sector, the hardware begins
at one end of the data and writes byte by byte until it gets to
the other end.  The write might go from beginning to end or from
end to beginning.  If a power failure occurs in the middle of a
sector write it might be that part of the sector was modified
and another part was left unchanged.  The key assumption by SQLite
is that if any part of the sector gets changed, then either the
first or the last bytes will be changed.  So the hardware will
never start writing a sector in the middle and work towards the
ends.  We do not know if this assumption is always true but it
seems reasonable.

The previous paragraph states that SQLite does not assume that
sector writes are atomic.  This is true by default.  But as of
SQLite version 3.5.0, there is a new interface called the
Virtual File System (VFS) interface.  The VFS is the only means
by which SQLite communicates to the underlying filesystem.  The
code comes with default VFS implementations for Unix and Windows
and there is a mechanism for creating new custom VFS implementations
at runtime.  In this new VFS interface there is a method called
xDeviceCharacteristics.  This method interrogates the underlying
filesystem to discover various properties and behaviors that the
filesystem may or may not exhibit.  The xDeviceCharacteristics
method might indicate that sector writes are atomic, and if it does
so indicate, SQLite will try to take advantage of that fact.  But
the default xDeviceCharacteristics method for both Unix and Windows
does not indicate atomic sector writes and so these optimizations
are normally omitted.

SQLite assumes that the operating system will buffer writes and
that a write request will return before data has actually been stored
in the mass storage device.
SQLite further assumes that write operations will be reordered by
the operating system.
For this reason, SQLite does a "flush" or "fsync" operation at key
points.  SQLite assumes that the flush or fsync will not return until
all pending write operations for the file that is being flushed have
completed.  We are told that the flush and fsync primitives
are broken on some versions of Windows and Linux.  This is unfortunate.
It opens SQLite up to the possibility of database corruption following
a power loss in the middle of a commit.  However, there is nothing 
that SQLite can do to test for or remedy the situation.  SQLite
assumes that the operating system that it is running on works as
advertised.  If that is not quite the case, well then hopefully you
will not lose power too often.

SQLite assumes that when a file grows in length that the new
file space originally contains garbage and then later is filled in
with the data actually written.  In other words, SQLite assumes that
the file size is updated before the file content.  This is a 
pessimistic assumption and SQLite has to do some extra work to make
sure that it does not cause database corruption if power is lost
between the time when the file size is increased and when the
new content is written.  The xDeviceCharacteristics method of
the VFS might indicate that the filesystem will always write the
data before updating the file size.  (This is the 
SQLITE_IOCAP_SAFE_APPEND property for those readers who are looking
at the code.)  When the xDeviceCharacteristics method indicates
that files content is written before the file size is increased,
SQLite can forego some of its pedantic database protection steps
and thereby decrease the amount of disk I/O needed to perform a
commit.  The current implementation, however, makes no such assumptions
for the default VFSes for Windows and Unix.

SQLite assumes that a file deletion is atomic from the
point of view of a user process.  By this we mean that if SQLite
requests that a file be deleted and the power is lost during the
delete operation, once power is restored either the file will
exist completely with all if its original content unaltered, or
else the file will not be seen in the filesystem at all.  If
after power is restored the file is only partially deleted,
if some of its data has been altered or erased,
or the file has been truncated but not completely removed, then
database corruption will likely result.

SQLite assumes that the detection and/or correction of 
bit errors caused by cosmic rays, thermal noise, quantum
fluctuations, device driver bugs, or other mechanisms, is the 
responsibility of the underlying hardware and operating system.  
SQLite does not add any redundancy to the database file for
the purpose of detecting corruption or I/O errors.
SQLite assumes that the data it reads is exactly the same data 
that it previously wrote.

By default, SQLite assumes that an operating system call to write
a range of bytes will not damage or alter any bytes outside of that range
even if a power loss or OS crash occurs during that write.  We
call this the "powersafe overwrite" property.  
Prior to version 3.7.9 (2011-11-01),
SQLite did not assume powersafe overwrite.  But with the standard
sector size increasing from 512 to 4096 bytes on most disk drives, it
has become necessary to assume powersafe overwrite in order to maintain
historical performance levels and so powersafe overwrite is assumed by
default in recent versions of SQLite.  The assumption of powersafe 
overwrite property can be disabled at compile-time or a run-time if
desired.  See the powersafe overwrite documentation for further
details.



3.  Single File Commit

We begin with an overview of the steps SQLite takes in order to
perform an atomic commit of a transaction against a single database
file.  The details of file formats used to guard against damage from
power failures and techniques for performing an atomic commit across
multiple databases are discussed in later sections.



3.1.  Initial State



The state of the computer when a database connection is
first opened is shown conceptually by the diagram at the
right.
The area of the diagram on the extreme right (labeled "Disk") represents
information stored on the mass storage device.  Each rectangle is
a sector.  The blue color represents that the sectors contain
original data.
The middle area is the operating systems disk cache.  At the
onset of our example, the cache is cold and this is represented
by leaving the rectangles of the disk cache empty.
The left area of the diagram shows the content of memory for
the process that is using SQLite.  The database connection has
just been opened and no information has been read yet, so the
user space is empty.





3.2.  Acquiring A Read Lock



Before SQLite can write to a database, it must first read
the database to see what is there already.  Even if it is just
appending new data, SQLite still has to read in the database
schema from the "sqlite_schema" table so that it can know
how to parse the INSERT statements and discover where in the
database file the new information should be stored.

The first step toward reading from the database file
is obtaining a shared lock on the database file.  A "shared"
lock allows two or more database connections to read from the
database file at the same time.  But a shared lock prevents
another database connection from writing to the database file
while we are reading it.  This is necessary because if another
database connection were writing to the database file at the
same time we are reading from the database file, we might read
some data before the change and other data after the change.
This would make it appear as if the change made by the other
process is not atomic.

Notice that the shared lock is on the operating system
disk cache, not on the disk itself.  File locks
really are just flags within the operating system kernel,
usually.  (The details depend on the specific OS layer
interface.)  Hence, the lock will instantly vanish if the
operating system crashes or if there is a power loss.  It
is usually also the case that the lock will vanish if the
process that created the lock exits.




3.3.  Reading Information Out Of The Database



After the shared lock is acquired, we can begin reading
information from the database file.  In this scenario, we
are assuming a cold cache, so information must first be
read from mass storage into the operating system cache then
transferred from operating system cache into user space.
On subsequent reads, some or all of the information might
already be found in the operating system cache and so only
the transfer to user space would be required.

Usually only a subset of the pages in the database file
are read.  In this example we are showing three
pages out of eight being read.  In a typical application, a
database will have thousands of pages and a query will normally
only touch a small percentage of those pages.





3.4.  Obtaining A Reserved Lock



Before making changes to the database, SQLite first
obtains a "reserved" lock on the database file.  A reserved
lock is similar to a shared lock in that both a reserved lock
and shared lock allow other processes to read from the database
file.  A single reserve lock can coexist with multiple shared
locks from other processes.  However, there can only be a
single reserved lock on the database file.  Hence only a
single process can be attempting to write to the database
at one time.

The idea behind a reserved lock is that it signals that
a process intends to modify the database file in the near
future but has not yet started to make the modifications.
And because the modifications have not yet started, other
processes can continue to read from the database.  However,
no other process should also begin trying to write to the
database.



3.5.  Creating A Rollback Journal File


Prior to making any changes to the database file, SQLite first
creates a separate rollback journal file and writes into the 
rollback journal the original
content of the database pages that are to be altered.
The idea behind the rollback journal is that it contains
all information needed to restore the database back to 
its original state.

The rollback journal contains a small header (shown in green
in the diagram) that records the original size of the database
file.  So if a change causes the database file to grow, we
will still know the original size of the database.  The page
number is stored together with each database page that is 
written into the rollback journal.


  When a new file is created, most desktop operating systems
  (Windows, Linux, Mac OS X) will not actually write anything to
  disk.  The new file is created in the operating systems disk
  cache only.  The file is not created on mass storage until sometime
  later, when the operating system has a spare moment.  This creates
  the impression to users that I/O is happening much faster than
  is possible when doing real disk I/O.  We illustrate this idea in
  the diagram to the right by showing that the new rollback journal
  appears in the operating system disk cache only and not on the
  disk itself.



3.6.  Changing Database Pages In User Space


After the original page content has been saved in the rollback
journal, the pages can be modified in user memory.  Each database
connection has its own private copy of user space, so the changes
that are made in user space are only visible to the database connection
that is making the changes.  Other database connections still see
the information in operating system disk cache buffers which have
not yet been changed.  And so even though one process is busy
modifying the database, other processes can continue to read their
own copies of the original database content.



3.7.  Flushing The Rollback Journal File To Mass Storage


The next step is to flush the content of the rollback journal
file to nonvolatile storage.
As we will see later, 
this is a critical step in insuring that the database can survive
an unexpected power loss.
This step also takes a lot of time, since writing to nonvolatile
storage is normally a slow operation.

This step is usually more complicated than simply flushing
the rollback journal to the disk.  On most platforms two separate
flush (or fsync()) operations are required.  The first flush writes
out the base rollback journal content.  Then the header of the
rollback journal is modified to show the number of pages in the 
rollback journal.  Then the header is flushed to disk.  The details
on why we do this header modification and extra flush are provided
in a later section of this paper.



3.8.  Obtaining An Exclusive Lock


Prior to making changes to the database file itself, we must
obtain an exclusive lock on the database file.  Obtaining an
exclusive lock is really a two-step process.  First SQLite obtains
a "pending" lock.  Then it escalates the pending lock to an
exclusive lock.

A pending lock allows other processes that already have a
shared lock to continue reading the database file.  But it
prevents new shared locks from being established.  The idea
behind a pending lock is to prevent writer starvation caused
by a large pool of readers.  There might be dozens, even hundreds,
of other processes trying to read the database file.  Each process
acquires a shared lock before it starts reading, reads what it
needs, then releases the shared lock.  If, however, there are
many different processes all reading from the same database, it
might happen that a new process always acquires its shared lock before
the previous process releases its shared lock.  And so there is
never an instant when there are no shared locks on the database
file and hence there is never an opportunity for the writer to
seize the exclusive lock.  A pending lock is designed to prevent
that cycle by allowing existing shared locks to proceed but
blocking new shared locks from being established.  Eventually
all shared locks will clear and the pending lock will then be
able to escalate into an exclusive lock.



3.9.  Writing Changes To The Database File


Once an exclusive lock is held, we know that no other
processes are reading from the database file and it is
safe to write changes into the database file.  Usually
those changes only go as far as the operating systems disk
cache and do not make it all the way to mass storage.



3.10. 0 Flushing Changes To Mass Storage


Another flush must occur to make sure that all the
database changes are written into nonvolatile storage.
This is a critical step to ensure that the database will
survive a power loss without damage.  However, because
of the inherent slowness of writing to disk or flash memory, 
this step together with the rollback journal file flush in section
3.7 above takes up most of the time required to complete a
transaction commit in SQLite.



3.11. 1 Deleting The Rollback Journal


After the database changes are all safely on the mass
storage device, the rollback journal file is deleted.
This is the instant where the transaction commits.
If a power failure or system crash occurs prior to this
point, then recovery processes to be described later make
it appear as if no changes were ever made to the database
file.  If a power failure or system crash occurs after
the rollback journal is deleted, then it appears as if
all changes have been written to disk.  Thus, SQLite gives
the appearance of having made no changes to the database
file or having made the complete set of changes to the
database file depending on whether or not the rollback
journal file exists.

Deleting a file is not really an atomic operation, but
it appears to be from the point of view of a user process.
A process is always able to ask the operating system "does
this file exist?" and the process will get back a yes or no
answer.  After a power failure that occurs during a 
transaction commit, SQLite will ask the operating system
whether or not the rollback journal file exists.  If the
answer is "yes" then the transaction is incomplete and is
rolled back.  If the answer is "no" then it means the transaction
did commit.

The existence of a transaction depends on whether or
not the rollback journal file exists and the deletion
of a file appears to be an atomic operation from the point of
view of a user-space process.  Therefore, 
a transaction appears to be an atomic operation.

The act of deleting a file is expensive on many systems.
As an optimization, SQLite can be configured to truncate
the journal file to zero bytes in length
or overwrite the journal file header with zeros.  In either
case, the resulting journal file is no longer capable of rolling
back and so the transaction still commits.  Truncating a file
to zero length, like deleting a file, is assumed to be an atomic
operation from the point of view of a user process.  Overwriting
the header of the journal with zeros is not atomic, but if any
part of the header is malformed the journal will not roll back.
Hence, one can say that the commit occurs as soon as the header
is sufficiently changed to make it invalid.  Typically this happens
as soon as the first byte of the header is zeroed.



3.12. 2 Releasing The Lock


The last step in the commit process is to release the
exclusive lock so that other processes can once again
start accessing the database file.

In the diagram at the right, we show that the information
that was held in user space is cleared when the lock is released.
This used to be literally true for older versions of SQLite.  But
more recent versions of SQLite keep the user space information
in memory in case it might be needed again at the start of the
next transaction.  It is cheaper to reuse information that is
already in local memory than to transfer the information back
from the operating system disk cache or to read it off of the
disk drive again.  Prior to reusing the information in user space,
we must first reacquire the shared lock and then we have to check
to make sure that no other process modified the database file while
we were not holding a lock.  There is a counter in the first page
of the database that is incremented every time the database file
is modified.  We can find out if another process has modified the
database by checking that counter.  If the database was modified,
then the user space cache must be cleared and reread.  But it is
commonly the case that no changes have been made and the user
space cache can be reused for a significant performance savings.




4.  Rollback

An atomic commit is supposed to happen instantaneously.  But the processing
described above clearly takes a finite amount of time.
Suppose the power to the computer were cut
part way through the commit operation described above.  In order
to maintain the illusion that the changes were instantaneous, we
have to "rollback" any partial changes and restore the database to
the state it was in prior to the beginning of the transaction.



4.1.  When Something Goes Wrong...


Suppose the power loss occurred
during step 3.10 above,
while the database changes were being written to disk.
After power is restored, the situation might be something
like what is shown to the right.  We were trying to change
three pages of the database file but only one page was
successfully written.  Another page was partially written
and a third page was not written at all.

The rollback journal is complete and intact on disk when
the power is restored.  This is a key point.  The reason for
the flush operation in step 3.7
is to make absolutely sure that
all of the rollback journal is safely on nonvolatile storage
prior to making any changes to the database file itself.



4.2.  Hot Rollback Journals


The first time that any SQLite process attempts to access
the database file, it obtains a shared lock as described in
section 3.2 above.
But then it notices that there is a 
rollback journal file present.  SQLite then checks to see if
the rollback journal is a "hot journal".   A hot journal is
a rollback journal that needs to be played back in order to
restore the database to a sane state.  A hot journal only
exists when an earlier process was in the middle of committing
a transaction when it crashed or lost power.

A rollback journal is a "hot" journal if all of the following
are true:


The rollback journal exists.
The rollback journal is not an empty file.
There is no reserved lock on the main database file.
The header of the rollback journal is well-formed and in particular
    has not been zeroed out.
The rollback journal does not
contain the name of a super-journal file (see
section 5.5 below) or if does
contain the name of a super-journal, then that super-journal
file exists.


The presence of a hot journal is our indication
that a previous process was trying to commit a transaction but
it aborted for some reason prior to the completion of the
commit.  A hot journal means that
the database file is in an inconsistent state and needs to
be repaired (by rollback) prior to being used.




4.3.  Obtaining An Exclusive Lock On The Database


The first step toward dealing with a hot journal is to
obtain an exclusive lock on the database file.  This prevents two
or more processes from trying to rollback the same hot journal
at the same time.



4.4.  Rolling Back Incomplete Changes


Once a process obtains an exclusive lock, it is permitted
to write to the database file.  It then proceeds to read the
original content of pages out of the rollback journal and write
that content back to where it came from in the database file.
Recall that the header of the rollback journal records the original
size of the database file prior to the start of the aborted
transaction.  SQLite uses this information to truncate the
database file back to its original size in cases where the
incomplete transaction caused the database to grow.  At the
end of this step, the database should be the same size and
contain the same information as it did before the start of
the aborted transaction.




4.5.  Deleting The Hot Journal


After all information in the rollback journal has been
played back into the database file (and flushed to disk in case
we encounter yet another power failure), the hot rollback journal
can be deleted.

As in section 3.11, the journal
file might be truncated to zero length or its header might
be overwritten with zeros as an optimization on systems where
deleting a file is expensive.  Either way, the journal is no 
longer hot after this step.




4.6.  Continue As If The Uncompleted Writes Had Never Happened


The final recovery step is to reduce the exclusive lock back
to a shared lock.  Once this happens, the database is back in the
state that it would have been if the aborted transaction had never
started.  Since all of this recovery activity happens completely
automatically and transparently, it appears to the program using
SQLite as if the aborted transaction had never begun.




5.  Multi-file Commit

SQLite allows a single 
database connection to talk to
two or more database files simultaneously through the use of
the ATTACH DATABASE command.
When multiple database files are modified within a single
transaction, all files are updated atomically.  
In other words, either all of the database files are updated or
else none of them are.
Achieving an atomic commit across multiple database files is
more complex that doing so for a single file.  This section
describes how SQLite works that bit of magic.



5.1.  Separate Rollback Journals For Each Database


When multiple database files are involved in a transaction,
each database has its own rollback journal and each database
is locked separately.  The diagram at the right shows a scenario
where three different database files have been modified within
one transaction.  The situation at this step is analogous to 
the single-file transaction scenario at 
step 3.6.  Each database file has
a reserved lock.  For each database, the original content of pages 
that are being changed have been written into the rollback journal
for that database, but the content of the journals have not yet
been flushed to disk.  No changes have been made to the database
file itself yet, though presumably there are changes being held
in user memory.

For brevity, the diagrams in this section are simplified from
those that came before.  Blue color still signifies original content
and pink still signifies new content.  But the individual pages
in the rollback journal and the database file are not shown and
we are not making the distinction between information in the
operating system cache and information that is on disk.  All of
these factors still apply in a multi-file commit scenario.  They
just take up a lot of space in the diagrams and they do not add
any new information, so they are omitted here.




5.2.  The Super-Journal File


The next step in a multi-file commit is the creation of a
"super-journal" file.  The name of the super-journal file is
the same name as the original database filename (the database
that was opened using the 
sqlite3_open() interface,
not one of the ATTACHed auxiliary
databases) with the text "-mjHHHHHHHH" appended where
HHHHHHHH is a random 32-bit hexadecimal number.  The
random HHHHHHHH suffix changes for every new super-journal.

(Nota bene: The formula for computing the super-journal filename
given in the previous paragraph corresponds to the implementation as
of SQLite version 3.5.0.  But this formula is not part of the SQLite
specification and is subject to change in future releases.)

Unlike the rollback journals, the super-journal does not contain
any original database page content.  Instead, the super-journal contains
the full pathnames for rollback journals for every database that is
participating in the transaction.

After the super-journal is constructed, its content is flushed
to disk before any further actions are taken.  On Unix, the directory
that contains the super-journal is also synced in order to make sure
the super-journal file will appear in the directory following a
power failure.

The purpose of the super-journal is to ensure that multi-file
transactions are atomic across a power-loss.  But if the database files
have other settings that compromise integrity across a power-loss event
(such as PRAGMA synchronous=OFF or PRAGMA journal_mode=MEMORY) then
the creation of the super-journal is omitted, as an optimization.




5.3.  Updating Rollback Journal Headers


The next step is to record the full pathname of the super-journal file
in the header of every rollback journal.  Space to hold the 
super-journal filename was reserved at the beginning of each rollback journal
as the rollback journals were created.

The content of each rollback journal is flushed to disk both before
and after the super-journal filename is written into the rollback
journal header.  It is important to do both of these flushes.  Fortunately,
the second flush is usually inexpensive since typically only a single
page of the journal file (the first page) has changed.

This step is analogous to 
step 3.7 in the single-file commit
scenario described above.




5.4.  Updating The Database Files


Once all rollback journal files have been flushed to disk, it
is safe to begin updating database files.  We have to obtain an
exclusive lock on all database files before writing the changes.
After all the changes are written, it is important to flush the
changes to disk so that they will be preserved in the event of
a power failure or operating system crash.

This step corresponds to steps
3.8,
3.9, and
3.10 in the single-file commit
scenario described previously.




5.5.  Delete The Super-Journal File


The next step is to delete the super-journal file.
This is the point where the multi-file transaction commits.
This step corresponds to 
step 3.11 in the single-file
commit scenario where the rollback journal is deleted.

If a power failure or operating system crash occurs at this
point, the transaction will not rollback when the system reboots
even though there are rollback journals present.  The
difference is the super-journal pathname in the header of the
rollback journal.  Upon restart, SQLite only considers a journal
to be hot and will only playback the journal if there is no
super-journal filename in the header (which is the case for
a single-file commit) or if the super-journal file still
exists on disk.




5.6.  Clean Up The Rollback Journals


The final step in a multi-file commit is to delete the
individual rollback journals and drop the exclusive locks on
the database files so that other processes can see the changes.
This corresponds to 
step 3.12 in the single-file
commit sequence.

The transaction has already committed at this point so timing
is not critical in the deletion of the rollback journals.
The current implementation deletes a single rollback journal
then unlocks the corresponding database file before proceeding
to the next rollback journal.  But in the future we might change
this so that all rollback journals are deleted before any database
files are unlocked.  As long as the rollback journal is deleted before
its corresponding database file is unlocked it does not matter in what
order the rollback journals are deleted or the database files are
unlocked.



6.  Additional Details Of The Commit Process

Section 3.0 above provides an overview of
how atomic commit works in SQLite.  But it glosses over a number of
important details.  The following subsections will attempt to fill
in the gaps.



6.1.  Always Journal Complete Sectors

When the original content of a database page is written into
the rollback journal (as shown in section 3.5),
SQLite always writes a complete sector of data, even if the
page size of the database is smaller than the sector size.  
Historically, the sector size in SQLite has been hard coded to 512
bytes and since the minimum page size is also 512 bytes, this has never
been an issue.  But beginning with SQLite version 3.3.14, it is possible
for SQLite to use mass storage devices with a sector size larger than 512
bytes.  So, beginning with version 3.3.14, whenever any page within a
sector is written into the journal file, all pages in that same sector
are stored with it.

It is important to store all pages of a sector in the rollback
journal in order to prevent database corruption following a power
loss while writing the sector.  Suppose that pages 1, 2, 3, and 4 are
all stored in sector 1 and that page 2 is modified.  In order to write
the changes to page 2, the underlying hardware must also rewrite the
content of pages 1, 3, and 4 since the hardware must write the complete
sector.  If this write operation is interrupted by a power outage,
one or more of the pages 1, 3, or 4 might be left with incorrect data.
Hence, to avoid lasting corruption to the database, the original content
of all of those pages must be contained in the rollback journal.



6.2.  Dealing With Garbage Written Into Journal Files

When data is appended to the end of the rollback journal,
SQLite normally makes the pessimistic assumption that the file
is first extended with invalid "garbage" data and that afterwards
the correct data replaces the garbage.  In other words, SQLite assumes
that the file size is increased first and then afterwards the content
is written into the file.  If a power failure occurs after the file
size has been increased but before the file content has been written,
the rollback journal can be left containing garbage data.  If after
power is restored, another SQLite process sees the rollback journal
containing the garbage data and tries to roll it back into the original
database file, it might copy some of the garbage into the database file
and thus corrupt the database file.

SQLite uses two defenses against this problem.  In the first place,
SQLite records the number of pages in the rollback journal in the header
of the rollback journal.  This number is initially zero.  So during an
attempt to rollback an incomplete (and possibly corrupt) rollback
journal, the process doing the rollback will see that the journal
contains zero pages and will thus make no changes to the database.  Prior
to a commit, the rollback journal is flushed to disk to ensure that
all content has been synced to disk and there is no "garbage" left
in the file, and only then is the page count in the header changed from
zero to true number of pages in the rollback journal.  The rollback journal
header is always kept in a separate sector from any page data so that
it can be overwritten and flushed without risking damage to a data
page if a power outage occurs.  Notice that the rollback journal
is flushed to disk twice: once to write the page content and a second
time to write the page count in the header.

The previous paragraph describes what happens when the
synchronous pragma setting is "full".


PRAGMA synchronous=FULL;


The default synchronous setting is full so the above is what usually
happens.  However, if the synchronous setting is lowered to "normal",
SQLite only flushes the rollback journal once, after the page count has
been written.
This carries a risk of corruption because it might happen that the 
modified (non-zero) page count reaches the disk surface before all
of the data does.  The data will have been written first, but SQLite
assumes that the underlying filesystem can reorder write requests and
that the page count can be burned into oxide first even though its
write request occurred last.  So as a second line of defense, SQLite
also uses a 32-bit checksum on every page of data in the rollback
journal.  This checksum is evaluated for each page during rollback
while rolling back a journal as described in 
section 4.4.  If an incorrect checksum
is seen, the rollback is abandoned.  Note that the checksum does
not guarantee that the page data is correct since there is a small
but finite probability that the checksum might be right even if the data is
corrupt.  But the checksum does at least make such an error unlikely.


Note that the checksums in the rollback journal are not necessary
if the synchronous setting is FULL.  We only depend on the checksums
when synchronous is lowered to NORMAL.  Nevertheless, the checksums
never hurt and so they are included in the rollback journal regardless
of the synchronous setting.



6.3.  Cache Spill Prior To Commit

The commit process shown in section 3.0
assumes that all database changes fit in memory until it is time to
commit.  This is the common case.  But sometimes a larger change will
overflow the user-space cache prior to transaction commit.  In those
cases, the cache must spill to the database before the transaction
is complete.

At the beginning of a cache spill, the status of the database
connection is as shown in step 3.6.
Original page content has been saved in the rollback journal and
modifications of the pages exist in user memory.  To spill the cache,
SQLite executes steps 3.7 through
3.9.  In other words, the rollback journal
is flushed to disk, an exclusive lock is acquired, and changes are
written into the database.  But the remaining steps are deferred
until the transaction really commits.  A new journal header is
appended to the end of the rollback journal (in its own sector)
and the exclusive database lock is retained, but otherwise processing
returns to step 3.6.  When the transaction
commits, or if another cache spill occurs, steps
3.7 and 3.9 are
repeated.  (Step 3.8 is omitted on second
and subsequent passes since an exclusive database lock is already held
due to the first pass.)

A cache spill causes the lock on the database file to
escalate from reserved to exclusive.  This reduces concurrency.
A cache spill also causes extra disk flush or fsync operations to
occur and these operations are slow, hence a cache spill can
seriously reduce performance.
For these reasons a cache spill is avoided whenever possible.



7.  Optimizations

Profiling indicates that for most systems and in most circumstances
SQLite spends most of its time doing disk I/O.  It follows then that
anything we can do to reduce the amount of disk I/O will likely have a
large positive impact on the performance of SQLite.  This section
describes some of the techniques used by SQLite to try to reduce the
amount of disk I/O to a minimum while still preserving atomic commit.



7.1.  Cache Retained Between Transactions

Step 3.12 of the commit process shows
that once the shared lock has been released, all user-space cache
images of database content must be discarded.  This is done because
without a shared lock, other processes are free to modify the database
file content and so any user-space image of that content might become
obsolete.  Consequently, each new transaction would begin by rereading
data which had previously been read.  This is not as bad as it sounds
at first since the data being read is still likely in the operating
systems file cache.  So the "read" is really just a copy of data
from kernel space into user space.  But even so, it still takes time.

Beginning with SQLite version 3.3.14 a mechanism has been added
to try to reduce the needless rereading of data.  In newer versions
of SQLite, the data in the user-space pager cache is retained when
the lock on the database file is released.  Later, after the
shared lock is acquired at the beginning of the next transaction,
SQLite checks to see if any other process has modified the database
file.  If the database has been changed in any way since the lock
was last released, the user-space cache is erased at that point.
But commonly the database file is unchanged and the user-space cache
can be retained, and some unnecessary read operations can be avoided.

In order to determine whether or not the database file has changed,
SQLite uses a counter in the database header (in bytes 24 through 27)
which is incremented during every change operation.  SQLite saves a copy
of this counter prior to releasing its database lock.  Then after
acquiring the next database lock it compares the saved counter value
against the current counter value and erases the cache if the values
are different, or reuses the cache if they are the same.


7.2.  Exclusive Access Mode

SQLite version 3.3.14 adds the concept of "Exclusive Access Mode".
In exclusive access mode, SQLite retains the exclusive
database lock at the conclusion of each transaction.  This prevents
other processes from accessing the database, but in many deployments
only a single process is using a database so this is not a
serious problem.  The advantage of exclusive access mode is that
disk I/O can be reduced in three ways:


It is not necessary to increment the change counter in the
database header for transactions after the first transaction.  This
will often save a write of page one to both the rollback
journal and the main database file.

No other processes can change the database so there is never
a need to check the change counter and clear the user-space cache
at the beginning of a transaction.

Each transaction can be committed by overwriting the rollback
journal header with zeros rather than deleting the journal file.
This avoids having to modify the directory entry for the journal file
and it avoids having to deallocate disk sectors associated with the 
journal.  Furthermore, the next transaction will overwrite existing
journal file content rather than append new content and on most systems
overwriting is much faster than appending.


The third optimization, zeroing the journal file header rather than
deleting the rollback journal file,
does not depend on holding an exclusive lock at all times.
This optimization can be set independently of exclusive lock mode
using the journal_mode pragma
as described in section 7.6 below.



7.3.  Do Not Journal Freelist Pages

When information is deleted from an SQLite database, the pages used
to hold the deleted information are added to a "freelist".  Subsequent
inserts will draw pages off of this freelist rather than expanding the
database file.

Some freelist pages contain critical data; specifically the locations
of other freelist pages.  But most freelist pages contain nothing useful.
These latter freelist pages are called "leaf" pages.  We are free to
modify the content of a leaf freelist page in the database without
changing the meaning of the database in any way.

Because the content of leaf freelist pages is unimportant, SQLite
avoids storing leaf freelist page content in the rollback journal
in step 3.5 of the commit process.
If a leaf freelist page is changed and that change does not get rolled back
during a transaction recovery, the database is not harmed by the omission.
Similarly, the content of a new freelist page is never written back
into the database at step 3.9 nor
read from the database at step 3.3.
These optimizations can greatly reduce the amount of I/O that occurs
when making changes to a database file that contains free space.



7.4.  Single Page Updates And Atomic Sector Writes

Beginning in SQLite version 3.5.0, the new Virtual File System (VFS)
interface contains a method named xDeviceCharacteristics which reports
on special properties that the underlying mass storage device
might have.  Among the special properties that
xDeviceCharacteristics might report is the ability of to do an
atomic sector write.

Recall that by default SQLite assumes that sector writes are
linear but not atomic.  A linear write starts at one end of the
sector and changes information byte by byte until it gets to the
other end of the sector.  If a power loss occurs in the middle of
a linear write then part of the sector might be modified while the
other end is unchanged.  In an atomic sector write, either the entire
sector is overwritten or else nothing in the sector is changed.

We believe that most modern disk drives implement atomic sector
writes.  When power is lost, the drive uses energy stored in capacitors
and/or the angular momentum of the disk platter to provide power to 
complete any operation in progress.  Nevertheless, there are so many
layers in between the write system call and the on-board disk drive
electronics that we take the safe approach in both Unix and w32 VFS
implementations and assume that sector writes are not atomic.  On the
other hand, device
manufacturers with more control over their filesystems might want
to consider enabling the atomic write property of xDeviceCharacteristics
if their hardware really does do atomic writes.

When sector writes are atomic and the page size of a database is
the same as a sector size, and when there is a database change that
only touches a single database page, then SQLite skips the whole
journaling and syncing process and simply writes the modified page
directly into the database file.  The change counter in the first
page of the database file is modified separately since no harm is
done if power is lost before the change counter can be updated.



7.5.  Filesystems With Safe Append Semantics

Another optimization introduced in SQLite version 3.5.0 makes
use of "safe append" behavior of the underlying disk.
Recall that SQLite assumes that when data is appended to a file
(specifically to the rollback journal) that the size of the file
is increased first and that the content is written second.  So
if power is lost after the file size is increased but before the
content is written, the file is left containing invalid "garbage"
data.  The xDeviceCharacteristics method of the VFS might, however,
indicate that the filesystem implements "safe append" semantics.
This means that the content is written before the file size is
increased so that it is impossible for garbage to be introduced
into the rollback journal by a power loss or system crash.

When safe append semantics are indicated for a filesystem,
SQLite always stores the special value of -1 for the page count
in the header of the rollback journal.  The -1 page count value
tells any process attempting to rollback the journal that the
number of pages in the journal should be computed from the journal
size.  This -1 value is never changed.  So that when a commit
occurs, we save a single flush operation and a sector write of
the first page of the journal file.  Furthermore, when a cache
spill occurs we no longer need to append a new journal header
to the end of the journal; we can simply continue appending
new pages to the end of the existing journal.


7.6.  Persistent Rollback Journals

Deleting a file is an expensive operation on many systems.
So as an optimization, SQLite can be configured to avoid the
delete operation of section 3.11.
Instead of deleting the journal file in order to commit a transaction,
the file is either truncated to zero bytes in length or its
header is overwritten with zeros.  Truncating the file to zero
length saves having to make modifications to the directory containing
the file since the file is not removed from the directory. 
Overwriting the header has the additional savings of not having
to update the length of the file (in the "inode" on many systems)
and not having to deal with newly freed disk sectors.  Furthermore,
at the next transaction the journal will be created by overwriting
existing content rather than appending new content onto the end
of a file, and overwriting is often much faster than appending.

SQLite can be configured to commit transactions by overwriting
the journal header with zeros instead of deleting the journal file
by setting the "PERSIST" journaling mode using the 
journal_mode PRAGMA.
For example:


PRAGMA journal_mode=PERSIST;


The use of persistent journal mode provides a noticeable performance
improvement on many systems.  Of course, the drawback is that the 
journal files remain on the disk, using disk space and cluttering
directories, long after the transaction commits.  The only safe way
to delete a persistent journal file is to commit a transaction
with journaling mode set to DELETE:


PRAGMA journal_mode=DELETE;
BEGIN EXCLUSIVE;
COMMIT;


Beware of deleting persistent journal files by any other means
since the journal file might be hot, in which case deleting it will
corrupt the corresponding database file.

Beginning in SQLite version 3.6.4 (2008-10-15), 
the TRUNCATE journal mode is
also supported:


PRAGMA journal_mode=TRUNCATE;


In truncate journal mode, the transaction is committed by truncating
the journal file to zero length rather than deleting the journal file
(as in DELETE mode) or by zeroing the header (as in PERSIST mode).
TRUNCATE mode shares the advantage of PERSIST mode that the directory
that contains the journal file and database does not need to be updated.
Hence truncating a file is often faster than deleting it.  TRUNCATE has
the additional advantage that it is not followed by a
system call (ex: fsync()) to synchronize the change to disk.  It might
be safer if it did.
But on many modern filesystems, a truncate is an atomic and
synchronous operation and so we think that TRUNCATE will usually be safe
in the face of power failures.  If you are uncertain about whether or
not TRUNCATE will be synchronous and atomic on your filesystem and it is
important to you that your database survive a power loss or operating
system crash that occurs during the truncation operation, then you might
consider using a different journaling mode.

On embedded systems with synchronous filesystems, TRUNCATE results
in slower behavior than PERSIST.  The commit operation is the same speed.
But subsequent transactions are slower following a TRUNCATE because it is
faster to overwrite existing content than to append to the end of a file.
New journal file entries will always be appended following a TRUNCATE but
will usually overwrite with PERSIST.



8.  Testing Atomic Commit Behavior

The developers of SQLite are confident that it is robust
in the face of power failures and system crashes because the
automatic test procedures do extensive checks on
the ability of SQLite to recover from simulated power loss.
We call these the "crash tests".

Crash tests in SQLite use a modified VFS that can simulate
the kinds of filesystem damage that occur during a power
loss or operating system crash.  The crash-test VFS can simulate
incomplete sector writes, pages filled with garbage data because
a write has not completed, and out of order writes, all occurring
at varying points during a test scenario.  Crash tests execute
transactions over and over, varying the time at which a simulated
power loss occurs and the properties of the damage inflicted.
Each test then reopens the database after the simulated crash and
verifies that the transaction either occurred completely
or not at all and that the database is in a completely
consistent state.

The crash tests in SQLite have discovered a number of very
subtle bugs (now fixed) in the recovery mechanism.  Some of 
these bugs were very obscure and unlikely to have been found
using only code inspection and analysis techniques.  From this
experience, the developers of SQLite feel confident that any other
database system that does not use a similar crash test system
likely contains undetected bugs that will lead to database
corruption following a system crash or power failure.



9.  Things That Can Go Wrong

The atomic commit mechanism in SQLite has proven to be robust,
but it can be circumvented by a sufficiently creative
adversary or a sufficiently broken operating system implementation.
This section describes a few of the ways in which an SQLite database
might be corrupted by a power failure or system crash.
(See also: How To Corrupt Your Database Files.)



9.1.  Broken Locking Implementations

SQLite uses filesystem locks to make sure that only one
process and database connection is trying to modify the database
at a time.  The filesystem locking mechanism is implemented
in the VFS layer and is different for every operating system.
SQLite depends on this implementation being correct.  If something
goes wrong and two or more processes are able to write the same
database file at the same time, severe damage can result.

We have received reports of implementations of both
Windows network filesystems and NFS in which locking was
subtly broken.  We can not verify these reports, but as
locking is difficult to get right on a network filesystem
we have no reason to doubt them.  You are advised to 
avoid using SQLite on a network filesystem in the first place,
since performance will be slow.  But if you must use a 
network filesystem to store SQLite database files, consider
using a secondary locking mechanism to prevent simultaneous
writes to the same database even if the native filesystem
locking mechanism malfunctions.

The versions of SQLite that come preinstalled on Apple
Mac OS X computers contain a version of SQLite that has been
extended to use alternative locking strategies that work on
all network filesystems that Apple supports.  These extensions
used by Apple work great as long as all processes are accessing
the database file in the same way.  Unfortunately, the locking
mechanisms do not exclude one another, so if one process is
accessing a file using (for example) AFP locking and another
process (perhaps on a different machine) is using dot-file locks,
the two processes might collide because AFP locks do not exclude
dot-file locks or vice versa.



9.2.  Incomplete Disk Flushes

SQLite uses the fsync() system call on Unix and the FlushFileBuffers()
system call on w32 in order to sync the file system buffers onto disk
oxide as shown in step 3.7 and
step 3.10.  Unfortunately, we have received
reports that neither of these interfaces works as advertised on many
systems.  We hear that FlushFileBuffers() can be completely disabled
using registry settings on some Windows versions.  Some historical
versions of Linux contain versions of fsync() which are no-ops on
some filesystems, we are told.  Even on systems where 
FlushFileBuffers() and fsync() are said to be working, often
the IDE disk control lies and says that data has reached oxide
while it is still held only in the volatile control cache.

On the Mac, you can set this pragma:


PRAGMA fullfsync=ON;


Setting fullfsync on a Mac will guarantee that data really does
get pushed out to the disk platter on a flush.  But the implementation
of fullfsync involves resetting the disk controller.  And so not only
is it profoundly slow, it also slows down other unrelated disk I/O.
So its use is not recommended.



9.3.  Partial File Deletions

SQLite assumes that file deletion is an atomic operation from the
point of view of a user process.  If power fails in the middle of
a file deletion, then after power is restored SQLite expects to see
either the entire file with all of its original data intact, or it
expects not to find the file at all.  Transactions may not be atomic
on systems that do not work this way.



9.4.  Garbage Written Into Files

SQLite database files are ordinary disk files that can be
opened and written by ordinary user processes.  A rogue process
can open an SQLite database and fill it with corrupt data.  
Corrupt data might also be introduced into an SQLite database
by bugs in the operating system or disk controller; especially
bugs triggered by a power failure.  There is nothing SQLite can
do to defend against these kinds of problems.



9.5.  Deleting Or Renaming A Hot Journal

If a crash or power loss does occur and a hot journal is left on
the disk, it is essential that the original database file and the hot
journal remain on disk with their original names until the database
file is opened by another SQLite process and rolled back.  
During recovery at step 4.2 SQLite locates
the hot journal by looking for a file in the same directory as the
database being opened and whose name is derived from the name of the
file being opened.  If either the original database file or the
hot journal have been moved or renamed, then the hot journal will
not be seen and the database will not be rolled back.

We suspect that a common failure mode for SQLite recovery happens
like this:  A power failure occurs.  After power is restored, a well-meaning
user or system administrator begins looking around on the disk for
damage.  They see their database file named "important.data".  This file
is perhaps familiar to them.  But after the crash, there is also a
hot journal named "important.data-journal".  The user then deletes
the hot journal, thinking that they are helping to cleanup the system.
We know of no way to prevent this other than user education.

If there are multiple (hard or symbolic) links to a database file,
the journal will be created using the name of the link through which
the file was opened.  If a crash occurs and the database is opened again
using a different link, the hot journal will not be located and no
rollback will occur.

Sometimes a power failure will cause a filesystem to be corrupted
such that recently changed filenames are forgotten and the file is
moved into a "/lost+found" directory.  When that happens, the hot
journal will not be found and recovery will not occur.
SQLite tries to prevent this
by opening and syncing the directory containing the rollback journal
at the same time it syncs the journal file itself.  However, the
movement of files into /lost+found can be caused by unrelated processes
creating unrelated files in the same directory as the main database file.
And since this is out from under the control of SQLite, there is nothing
that SQLite can do to prevent it.  If you are running on a system that
is vulnerable to this kind of filesystem namespace corruption (most
modern journalling filesystems are immune, we believe) then you might
want to consider putting each SQLite database file in its own private
subdirectory.



10. 10.0 Future Directions And Conclusion

Every now and then someone discovers a new failure mode for
the atomic commit mechanism in SQLite and the developers have to
put in a patch.  This is happening less and less and the
failure modes are becoming more and more obscure.  But it would
still be foolish to suppose that the atomic commit logic of
SQLite is entirely bug-free.  The developers are committed to fixing
these bugs as quickly as they might be found.


The developers are also on the lookout for new ways to
optimize the commit mechanism.  The current VFS implementations
for Unix (Linux and Mac OS X) and Windows make pessimistic assumptions about
the behavior of those systems.  After consultation with experts
on how these systems work, we might be able to relax some of the
assumptions on these systems and allow them to run faster.  In
particular, we suspect that most modern filesystems exhibit the
safe append property and that many of them might support atomic
sector writes.  But until this is known for certain, SQLite will
take the conservative approach and assume the worst.


c2: The Use Of assert() In SQLite
c5: assert.html
c4:
1. Assert() And Similar Macros In SQLite


The assert(X) macro is 
part of standard C, in the
&lt;assert.h&gt; header file.
SQLite adds three other assert()-like macros named NEVER(X), ALWAYS(X),
and testcase(X).


assert(X) &rarr;
The assert(X) statement indicates that the condition X is always true.
In other words, X is an invariant.  The assert(X) macro works like a
procedure in that it has no return value.

ALWAYS(X) &rarr;
The ALWAYS(X) function indicates that condition X is always true as far
as the developers know, but there is no proof the X is true, or the
proof is complex and error-prone, or the proof depends on implementation
details that are likely to change in the future.  ALWAYS(X) behaves like
a function that returns the boolean value X, and is intended to be used
within the conditional of an "if" statement.

NEVER(X) &rarr;
The NEVER(X) function indicates that condition X is never true.  This
is the negative analog of the ALWAYS(X) function.

testcase(X) &rarr;
The testcase(X) statement indicates that X is sometimes true and sometimes
false.  In other words, testcase(X) indicates that X is definitely not an
invariant.  Since SQLite uses 100% MC/DC testing, the presence of a
testcase(X) macro indicates that not only is it possible for X to be either
true or false, but there are test cases to demonstrate this.



SQLite version 3.22.0 (2018-01-22) contains 5290 assert() macros,
839 testcase() macros, 88 ALWAYS() macros, and 63 NEVER() macros.

1.1. Philosophy of assert()

In SQLite, the presence of assert(X) means that the developers have
a proof that X is always true.  Readers can depend upon X being true to
help them reason about the code.  An assert(X) is a strong statement
about the truth of X.  There is no doubt.

The ALWAYS(X) and NEVER(X) macros are a weaker statement about the
truth of X.  The presence of ALWAYS(X) or NEVER(X) means that the developers
believe X is always or never true, but there is no proof, or the proof
is complex and error-prone, or the proof depends on other aspects 
of the system that seem likely to change.

Other systems sometimes use assert(X) in a way that is
similar to the use of ALWAYS(X) or NEVER(X) in SQLite.
Developers will add an assert(X) as a 
tacit acknowledgement that they
do not fully believe that X is always true.
We believe that this use of assert(X) is wrong and violates the intent
and purpose of having assert(X) available in C in the first place.
An assert(X) should not be seen as a safety-net or top-rope used to
guard against mistakes.  Nor is assert(X) appropriate for defense-in-depth.
An ALWAYS(X) or NEVER(X) macro, or something similar, should be used in 
those cases because ALWAYS(X) or NEVER(X) will be followed by code to
actually deal with the problem when the programmers reasoning
turns out to be wrong.  Since the code that follows ALWAYS(X) or NEVER(X)
is untested, it should be something very simple, like a "return" statement,
that is easily verified by inspection.


Because assert() can be and is commonly misused, some programming language
theorists and designers look upon it with disfavor.
For example, the designers of the Go programming language 
intentionally omit a built-in assert().
They feel that the harm caused by misuse of assert()
outweighs the benefits of including it as a language built-in.
The SQLite developers disagree.  In fact, the original purpose of this
article is to push back against the common notion that assert() is harmful.
In our experience, SQLite would be much more difficult to develop, test,
and maintain without assert().

1.2. Different Behaviors According To Build Type

Three separate builds are used to validate the SQLite software.

 A functionality testing build is used to validate the source code.
 A coverage testing build is used to validate the test suite, to confirm
     that the test suite provides 100% MC/DC.
 The release build is used to validate the generated machine code.

All tests must give the same answer in all three
builds. See the "How SQLite Is Tested" document for more detail.

The various assert()-like
macros behave differently according to how SQLite is built.


Functionality TestingCoverage TestingRelease
assert(X)
abort() if X is false
no-op
no-op

ALWAYS(X)
abort() if X is false
always true
pass through the value X

NEVER(X)
abort() if X is true
always false
pass through the value X

testcase(X)
no-op
do some harmless work if X is true
no-op



The default behavior of assert(X) in standard C is that it is enabled
for release builds.  This is a reasonable default.  However, the
SQLite code base has many assert() statements in performance-sensitive
areas of the code.  Leaving assert(X) turned on causes SQLite to run about
three times slower.  Also, SQLite strives to provide 100% MC/DC in an
as-delivered configuration, which is obviously impossible if assert(X)
statements are enabled.  For these reasons, assert(X) is a no-op for
release builds in SQLite.

The ALWAYS(X) and NEVER(X) macros behave like assert(X) during
functionality testing, because the developers want to be immediately
alerted to the issue if the value of X is different from what is expected.
But for delivery, ALWAYS(X) and NEVER(X) are simple pass-through macros,
which provide defense-in-depth.  For coverage testing ALWAYS(X) and NEVER(X)
are hard-coded boolean values so that they do not cause unreachable
machine code to be generated.

The testcase(X) macro is normally a no-op, but for a coverage test
build it does generate a small amount of extra code that includes at least
one branch, in order to verify that test cases exist for which X is both
true and false.

2. Examples

An assert() statement is often used to validate pre-conditions on 
internal functions and methods.
Example: https://sqlite.org/src/artifact/c1e97e4c6f?ln=1048.
This is deemed better than simply stating the pre-condition in a header 
comment, since the assert() is actually executed.  In a highly tested
program like SQLite, the reader knows that the pre-condition is true
for all of the hundreds of millions of test cases run against SQLite,
since it has been verified by the assert().
In contrast, a text pre-condition statement in a header comment
is untested.  It might have been true when the code was written, 
but who is to say that it is still true now?


Sometimes SQLite uses compile-time evaluatable assert() statements.
Consider the code at
https://sqlite.org/src/artifact/c1e97e4c6f?ln=2130-2138.
Four assert() statements verify the values for compile-time constants
so that the reader can quickly check the validity of the if-statement
that follows, without having to look up the constant values in a separate
header file.


Sometimes compile-time assert() statements are used to verify that
SQLite has been correctly compiled.  For example, the code at
https://sqlite.org/src/artifact/c1e97e4c6f?ln=157
verifies that the SQLITE_PTRSIZE preprocessor macro is set correctly
for the target architecture.


The CORRUPT_DB macro is used in many assert() statements.
In functional testing builds, CORRUPT_DB references a global variable
that is true if the database file might contain corruption.  This variable
is true by default, since we do not normally know whether or not a database
is corrupt, but during testing while working on databases that are known
to be well-formed, that global variable can be set to false.
Then the CORRUPT_DB macro
can be used in assert() statements such as seen at
https://sqlite.org/src/artifact/18a53540aa3?ln=1679-1680.
Those assert()s specify pre-conditions to the routine that are true for
consistent database files, but which might be false if the database file
is corrupt. Knowledge of these kinds of conditions is very helpful to
readers who are trying to understand a block of code in isolation.


ALWAYS(X) and NEVER(X) functions are used in places where we always
want the test to occur even though the developers believe the value of
X is always true or false.  For example, the sqlite3BtreeCloseCursor()
routine shown must remove the closing cursor from a linked list of all
cursors.  We know that the cursor is on the list, so that the loop
must terminate by the "break" statement, but it is convenient to
use the ALWAYS(X) test at
https://sqlite.org/src/artifact/18a53540aa3?ln=4371 to prevent
running off the end of the linked list in case there is an error in some
other part of the code that has corrupted the linked list.


An ALWAYS(X) or NEVER(X) sometimes verifies pre-conditions that are
subject to change if other parts of the code are modified in
subtle ways.  At https://sqlite.org/src/artifact/18a53540aa3?ln=5512-5516
we have a test for two pre-conditions that are true only because
of the limited scope of use of the sqlite3BtreeRowCountEst() function.
Future enhancements to SQLite might use sqlite3BtreeRowCountEst() in
new ways where those preconditions no longer hold, and the NEVER()
macros will quickly alert the developers to that fact when the
situation arises.  But if, for some reason, the pre-conditions are
not satisfied in a release build, the program will still behave sanely
and will not do an undefined memory access.


The testcase() macro is often used to verify that boundary
cases of an inequality comparison are checked.  For example, at
https://sqlite.org/src/artifact/18a53540aa3?ln=5766.  These
kind of checks help to prevent off-by-one errors.


c2: NUL Characters In Strings
c5: nulinstr.html
c4:
1. Introduction


SQLite allows NUL characters (ASCII 0x00, Unicode \u0000) in the middle
of string values stored in the database.  However, the use of NUL within
strings can lead to surprising behaviors:



The length() SQL function only counts characters up through and excluding
the first NUL.



The quote() SQL function only shows characters up through and excluding
the first NUL.


The .dump command in the CLI omits the first NUL character and all
subsequent text in the SQL output that it generates.  In fact, the
CLI omits everything past the first NUL character in all contexts.



The use of NUL characters in SQL text strings is not recommended.

2. Unexpected Behavior


Consider the following SQL:

CREATE TABLE t1(
  a INTEGER PRIMARY KEY,
  b TEXT
);
INSERT INTO t1(a,b) VALUES(1, 'abc'||char(0)||'xyz');

SELECT a, b, length(b) FROM t1;



The SELECT statement above shows output of:

1,'abc',3



(Through this document, we assume that the CLI has ".mode quote" set.)
But if you run:

SELECT * FROM t1 WHERE b='abc';



Then no rows are returned.  SQLite knows that the t1.b column actually
holds a 7-character string, and the 7-character string 'abc'||char(0)||'xyz'
is not equal to the 3-character string 'abc', and so no rows are returned.
But a user might be easily confused by this because the CLI output
seems to show that the string has only 3 characters.  This seems like
a bug.  But it is how SQLite works.

3. How To Tell If You Have NUL Characters In Your Strings


If you CAST a string into a BLOB, then the entire length of the
string is shown.  For example:

SELECT a, CAST(b AS BLOB) FROM t1;



Gives this result:

1,X'6162630078797a'



In the BLOB output, you can clearly see the NUL character as the 4th
character in the 7-character string.


Another, more automated, way
to tell if a string value X contains embedded NUL characters is to
use an expression like this:

instr(X,char(0))



If this expression returns a non-zero value N, then there exists an 
embedded NUL at the N-th character position.  Thus to count the number
fo rows that contain embedded NUL characters:

SELECT count(*) FROM t1 WHERE instr(b,char(0))>0;


4. Removing NUL Characters From A Text Field


The following example shows how to remove NUL character, and all text
that follows, from a column of a table.  So if you have a database file
that contains embedded NULs and you would like to remove them, running
UPDATE statements similar to the following might help:

UPDATE t1 SET b=substr(b,1,instr(b,char(0)))
 WHERE instr(b,char(0));


c2: Clustered Indexes and the WITHOUT ROWID Optimization
c5: withoutrowid.html
c4:
1. Introduction

By default, every row in SQLite has a special column, usually called the
"rowid", that uniquely identifies that row within the table.  However
if the phrase "WITHOUT ROWID" is added to the end of a CREATE TABLE statement,
then the special "rowid" column is omitted.  There are sometimes
space and performance advantages to omitting the rowid.

A WITHOUT ROWID table is a table that uses a 
Clustered Index
as the primary key.

1.1. Syntax

To create a WITHOUT ROWID table, simply add the keywords "WITHOUT ROWID"
to the end of the CREATE TABLE statement.  For example:


CREATE TABLE IF NOT EXISTS wordcount(
  word TEXT PRIMARY KEY,
  cnt INTEGER
) WITHOUT ROWID;


As with all SQL syntax, the case of the keywords does not matter.  
One can write "WITHOUT rowid" or "without rowid" or "WiThOuT rOwId" and
it will mean the same thing.

Every WITHOUT ROWID table must have a PRIMARY KEY.  An error is raised
if a CREATE TABLE statement with the WITHOUT ROWID clause lacks a PRIMARY KEY.

In most contexts, the special "rowid" column of normal tables can 
also be called "oid" or "_rowid_".  However, only "rowid" works as 
the keyword in the CREATE TABLE statement.

1.2. Compatibility

SQLite version 3.8.2 (2013-12-06) or later 
is necessary in order to use a WITHOUT
ROWID table.  An attempt to open a database that contains one or more WITHOUT
ROWID tables using an earlier version of SQLite will result in a
"malformed database schema" error.

1.3. Quirks

WITHOUT ROWID is found only in SQLite and is not compatible
with any other SQL database engine, as far as we know.
In an elegant system, all tables would behave as WITHOUT ROWID
tables even without the WITHOUT ROWID keyword.  However, when SQLite was
first designed, it used only integer rowids for row keys 
to simplify the implementation.
This approach worked well for many years.  But as the demands on
SQLite grew, the need for tables in which the PRIMARY KEY really did
correspond to the underlying row key grew more acute.  The WITHOUT ROWID
concept was added
in order to meet that need without breaking backwards
compatibility with the billions of SQLite databases already in use at
the time (circa 2013).

2. Differences From Ordinary Rowid Tables

The WITHOUT ROWID syntax is an optimization.  It provides no new
capabilities.  Anything that can be done using a WITHOUT ROWID table
can also be done in exactly the same way, and exactly the same syntax,
using an ordinary rowid table.  The only advantage of a WITHOUT ROWID
table is that it can sometimes use less disk space and/or perform a little
faster than an ordinary rowid table.

For the most part, ordinary rowid tables and WITHOUT ROWID tables
are interchangeable.  But there are some additional restrictions on
WITHOUT ROWID tables that do not apply to ordinary rowid tables:



Every WITHOUT ROWID table must have a PRIMARY KEY.
An attempt to create a WITHOUT ROWID table without a PRIMARY KEY results
in an error.


The special behaviors associated "INTEGER PRIMARY KEY" do not apply
on WITHOUT ROWID tables.
In an ordinary table, "INTEGER PRIMARY KEY" means that the column is an
alias for the rowid.  But since there is no rowid in a WITHOUT ROWID
table, that special meaning no longer applies.  An "INTEGER PRIMARY KEY" 
column in a WITHOUT ROWID table works
like an "INT PRIMARY KEY" column in an ordinary table: It is a PRIMARY KEY
that has integer affinity.


AUTOINCREMENT does not work on WITHOUT ROWID tables.
The AUTOINCREMENT mechanism assumes the presence of a rowid and so it
does not work on a WITHOUT ROWID table.  An error is raised if the
 "AUTOINCREMENT" keyword is used in the CREATE TABLE statement for
a WITHOUT ROWID table.


NOT NULL is enforced on every column of the PRIMARY KEY in a WITHOUT
ROWID table.
This is in accordance with the SQL standard.  Each column of a PRIMARY KEY
is supposed to be individually NOT NULL.  However, NOT NULL was not enforced
on PRIMARY KEY columns by early versions of SQLite due to a bug.  By the
time that this bug was discovered, so many SQLite databases were already
in circulation that the decision was made not to fix this bug for fear of
breaking compatibility.  So, ordinary rowid tables in SQLite violate the
SQL standard and allow NULL values in PRIMARY KEY fields.  But WITHOUT ROWID
tables do follow the standard and will throw an error on any attempt to
insert a NULL into a PRIMARY KEY column.


The sqlite3_last_insert_rowid() function
does not work for WITHOUT ROWID tables.
Inserts into a WITHOUT ROWID do not change the value returned by the
sqlite3_last_insert_rowid() function.  The last_insert_rowid() SQL
function is also unaffected since it is just a wrapper around
sqlite3_last_insert_rowid().


The incremental blob I/O mechanism does not work
for WITHOUT ROWID tables.
Incremental BLOB I/O uses the rowid to create an sqlite3_blob object for
doing the direct I/O.  However, WITHOUT ROWID tables do not have a rowid,
and so there is no way to create an sqlite3_blob object for a WITHOUT
ROWID table.


The sqlite3_update_hook() interface does not fire callbacks for changes
to a WITHOUT ROWID table.
Part of the callback from sqlite3_update_hook() is the rowid of the table
row that has changed.  However, WITHOUT ROWID tables do not have a rowid.
Hence, the update hook is not invoked when a WITHOUT ROWID table changes.




3. Benefits Of WITHOUT ROWID Tables

A WITHOUT ROWID table is an optimization that can reduce storage and
processing requirements.

In an ordinary SQLite table, the PRIMARY KEY is really just a 
UNIQUE index.  The key used to look up records on disk
is the rowid.
The special "INTEGER PRIMARY KEY" column type in ordinary SQLite tables 
causes the column to be an alias for the rowid, and so an INTEGER PRIMARY
KEY is a true PRIMARY KEY.  But any other kind of PRIMARY KEYs, including
"INT PRIMARY KEY" are just unique indexes in an ordinary rowid table.

Consider a table (shown below) intended to store a
vocabulary of words together with a count of the number of occurrences of
each word in some text corpus:


CREATE TABLE IF NOT EXISTS wordcount(
  word TEXT PRIMARY KEY,
  cnt INTEGER
);


As an ordinary SQLite table, "wordcount" is implemented as two
separate B-Trees.  The main table uses the hidden rowid value as the key
and stores the "word" and "cnt" columns as data.  The "TEXT PRIMARY KEY"
phrase of the CREATE TABLE statement
causes the creation of an unique index on the "word" column.  This index is a
separate B-Tree that uses "word" and the "rowid" as the key and stores no
data at all.  Note that the complete text of every "word" is stored twice:
once in the main table and again in the index.

Consider querying this table to find the number of occurrences of the
word "xyzzy".:


SELECT cnt FROM wordcount WHERE word='xyzzy';


This query first has to search the index B-Tree looking for any entry
that contains the matching value for "word".  When an entry is found in
the index, the rowid is extracted and used to search the main table.
Then the "cnt" value is read out of the main table and returned.  Hence, two
separate binary searches are required to fulfill the request.

A WITHOUT ROWID table uses a different data design for the equivalent
table.


CREATE TABLE IF NOT EXISTS wordcount(
  word TEXT PRIMARY KEY,
  cnt INTEGER
) WITHOUT ROWID;


In this latter table, there is only a single B-Tree which uses the "word"
column as its key and the "cnt" column as its data.  (Technicality:  the
low-level implementation actually stores both "word" and "cnt" in the "key"
area of the B-Tree.  But unless you are looking at the low-level byte encoding
of the database file, that fact is unimportant.)  Because there is only
a single B-Tree, the text of the "word" column is only stored once in the
database.  Furthermore, querying the "cnt" value for a specific "word"
only involves a single binary search into the main B-Tree, since the "cnt"
value can be retrieved directly from the record found by that first search
and without the need to do a second binary search on the rowid.

Thus, in some cases, a WITHOUT ROWID table can use about half the amount
of disk space and can operate nearly twice as fast.  Of course, in a 
real-world schema, there will typically be secondary indices and/or
UNIQUE constraints, and the situation is more complicated.  But even then,
there can often be space and performance advantages to using WITHOUT ROWID
on tables that have non-integer or composite PRIMARY KEYs.



4. When To Use WITHOUT ROWID

The WITHOUT ROWID optimization is likely to be helpful for tables
that have non-integer or composite (multi-column) PRIMARY KEYs and that do
not store large strings or BLOBs.

WITHOUT ROWID tables will work correctly (that is to say, they
provide the correct answer) for tables with a single INTEGER PRIMARY KEY. 
However, ordinary rowid tables will run faster in that case.  
Hence, it is good design
to avoid creating WITHOUT ROWID tables with single-column PRIMARY KEYs 
of type INTEGER.

WITHOUT ROWID tables work best when individual rows are not too large.
A good rule-of-thumb is that the average size of a single row in a
WITHOUT ROWID table should be less than about 1/20th the size of 
a database page.  That means that rows should not contain more than about
50 bytes each for a 1KiB page size or about 200 bytes each for 4KiB
page size.  WITHOUT ROWID tables will work (in the sense that
they get the correct answer) for arbitrarily large rows - up to 2GB in size -
but traditional rowid tables tend to work faster for large row sizes.
This is because rowid tables are implemented as B*-Trees where
all content is stored in the leaves of the tree, whereas WITHOUT ROWID 
tables are implemented using ordinary B-Trees with content stored on both
leaves and intermediate nodes.  Storing content in 
intermediate nodes mean that each intermediate node entry takes up more
space on the page and thus reduces the fan-out, increasing the search cost.

The "sqlite3_analyzer.exe" utility program, available as source code
in the SQLite source tree or as a precompiled binary on the
SQLite Download page, can be
used to measure the average sizes of table rows in an existing SQLite
database.

Note that except for a few corner-case differences detailed above,
WITHOUT ROWID tables and rowid tables work the same.  They both generate
the same answers given the same SQL statements.  So it is a simple matter
to run experiments on an application, late in the development cycle,
to test whether or not the use of WITHOUT ROWID tables will be helpful.
A good strategy is to simply not worry about WITHOUT ROWID until near
the end of product development, then go back and run tests to see
if adding WITHOUT ROWID to tables with non-integer PRIMARY KEYs helps
or hurts performance, and retaining the WITHOUT ROWID only in those cases
where it helps.


c2: sqldiff.exe: Database Difference Utility
c5: sqldiff.html
c4:
1. Usage


The sqldiff.exe binary is a command-line utility program that
displays the differences between SQLite databases.  Example
usage:

sqldiff &#91;options&#93; database1.sqlite database2.sqlite



The usual output is an SQL script that will transform
database1.sqlite (the "source" database) into database2.sqlite
(the "destination" database).  This behavior can be
altered using command-line switches:


--changeset FILE
Do not write changes to standard output.  Instead, write a (binary)
       changeset file into FILE.  The changeset can be interpreted using
       the sessions extension to SQLite.
--lib LIBRARY
-L LIBRARY
Load the shared library or DLL file LIBRARY into SQLite prior to
       computing the differences.  This can be used to add application-defined
       collating sequences that are required by the schema.
--primarykey
Use the schema-defined PRIMARY KEY instead of the rowid to
       pair rows in the source and destination database.  (See additional
       explanation below.)
--schema
Show only differences in the schema not the table content
--summary
Show how many rows have changed on each table, but do not show
       the actual changes
--table TABLE
Show only the differences in content for TABLE, not for the
       entire database
--transaction
Wrap SQL output in a single large transaction
--vtab
Add support for handling FTS3, FTS5 and rtree virtual tables. 
       See below for details. 



2. How It Works

The sqldiff.exe utility works by finding rows in the source and
destination that are logical "pairs".  The default behavior is to
treat two rows as pairs if they are in tables with the same name
and they have the same rowid, or in the case of a WITHOUT ROWID
table if they have the same PRIMARY KEY.  Any differences in the
content of paired rows are output as UPDATEs.  Rows in the source
database that could not be paired are output as DELETEs.  Rows in
the destination database that could not be paired are output as
INSERTs.

The --primarykey flag changes the pairing algorithm slightly so
that the schema-declared PRIMARY KEY is always used for pairing,
even on tables that have a rowid.  This is often a better choice
for finding differences, however it can lead to missed differences in
the case of rows that have one or more PRIMARY KEY columns set to
NULL.

3. Limitations



The sqldiff.exe utility is unable to compute differences for
rowid tables for which the rowid is inaccessible.  An example of
a table with an inaccessible rowid is:

CREATE TABLE inaccessible_rowid(
   "rowid" TEXT,
   "oid" TEXT,
   "_rowid_" TEXT
);



The sqldiff.exe utility does not (currently) display differences in
TRIGGERs or VIEWs.


By default, differences in the schema or content of virtual tables are
not reported on. 

However, if a virtual table implementation creates real tables (sometimes
referred to as "shadow" tables) within the database to store its data in, then
sqldiff.exe does calculate the difference between these. This can have
surprising effects if the resulting SQL script is then run on a database that
is not exactly the same as the source database. For several of SQLite's
bundled virtual tables (FTS3, FTS5, rtree and others), the surprising effects
may include corruption of the virtual table content.

 If the --vtab option is passed to sqldiff.exe, then it ignores all 
underlying shadow tables belonging to an FTS3, FTS5 or rtree virtual table
and instead includes the virtual table differences directly.


c2: SQLite Library Footprint
c5: footprint.html
c4:
Size Of The SQLite Library


The code space used by the SQLite library depends on the target
platform, the compiler, and optimization settings.  These variables
also affect performance.



The chart below shows the relative size and performance for SQLite
as of 2017-10-08 for various compilers and optimization settings
as tested on Ubuntu 16.04.3 on x86_64.  General observations:



The Clang/LLVM compiler is not competitive with GCC.  Clang-generated
binaries are consistently larger and slower than GCC-generated binaries.


Profile guided optimization (PGO) is not helpful with SQLite.  PGO results
in binaries that are about 1% larger and about 0.33% slower.


GCC-7 generates binaries that are smaller and faster than GCC-5, though
the difference is not that great.


Compiling with GCC and -Os results in a binary that is slightly less 
than 500KB in size. (Update 2018-07-07: Due to the addition of new
features such as UPSERT and window functions, the library footprint
is now slightly larger than 500KB.)


The only significant design decision that developers need to make is
whether to use -Os (optimize for size) or -O6 (optimize for speed).
The -O6 setting makes binaries that run about 2% or 3% faster, but which
are also 66% larger.  The performance here is measured by counting CPU
cycles using cachegrind.  I-cache misses are not considered in the
analysis.  If I-cache misses are considered, builds with -O6 might not
be any faster than builds with -Os.


Taking into consideration all of the above, the SQLite developers recommend
compiling SQLite using GCC-7 with the -Os optimization setting.








Details



Measurements above were conducted using SQLite version 
5594a121bf132a98 from
2017-10-08.


The only SQLite compile-time option used was -DSQLITE_ENABLE_MEMSYS5.
The optional memsys5 memory allocator is used for performance testing
because it gives results that are more repeatable than the library-supplied
malloc()/free() on Ubuntu.


Performance can be improved and the size reduced by
enabling -DSQLITE_THREADSAFE=0,
-DSQLITE_DEFAULT_MEMSTATUS=0,
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1,
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS,
-DSQLITE_MAX_EXPR_DEPTH=0,
-DSQLITE_OMIT_DECLTYPE,
-DSQLITE_OMIT_DEPRECATED,
-DSQLITE_OMIT_PROGRESS_CALLBACK,
-DSQLITE_OMIT_SHARED_CACHE, and
-DSQLITE_USE_ALLOCA.
All these options together result in about a 3.5% performance increase and
a 3.0% size reduction.


Adding optional features like -DSQLITE_ENABLE_JSON1,
-DSQLITE_ENABLE_FTS5, or -DSQLITE_ENABLE_RTREE will increase the
size of the library, obviously.


Performance was measured using the
speedtest1.c utility program,
which attempts to mimic a typical workload for SQLite.  Options to
the test runs are:

--shrink-memory --reprepare --stats --heap 10000000 64 --size 5

Performance was measured by running speedtest1 using cachegrind and
observing the "I refs" output.


c2: EXPLAIN QUERY PLAN
c5: eqp.html
c4:
1. The EXPLAIN QUERY PLAN Command


Warning: The data returned by the EXPLAIN QUERY PLAN command is 
intended for interactive debugging only.  The output format may change
between SQLite releases. Applications should not depend on the output
format of the EXPLAIN QUERY PLAN command.


Alert: As warned above, the EXPLAIN QUERY PLAN output format did
change substantially with the version 3.24.0 release (2018-06-04).
Further changes are possible in subsequent releases.


The EXPLAIN QUERY PLAN SQL command is used to obtain a high-level
description of the strategy or plan that SQLite uses to implement a specific
SQL query.  Most significantly, EXPLAIN QUERY PLAN reports on the way in 
which the query uses database indices. This document is a guide to
understanding and interpreting the EXPLAIN QUERY PLAN output.  Background
information is available separately:


 A primer on How SQLite Works.
 Notes on the query optimizer.
 How indexing works.
 The next generation query planner.


A query plan is represented as a tree.
In raw form, as returned by sqlite3_step(), each node of the tree
consists of four fields:  An integer node id, an integer parent id,
an auxiliary integer field that is not currently used, and a description
of the node.
The entire tree is therefore a table with four columns and zero or more
rows.
The command-line shell will usually intercept this table and renders
it as an ASCII-art graph for more convenient viewing.  To disable the
shells automatic graph rendering and to display EXPLAIN QUERY PLAN
output in its tabular format, run the command ".explain off" to set
the "EXPLAIN formatting mode" to off.  To restore automatic graph rendering,
run ".explain auto".  You can see the current "EXPLAIN formatting mode" 
setting using the ".show" command.

One can also set the CLI into automatic EXPLAIN QUERY PLAN mode
using the ".eqp on" command:

sqlite&gt; .eqp on


 In automatic EXPLAIN QUERY PLAN mode, the shell automatically runs
a separate EXPLAIN QUERY PLAN query for each statement you enter and
displays the result before actually running the query.  Use the
".eqp off" command to turn automatic EXPLAIN QUERY PLAN mode back off.

EXPLAIN QUERY PLAN is most useful on a SELECT statement,
but may also appear with other statements that read data from database
tables (e.g. UPDATE, DELETE, INSERT INTO ... SELECT).

1.1. Table and Index Scans


  When processing a SELECT (or other) statement, SQLite may retrieve data from
  database tables in a variety of ways. It may scan through all the records in
  a table (a full-table scan), scan a contiguous subset of the records in a
  table based on the rowid index, scan a contiguous subset of the entries in a
  database index, or use a combination of the above strategies
  in a single scan. The various ways in which SQLite may retrieve data from a
  table or index are described in detail here.


  For each table read by the query, the output of EXPLAIN QUERY 
  PLAN includes a record for which the value in the "detail" column begins
  with either "SCAN" or "SEARCH". "SCAN" is used for a full-table scan,
  including cases where SQLite iterates through all records in a table
  in an order defined by an index. "SEARCH" indicates that only a subset of 
  the table rows are visited. Each SCAN or SEARCH record includes the
  following information:


   The name of the table data is read from.
   Whether or not an index or automatic index is used.
   Whether or not the covering index optimization applies.
   Which terms of the WHERE clause are used for indexing.



  For example, the following EXPLAIN QUERY PLAN command operates on a SELECT
  statement that is implemented by performing a full-table scan on table t1:
sqlite&gt; EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
QUERY PLAN
`--SCAN TABLE t1



  The example above shows
  SQLite picking full-table scan will visit all rows in the table.
  If the query were able to use an index, then the 
  SCAN/SEARCH record would include the name of the index and, for a
  SEARCH record, an indication of how the subset of rows visited is
  identified. For example:
sqlite&gt; CREATE INDEX i1 ON t1(a);
sqlite&gt; EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
QUERY PLAN
`--SEARCH TABLE t1 USING INDEX i1 (a=?)



  The previous example, SQLite uses index "i1" to optimize
  a WHERE clause term of the form (a=?) - in this case "a=1".
  The previous example could not use a covering index, but the following
  example can, and that fact is reflected in the output:
sqlite&gt; CREATE INDEX i2 ON t1(a, b);
sqlite&gt; EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; 
QUERY PLAN
`--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)



  All joins in SQLite are implemented using nested scans. When a
  SELECT query that features a join is analyzed using EXPLAIN QUERY PLAN, one
  SCAN or SEARCH record is output for each nested loop. For example:
sqlite&gt; EXPLAIN QUERY PLAN SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2;
QUERY PLAN
|--SEARCH TABLE t1 USING INDEX i2 (a=? AND b>?)
`--SCAN TABLE t2



  The order of the entries indicates the nesting order. In
  this case, the scan of table t1 using index i2 is the outer loop (since it
  appears first)
  and the full-table scan of table t2 is the inner loop (since it appears
  last).
  In the following example, the positions of t1 and t2 in the FROM 
  clause of the SELECT are reversed. The query strategy remains the same.
  The output from EXPLAIN QUERY PLAN shows how the query is actually
  evaluated, not how it is specified in the SQL statement.
sqlite&gt; EXPLAIN QUERY PLAN SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2;
QUERY PLAN
|--SEARCH TABLE t1 USING INDEX i2 (a=? AND b>?)
`--SCAN TABLE t2





  If the WHERE clause of a query contains an OR expression, then SQLite might
  use the "OR by union" strategy (also known as the
  OR optimization). In this case there will be single top-level record
  for the search, with two sub-records, one for each index:
sqlite&gt; CREATE INDEX i3 ON t1(b);
sqlite&gt; EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
QUERY PLAN
`--MULTI-INDEX OR
   |--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
   `--SEARCH TABLE t1 USING INDEX i3 (b=?)


1.2. Temporary Sorting B-Trees


  If a SELECT query contains an ORDER BY, GROUP BY or DISTINCT clause, 
  SQLite may need to use a temporary b-tree structure to sort the output
  rows. Or, it might use an index. Using an index is 
  almost always much more efficient than performing a sort.
  If a temporary b-tree is required, a record is added to the EXPLAIN
  QUERY PLAN output with the "detail" field set to a string value of
  the form "USE TEMP B-TREE FOR xxx", where xxx is one of "ORDER BY",
  "GROUP BY" or "DISTINCT". For example:

sqlite&gt; EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
QUERY PLAN
|--SCAN TABLE t2
`--USE TEMP B-TREE FOR ORDER BY



  In this case using the temporary b-tree can be avoided by creating an index
  on t2(c), as follows:

sqlite&gt; CREATE INDEX i4 ON t2(c);
sqlite&gt; EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c; 
QUERY PLAN
`--SCAN TABLE t2 USING INDEX i4


1.3. Subqueries


  In all the examples above, there has only been a single SELECT statement.
  If a query contains sub-selects, those are shown as being children of
  the outer SELECT.  For example:

sqlite&gt; EXPLAIN QUERY PLAN SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
|--SCAN TABLE t2 USING COVERING INDEX i4
|--SCALAR SUBQUERY
|  `--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
`--CORRELATED SCALAR SUBQUERY
   `--SEARCH TABLE t1 USING INDEX i3 (b=?)



  The example above contains two "SCALAR" subqueries.  The subqueries
  are SCALAR in the sense that they return a single value - a one-row,
  one-column table.  If the actual query returns more than that, then
  only the first column of the first row is used.

  The first subquery above is constant with respect to the outer query.
  The value for the first subquery can be computed once and then reused
  for each row of the outer SELECT.  The second subquery, however, is
  "CORRELATED".  The value of the second subquery changes depending
  on values in the current row of the outer query.  Hence, the second
  subquery must be run once for each output row in the outer SELECT.


  Unless the flattening optimization is applied, if a subquery appears in
  the FROM clause of a SELECT statement, SQLite can either run the subquery and
  stores the results in a temporary table, or it can run the subquery as a
  co-routine.  The following query is an example of the latter.  The subquery
  is run by a co-routine.  The outer query blocks whenever it needs another
  row of input from the subquery.  Control switches to the co-routine which
  produces the desired output row, then control switches back to the main
  routine which continues processing.  

sqlite&gt; EXPLAIN QUERY PLAN SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
QUERY PLAN
|--CO-ROUTINE 0x20FC3E0
|  `--SCAN TABLE t1 USING COVERING INDEX i2
|--SCAN SUBQUERY 0x20FC3E0
`--USE TEMP B-TREE FOR GROUP BY



  
  If the flattening optimization is used on a subquery in the FROM clause
  of a SELECT statement, that effectively merges the subquery into the outer
  query.  The output of EXPLAIN QUERY PLAN reflects this, as in the following
  example:

sqlite&gt; EXPLAIN QUERY PLAN SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
QUERY PLAN
|--SEARCH TABLE t2 USING INDEX i4 (c=?)
`--SCAN TABLE t1




  If the content of a subquery might need to be visited more than once, then
  the use of a co-routine is undesirable, as the co-routine would then have to
  compute the data more than once.  And if the subquery cannot be flattened,
  that means the subquery must be manifested into a transient table.

sqlite&gt; SELECT * FROM
      &gt;   (SELECT * FROM t1 WHERE a=1 ORDER BY b LIMIT 2) AS x,
      &gt;   (SELECT * FROM t2 WHERE c=1 ORDER BY d LIMIT 2) AS y;
QUERY PLAN
|--MATERIALIZE 0x18F06F0
|  `--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|--MATERIALIZE 0x18F80D0
|  |--SEARCH TABLE t2 USING INDEX i4 (c=?)
|  `--USE TEMP B-TREE FOR ORDER BY
|--SCAN SUBQUERY 0x18F06F0 AS x
`--SCAN SUBQUERY 0x18F80D0 AS y


1.4. Compound Queries


  Each component query of a compound query (UNION, UNION ALL, EXCEPT or 
  INTERSECT) is assigned computed separately and is given its own line in
  the EXPLAIN QUERY PLAN output.

sqlite&gt; EXPLAIN QUERY PLAN SELECT a FROM t1 UNION SELECT c FROM t2;
QUERY PLAN
`--COMPOUND QUERY
   |--LEFT-MOST SUBQUERY
   |  `--SCAN TABLE t1 USING COVERING INDEX i1
   `--UNION USING TEMP B-TREE
      `--SCAN TABLE t2 USING COVERING INDEX i4



  The "USING TEMP B-TREE" clause in the above output indicates that a 
  temporary b-tree structure is used to implement the UNION of the results
  of the two sub-selects.  An alternative method of computing a compound
  is to run each subquery as a co-routine, arrange for their outputs to
  appear in sorted order, and merge the results together.  When the query
  planner chooses this latter approach, the EXPLAIN QUERY PLAN output
  looks like this:

sqlite&gt; EXPLAIN QUERY PLAN SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1;
QUERY PLAN
`--MERGE (EXCEPT)
   |--LEFT
   |  `--SCAN TABLE t1 USING COVERING INDEX i1
   `--RIGHT
      |--SCAN TABLE t2
      `--USE TEMP B-TREE FOR ORDER BY


c2: SQLite Database Speed Comparison
c5: speed.html
c4:
Database Speed Comparison


Note:  This document is very very old.  It describes a speed comparison between
archaic versions of SQLite, MySQL and PostgreSQL.  

The numbers here have become meaningless.  This page has been retained only
as an historical artifact.  


Executive Summary

A series of tests were run to measure the relative performance of
SQLite 2.7.6, PostgreSQL 7.1.3, and MySQL 3.23.41.
The following are general
conclusions drawn from these experiments:




  SQLite 2.7.6 is significantly faster (sometimes as much as 10 or
  20 times faster) than the default PostgreSQL 7.1.3 installation
  on RedHat 7.2 for most common operations.  


  SQLite 2.7.6 is often faster (sometimes
  more than twice as fast) than MySQL 3.23.41
  for most common operations.


  SQLite does not execute CREATE INDEX or DROP TABLE as fast as
  the other databases.  But this is not seen as a problem because
  those are infrequent operations.


  SQLite works best if you group multiple operations together into
  a single transaction.




The results presented here come with the following caveats:




  These tests did not attempt to measure multi-user performance or
  optimization of complex queries involving multiple joins and subqueries.


  These tests are on a relatively small (approximately 14 megabyte) database.
  They do not measure how well the database engines scale to larger problems.



Test Environment


The platform used for these tests is a 1.6GHz Athlon with 1GB or memory
and an IDE disk drive.  The operating system is RedHat Linux 7.2 with
a stock kernel.



The PostgreSQL and MySQL servers used were as delivered by default on
RedHat 7.2.  (PostgreSQL version 7.1.3 and MySQL version 3.23.41.)
No effort was made to tune these engines.  Note in particular
the default MySQL configuration on RedHat 7.2 does not support
transactions.  Not having to support transactions gives MySQL a
big speed advantage, but SQLite is still able to hold its own on most
tests.



I am told that the default PostgreSQL configuration in RedHat 7.3
is unnecessarily conservative (it is designed to
work on a machine with 8MB of RAM) and that PostgreSQL could
be made to run a lot faster with some knowledgeable configuration
tuning.
Matt Sergeant reports that he has tuned his PostgreSQL installation
and rerun the tests shown below.  His results show that
PostgreSQL and MySQL run at about the same speed.  For Matt's
results, visit



http://www.sergeant.org/sqlite_vs_pgsync.html



SQLite was tested in the same configuration that it appears
on the website.  It was compiled with -O6 optimization and with
the -DNDEBUG=1 switch which disables the many "assert()" statements
in the SQLite code.  The -DNDEBUG=1 compiler option roughly doubles
the speed of SQLite.



All tests are conducted on an otherwise quiescent machine.
A simple Tcl script was used to generate and run all the tests.
A copy of this Tcl script can be found in the SQLite source tree
in the file tools/speedtest.tcl.



The times reported on all tests represent wall-clock time 
in seconds.  Two separate time values are reported for SQLite.
The first value is for SQLite in its default configuration with
full disk synchronization turned on.  With synchronization turned
on, SQLite executes
an fsync() system call (or the equivalent) at key points
to make certain that critical data has 
actually been written to the disk drive surface.  Synchronization
is necessary to guarantee the integrity of the database if the
operating system crashes or the computer powers down unexpectedly
in the middle of a database update.  The second time reported for SQLite is
when synchronization is turned off.  With synchronization off,
SQLite is sometimes much faster, but there is a risk that an
operating system crash or an unexpected power failure could
damage the database.  Generally speaking, the synchronous SQLite
times are for comparison against PostgreSQL (which is also
synchronous) and the asynchronous SQLite times are for 
comparison against the asynchronous MySQL engine.


Test 1: 1000 INSERTs

CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));
INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
... 995 lines omitted
INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');


PostgreSQL:&nbsp;&nbsp;&nbsp;4.373
MySQL:&nbsp;&nbsp;&nbsp;0.114
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;13.061
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.223



Because it does not have a central server to coordinate access,
SQLite must close and reopen the database file, and thus invalidate
its cache, for each transaction.  In this test, each SQL statement
is a separate transaction so the database file must be opened and closed
and the cache must be flushed 1000 times.  In spite of this, the asynchronous
version of SQLite is still nearly as fast as MySQL.  Notice how much slower
the synchronous version is, however.  SQLite calls fsync() after 
each synchronous transaction to make sure that all data is safely on
the disk surface before continuing.  For most of the 13 seconds in the
synchronous test, SQLite was sitting idle waiting on disk I/O to complete.


Test 2: 25000 INSERTs in a transaction

BEGIN;
CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
... 24997 lines omitted
INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;4.900
MySQL:&nbsp;&nbsp;&nbsp;2.184
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;0.914
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.757



When all the INSERTs are put in a transaction, SQLite no longer has to
close and reopen the database or invalidate its cache between each statement.
It also does not
have to do any fsync()s until the very end.  When unshackled in
this way, SQLite is much faster than either PostgreSQL and MySQL.


Test 3: 25000 INSERTs into an indexed table

BEGIN;
CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));
CREATE INDEX i3 ON t3(c);
... 24998 lines omitted
INSERT INTO t3 VALUES(24999,88509,'eighty eight thousand five hundred nine');
INSERT INTO t3 VALUES(25000,84791,'eighty four thousand seven hundred ninety one');
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;8.175
MySQL:&nbsp;&nbsp;&nbsp;3.197
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;1.555
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;1.402



There were reports that SQLite did not perform as well on an indexed table.
This test was recently added to disprove those rumors.  It is true that
SQLite is not as fast at creating new index entries as the other engines
(see Test 6 below) but its overall speed is still better.


Test 4: 100 SELECTs without an index

BEGIN;
SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b
SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b
... 96 lines omitted
SELECT count(*), avg(b) FROM t2 WHERE b>=9800 AND b
SELECT count(*), avg(b) FROM t2 WHERE b>=9900 AND b
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;3.629
MySQL:&nbsp;&nbsp;&nbsp;2.760
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;2.494
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;2.526




This test does 100 queries on a 25000 entry table without an index,
thus requiring a full table scan.   Prior versions of SQLite used to
be slower than PostgreSQL and MySQL on this test, but recent performance
enhancements have increased its speed so that it is now the fastest
of the group.


Test 5: 100 SELECTs on a string comparison

BEGIN;
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one%';
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%two%';
... 96 lines omitted
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%ninety nine%';
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one hundred%';
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;13.409
MySQL:&nbsp;&nbsp;&nbsp;4.640
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;3.362
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;3.372



This test still does 100 full table scans but it uses
uses string comparisons instead of numerical comparisons.
SQLite is over three times faster than PostgreSQL here and about 30%
faster than MySQL.


Test 6: Creating an index

CREATE INDEX i2a ON t2(a);CREATE INDEX i2b ON t2(b);

PostgreSQL:&nbsp;&nbsp;&nbsp;0.381
MySQL:&nbsp;&nbsp;&nbsp;0.318
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;0.777
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.659



SQLite is slower at creating new indices.  This is not a huge problem
(since new indices are not created very often) but it is something that
is being worked on.  Hopefully, future versions of SQLite will do better
here.


Test 7: 5000 SELECTs with an index

SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b
SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b
SELECT count(*), avg(b) FROM t2 WHERE b>=200 AND b
... 4994 lines omitted
SELECT count(*), avg(b) FROM t2 WHERE b>=499700 AND b
SELECT count(*), avg(b) FROM t2 WHERE b>=499800 AND b
SELECT count(*), avg(b) FROM t2 WHERE b>=499900 AND b


PostgreSQL:&nbsp;&nbsp;&nbsp;4.614
MySQL:&nbsp;&nbsp;&nbsp;1.270
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;1.121
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;1.162



All three database engines run faster when they have indices to work with.
But SQLite is still the fastest.


Test 8: 1000 UPDATEs without an index

BEGIN;
UPDATE t1 SET b=b*2 WHERE a>=0 AND a
UPDATE t1 SET b=b*2 WHERE a>=10 AND a
... 996 lines omitted
UPDATE t1 SET b=b*2 WHERE a>=9980 AND a
UPDATE t1 SET b=b*2 WHERE a>=9990 AND a
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;1.739
MySQL:&nbsp;&nbsp;&nbsp;8.410
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;0.637
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.638



For this particular UPDATE test, MySQL is consistently
five or ten times
slower than PostgreSQL and SQLite.  I do not know why.  MySQL is
normally a very fast engine.  Perhaps this problem has been addressed
in later versions of MySQL.


Test 9: 25000 UPDATEs with an index

BEGIN;
UPDATE t2 SET b=468026 WHERE a=1;
UPDATE t2 SET b=121928 WHERE a=2;
... 24996 lines omitted
UPDATE t2 SET b=35065 WHERE a=24999;
UPDATE t2 SET b=347393 WHERE a=25000;
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;18.797
MySQL:&nbsp;&nbsp;&nbsp;8.134
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;3.520
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;3.104



As recently as version 2.7.0, SQLite ran at about the same speed as
MySQL on this test.  But recent optimizations to SQLite have more
than doubled speed of UPDATEs.


Test 10: 25000 text UPDATEs with an index

BEGIN;
UPDATE t2 SET c='one hundred forty eight thousand three hundred eighty two' WHERE a=1;
UPDATE t2 SET c='three hundred sixty six thousand five hundred two' WHERE a=2;
... 24996 lines omitted
UPDATE t2 SET c='three hundred eighty three thousand ninety nine' WHERE a=24999;
UPDATE t2 SET c='two hundred fifty six thousand eight hundred thirty' WHERE a=25000;
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;48.133
MySQL:&nbsp;&nbsp;&nbsp;6.982
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;2.408
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;1.725



Here again, version 2.7.0 of SQLite used to run at about the same speed
as MySQL.  But now version 2.7.6 is over two times faster than MySQL and
over twenty times faster than PostgreSQL.



In fairness to PostgreSQL, it started thrashing on this test.  A
knowledgeable administrator might be able to get PostgreSQL to run a lot
faster here by tweaking and tuning the server a little.


Test 11: INSERTs from a SELECT

BEGIN;INSERT INTO t1 SELECT b,a,c FROM t2;INSERT INTO t2 SELECT b,a,c FROM t1;COMMIT;

PostgreSQL:&nbsp;&nbsp;&nbsp;61.364
MySQL:&nbsp;&nbsp;&nbsp;1.537
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;2.787
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;1.599



The asynchronous SQLite is just a shade slower than MySQL on this test.
(MySQL seems to be especially adept at INSERT...SELECT statements.)
The PostgreSQL engine is still thrashing - most of the 61 seconds it used
were spent waiting on disk I/O.


Test 12: DELETE without an index

DELETE FROM t2 WHERE c LIKE '%fifty%';

PostgreSQL:&nbsp;&nbsp;&nbsp;1.509
MySQL:&nbsp;&nbsp;&nbsp;0.975
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;4.004
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.560



The synchronous version of SQLite is the slowest of the group in this test,
but the asynchronous version is the fastest.  
The difference is the extra time needed to execute fsync().


Test 13: DELETE with an index

DELETE FROM t2 WHERE a>10 AND a
PostgreSQL:&nbsp;&nbsp;&nbsp;1.316
MySQL:&nbsp;&nbsp;&nbsp;2.262
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;2.068
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.752



This test is significant because it is one of the few where
PostgreSQL is faster than MySQL.  The asynchronous SQLite is,
however, faster then both the other two.


Test 14: A big INSERT after a big DELETE

INSERT INTO t2 SELECT * FROM t1;

PostgreSQL:&nbsp;&nbsp;&nbsp;13.168
MySQL:&nbsp;&nbsp;&nbsp;1.815
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;3.210
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;1.485



Some older versions of SQLite (prior to version 2.4.0)
would show decreasing performance after a
sequence of DELETEs followed by new INSERTs.  As this test shows, the
problem has now been resolved.


Test 15: A big DELETE followed by many small INSERTs

BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES(1,10719,'ten thousand seven hundred nineteen');
... 11997 lines omitted
INSERT INTO t1 VALUES(11999,72836,'seventy two thousand eight hundred thirty six');
INSERT INTO t1 VALUES(12000,64231,'sixty four thousand two hundred thirty one');
COMMIT;


PostgreSQL:&nbsp;&nbsp;&nbsp;4.556
MySQL:&nbsp;&nbsp;&nbsp;1.704
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;0.618
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.406



SQLite is very good at doing INSERTs within a transaction, which probably
explains why it is so much faster than the other databases at this test.


Test 16: DROP TABLE

DROP TABLE t1;DROP TABLE t2;DROP TABLE t3;

PostgreSQL:&nbsp;&nbsp;&nbsp;0.135
MySQL:&nbsp;&nbsp;&nbsp;0.015
SQLite 2.7.6:&nbsp;&nbsp;&nbsp;0.939
SQLite 2.7.6 (nosync):&nbsp;&nbsp;&nbsp;0.254



SQLite is slower than the other databases when it comes to dropping tables.
This probably is because when SQLite drops a table, it has to go through and
erase the records in the database file that deal with that table.  MySQL and
PostgreSQL, on the other hand, use separate files to represent each table
so they can drop a table simply by deleting a file, which is much faster.



On the other hand, dropping tables is not a very common operation 
so if SQLite takes a little longer, that is not seen as a big problem.


c2: Implementation Limits For SQLite
c5: limits.html
c4:
Limits In SQLite


"Limits" in the context of this article means sizes or
quantities that can not be exceeded.  We are concerned
with things like the maximum number of bytes in a
BLOB or the maximum number of columns in a table.



SQLite was originally designed with a policy of avoiding
arbitrary limits.
Of course, every program that runs on a machine with finite
memory and disk space has limits of some kind.  But in SQLite, 
those limits
were not well defined.  The policy was that if it would fit
in memory and you could count it with a 32-bit integer, then
it should work.



Unfortunately, the no-limits policy has been shown to create
problems.  Because the upper bounds were not well
defined, they were not tested, and bugs were often found
when pushing SQLite to extremes.  For this reason, versions
of SQLite since about release 3.5.8 (2008-04-16)
have well-defined limits, and those limits are tested as part of
the test suite.



This article defines what the limits of SQLite are and how they
can be customized for specific applications.  The default settings
for limits are normally quite large and adequate for almost every
application.  Some applications may want to increase a limit here
or there, but we expect such needs to be rare.  More commonly,
an application might want to recompile SQLite with much lower
limits to avoid excess resource utilization in the event of
bug in higher-level SQL statement generators or to help thwart 
attackers who inject malicious SQL statements.



Some limits can be changed at run-time on a per-connection basis
using the sqlite3_limit() interface with one of the
limit categories defined for that interface.
Run-time limits are designed for applications that have multiple
databases, some of which are for internal use only and others which
can be influenced or controlled by potentially hostile external agents.
For example, a web browser application might use an internal database
to track historical page views but have one or more separate databases
that are created and controlled by javascript applications that are
downloaded from the internet.
The sqlite3_limit() interface allows internal databases managed by
trusted code to be unconstrained while simultaneously  placing tight
limitations on databases created or controlled by untrusted external
code in order to help prevent a denial of service attack.





Maximum length of a string or BLOB


The maximum number of bytes in a string or BLOB in SQLite is defined
by the preprocessor macro SQLITE_MAX_LENGTH.  The default value
of this macro is 1 billion (1 thousand million or 1,000,000,000).
You can raise or lower this value at compile-time using a command-line 
option like this:


-DSQLITE_MAX_LENGTH=123456789


The current implementation will only support a string or BLOB
length up to 231-1 or 2147483647.  And
some built-in functions such as hex() might fail well before that
point.  In security-sensitive applications it is best not to
try to increase the maximum string and blob length.  In fact,
you might do well to lower the maximum string and blob length
to something more in the range of a few million if that is
possible.



During part of SQLite's INSERT and SELECT processing, the complete
content of each row in the database is encoded as a single BLOB.
So the SQLITE_MAX_LENGTH parameter also determines the maximum
number of bytes in a row.



The maximum string or BLOB length can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_LENGTH,size) interface.


Maximum Number Of Columns


The SQLITE_MAX_COLUMN compile-time parameter is used to set an upper
bound on:



The number of columns in a table
The number of columns in an index
The number of columns in a view
The number of terms in the SET clause of an UPDATE statement
The number of columns in the result set of a SELECT statement
The number of terms in a GROUP BY or ORDER BY clause
The number of values in an INSERT statement



The default setting for SQLITE_MAX_COLUMN is 2000.  You can change it
at compile time to values as large as 32767. On the other hand, many
experienced database designers will argue that a well-normalized database
will never need more than 100 columns in a table.



In most applications, the number of columns is small - a few dozen.
There are places in the SQLite code generator that use algorithms
that are O(N&sup2;) where N is the number of columns.  
So if you redefine SQLITE_MAX_COLUMN to be a
really huge number and you generate SQL that uses a large number of
columns, you may find that sqlite3_prepare_v2()
runs slowly.



The maximum number of columns can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_COLUMN,size) interface.



Maximum Length Of An SQL Statement


The maximum number of bytes in the text of an SQL statement is 
limited to SQLITE_MAX_SQL_LENGTH which defaults to 1000000.  You
can redefine this limit to be as large as the smaller of SQLITE_MAX_LENGTH
and 1073741824.  



If an SQL statement is limited to be a million bytes in length, then
obviously you will not be able to insert multi-million byte strings
by embedding them as literals inside of INSERT statements.  But
you should not do that anyway.  Use host parameters 
for your data.  Prepare short SQL statements like this:



INSERT INTO tab1 VALUES(?,?,?);



Then use the sqlite3_bind_XXXX() functions
to bind your large string values to the SQL statement.  The use of binding
obviates the need to escape quote characters in the string, reducing the
risk of SQL injection attacks.  It also runs faster since the large
string does not need to be parsed or copied as much.



The maximum length of an SQL statement can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_SQL_LENGTH,size) interface.

Maximum Number Of Tables In A Join


SQLite does not support joins containing more than 64 tables.
This limit arises from the fact that the SQLite code generator
uses bitmaps with one bit per join-table in the query optimizer.



SQLite uses an efficient query planner algorithm
and so even a large join can be prepared quickly.
Hence, there is no mechanism to raise or lower the limit on the
number of tables in a join.


Maximum Depth Of An Expression Tree


SQLite parses expressions into a tree for processing.  During
code generation, SQLite walks this tree recursively.  The depth
of expression trees is therefore limited in order to avoid
using too much stack space.



The SQLITE_MAX_EXPR_DEPTH parameter determines the maximum expression
tree depth.  If the value is 0, then no limit is enforced.  The
current implementation has a default value of 1000.



The maximum depth of an expression tree can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_EXPR_DEPTH,size) interface if the
SQLITE_MAX_EXPR_DEPTH is initially positive.  In other words, the maximum
expression depth can be lowered at run-time if there is already a 
compile-time limit on the expression depth.  If SQLITE_MAX_EXPR_DEPTH is
set to 0 at compile time (if the depth of expressions is unlimited) then
the sqlite3_limit(db,SQLITE_LIMIT_EXPR_DEPTH,size) is a no-op.




Maximum Number Of Arguments On A Function


The SQLITE_MAX_FUNCTION_ARG parameter determines the maximum number
of parameters that can be passed to an SQL function.  The default value
of this limit is 100.  SQLite should work with functions that have 
thousands of parameters.  However, we suspect that anybody who tries
to invoke a function with more than a few parameters is really
trying to find security exploits in systems that use SQLite, 
not do useful work, 
and so for that reason we have set this parameter relatively low.

The number of arguments to a function is sometimes stored in a signed
character.  So there is a hard upper bound on SQLITE_MAX_FUNCTION_ARG
of 127.


The maximum number of arguments in a function can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_FUNCTION_ARG,size) interface.


Maximum Number Of Terms In A Compound SELECT Statement


A compound SELECT statement is two or more SELECT statements connected
by operators UNION, UNION ALL, EXCEPT, or INTERSECT.  We call each
individual SELECT statement within a compound SELECT a "term".



The code generator in SQLite processes compound SELECT statements using
a recursive algorithm.  In order to limit the size of the stack, we
therefore limit the number of terms in a compound SELECT.  The maximum
number of terms is SQLITE_MAX_COMPOUND_SELECT which defaults to 500.
We think this is a generous allotment since in practice we almost
never see the number of terms in a compound select exceed single digits.



The maximum number of compound SELECT terms can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_COMPOUND_SELECT,size) interface.




Maximum Length Of A LIKE Or GLOB Pattern


The pattern matching algorithm used in the default LIKE and GLOB
implementation of SQLite can exhibit O(N&sup2;) performance (where
N is the number of characters in the pattern) for certain pathological
cases.  To avoid denial-of-service attacks from miscreants who are able
to specify their own LIKE or GLOB patterns, the length of the LIKE
or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
The default value of this limit is 50000.  A modern workstation can
evaluate even a pathological LIKE or GLOB pattern of 50000 bytes
relatively quickly.  The denial of service problem only comes into
play when the pattern length gets into millions of bytes.  Nevertheless,
since most useful LIKE or GLOB patterns are at most a few dozen bytes
in length, paranoid application developers may want to reduce this
parameter to something in the range of a few hundred if they know that
external users are able to generate arbitrary patterns.



The maximum length of a LIKE or GLOB pattern can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_LIKE_PATTERN_LENGTH,size) interface.


Maximum Number Of Host Parameters In A Single SQL Statement


A host parameter is a place-holder in an SQL statement that is filled
in using one of the
sqlite3_bind_XXXX() interfaces.
Many SQL programmers are familiar with using a question mark ("?") as a
host parameter.  SQLite also supports named host parameters prefaced
by ":", "$", or "@" and numbered host parameters of the form "?123".



Each host parameter in an SQLite statement is assigned a number.  The
numbers normally begin with 1 and increase by one with each new
parameter.  However, when the "?123" form is used, the host parameter
number is the number that follows the question mark.



SQLite allocates space to hold all host parameters between 1 and the
largest host parameter number used.  Hence, an SQL statement that contains
a host parameter like ?1000000000 would require gigabytes of storage.
This could easily overwhelm the resources of the host machine.
To prevent excessive memory allocations, 
the maximum value of a host parameter number is SQLITE_MAX_VARIABLE_NUMBER,
which defaults to 999 for SQLite versions prior to 3.32.0 (2020-05-22)
or 32766 for SQLite versions after 3.32.0.



The maximum host parameter number can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_VARIABLE_NUMBER,size) interface.


Maximum Depth Of Trigger Recursion


SQLite limits the depth of recursion of triggers in order to prevent
a statement involving recursive triggers from using an unbounded amount
of memory.  


Prior to SQLite version 3.6.18 (2009-09-11), 
triggers were not recursive and so
this limit was meaningless.  Beginning with version 3.6.18, recursive triggers
were supported but had to be explicitly enabled using the
PRAGMA recursive_triggers statement.  
Beginning with version 3.7.0 (2009-09-11), 
recursive triggers are enabled by default but can be manually disabled
using PRAGMA recursive_triggers.  The SQLITE_MAX_TRIGGER_DEPTH is
only meaningful if recursive triggers are enabled.

The default maximum trigger recursion depth is 1000.

Maximum Number Of Attached Databases


The ATTACH statement is an SQLite extension
that allows two or more databases to be associated to the same database
connection and to operate as if they were a single database.  The number
of simultaneously attached databases is limited to SQLITE_MAX_ATTACHED
which is set to 10 by default.
The maximum number of attached databases cannot be increased above 125.


The maximum number of attached databases can be lowered at run-time using
the sqlite3_limit(db,SQLITE_LIMIT_ATTACHED,size) interface.


Maximum Number Of Pages In A Database File


SQLite is able to limit the size of a database file to prevent
the database file from growing too large and consuming too much
disk space.
The SQLITE_MAX_PAGE_COUNT parameter, which is normally set to
1073741823, is the maximum number of pages allowed in a single
database file.  An attempt to insert new data that would cause
the database file to grow larger than this will return
SQLITE_FULL.



The largest possible setting for SQLITE_MAX_PAGE_COUNT is 4294967294.
When used with the maximum page size of 65536, this gives a maximum
SQLite database size of about 281 terabytes.


The 
max_page_count PRAGMA can be used to raise or lower this
limit at run-time.

Maximum Number Of Rows In A Table


The theoretical maximum number of rows in a table is
264 (18446744073709551616 or about 1.8e+19).
This limit is unreachable since the maximum database size of 281 terabytes
will be reached first.  A 281 terabytes database can hold no more than
approximately 2e+13 rows, and then only if there are no indices and if
each row contains very little data.
Maximum Database Size


Every database consists of one or more "pages".  Within a single database,
every page is the same size, but different database can have page sizes
that are powers of two between 512 and 65536, inclusive.  The maximum
size of a database file is 4294967294 pages.  At the maximum page size
of 65536 bytes, this translates into a maximum database size of 
approximately 1.4e+14 bytes (281 terabytes, or 256 tebibytes, or
281474 gigabytes or 256,000 gibibytes).

This particular upper bound is untested since the developers do not 
have access to hardware capable of reaching this limit.  However, tests
do verify that SQLite behaves correctly and sanely when a database 
reaches the maximum file size of the underlying filesystem (which is
usually much less than the maximum theoretical database size) and when
a database is unable to grow due to disk space exhaustion.
Maximum Number Of Tables In A Schema


Each table and index requires at least one page in the database file.
An "index" in the previous sentence means an index created explicitly
using a CREATE INDEX statement or implicit indices created by UNIQUE
and PRIMARY KEY constraints.  Since the maximum number of pages in a
database file is 2147483646 (a little over 2 billion) this is also then
an upper bound on the number of tables and indices in a schema.

Whenever a database is opened, the entire schema is scanned and parsed
and a parse tree for the schema is held in memory.  That means that
database connection startup time and initial memory usage
is proportional to the size of the schema.


c2: SQLite As An Application File Format
c5: appfileformat.html
c4:
SQLite As An Application File Format


Executive Summary

An SQLite database file with a defined schema
often makes an excellent application file format.
Here are a dozen reasons why this is so:


 Simplified Application Development
 Single-File Documents
 High-Level Query Language
 Accessible Content
 Cross-Platform
 Atomic Transactions
 Incremental And Continuous Updates
 Easily Extensible
 Performance
 Concurrent Use By Multiple Processes
 Multiple Programming Languages
 Better Applications


Each of these points will be described in more detail below,
after first considering more closely the meaning of
"application file format".  See also the short version of this
whitepaper.

What Is An Application File Format?


An "application file format" is the file format
used to persist application state to disk or to exchange
information between programs.
There are thousands of application file formats in use today.
Here are just a few examples:


DOC - Word Perfect and Microsoft Office documents
DWG - AutoCAD drawings
PDF - Portable Document Format from Adobe
XLS - Microsoft Excel Spreadsheet
GIT - Git source code repository
EPUB - The Electronic Publication format used by non-Kindle eBooks
ODT - The Open Document format used by OpenOffice and others
PPT - Microsoft PowerPoint presentations
ODP - The Open Document presentation format used by OpenOffice and others


We make a distinction between a "file format" and an "application format".
A file format is used to store a single object.  So, for example, a GIF or
JPEG file stores a single image, and an XHTML file stores text,
so those are "file formats" and not "application formats".  An EPUB file, 
in contrast, stores both text and images (as contained XHTML and GIF/JPEG
files) and so it is considered an "application format".  This article is
about "application formats".

The boundary between a file format and an application format is fuzzy.
This article calls JPEG a file format, but for an image editor, JPEG 
might be considered the application format.  Much depends on context.
For this article, let us say that a file format stores a single object
and an application format stores many different objects and their relationships
to one another.

Most application formats fit into one of these three categories:


Fully Custom Formats.
Custom formats are specifically designed for a single application.
DOC, DWG, PDF, XLS, and PPT are examples of custom formats.  Custom
formats are usually contained within a single file, for ease of transport.
They are also usually binary, though the DWG format is a notable exception.
Custom file formats require specialized application code
to read and write and are not normally accessible from commonly
available tools such as unix command-line programs and text editors.
In other words, custom formats are usually "opaque blobs".
To access the content of a custom application file format, one needs
a tool specifically engineered to read and/or write that format.

Pile-of-Files Formats.
Sometimes the application state is stored as a hierarchy of
files.  Git is a prime example of this, though the phenomenon occurs
frequently in one-off and bespoke applications.  A pile-of-files format
essentially uses the filesystem as a key/value database, storing small
chunks of information into separate files.  This gives the
advantage of making the content more accessible to common utility
programs such as text editors or "awk" or "grep".  But even if many 
of the files in a pile-of-files format
are easily readable, there are usually some files that have their
own custom format (example: Git "Packfiles") and are hence
"opaque blobs" that are not readable
or writable without specialized tools.  It is also much less convenient
to move a pile-of-files from one place or machine to another, than
it is to move a single file.  And it is hard to make a pile-of-files
document into an email attachment, for example.  Finally, a pile-of-files
format breaks the "document metaphor":
there is no one file that a user can point to
that is "the document".

Wrapped Pile-of-Files Formats.
Some applications use a Pile-of-Files that is then encapsulated into
some kind of single-file container, usually a ZIP archive.  
EPUB, ODT,and ODP are examples of this approach.
An EPUB book is really just a ZIP archive that contains various
XHTML files for the text of book chapters, GIF and JPEG images for
the artwork, and a specialized catalog file that tells the eBook
reader how all the XML and image files fit together.  OpenOffice
documents (ODT and ODP) are also ZIP archives containing XML and
images that represent their content as well as "catalog" files that
show the interrelationships between the component parts.

A wrapped pile-of-files format is a compromise between a full
custom file format and a pure pile-of-files format.
A wrapped pile-of-files format is not an opaque blob in the same sense
as a custom format, since the component parts can still be accessed
using any common ZIP archiver, but the format is not quite as accessible
as a pure pile-of-files format because one does still need the ZIP 
archiver, and one cannot normally use command-line tools like "find"
on the file hierarchy without first un-zipping it.  On the other
hand, a wrapped pile-of-files format does preserve the document
metaphor by putting all content into a single disk file.  And
because it is compressed, the wrapped pile-of-files format tends to
be more compact.

As with custom file formats, and unlike pure pile-of-file formats,
a wrapped pile-of-files format is not as easy to edit, since
usually the entire file must be rewritten in order to change any
component part.


The purpose of this document is to argue in favor of a fourth
new category of application file format: An SQLite database file.

SQLite As The Application File Format


Any application state that can be recorded in a pile-of-files can
also be recorded in an SQLite database with a simple key/value schema
like this:

CREATE TABLE files(filename TEXT PRIMARY KEY, content BLOB);

If the content is compressed, then such an SQLite Archive database is
the same size (&#177;1%)
as an equivalent ZIP archive, and it has the advantage
of being able to update individual "files" without rewriting
the entire document.


But an SQLite database is not limited to a simple key/value structure
like a pile-of-files database.  An SQLite database can have dozens
or hundreds or thousands of different tables, with dozens or
hundreds or thousands of fields per table, each with different datatypes
and constraints and particular meanings, all cross-referencing each other,
appropriately and automatically indexed for rapid retrieval,
and all stored efficiently and compactly in a single disk file.
And all of this structure is succinctly documented for humans
by the SQL schema.

In other words, an SQLite database can do everything that a 
pile-of-files or wrapped pile-of-files format can do, plus much more,
and with greater lucidity.
An SQLite database is a more versatile container than key/value
filesystem or a ZIP archive.  (For a detailed example, see the
OpenOffice case study essay.)

The power of an SQLite database could, in theory, be achieved using
a custom file format.  But any custom file format that is as expressive
as a relational database would likely require an enormous design specification 
and many tens or hundreds of thousands of lines of code to 
implement.  And the end result would be an "opaque blob" that is
inaccessible without specialized tools.


Hence, in comparison to other approaches, the use of
an SQLite database as an application file format has
compelling advantages.  Here are a few of these advantages,
enumerated and expounded:



Simplified Application Development.
No new code is needed for reading or writing the application file.
One has merely to link against the SQLite library, or include the 
single "sqlite3.c" source file with the rest of the
application C code, and SQLite will take care of all of the application
file I/O.  This can reduce application code size by many thousands of
lines, with corresponding saving in development and maintenance costs.

SQLite is one of the
most used software libraries in the world.
There are literally tens of billions of SQLite database files in use 
daily, on smartphones and gadgets and in desktop applications.
SQLite is carefully tested and proven reliable.  It is not
a component that needs much tuning or debugging, allowing developers
to stay focused on application logic.

Single-File Documents.
An SQLite database is contained in a single file, which is easily
copied or moved or attached.  The "document" metaphor is preserved.

SQLite does not have any file naming requirements
and so the application can use any custom file suffix that it wants
to help identify the file as "belonging" to the application.
SQLite database files contain a 4-byte Application ID in
their headers that can be set to an application-defined value
and then used to identify the "type" of the document for utility
programs such as file(1), further
enhancing the document metaphor.


High-Level Query Language.
SQLite is a complete relational database engine, which means that the
application can access content using high-level queries.  Application
developers need not spend time thinking about "how" to retrieve the
information they need from a document.  Developers write SQL that
expresses "what" information they want and let the database engine
to figure out how to best retrieve that content.  This helps developers
operate "heads up" and remain focused on solving the user's problem,
and avoid time spent "heads down" fiddling with low-level file
formatting details.

A pile-of-files format can be viewed as a key/value database.  
A key/value database is better than no database at all.
But without transactions or indices or a high-level query language or
a proper schema,
it is much harder and more error prone to use a key/value database than
a relational database.

Accessible Content.
Information held in an SQLite database file is accessible using 
commonly available open-source command-line tools - tools that 
are installed by default on Mac and Linux systems and that are 
freely available as a self-contained EXE file on Windows.
Unlike custom file formats, application-specific programs are
not required to read or write content in an SQLite database.
An SQLite database file is not an opaque blob.  It is true
that command-line tools such as text editors or "grep" or "awk" are
not useful on an SQLite database, but the SQL query language is a much
more powerful and convenient way for examining the content, so the
inability to use "grep" and "awk" and the like is not seen as a loss.

An SQLite database is a well-defined and well-documented
file format that is in widespread use by literally millions of applications
and is backwards compatible to its inception in 2004 and which promises
to continue to be compatible in decades to come.  The longevity of
SQLite database files is particularly important to bespoke applications,
since it allows the document content to be accessed far in the
future, long after all traces of the original application have been lost.
Data lives longer than code.
SQLite databases are recommended by the US Library of Congress
as a storage format for long-term preservation of digital content.


Cross-Platform.
SQLite database files are portable between 32-bit and 64-bit machines and
between big-endian and little-endian architectures and between any of the
various flavors of Windows and Unix-like operating systems.
The application using an SQLite application file format can store
binary numeric data without having to worry about the byte-order of
integers or floating point numbers.
Text content can be read or written as UTF-8, UTF-16LE, or UTF-16BE and 
SQLite will automatically perform any necessary translations on-the-fly.

Atomic Transactions.
Writes to an SQLite database are atomic.  
They either happen completely
or not at all, even during system crashes or power failures.  So
there is no danger of corrupting a document just because the power happened
to go out at the same instant that a change was being written to disk.

SQLite is transactional, meaning that multiple changes can be grouped
together such that either all or none of them occur, and so that the
changes can be rolled back if a problem is found prior to commit.
This allows an application to make a change incrementally, then run
various sanity and consistency checks on the resulting data prior to
committing the changes to disk.  The
Fossil DVCS 
uses this technique
to verify that no repository history has been lost prior to each change.

Incremental And Continuous Updates.
When writing to an SQLite database file, only those parts of the file that
actually change are written out to disk.  This makes the writing happen faster
and saves wear on SSDs.  This is an enormous advantage over custom
and wrapped pile-of-files formats, both of which usually require a
rewrite of the entire document in order to change a single byte.  
Pure pile-of-files formats can also
do incremental updates to some extent, though the granularity of writes is 
usually larger with pile-of-file formats (a single file) than with SQLite
(a single page).

SQLite also supports continuous update.
Instead of collecting changes in memory and then writing
them to disk only on a File/Save action, changes can be written back to
the disk as they occur.  This avoids loss of work on a system crash or
power failure.  An automated undo/redo stack, managed using triggers,
can be kept in the on-disk database, meaning that undo/redo can occur 
across session boundaries.

Easily Extensible.
As an application grows, new features can be added to an
SQLite application file format simply by adding new tables to the schema
or by adding new columns to existing tables.  Adding columns or tables
does not change the meaning of prior queries, so with a 
modicum of care to ensuring that the meaning of legacy columns and
tables are preserved, backwards compatibility is maintained.

It is possible to extend custom or pile-of-files formats too, of course,
but doing is often much harder.  If indices are added, then all application
code that changes the corresponding tables must be located and modified to
keep those indices up-to-date.  If columns are added, then all application
code that accesses the corresponding table must be located and modified to 
take into account the new columns.

Performance.
In many cases, an SQLite application file format will be 
faster than a pile-of-files format or
a custom format.  In addition to being faster for raw read and
writes, SQLite can often dramatically improves start-up times because 
instead of having to
read and parse the entire document into memory, the application can
do queries to extract only the information needed for the initial screen.
As the application progresses, it only needs to load as much material as
is needed to draw the next screen, and can discard information from
prior screens that is no longer in use.  This helps keep the memory
footprint of the application under control.

A pile-of-files format can be read incrementally just like SQLite.
But many developers are surprised to learn that SQLite can read and 
write smaller BLOBs (less than about 100KB in size) from its database 
faster than those same blobs can be read or written as separate files 
from the filesystem.  (See
35% Faster Than The Filesystem and
Internal Versus External BLOBs for further information.)
There is overhead associated with operating a relational
database engine, however one should not assume that direct file I/O
is faster than SQLite database I/O, as often it is not.

In either case, if performance problems do arise in an SQLite application 
those problems can often be resolved by adding one or two CREATE INDEX
statements to the schema or perhaps running ANALYZE one time
and without having to touch a single line of
application code.  But if a performance problem comes up in a custom or 
pile-of-files format, the fix will often require extensive changes
to application code to add and maintain new indices or to extract 
information using different algorithms.

Concurrent Use By Multiple Processes.
SQLite automatically coordinates concurrent access to the same
document from multiple threads and/or processes.  Two or more
applications can connect and read from the same document at the
same time.  Writes are serialized, but as writes normally only
take milliseconds, applications simply take turns writing.
SQLite automatically ensures that the low-level format of the
document is uncorrupted.  Accomplishing the same with a custom
or pile-of-files format, in contrast, requires extensive support
in the application.  And the application logic needed to support
concurrency is a notorious bug-magnet.

Multiple Programming Languages.
Though SQLite is itself written in ANSI-C, interfaces exist for
just about every other programming language you can think of:
C++, C#, Objective-C, Java, Tcl, Perl, Python, Ruby, Erlang,
JavaScript, and so forth.  So programmers can develop in whatever
language they are most comfortable with and which best matches
the needs of the project.

An SQLite application file format is a great 
choice in cases where there is a collection or "federation" of
separate programs, often written in different languages and by
different development teams.
This comes up commonly in research or laboratory
environments where one team is responsible for data acquisition
and other teams are responsible for various stages of analysis.
Each team can use whatever hardware, operating system,
programming language and development methodology that they are 
most comfortable with, and as long as all programs use an SQLite 
database with a common schema, they can all interoperate.


Better Applications.
If the application file format is an SQLite database, the complete
documentation for that file format consists of the database schema,
with perhaps a few extra words about what each table and column
represents.  The description of a custom file format,
on the other hand, typically runs on for hundreds of 
pages.  A pile-of-files format, while much simpler and easier to
describe than a fully custom format, still tends to be much larger
and more complex than an SQL schema dump, since the names and format
for the individual files must still be described.

This is not a trivial point.  A clear, concise, and easy to understand
file format is a crucial part of any application design.
Fred Brooks, in his all-time best-selling computer science text,
The Mythical Man-Month says:
Representation is the
essence of computer programming....
Show me your flowcharts and conceal your tables, and I shall 
continue to be mystified.  Show me your tables, and I won't usually
need your flowcharts; they'll be obvious.
Rob Pike, in his
Rules of Programming expresses the same idea this way:

Data dominates.  If you've chosen the right data structures
and organized things well, the algorithms will almost always
be self-evident.  Data structures, not algorithms, are central
to programming.
 Linus Torvalds used different words to say
much the same thing on the Git mailing list on 2006-06-27: 

Bad programmers worry about the code.  Good programmers worry
about data structures and their relationships.


The point is this: an SQL database schema almost always does 
a far better job of defining and organizing the tables and 
data structures and their relationships.
And having clear, concise, and well-defined representation
almost always results in an application that performs better,
has fewer problems, and is easier to develop and maintain.


Conclusion


SQLite is not the perfect application file format for every situation.
But in many cases, SQLite is a far better choice than either a custom
file format, a pile-of-files, or a wrapped pile-of-files.
SQLite is a high-level, stable, reliable, cross-platform, widely-deployed,
extensible, performant, accessible, concurrent file format.  It deserves
your consideration as the standard file format on your next application
design.


c2: SQLite Consortium
c5: consortium.html
c4:
The SQLite Consortium


The SQLite Consortium is a membership association dedicated to
insuring the continuing vitality and independence of SQLite.
SQLite is high-quality, public domain software.  The goal of
the SQLite Consortium is to make sure it stays that way.



Consortium members contribute funding to support the ongoing
development and maintenance of SQLite and in return receive
enterprise-level technical support and legal assurances that
SQLite will remain independent and open-source.  Consortium 
members have direct access to
the SQLite developers and receive priority consideration for
any bug fixes or feature requests.  However, technical control
and direction of SQLite remains with the SQLite architect and
developers.  An important goal of the SQLite Consortium, after
all, is to make sure that SQLite does not fall under the governance
of any single company but remains independent and fully under the
control of the SQLite developers.



Companies that use SQLite as a critical component in their
products or infrastructure may want to consider becoming
SQLite Consortium Members as inexpensive insurance
in the future vitality and independence of SQLite.  The SQLite Consortium 
membership fee is a fraction of the cost of devoting internal
staff to supporting the SQLite code base.  Benefits of
membership include:




Consortium members have the guaranteed, undivided attention of the SQLite
developers for 23 staff-days per year and for as much additional time 
above and beyond that amount that the core developers have available.
There are no arbitrary limits on contact time.
The consortium will never be over-subscribed.  New SQLite developers
will be recruited and trained as necessary to cover the 23 day/year
support commitment.



Consortium members can call any developer at any time, day or
night, and expect to get their full and immediate attention.
Consortium members have access to the home telephone numbers
and cellphone numbers and work schedules of the core developers
so that the developers can be tracked down quickly in a crisis.



The SQLite developers are eager and happy to write new code
or debug existing code for consortium members.
Consortium members can request and expect to receive significant
new enhancements to the public SQLite code base.  Consortium
members can also request their own private, proprietary extensions
and enhancements.



Consortium members can receive support for any
version of SQLite no matter how old.
Bug fixes will be back ported to older versions of SQLite upon
request.



Consortium members can receive private
email and/or telephone notifications and briefings covering
new bugs or recently added features.
The core developers are constantly watching out for the
interests of consortium members and will attempt to protect
those interests in every way possible and alert members
when their interests are threatened in any way.



The SQLite developers will set up customized regression tests
to fully and completely test SQLite as configured by consortium
members.  Normally, only the standard SQLite configuration is fully
tested at each release.  Consortium members that use a non-standard 
configuration can request that their configuration be tested to the 
same level of detail.



Support requests are accepted from any employee or contractor working
for a consortium member.
Support is not limited to a single development
team as it is with a maintenance subscription or technical support
agreement.



Support requests, comments, and suggestions for future
changes to SQLite coming from consortium members take priority 
over requests from all other sources.
Consortium members go to the front of the line.



We will be happy to 
recognize consortium members
 on the SQLite website
with a logo and/or a brief acknowledgement of their contribution to the
project.  This is an opportunity for companies to build good will by
demonstrating that they are giving back to the community.  Or, members 
can remain anonymous.





How To Become A Consortium Member


Membership in the SQLite Consortium is via
contract with
Hipp, Wyrick &amp; Company, Inc..
Please call +1.704.948.4565 during US east-coast business hours
for additional information.


c2: Benefits of SQLite As A File Format
c5: aff_short.html
c4:
SQLite As An Application File Format


(Note:  The current page is a brief summary of why SQLite makes
a good application file format.  The topic is considered at greater
detail in a separate technical note.)


SQLite has been used with great success as the on-disk file format
for desktop applications such as version control systems,
financial analysis tools, media cataloging and editing suites, CAD
packages, record keeping programs, and so forth.  The traditional
File/Open operation calls sqlite3_open() to attach to the database
file.  Updates happen automatically as application content is revised
so the File/Save menu option becomes superfluous.  The File/Save_As
menu option can be implemented using the backup API.



There are many advantages to using SQLite as an application file format,
including:



Better performance

 Reading and writing from an SQLite database
     is often faster than reading and writing individual files from disk.
     See 35% Faster Than The Filesystem
     and Internal Versus External BLOBs.
 The application only has to load the data it needs, rather
     than reading the entire file and holding a complete parse
     in memory.
 Small edits only overwrite the parts of the file that change,
     reducing write time and wear on SSD drives.

Reduced application cost and complexity

 No application file I/O code to write and debug.
 Content can be accessed and updated using concise SQL queries instead
     of lengthy and error-prone procedural routines.
 The file format can be extended in future releases simply
     by adding new tables and/or column, preserving backwards compatibility.
 Applications can leverage the
     full-text search and RTREE indexes and use triggers to implement
     an automated undo/redo stack.
 Performance problems can often be resolved, even late in the
     development cycle, using CREATE INDEX, avoiding costly
     redesign, rewrite, and retest efforts.

Portability

 The application file is portable across all operating systems,
     32-bit and 64-bit and big- and little-endian architectures.
 A federation of programs, perhaps all written in different programming
     languages, can access the same application file with no
     compatibility concerns.
 Multiple processes can attach to the same application
     file and can read and write without interfering with each another.
 Diverse content which might otherwise be stored as a "pile-of-files"
     is encapsulated into a single disk file for simpler transport
     via scp/ftp, USB stick, and/or email attachment.

Reliability

 Content can be updated continuously and atomically so 
     that little or no work is lost in a power failure or crash.
 Bugs are far less likely in SQLite than in custom-written file I/O code.
 SQL queries are many times smaller than the equivalent procedural
     code, and since the number of bugs per line of code is roughly
     constant, this means fewer bugs overall.

Accessibility

 SQLite database content can be viewed using a wide variety
     third-party tools.
 Content stored in an SQLite database is more likely to be 
     recoverable decades in the future, long after all traces of
     the original application have been lost. Data lives longer than code.
 SQLite database files are recommended by the US Library of Congress
     as a storage format for long-term preservation of digital content.




SQLite allows database files to have any desired filename extension, so
an application can choose a custom filename extension for its own use, if
desired.  The application_id pragma can be used to set an "Application ID"
integer in the database file so that tools like
file(1) can determine that the file
is associated with your application and is not just a generic
SQL database.


c2: Code Of Ethics
c5: codeofethics.html
c4:
1. Overview

This document was originally called a "Code of Conduct" and
was created (in a slightly different format) for the purpose of
filling in a box on "supplier registration" forms
submitted to the SQLite developers by various minor clients.  However,
we subsequently learned that "Code of Conduct" has a specific technical
meaning within many software development communities, a meaning which
was at odds with the intent of this document.  Hence, this document
is now renamed and replaced by a 
Code of Conduct that does comply with the
specific technical requirements was inserted in the place of
the old name.


This document is still sometimes used as a "Code of Conduct" on supplier
registration forms.  But it is not a Code of Conduct in the same sense
that many communities mean a Code of Conduct.  Rather,
this document describes the ethical principles upon
which SQLite is based.  Another way to look at this document is
as a succinct description of the SQLite Founder's idea of what it
means to be "virtuous".


Readers can also interpret this document as a primer on the
world-view of the SQLite Founder, to help them better understand
"where he is coming from".

1.1. Instruments of Good Works

The founder of SQLite, and all of the current developers at the time
when this document was composed, have pledged to govern their
interactions with each other, with their clients,
and with the larger SQLite user community in
accordance with the "instruments of good works" from chapter 4 of
The Rule of St. Benedict
(hereafter: "The Rule").
This code of ethics has proven its mettle in thousands of diverse
communities for over 1,500 years, and has served as a baseline for many
civil law codes since the time of Charlemagne.

1.2. Scope of Application


No one is required to follow The Rule, to know The Rule, or even
to think that The Rule is a good idea.  The Founder of SQLite believes
that anyone who follows The Rule will live a happier and more productive 
life, but individuals are free to dispute or ignore that advice if
they wish.


The founder of SQLite and all
current developers have pledged to follow spirit of The Rule
to the best of their ability. They
view The Rule as their promise to all SQLite users of how the developers
are expected to behave in community.
This is a one-way promise, or covenant.
In other words, the developers are saying: "We will treat you this
way regardless of how you treat us."


2. The Rule


 First of all, love the Lord God with your whole heart,
     your whole soul, and your whole strength.
 Then, love your neighbor as yourself.
 Do not murder.
 Do not commit adultery.
 Do not steal.
 Do not covet.
 Do not bear false witness.
 Honor all.
 Do not do to another what you would not have done to yourself.
 Deny oneself in order to follow Christ.
 Chastise the body.
 Do not become attached to pleasures.
 Love fasting.
 Relieve the poor.
 Clothe the naked.
 Visit the sick.
 Bury the dead.
 Be a help in times of trouble.
 Console the sorrowing.
 Be a stranger to the world's ways.
 Prefer nothing more than the love of Christ.
 Do not give way to anger.
 Do not nurse a grudge.
 Do not entertain deceit in your heart.
 Do not give a false peace.
 Do not forsake charity.
 Do not swear, for fear of perjuring yourself.
 Utter only truth from heart and mouth.
 Do not return evil for evil.
 Do no wrong to anyone, and bear patiently wrongs done to yourself.
 Love your enemies.
 Do not curse those who curse you, but rather bless them.
 Bear persecution for justice's sake.
 Be not proud.
 Be not addicted to wine.
 Be not a great eater.
 Be not drowsy.
 Be not lazy.
 Be not a grumbler.
 Be not a detractor.
 Put your hope in God.
 Attribute to God, and not to self, whatever good you see in yourself.
 Recognize always that evil is your own doing,
     and to impute it to yourself.
 Fear the Day of Judgment.
 Be in dread of hell.
 Desire eternal life with all the passion of the spirit.
 Keep death daily before your eyes.
 Keep constant guard over the actions of your life.
 Know for certain that God sees you everywhere.
 When wrongful thoughts come into your heart, dash them against
     Christ immediately.
 Disclose wrongful thoughts to your spiritual mentor.
 Guard your tongue against evil and depraved speech.
 Do not love much talking.
 Speak no useless words or words that move to laughter.
 Do not love much or boisterous laughter.
 Listen willingly to holy reading.
 Devote yourself frequently to prayer.
 Daily in your prayers, with tears and sighs, confess your
     past sins to God, and amend them for the future.
 Fulfill not the desires of the flesh; hate your own will.
 Obey in all things the commands of those whom God has placed
     in authority over you even though they (which God forbid) should 
     act otherwise, mindful of the Lord's precept, "Do what they say, 
     but not what they do."
 Do not wish to be called holy before one is holy; but first to be
     holy, that you may be truly so called.
 Fulfill God's commandments daily in your deeds.
 Love chastity.
 Hate no one.
 Be not jealous, nor harbor envy.
 Do not love quarreling.
 Shun arrogance.
 Respect your seniors.
 Love your juniors.
 Pray for your enemies in the love of Christ.
 Make peace with your adversary before the sun sets.
 Never despair of God's mercy.


c2: About SQLite
c5: about.html
c4:
About SQLite


Executive Summary

 Full-featured SQL
 Billions and billions of deployments
 Single-file database
 Public domain source code
 All source code in one file (sqlite3.c)
 Small footprint
 Max DB size: 281 terabytes
     (248 bytes)
 Max row size: 1 gigabyte
 Faster than direct file I/O
 Aviation-grade quality and testing
 Zero-configuration
 ACID transactions, even after power loss
 Stable, enduring file format
 Extensive, detailed documentation
 Long-term support


SQLite is an in-process library that implements a
self-contained, 
serverless,
zero-configuration,
transactional
SQL database engine.
The code for SQLite is in the
public domain and is thus free for
use for any purpose, commercial or private.
SQLite is the most widely deployed database in the world
with more applications than we can
count, including several high-profile projects.

SQLite is an embedded SQL database engine.
Unlike most other SQL databases, SQLite does not have a separate
server process.  SQLite reads and writes directly to ordinary disk
files.  A complete SQL database with multiple tables, indices,
triggers, and views, is contained in a single disk file.
The database file format is cross-platform - you can freely copy a database
between 32-bit and 64-bit systems or between 
big-endian and
little-endian
architectures.  These features make SQLite a popular choice as
an Application File Format.  SQLite database files are a
recommended storage format by the US Library of Congress.
Think of SQLite not as a replacement for 
Oracle but
as a replacement for fopen()

SQLite is a compact library.
With all features enabled, the library size can be less than 600KiB,
depending on the target platform and compiler optimization settings.
(64-bit code is larger.  And some compiler optimizations
such as aggressive function inlining and loop unrolling can cause the
object code to be much larger.)
There is a tradeoff between memory usage and speed.  
SQLite generally runs faster the more memory
you give it.  Nevertheless, performance is usually quite good even
in low-memory environments.  Depending on how it is used, SQLite can be
faster than direct filesystem I/O.

SQLite is 
very carefully tested prior to every
release and has a reputation for being very reliable.
Most of the SQLite source code is devoted purely to testing and
verification.  An automated test suite runs millions and millions of
test cases involving hundreds of millions of individual SQL statements
and achieves 100% branch test coverage.  
SQLite responds gracefully to memory
allocation failures and disk I/O errors.  Transactions are
ACID
even if interrupted by system crashes or power failures.  
All of this is verified by
the automated tests using special test harnesses which simulate 
system failures.
Of course, even with all this testing, there are still bugs.
But unlike some similar projects (especially commercial competitors)
SQLite is open and honest about all bugs and provides
bugs lists and
minute-by-minute 
chronologies of code changes.

The SQLite code base is supported by an
international team of developers who work on
SQLite full-time.
The developers continue to expand the capabilities of SQLite
and enhance its reliability and performance while maintaining
backwards compatibility with the 
published interface spec,
SQL syntax, and database file format.
The source code is absolutely free to anybody who wants it,
but professional support is also available.

The SQLite project was started on 
2000-05-09.
The future is always hard to predict, but the intent of the developers
is to support SQLite through the year 2050.  Design decisions are made
with that objective in mind.

We the developers hope that you find SQLite useful and we
entreat you to use it well: to make good and beautiful products that
are fast, reliable, and simple to use.  Seek forgiveness for yourself
as you forgive others.  And just as you have received SQLite for free,
so also freely give, paying the debt forward.


c2: SQLite Download Page
c5: download.html
c4:
SQLite Download Page








Build Product Names


Build products are named using one of the following templates:


 sqlite-product-version.zip
 sqlite-product-version.tar.gz
 sqlite-product-os-cpu-version.zip
 sqlite-product-date.zip


Templates (1) and (2) are used for source-code products.  Template (1) is
used for generic source-code products and templates (2) is used for source-code
products that are generally only useful on unix-like platforms.  Template (3)
is used for precompiled binaries products.  Template (4) is used for
unofficial pre-release "snapshots" of source code.

The version is encoded so that filenames sort in order of
increasing version number when viewed using "ls".  For version 3.X.Y the
filename encoding is 3XXYY00.  For branch version 3.X.Y.Z, the encoding is
3XXYYZZ.

The date in template (4) is of the form: YYYYMMDDHHMM





Source Code Repositories


The SQLite source code is maintained in three geographically-dispersed
self-synchronizing
Fossil repositories that are
available for anonymous read-only access.  Anyone can 
view the repository contents and download historical versions
of individual files or ZIP archives of historical check-ins.
You can also clone the entire repository.

See the How To Compile SQLite page for additional information
on how to use the raw SQLite source code.
Note that a recent version of Tcl
is required in order to build from the repository sources. 
The amalgamation source code files
(the "sqlite3.c" and "sqlite3.h" files) build products and are
not contained in raw source code tree.


https://www.sqlite.org/cgi/src (Dallas)
https://www2.sqlite.org/cgi/src (Newark)
https://www3.sqlite.org/cgi/src (San Francisco)


The documentation is maintained in separate
Fossil repositories located
at:


https://www.sqlite.org/cgi/docsrc (Dallas)
https://www2.sqlite.org/cgi/docsrc (Newark)
https://www3.sqlite.org/cgi/docsrc (San Francisco)


c2: An Asynchronous I/O Module For SQLite
c5: asyncvfs.html
c4:
An Asynchronous I/O Module For SQLite


NOTE: 
WAL mode with PRAGMA synchronous set to NORMAL avoids calls to
fsync() during transaction commit and only invokes fsync() during
a checkpoint operation.  The use of WAL mode largely obviates the
need for this asynchronous I/O module.  Hence, this module is no longer
supported.  The source code continues to exist in the SQLite source tree,
but it is not a part of any standard build and is no longer maintained.
This documentation is retained for historical reference.

Normally, when SQLite writes to a database file, it waits until the write
operation is finished before returning control to the calling application.
Since writing to the file-system is usually very slow compared with CPU
bound operations, this can be a performance bottleneck. The asynchronous I/O
backend is an extension that causes SQLite to perform all write requests
using a separate thread running in the background. Although this does not
reduce the overall system resources (CPU, disk bandwidth etc.), it does
allow SQLite to return control to the caller quickly even when writing to
the database.

1.0 FUNCTIONALITY

With asynchronous I/O, write requests are handled by a separate thread
running in the background.  This means that the thread that initiates
a database write does not have to wait for (sometimes slow) disk I/O
to occur.  The write seems to happen very quickly, though in reality
it is happening at its usual slow pace in the background.

Asynchronous I/O appears to give better responsiveness, but at a price.
You lose the Durable property.  With the default I/O backend of SQLite,
once a write completes, you know that the information you wrote is
safely on disk.  With the asynchronous I/O, this is not the case.  If
your program crashes or if a power loss occurs after the database
write but before the asynchronous write thread has completed, then the
database change might never make it to disk and the next user of the
database might not see your change.

You lose Durability with asynchronous I/O, but you still retain the
other parts of ACID:  Atomic,  Consistent, and Isolated.  Many
applications get along fine without the Durability.

1.1 How it Works

Asynchronous I/O works by creating an SQLite VFS object
and registering it with sqlite3_vfs_register().
When files opened via 
this VFS are written to (using the vfs xWrite() method), the data is not 
written directly to disk, but is placed in the "write-queue" to be
handled by the background thread.

When files opened with the asynchronous VFS are read from 
(using the vfs xRead() method), the data is read from the file on 
disk and the write-queue, so that from the point of view of
the vfs reader the xWrite() appears to have already completed.

The asynchronous I/O VFS is registered (and unregistered) by calls to the 
API functions sqlite3async_initialize() and sqlite3async_shutdown().
See section "Compilation and Usage" below for details.

1.2 Limitations

In order to gain experience with the main ideas surrounding asynchronous 
IO, this implementation is deliberately kept simple. Additional 
capabilities may be added in the future.

For example, as currently implemented, if writes are happening at a 
steady stream that exceeds the I/O capability of the background writer
thread, the queue of pending write operations will grow without bound.
If this goes on for long enough, the host system could run out of memory. 
A more sophisticated module could to keep track of the quantity of 
pending writes and stop accepting new write requests when the queue of 
pending writes grows too large.

1.3 Locking and Concurrency

Multiple connections from within a single process that use this
implementation of asynchronous IO may access a single database
file concurrently. From the point of view of the user, if all
connections are from within a single process, there is no difference
between the concurrency offered by "normal" SQLite and SQLite
using the asynchronous backend.

If file-locking is enabled (it is enabled by default), then connections
from multiple processes may also read and write the database file.
However concurrency is reduced as follows:


 When a connection using asynchronous IO begins a database
        transaction, the database is locked immediately. However the
        lock is not released until after all relevant operations
        in the write-queue have been flushed to disk. This means
        (for example) that the database may remain locked for some 
        time after a "COMMIT" or "ROLLBACK" is issued.

 If an application using asynchronous IO executes transactions
        in quick succession, other database users may be effectively
        locked out of the database. This is because when a BEGIN
        is executed, a database lock is established immediately. But
        when the corresponding COMMIT or ROLLBACK occurs, the lock
        is not released until the relevant part of the write-queue 
        has been flushed through. As a result, if a COMMIT is followed
        by a BEGIN before the write-queue is flushed through, the database 
        is never unlocked,preventing other processes from accessing 
        the database.


File-locking may be disabled at runtime using the sqlite3async_control()
API (see below). This may improve performance when an NFS or other 
network file-system, as the synchronous round-trips to the server be 
required to establish file locks are avoided. However, if multiple 
connections attempt to access the same database file when file-locking
is disabled, application crashes and database corruption is a likely
outcome.


2.0 COMPILATION AND USAGE


The asynchronous IO extension consists of a single file of C code
(sqlite3async.c), and a header file (sqlite3async.h), located in the

ext/async/ subfolder of the SQLite source tree, that defines the 
C API used by applications to activate and control the modules 
functionality.


To use the asynchronous IO extension, compile sqlite3async.c as
part of the application that uses SQLite. Then use the APIs defined
in sqlite3async.h to initialize and configure the module.


The asynchronous IO VFS API is described in detail in comments in 
sqlite3async.h. Using the API usually consists of the following steps:


Register the asynchronous IO VFS with SQLite by calling the
       sqlite3async_initialize() function.

Create a background thread to perform write operations and call
       sqlite3async_run().

Use the normal SQLite API to read and write to databases via 
       the asynchronous IO VFS.


Refer to comments in the

sqlite3async.h header file for details.


3.0 PORTING

Currently the asynchronous IO extension is compatible with win32 systems
and systems that support the pthreads interface, including Mac OS X, Linux, 
and other varieties of Unix. 

To port the asynchronous IO extension to another platform, the user must
implement mutex and condition variable primitives for the new platform.
Currently there is no externally available interface to allow this, but
modifying the code within sqlite3async.c to include the new platforms
concurrency primitives is relatively easy. Search within sqlite3async.c
for the comment string "PORTING FUNCTIONS" for details. Then implement
new versions of each of the following:


static void async_mutex_enter(int eMutex);
static void async_mutex_leave(int eMutex);
static void async_cond_wait(int eCond, int eMutex);
static void async_cond_signal(int eCond);
static void async_sched_yield(void);


The functionality required of each of the above functions is described
in comments in sqlite3async.c.


c2: SQLite Foreign Key Support
c5: foreignkeys.html
c4:
Overview

This document describes the support for SQL foreign key constraints
   introduced in SQLite version 3.6.19 (2009-10-14). 

The first section introduces the 
   concept of an SQL foreign key by example and defines the terminology 
   used for the remainder of the document. Section 2 describes the steps 
   an application must take in order to enable foreign key constraints in 
   SQLite (it is disabled by default). The next section, section 3, 
   describes the indexes that the user must create in order to use 
   foreign key constraints, and those that should be created in order for
   foreign key constraints to function efficiently. Section 4 describes
   the advanced foreign key related features supported by SQLite and
   section 5 describes the way the ALTER and DROP TABLE commands are
   enhanced to support foreign key constraints. Finally, section 6 
   enumerates the missing features and limits of the current implementation.

This document does not contain a full description of the syntax used
   to create foreign key constraints in SQLite. This may be found as 
   part of the documentation for the CREATE TABLE statement.

1. Introduction to Foreign Key Constraints

  
    SQL foreign key constraints are used to enforce "exists" relationships 
    between tables. For example, consider a database schema created using 
    the following SQL commands:

CREATE TABLE artist(
  artistid    INTEGER PRIMARY KEY, 
  artistname  TEXT
);
CREATE TABLE track(
  trackid     INTEGER,
  trackname   TEXT, 
  trackartist INTEGER     -- Must map to an artist.artistid!
);


  
    The applications using this database are entitled to assume that for
    each row in the track table there exists a corresponding row in the
    artist table. After all, the comment in the declaration says so.
    Unfortunately, if a user edits the database using an external tool or 
    if there is a bug in an application, rows might be inserted into the 
    track table that do not correspond to any row in the artist
    table. Or rows might be deleted from the artist table, leaving
    orphaned rows in the track table that do not correspond to any of
    the remaining rows in artist. This might cause the application
    or applications to malfunction later on, or at least make coding the
    application more difficult.

  
    One solution is to add an SQL foreign key constraint to the database 
    schema to enforce the relationship between the artist and 
    track table. To do so, a foreign key definition may be added
    by modifying the declaration of the track table to the following:

CREATE TABLE track(
  trackid     INTEGER, 
  trackname   TEXT, 
  trackartist INTEGER,
  FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);


  
    This way, the constraint is enforced by SQLite. Attempting to insert
    a row into the track table that does not correspond to any
    row in the artist table will fail, as will attempting to
    delete a row from the artist table when there exist dependent 
    rows in the track table There is one exception: if the foreign
    key column in the track table is NULL, then no corresponding
    entry in the artist table is required. Expressed in SQL, this
    means that for every row in the track table, the following
    expression evaluates to true:
trackartist IS NULL OR EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)


  Tip: If the application requires a stricter relationship between 
     artist and track, where NULL values are not permitted 
     in the trackartist column, simply add the appropriate 
     "NOT NULL" constraint to the schema.

  There are several other ways to add an equivalent foreign key declaration 
     to a CREATE TABLE statement. Refer to the 
     CREATE TABLE documentation for details.

  The following SQLite command-line session illustrates the effect of the
     foreign key constraint added to the track table:

sqlite&gt; SELECT * FROM artist;
artistid  artistname       
--------  -----------------
1         Dean Martin      
2         Frank Sinatra    

sqlite> SELECT * FROM track;
trackid  trackname          trackartist
-------  -----------------  -----------
11       That's Amore       1  
12       Christmas Blues    1  
13       My Way             2  

sqlite&gt; -- This fails because the value inserted into the trackartist column (3)
sqlite&gt; -- does not correspond to row in the artist table.
sqlite&gt; INSERT INTO track VALUES(14, 'Mr. Bojangles', 3);
SQL error: foreign key constraint failed

sqlite&gt; -- This succeeds because a NULL is inserted into trackartist. A
sqlite&gt; -- corresponding row in the artist table is not required in this case.
sqlite&gt; INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL);

sqlite&gt; -- Trying to modify the trackartist field of the record after it has 
sqlite&gt; -- been inserted does not work either, since the new value of trackartist (3)
sqlite&gt; -- Still does not correspond to any row in the artist table.
sqlite&gt; UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
SQL error: foreign key constraint failed

sqlite&gt; -- Insert the required row into the artist table. It is then possible to
sqlite&gt; -- update the inserted row to set trackartist to 3 (since a corresponding
sqlite&gt; -- row in the artist table now exists).
sqlite&gt; INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
sqlite&gt; UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';

sqlite&gt; -- Now that "Sammy Davis Jr." (artistid = 3) has been added to the database,
sqlite&gt; -- it is possible to INSERT new tracks using this artist without violating
sqlite&gt; -- the foreign key constraint:
sqlite&gt; INSERT INTO track VALUES(15, 'Boogie Woogie', 3);


  
    As you would expect, it is not possible to manipulate the database to a state
    that violates the foreign key constraint by deleting or updating rows in the 
    artist table either:
sqlite&gt; -- Attempting to delete the artist record for "Frank Sinatra" fails, since
sqlite&gt; -- the track table contains a row that refer to it.
sqlite&gt; DELETE FROM artist WHERE artistname = 'Frank Sinatra';
SQL error: foreign key constraint failed

sqlite&gt; -- Delete all the records from the track table that refer to the artist
sqlite&gt; -- "Frank Sinatra". Only then is it possible to delete the artist.
sqlite&gt; DELETE FROM track WHERE trackname = 'My Way';
sqlite&gt; DELETE FROM artist WHERE artistname = 'Frank Sinatra';

sqlite&gt; -- Try to update the artistid of a row in the artist table while there
sqlite&gt; -- exists records in the track table that refer to it. 
sqlite&gt; UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
SQL error: foreign key constraint failed

sqlite&gt; -- Once all the records that refer to a row in the artist table have
sqlite&gt; -- been deleted, it is possible to modify the artistid of the row.
sqlite&gt; DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues');
sqlite&gt; UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';


  
    SQLite uses the following terminology:


  
    The parent table is the table that a foreign key constraint
        refers to. The parent table in the example in this section is the
        artist table. Some books and articles refer to this as the
        referenced table, which is arguably more correct, but tends
        to lead to confusion.

    The child table is the table that a foreign key constraint
        is applied to and the table that contains the REFERENCES clause.
        The example in this section uses the track table
        as the child table. Other books and articles refer to this as the
        referencing table.

    The parent key is the column or set of columns in the parent 
        table that the foreign key constraint refers to. This is normally, but
        not always, the primary key of the parent table.  The parent key must
        be a named column or columns in the parent table, not the rowid.

    The child key is the column or set of columns in the child 
        table that are constrained by the foreign key constraint and which
        hold the REFERENCES clause.
  

  
    The foreign key constraint is satisfied if for each row in the child table 
    either one or more of the child key columns are NULL, or there exists a 
    row in the parent table for which each parent key column contains a value
    equal to the value in its associated child key column.

  
    In the above paragraph, the term "equal" means equal when values are 
    compared using the rules specified 
    here. The following clarifications apply:
    
  
    When comparing text values, the collating sequence
        associated with the parent key column is always used.
    When comparing values, if the parent key column has an affinity,
        then that affinity is applied to the child key value before the
        comparison is performed.  
  


2. 
  Enabling Foreign Key Support

  
    In order to use foreign key constraints in SQLite, the library must
    be compiled with neither SQLITE_OMIT_FOREIGN_KEY or 
    SQLITE_OMIT_TRIGGER defined. If SQLITE_OMIT_TRIGGER is defined 
    but SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior 
    to version 3.6.19 (2009-10-14)
    - foreign key definitions are parsed and may be 
    queried using PRAGMA foreign_key_list, but foreign key constraints 
    are not enforced. The PRAGMA foreign_keys command is a no-op in this 
    configuration. If OMIT_FOREIGN_KEY is defined, then foreign key 
    definitions cannot even be parsed (attempting to specify a foreign
    key definition is a syntax error).

  
    Assuming the library is compiled with foreign key constraints enabled,
    it must still be enabled by the application at runtime, using the
    PRAGMA foreign_keys command. For example:

sqlite&gt; PRAGMA foreign_keys = ON;


  
    Foreign key constraints are disabled by default 
    (for backwards compatibility),
    so must be enabled separately for each database connection.
    (Note, however, that future releases of SQLite might change
    so that foreign key constraints enabled by default.  Careful
    developers will not
    make any assumptions about whether or not foreign keys are enabled by
    default but will instead enable or disable them as necessary.)
    The application can also use a PRAGMA foreign_keys statement to
    determine if foreign keys are currently enabled. The following 
    command-line session demonstrates this:
sqlite> PRAGMA foreign_keys;
0
sqlite> PRAGMA foreign_keys = ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_keys = OFF;
sqlite> PRAGMA foreign_keys;
0


  Tip: If the command "PRAGMA foreign_keys" returns no data instead of a
     single row containing "0" or "1", then the version of SQLite you are
     using does not support foreign keys (either because it is older than
     3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or 
     SQLITE_OMIT_TRIGGER defined).

  
    It is not possible to enable or disable foreign key constraints
    in the middle of a multi-statement transaction (when SQLite
    is not in autocommit mode).  Attempting to do so does not return
    an error; it simply has no effect.

3. Required and Suggested Database Indexes

  
    Usually, the parent key of a foreign key constraint is the primary key of
    the parent table. If they are not the primary key, then the parent key
    columns must be collectively subject to a UNIQUE constraint or have
    a UNIQUE index. 
    If the parent key columns have a UNIQUE index,
    then that index must use the collation sequences that are specified
    in the CREATE TABLE statement for the parent table.
    For example,

CREATE TABLE parent(a PRIMARY KEY, b UNIQUE, c, d, e, f);
CREATE UNIQUE INDEX i1 ON parent(c, d);
CREATE INDEX i2 ON parent(e);
CREATE UNIQUE INDEX i3 ON parent(f COLLATE nocase);

CREATE TABLE child1(f, g REFERENCES parent(a));                        -- Ok
CREATE TABLE child2(h, i REFERENCES parent(b));                        -- Ok
CREATE TABLE child3(j, k, FOREIGN KEY(j, k) REFERENCES parent(c, d));  -- Ok
CREATE TABLE child4(l, m REFERENCES parent(e));                        -- Error!
CREATE TABLE child5(n, o REFERENCES parent(f));                        -- Error!
CREATE TABLE child6(p, q, FOREIGN KEY(p, q) REFERENCES parent(b, c));  -- Error!
CREATE TABLE child7(r REFERENCES parent(c));                           -- Error!


  
    The foreign key constraints created as part of tables child1, 
    child2 and child3 are all fine. The foreign key
    declared as part of table child4 is an error because even though
    the parent key column is indexed, the index is not UNIQUE.
    The foreign key for table child5
    is an error because even though the parent key column has a unique
    index, the index uses a different collating sequence.
    Tables child6 and child7 are incorrect because while
    both have UNIQUE indices on their parent keys, the keys are not an
    exact match to the columns of a single UNIQUE index.

  
    If the database schema contains foreign key errors that require looking
    at more than one table definition to identify, then those errors are not
    detected when the tables are created. Instead, such errors prevent
    the application from preparing SQL statements that modify the content
    of the child or parent tables in ways that use the foreign keys.
    Errors reported when content is changed are "DML errors" and errors
    reported when the schema is changed are "DDL errors".
    So, in other words, misconfigured foreign key constraints that require
    looking at both the child and parent are DML errors.
    The English language error message for foreign key DML errors is usually
    "foreign key mismatch" but can also be "no such table" if the parent
    table does not exist.
    Foreign key DML errors are reported if:

  
     The parent table does not exist, or
     The parent key columns named in the foreign key constraint do
         not exist, or
     The parent key columns named in the foreign key constraint are not
         the primary key of the parent table and are not subject to a unique
         constraint using collating sequence specified in the CREATE TABLE, or
     The child table references the primary key of the parent without
         specifying the primary key columns and the number of primary key
         columns in the parent do not match the number of child key columns.
  

  
    The last bullet above is illustrated by the following:

CREATE TABLE parent2(a, b, PRIMARY KEY(a,b));

CREATE TABLE child8(x, y, FOREIGN KEY(x,y) REFERENCES parent2);        -- Ok
CREATE TABLE child9(x REFERENCES parent2);                             -- Error!
CREATE TABLE child10(x,y,z, FOREIGN KEY(x,y,z) REFERENCES parent2);    -- Error!


  
    By contrast, if foreign key errors can be recognized simply by looking
    at the definition of the child table and without having to consult the
    parent table definition, then the 
    CREATE TABLE statement for the child table fails.  Because the error
    occurs during a schema change, this is a DDL error.
    Foreign key DDL errors are reported regardless of
    whether or not foreign key constraints are enabled when the
    table is created.

  
    Indices are not required for child key columns but they are almost
    always beneficial. Returning to
    the example in section 1, each time an application
    deletes a row from the artist table (the parent table), it
    performs the equivalent of the following SELECT statement to search
    for referencing rows in the track table (the child table).

SELECT rowid FROM track WHERE trackartist = ?


 
   where ? in the above is replaced with the value of the artistid
   column of the record being deleted from the artist table (recall
   that the trackartist column is the child key and the artistid
   column is the parent key). Or, more generally:

SELECT rowid FROM &lt;child-table&gt; WHERE &lt;child-key&gt; = :parent_key_value


 
   If this SELECT returns any rows at all, then SQLite concludes that
   deleting the row from the parent table would violate the foreign key
   constraint and returns an error.
   Similar queries may be run if the content of the parent key
   is modified or a new row is inserted into the parent table.
   If these queries cannot use an index, they are forced to do a
   linear scan of the entire child table.  In a non-trivial database, this may
   be prohibitively expensive.

 
   So, in most real systems, an index should be created on the child key columns
   of each foreign key constraint. The child key index does not have
   to be (and usually will not be) a UNIQUE index.
   Returning again to the example in section 1, the
   complete database schema for efficient implementation of the foreign key 
   constraint might be:

CREATE TABLE artist(
  artistid    INTEGER PRIMARY KEY, 
  artistname  TEXT
);
CREATE TABLE track(
  trackid     INTEGER,
  trackname   TEXT, 
  trackartist INTEGER REFERENCES artist
);
CREATE INDEX trackindex ON track(trackartist);


  
    The block above uses a shorthand form to create the foreign key constraint.
    Attaching a "REFERENCES &lt;parent-table&gt;" clause to a column
    definition creates a foreign key constraint that maps the column to the
    primary key of &lt;parent-table&gt;. Refer to the CREATE TABLE 
    documentation for further details.


4. Advanced Foreign Key Constraint Features

4.1. Composite Foreign Key Constraints

  
    A composite foreign key constraint is one where the child and parent keys
    are both composite keys. For example, consider
    the following database schema:

CREATE TABLE album(
  albumartist TEXT,
  albumname TEXT,
  albumcover BINARY,
  PRIMARY KEY(albumartist, albumname)
);

CREATE TABLE song(
  songid     INTEGER,
  songartist TEXT,
  songalbum TEXT,
  songname   TEXT,
  FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist, albumname)
);


  
    In this system, each entry in the song table is required to map to an entry
    in the album table with the same combination of artist and album.

  
    Parent and child keys must have the same cardinality.
    In SQLite, if any of the child key columns (in this case songartist 
    and songalbum) are NULL, then there is no requirement for a corresponding
    row in the parent table.

4.2. Deferred Foreign Key Constraints

  
    Each foreign key constraint in SQLite is classified as either immediate
     or deferred. Foreign key constraints are immediate by default.
     All the foreign key examples presented
     so far have been of immediate foreign key constraints.

  
    If a statement modifies the contents of the database so that an immediate 
    foreign key constraint is in violation at the conclusion the statement, 
    an exception is thrown and 
    the effects of the statement are reverted. By contrast, if
    a statement modifies the contents of the database such that a deferred 
    foreign key constraint is violated, the violation is not reported
    immediately. Deferred foreign key constraints are not checked
    until the transaction tries to COMMIT.
    For as long as the user has 
    an open transaction, the database is allowed to exist in a state that 
    violates any number of deferred foreign key constraints. However, 
    COMMIT will fail as long as foreign key constraints remain in
    violation.

  
    If the current statement is not inside an explicit transaction (a 
    BEGIN/COMMIT/ROLLBACK block), then an implicit
    transaction is committed
    as soon as the statement has finished executing. In this case deferred
    constraints behave the same as immediate constraints.

  
    To mark a foreign key constraint as deferred, its declaration must
    include the following clause:

DEFERRABLE INITIALLY DEFERRED                -- A deferred foreign key constraint


  
    The full syntax for specifying foreign key constraints is available as part
    of the CREATE TABLE documentation. Replacing the phrase above
    with any of the following 
    creates an immediate foreign key constraint.

NOT DEFERRABLE INITIALLY DEFERRED            -- An immediate foreign key constraint
NOT DEFERRABLE INITIALLY IMMEDIATE           -- An immediate foreign key constraint
NOT DEFERRABLE                               -- An immediate foreign key constraint
DEFERRABLE INITIALLY IMMEDIATE               -- An immediate foreign key constraint
DEFERRABLE                                   -- An immediate foreign key constraint


  The defer_foreign_keys pragma can be used to temporarily change all foreign
    key constraints to deferred regardless of how they are declared.

  
    The following example illustrates the effect of using a deferred foreign
    key constraint.

-- Database schema. Both tables are initially empty. 
CREATE TABLE artist(
  artistid    INTEGER PRIMARY KEY, 
  artistname  TEXT
);
CREATE TABLE track(
  trackid     INTEGER,
  trackname   TEXT, 
  trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFERRED
);

sqlite3&gt; -- If the foreign key constraint were immediate, this INSERT would
sqlite3&gt; -- cause an error (since as there is no row in table artist with
sqlite3&gt; -- artistid=5). But as the constraint is deferred and there is an
sqlite3&gt; -- open transaction, no error occurs.
sqlite3&gt; BEGIN;
sqlite3&gt;   INSERT INTO track VALUES(1, 'White Christmas', 5);

sqlite3&gt; -- The following COMMIT fails, as the database is in a state that
sqlite3&gt; -- does not satisfy the deferred foreign key constraint. The
sqlite3&gt; -- transaction remains open.
sqlite3&gt; COMMIT;
SQL error: foreign key constraint failed

sqlite3&gt; -- After inserting a row into the artist table with artistid=5, the
sqlite3&gt; -- deferred foreign key constraint is satisfied. It is then possible
sqlite3&gt; -- to commit the transaction without error.
sqlite3&gt;   INSERT INTO artist VALUES(5, 'Bing Crosby');
sqlite3&gt; COMMIT;

  
    A nested savepoint transaction may be RELEASEd while the
    database is in a state that does not satisfy a deferred foreign key 
    constraint. A transaction savepoint (a non-nested savepoint that was
    opened while there was not currently an open transaction), on the 
    other hand, is subject to the same restrictions as a COMMIT - attempting 
    to RELEASE it while the database is in such a state will fail.

  
    If a COMMIT statement (or the RELEASE of a transaction SAVEPOINT) fails
    because the database is currently in a state that violates a deferred
    foreign key constraint and there are currently
    nested savepoints, the nested savepoints remain open.



4.3. 
  ON DELETE and ON UPDATE Actions


  
    Foreign key ON DELETE and ON UPDATE clauses are used to configure actions
    that take place when deleting rows from the parent table (ON DELETE), or 
    modifying the parent key values of existing rows (ON UPDATE). A single
    foreign key constraint may have different actions configured for ON DELETE
    and ON UPDATE. Foreign key actions are similar to triggers in many ways.

  
    The ON DELETE and ON UPDATE action associated with each foreign key in an
    SQLite database is one of "NO ACTION", "RESTRICT", "SET NULL",
    "SET DEFAULT" or "CASCADE". If an action is not explicitly specified, it 
    defaults to "NO ACTION".

  
     NO ACTION: Configuring "NO ACTION" means just that: when a
     parent key is modified or deleted from the database, no special action is
     taken.

     RESTRICT: The "RESTRICT" action means that the application
      is prohibited from deleting (for ON DELETE RESTRICT) or modifying
      (for ON UPDATE RESTRICT) a parent key when there exists one or more child
      keys mapped to it. The difference between the effect of a RESTRICT
      action and normal foreign key constraint enforcement is that the
      RESTRICT action processing happens as soon as the field is updated -
      not at the end of the current statement as it would with an immediate
      constraint, or at the end of the current transaction as it would with
      a deferred constraint.
      Even if the foreign key constraint it is 
      attached to is deferred, configuring a RESTRICT action causes SQLite to 
      return an error immediately if a parent key with dependent child keys is 
      deleted or modified.

     SET NULL: If the configured action is "SET NULL", then when
      a parent key is deleted (for ON DELETE SET NULL) or modified (for ON 
      UPDATE SET NULL), the child key columns of all rows in the child table
      that mapped to the parent key are set to contain SQL NULL values.

     SET DEFAULT: The "SET DEFAULT" actions are similar to
      "SET NULL",
      except that each of the child key columns is set to contain the columns 
      default value instead of NULL. Refer to the CREATE TABLE 
      documentation for details on how default values are assigned to table
      columns.

     CASCADE: A "CASCADE" action propagates the delete or update
      operation on the parent key to each dependent child key. For an "ON 
      DELETE CASCADE" action, this means that each row in the child table that
      was associated with the deleted parent row is also deleted. For an "ON
      UPDATE CASCADE" action, it means that the values stored in each dependent
      child key are modified to match the new parent key values.
  

  
    For example, adding an "ON UPDATE CASCADE" clause to the foreign key as
    shown below enhances the example schema from section 1 to allow the user
    to update the artistid (the parent key of the foreign key constraint) 
    column without breaking referential integrity:
-- Database schema
CREATE TABLE artist(
  artistid    INTEGER PRIMARY KEY, 
  artistname  TEXT
);
CREATE TABLE track(
  trackid     INTEGER,
  trackname   TEXT, 
  trackartist INTEGER REFERENCES artist(artistid) ON UPDATE CASCADE
);

sqlite&gt; SELECT * FROM artist;
artistid  artistname       
--------  -----------------
1         Dean Martin      
2         Frank Sinatra    

sqlite&gt; SELECT * FROM track;
trackid  trackname          trackartist
-------  -----------------  -----------
11       That's Amore       1
12       Christmas Blues    1
13       My Way             2  

sqlite&gt; -- Update the artistid column of the artist record for "Dean Martin".
sqlite&gt; -- Normally, this would raise a constraint, as it would orphan the two
sqlite&gt; -- dependent records in the track table. However, the ON UPDATE CASCADE clause
sqlite&gt; -- attached to the foreign key definition causes the update to "cascade"
sqlite&gt; -- to the child table, preventing the foreign key constraint violation.
sqlite&gt; UPDATE artist SET artistid = 100 WHERE artistname = 'Dean Martin';

sqlite&gt; SELECT * FROM artist;
artistid  artistname       
--------  -----------------
2         Frank Sinatra    
100       Dean Martin      

sqlite&gt; SELECT * FROM track;
trackid  trackname          trackartist
-------  -----------------  -----------
11       That's Amore       100
12       Christmas Blues    100  
13       My Way             2  


  
    Configuring an ON UPDATE or ON DELETE action does not mean that the foreign
    key constraint does not need to be satisfied. For example, if an
    "ON DELETE SET DEFAULT" action is configured,
    but there is no row in the parent table 
    that corresponds to the default values of the child key columns, deleting
    a parent key while dependent child keys exist still causes a foreign key
    violation. For example:

-- Database schema
CREATE TABLE artist(
  artistid    INTEGER PRIMARY KEY, 
  artistname  TEXT
);
CREATE TABLE track(
  trackid     INTEGER,
  trackname   TEXT, 
  trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DEFAULT
);

sqlite&gt; SELECT * FROM artist;
artistid  artistname       
--------  -----------------
3         Sammy Davis Jr.

sqlite&gt; SELECT * FROM track;
trackid  trackname          trackartist
-------  -----------------  -----------
14       Mr. Bojangles      3

sqlite&gt; -- Deleting the row from the parent table causes the child key
sqlite&gt; -- value of the dependent row to be set to integer value 0. However, this
sqlite&gt; -- value does not correspond to any row in the parent table. Therefore
sqlite&gt; -- the foreign key constraint is violated and an is exception thrown.
sqlite&gt; DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';
SQL error: foreign key constraint failed

sqlite&gt; -- This time, the value 0 does correspond to a parent table row. And
sqlite&gt; -- so the DELETE statement does not violate the foreign key constraint
sqlite&gt; -- and no exception is thrown.
sqlite&gt; INSERT INTO artist VALUES(0, 'Unknown Artist');
sqlite&gt; DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';

sqlite&gt; SELECT * FROM artist;
artistid  artistname       
--------  -----------------
0         Unknown Artist

sqlite&gt; SELECT * FROM track;
trackid  trackname          trackartist
-------  -----------------  -----------
14       Mr. Bojangles      0


  
    Those familiar with SQLite triggers
    will have noticed that the 
    "ON DELETE SET DEFAULT" action demonstrated in the example above is
    similar in effect to the following AFTER DELETE trigger:
CREATE TRIGGER on_delete_set_default AFTER DELETE ON artist BEGIN
  UPDATE child SET trackartist = 0 WHERE trackartist = old.artistid;
END;


  
    Whenever a row in the parent table of a foreign key constraint is deleted,
    or when the values stored in the parent key column or columns are modified, 
    the logical sequence of events is:

  
    Execute applicable BEFORE trigger programs,
    Check local (non foreign key) constraints,
    Update or delete the row in the parent table,
    Perform any required foreign key actions,
    Execute applicable AFTER trigger programs.
  

  
    There is one important difference between ON UPDATE foreign key actions and
    SQL triggers. An ON UPDATE action is only taken if the values of the
    parent key are modified so that the new parent key values are 
    not equal to the old. For example:

-- Database schema
CREATE TABLE parent(x PRIMARY KEY);
CREATE TABLE child(y REFERENCES parent ON UPDATE SET NULL);

sqlite&gt; SELECT * FROM parent;
x
----
key

sqlite&gt; SELECT * FROM child;
y
----
key

sqlite&gt; -- Since the following UPDATE statement does not actually modify
sqlite&gt; -- the parent key value, the ON UPDATE action is not performed and
sqlite&gt; -- the child key value is not set to NULL.
sqlite&gt; UPDATE parent SET x = 'key';
sqlite&gt; SELECT IFNULL(y, 'null') FROM child;
y
----
key

sqlite&gt; -- This time, since the UPDATE statement does modify the parent key
sqlite&gt; -- value, the ON UPDATE action is performed and the child key is set
sqlite&gt; -- to NULL.
sqlite&gt; UPDATE parent SET x = 'key2';
sqlite&gt; SELECT IFNULL(y, 'null') FROM child;
y
----
null


5. CREATE, ALTER and DROP TABLE commands

  
    This section describes the way the CREATE TABLE, ALTER TABLE,
    and DROP TABLE commands
    interact with SQLite's foreign keys.

  
    A CREATE TABLE command operates the same whether or not
    foreign key constraints are enabled.  The parent key definitions of 
    foreign key constraints are not checked when a table is created. There is
    nothing stopping the user from creating a foreign key definition that
    refers to a parent table that does not exist, or to parent key columns that
    do not exist or are not collectively bound by a PRIMARY KEY or UNIQUE constraint.

  
    The ALTER TABLE command works differently in two respects when foreign
    key constraints are enabled:

  
     
         It is not possible to use the "ALTER TABLE ... ADD COLUMN" syntax
         to add a column that includes a REFERENCES clause, unless the default
         value of the new column is NULL. Attempting to do so returns an
         error.

     
         If an "ALTER TABLE ... RENAME TO" command is used to rename a table
         that is the parent table of one or more foreign key constraints, the
         definitions of the foreign key constraints are modified to refer to
         the parent table by its new name. The text of the child CREATE
         TABLE statement or statements stored in the sqlite_schema table are 
         modified to reflect the new parent table name.
  

  
    If foreign key constraints are enabled when it is prepared, the 
    DROP TABLE command performs an implicit DELETE to remove all
    rows from the table before dropping it. The implicit DELETE does not cause
    any SQL triggers to fire, but may invoke foreign key actions or constraint
    violations. If an immediate foreign key constraint is violated, the DROP
    TABLE statement fails and the table is not dropped. If a deferred foreign
    key constraint is violated, then an error is reported when the user attempts
    to commit the transaction if the foreign key constraint violations still
    exist at that point. Any "foreign key mismatch" errors encountered as part 
    of an implicit DELETE are ignored.

  
    The intent of these enhancements to the ALTER TABLE and DROP TABLE
    commands is to ensure that they cannot be used to create a database that
    contains foreign key violations, at least while foreign key constraints are
    enabled. There is one exception to this rule though. If a parent key is
    not subject to a PRIMARY KEY or UNIQUE constraint created as part of the
    parent table definition, but is subject to a UNIQUE constraint by virtue
    of an index created using the CREATE INDEX command, then the child 
    table may be populated without causing a "foreign key mismatch" error. If
    the UNIQUE index is dropped from the database schema, then the parent table
    itself is dropped, no error will be reported. However the database may be
    left in a state where the child table of the foreign key constraint contains
    rows that do not refer to any parent table row. This case can be avoided
    if all parent keys in the database schema are constrained by PRIMARY KEY
    or UNIQUE constraints added as part of the parent table definition, not
    by external UNIQUE indexes.

  
    The properties of the DROP TABLE and ALTER TABLE commands described
    above only apply if foreign keys are enabled. If the user considers them
    undesirable, then the workaround is to use PRAGMA foreign_keys to 
    disable foreign key constraints before executing the DROP or ALTER TABLE 
    command. Of course, while foreign key constraints are disabled, there is nothing
    to stop the user from violating foreign key constraints and thus creating
    an internally inconsistent database.
   
    

6. Limits and Unsupported Features

  
    This section lists a few limitations and omitted features that are not
    mentioned elsewhere.

  
     
      No support for the MATCH clause. According to SQL92, a MATCH clause
         may be attached to a composite foreign key definition to modify the way
         NULL values that occur in child keys are handled. If "MATCH SIMPLE" is
         specified, then a child key is not required to correspond to any row
         of the parent table if one or more of the child key values are NULL.
         If "MATCH FULL" is specified, then if any of the child key values is
         NULL, no corresponding row in the parent table is required, but all
         child key values must be NULL. Finally, if the foreign key constraint
         is declared as "MATCH PARTIAL" and one of the child key values is NULL,
         there must exist at least one row in the parent table for which the
         non-NULL child key values match the parent key values.

       
         SQLite parses MATCH clauses (i.e. does not report a syntax error
         if you specify one), but does not enforce them. All foreign key 
         constraints in SQLite are handled as if MATCH SIMPLE were specified.
     
      No support for switching constraints between deferred and immediate 
         mode. Many systems allow the user to toggle individual foreign key
         constraints between deferred and immediate 
         mode at runtime (for example using the Oracle "SET CONSTRAINT" command).
         SQLite does not support this. In SQLite, a foreign key constraint is
         permanently marked as deferred or immediate when it is created.

    
      Recursion limit on foreign key actions. The 
         SQLITE_MAX_TRIGGER_DEPTH and SQLITE_LIMIT_TRIGGER_DEPTH
         settings determine the maximum allowable depth of trigger
         program recursion. For the purposes of these limits,
         foreign key actions are considered trigger programs. The
         PRAGMA recursive_triggers setting does not affect the operation 
         of foreign key actions. It is not possible to disable recursive foreign 
         key actions.


c2: The Geopoly Interface To The SQLite R*Tree Module
c5: geopoly.html
c4:
1. Overview


The Geopoly module is an alternative interface to the R-Tree extension that uses
the GeoJSON notation
(RFC-7946) to describe two-dimensional
polygons.  Geopoly includes functions for detecting when one polygon is
contained within or overlaps with another, for computing the
area enclosed by a polygon, for doing linear transformations of polygons,
for rendering polygons as
SVG, and other
similar operations.


The source code for Geopoly is included in the amalgamation but is not
included in the library unless the -DSQLITE_ENABLE_GEOPOLY compile-time option
is used.


Geopoly operates on "simple" polygons - that is, polygons for which
the boundary does not intersect itself.  Geopoly thus extends the capabilities
of the R-Tree extension which can only deal with rectangular areas.
On the other hand, the R-Tree extension is
able to handle between 1 and 5 coordinate dimensions, whereas Geopoly is restricted
to 2-dimensional shapes only.


Each polygon in the Geopoly module can be associated with an arbitrary
number of auxiliary data fields.

1.1. GeoJSON

The GeoJSON standard is syntax for
exchanging geospatial information using JSON.  GeoJSON is a rich standard
that can describe nearly any kind of geospatial content.

The Geopoly module only understands
a small subset of GeoJSON, but a critical subset.  
In particular, GeoJSON understands
the JSON array of vertexes that describes a simple polygon.

A polygon is defined by its vertexes.
Each vertex is a JSON array of two numeric values which are the
X and Y coordinates of the vertex.
A polygon is a JSON array of at least four of these vertexes, 
and hence is an array of arrays.
The first and last vertex in the array must be the same.
The polygon follows the right-hand rule:  When tracing a line from
one vertex to the next, the area to the right of the line is outside
of the polygon and the area to the left is inside the polygon.
In other words, the net rotation of the vertexes is counter-clockwise.


For example, the following JSON describes an isosceles triangle, sitting
on the X axis and with an area of 0.5:

&#91;&#91;0,0],&#91;1,0],&#91;0.5,1],&#91;0,0]]



A triangle has three vertexes, but the GeoJSON description of the triangle
has 4 vertexes because the first and last vertex are duplicates.

1.2. Binary storage format


Internally, Geopoly stores polygons in a binary format - an SQL BLOB.
Details of the binary format are given below.
All of the Geopoly interfaces are able to accept polygons in either the
GeoJSON format or in the binary format.

2. Using The Geopoly Extension


A geopoly table is created as follows:

CREATE VIRTUAL TABLE newtab USING geopoly(a,b,c);



The statement above creates a new geopoly table named "newtab".
Every geopoly table contains a built-in integer "rowid" column
and a "_shape" column that contains
the polygon associated with that row of the table.
The example above also defines three auxiliary data columns 
named "a", "b", and "c" that can store whatever additional
information the application needs to associate
with each polygon.  If there is no need to store auxiliary
information, the list of auxiliary columns can be omitted.


Store new polygons in the table using ordinary INSERT statements:

INSERT INTO newtab(_shape) VALUES('&#91;&#91;0,0],&#91;1,0],&#91;0.5,1],&#91;0,0]]');



UPDATE and DELETE statements work similarly.

2.1. Queries


To query the geopoly table using an indexed geospatial search, 
use one of the functions geopoly_overlap()
or geopoly_within() as a boolean function in the WHERE clause,
with the "_shape" column as the first argument to the function.
For example:

SELECT * FROM newtab WHERE geopoly_overlap(_shape, $query_polygon);



The previous example will return every row for which the _shape
overlaps the polygon in the $query_polygon parameter.  The
geopoly_within() function works similarly, but only returns rows for
which the _shape is completely contained within $query_polygon.


Queries (and also DELETE and UPDATE statements) in which the WHERE
clause contains a bare geopoly_overlap() or geopoly_within() function
make use of the underlying R*Tree data structures for a fast lookup that
only has to examine a subset of the rows in the table.  The number of
rows examines depends, of course, on the size of the $query_polygon.
Large $query_polygons will normally need to look at more rows than small
ones.


Queries against the rowid of a geopoly table are also very quick, even
for tables with a vast number of rows.
However, none of the auxiliary data columns are indexes, and so queries
against the auxiliary data columns will involve a full table scan.

3. Special Functions


The geopoly module defines several new SQL functions that are useful for
dealing with polygons.  All polygon arguments to these functions can be
either the GeoJSON format or the internal binary format.



3.1. The geopoly_overlap(P1,P2) Function


If P1 and P2 are both polygons, then the geopoly_overlap(P1,P2) function returns
a non-zero integer if there is any overlap between P1 and P2, or it returns
zero if P1 and P2 completely disjoint.
If either P1 or P2 is not a polygon, this routine returns NULL.


The geopoly_overlap(P1,P2) function is special in that the geopoly virtual
table knows how to use R*Tree indexes to optimize queries in which the 
WHERE clause uses geopoly_overlap() as a boolean function.  Only the
geopoly_overlap(P1,P2) and geopoly_within(P1,P2) functions have this
capability.



3.2. The geopoly_within(P1,P2) Function


If P1 and P2 are both polygons, then the geopoly_within(P1,P2) function returns
a non-zero integer if P1 is completely contained within P2, or it returns zero
if any part of P1 is outside of P2.  If P1 and P2 are the same polygon, this routine
returns non-zero.
If either P1 or P2 is not a polygon, this routine returns NULL.


The geopoly_within(P1,P2) function is special in that the geopoly virtual
table knows how to use R*Tree indexes to optimize queries in which the 
WHERE clause uses geopoly_within() as a boolean function.  Only the
geopoly_within(P1,P2) and geopoly_overlap(P1,P2) functions have this
capability.



3.3. The geopoly_area(P) Function


If P is a polygon, then geopoly_area(P) returns the area enclosed by
that polygon.  If P is not a polygon, geopoly_area(P) returns NULL.



3.4. The geopoly_blob(P) Function


If P is a polygon, then geopoly_blob(P) returns the binary encoding
of that polygon as a BLOB.
If P is not a polygon, geopoly_blob(P) returns NULL.



3.5. The geopoly_json(P) Function


If P is a polygon, then geopoly_json(P) returns the GeoJSON representation
of that polygon as a TEXT string.
If P is not a polygon, geopoly_json(P) returns NULL.



3.6. The geopoly_svg(P,...) Function


If P is a polygon, then geopoly_svg(P,...) returns a text string which is a
Scalable Vector Graphics (SVG)
representation of that polygon.  If there is more one argument, then second
and subsequent arguments are added as attributes to each SVG glyph.  For example:

SELECT geopoly_svg($polygon,'class="poly"','style="fill:blue;"');



If P is not a polygon, geopoly_svg(P,...) returns NULL.


Note that geopoly uses a traditional right-handed cartesian coordinate system
with the origin at the lower left, whereas SVG uses a left-handed coordinate
system with the origin at the upper left.  The geopoly_svg() routine makes no
attempt to transform the coordinate system, so the displayed images are shown
in mirror image and rotated.  If that is undesirable, the geopoly_xform() routine
can be used to transform the output from cartesian to SVG coordinates prior to
passing the polygons into geopoly_svg().



3.7. The geopoly_bbox(P) and geopoly_group_bbox(P) Functions


If P is a polygon, then geopoly_bbox(P) returns a new polygon that is
the smallest (axis-aligned) rectangle completely enclosing P.
If P is not a polygon, geopoly_bbox(P) returns NULL.


The geopoly_group_bbox(P) function is an aggregate version of geopoly_bbox(P).
The geopoly_group_bbox(P) function returns the smallest rectangle that will
enclose all P values seen during aggregation.



3.8. The geopoly_contains_point(P,X,Y) Function


If P is a polygon, then geopoly_contains_point(P,X,Y) returns a 
non-zero integer if and only
if the coordinate X,Y is inside or on the boundary of the polygon P.
If P is not a polygon, geopoly_contains_point(P,X,Y) returns NULL.



3.9. The geopoly_xform(P,A,B,C,D,E,F) Function


The geopoly_xform(P,A,B,C,D,E,F) function returns a new polygon that is an
affine transformation of the polygon P and where the transformation
is defined by values A,B,C,D,E,F. If P is not a valid polygon, this
routine returns NULL.


The transformation converts each vertex of the polygon according to the
following formula:

x1 = A*x0 + B*y0 + E
y1 = C*x0 + D*y0 + F



So, for example, to move a polygon by some amount DX, DY without changing
its shape, use:

geopoly_xform($polygon, 1, 0, 0, 1, $DX, $DY)



To rotate a polygon by R radians around the point 0, 0:

geopoly_xform($polygon, cos($R), sin($R), -sin($R), cos($R), 0, 0)



Note that a transformation that flips the polygon might cause the
order of vertexes to be reversed.  In other words, the transformation
might cause the vertexes to circulate in clockwise order instead of
counter-clockwise.  This can be corrected by sending the result
through the geopoly_ccw() function after transformation.




3.10. The geopoly_regular(X,Y,R,N) Function


The geopoly_regular(X,Y,R,N) function returns a convex, simple, regular,
equilateral, equiangular polygon with N sides, centered at X,Y, and with
a circumradius of R.  Or, if R is negative or if N is less than 3, the
function returns NULL.  The N value is capped at 1000 so that the routine
will never render a polygon with more than 1000 sides even if the N value
is larger than 1000.


As an example, the following graphic:



 3
 4
 5
 6
 7
 8
 10
 12
 16
 20



Was generated by this script:

SELECT '&lt;svg width="600" height="300">';
WITH t1(x,y,n,color) AS (VALUES
   (100,100,3,'red'),
   (200,100,4,'orange'),
   (300,100,5,'green'),
   (400,100,6,'blue'),
   (500,100,7,'purple'),
   (100,200,8,'red'),
   (200,200,10,'orange'),
   (300,200,12,'green'),
   (400,200,16,'blue'),
   (500,200,20,'purple')
)
SELECT
   geopoly_svg(geopoly_regular(x,y,40,n),
        printf('style="fill:none;stroke:%s;stroke-width:2"',color))
   || printf(' &lt;text x="%d" y="%d" alignment-baseline="central" text-anchor="middle">%d&lt;/text>',x,y+6,n)
  FROM t1;
SELECT '&lt;/svg>';




3.11. The geopoly_ccw(J) Function

The geopoly_ccw(J) function returns the polygon J with counter-clockwise (CCW) rotation.


RFC-7946 requires that polygons use CCW rotation.
But the spec also observes that many legacy GeoJSON files do not following the spec and
contain polygons with clockwise (CW) rotation.  The geopoly_ccw() function is useful for
applications that are reading legacy GeoJSON scripts.  If the input to geopoly_ccw() is
a correctly-formatted polygon, then no changes are made.  However, if the circulation of
the input polygon is backwards, then geopoly_ccw() reverses the circulation order so that
it conforms to the spec and so that it will work correctly with the Geopoly module.



4. Implementation Details

The geopoly module is an extension to the R-Tree extension.  Geopoly
uses the same underlying logic and shadow tables as the R-Tree extension.
Geopoly merely presents a different interface, and provides some extra logic
to compute polygon decoding, overlap, and containment.

4.1. Binary Encoding of Polygons


Geopoly stores all polygons internally using a binary format.  A binary
polygon consists of a 4-byte header following by an array of coordinate
pairs in which each dimension of each coordinate is a 32-bit floating point
number.


The first byte of the header is a flag byte.  The least significant bit
of the flag byte determines whether the coordinate pairs that follow the
header are stored big-endian or little-endian.  A value of 0 for the least
significant bit means big-endian and a value of 1 means little endian.
Other bits of the first byte in the header are reserved for future expansion.


The next three bytes in the header record the number of vertexes in the polygon
as a big-endian integer.  Thus there is an upper bound of about 16 million
vertexes per polygon.


Following the header is the array of coordinate pairs.  Each coordinate is
a 32-bit floating point number.  The use of 32-bit floating point values for
coordinates means that any point on the earth's surface can be mapped with
a resolution of approximately 2.5 meters.  Higher resolutions are of course
possible if the map is restricted to a single continent or country.
Note that the resolution of coordinates in the geopoly module is similar
in magnitude to daily movement of points on the earth's surface due to
tidal forces.


The list of coordinates in the binary format contains no redundancy.  
The last coordinate is not a repeat of the first as it is with GeoJSON.  
Hence, there is always one fewer coordinate pair in the binary representation of
a polygon compared to the GeoJSON representation.

4.2. Shadow Tables


The geopoly module is built on top of the R-Tree extension and uses the
same underlying shadow tables and algorithms.  For indexing purposes, each
polygon is represented in the shadow tables as a rectangular bounding box.
The underlying R-Tree implementation uses bounding boxes to limit the search
space.  Then the geoploy_overlap() and/or geopoly_within() routines further
refine the search to the exact answer.


c2: Application-Defined SQL Functions
c5: appfunc.html
c4:
1. Executive Summary

Applications that use SQLite can define custom SQL functions that call
back into application code to compute their results.  The custom SQL
function implementations can be embedded in the application code itself,
or can be loadable extensions.

Application-defined or custom SQL functions are created using the
sqlite3_create_function() family of interfaces.
Custom SQL functions can be scalar functions, aggregate functions,
or window functions.
Custom SQL functions can have any number of arguments from 0 up to
SQLITE_MAX_FUNCTION_ARG.
The sqlite3_create_function() interface specifies callbacks that are
invoked to carry out the processing for the new SQL function.

SQLite also supports custom table-valued functions, but they are
implemented by a different mechanism that is not covered in this document.

2. Defining New SQL Functions


The sqlite3_create_function() family of interfaces is used to create
new custom SQL functions.  Each member of this family is a wrapper around
a common core.  All family members accomplish the same thing; they merely
have different calling signatures.


sqlite3_create_function() &rarr;
The original version of sqlite3_create_function() allows the application
to create a single new SQL function that can be either a scalar or an
aggregate.  The name of the function is specified using UTF8.

sqlite3_create_function16() &rarr;
This variant works exactly like the sqlite3_create_function() original
except that the name of the function itself is specified as a UTF16
string rather than as a UTF8 string.

sqlite3_create_function_v2() &rarr;
This variant works like the original sqlite3_create_function() except
that it includes an additional parameter that is a pointer to a
destructor for the sqlite3_user_data() pointer that is passed in
as the 5th argument to all of the sqlite3_create_function() variants.
That destructor function (if it is non-NULL) is called when the
custom function is deleted - usually when the database connection is
closing.

sqlite3_create_window_function() &rarr;
This variant works like the original sqlite3_create_function() except
that it accepts a different set of callback pointers - the callback
pointers used by window function definitions.


2.1. Common Parameters

Many of the parameters passed to the sqlite3_create_function()
family of interfaces are common across the entire family.


db &rarr;
The 1st parameter is always a pointer to the database connection
on which the custom SQL function will work.  Custom SQL functions are
created separately for each database connection.  There is no short-hand
mechanism for creating SQL functions that work across all database
connections.

zFunctionName &rarr;
The 2nd parameter is the name of the SQL function that is being
created.  The name is usually in UTF8, except that the name should
be in UTF16 in the native byte order for sqlite3_create_function16().

The maximum length of a SQL function name is 255 bytes of UTF8.
Any attempt to create a function with a longer name will result in
an SQLITE_MISUSE error.

The SQL function creation interfaces may be called multiple
times with the same function name.
If two calls have the same function number but a different number of
arguments, for example, then two variants of the SQL function will
be registered, each taking a different number of arguments.

nArg &rarr;
The 3rd parameter is always the number of arguments that the function
accepts.  The value must be an integer between -1 and 
SQLITE_MAX_FUNCTION_ARG (default value: 127).  A value of -1 means
that the SQL function is a variadic function that can take any number
of arguments between 0 and SQLITE_MAX_FUNCTION_ARG.

eTextRep &rarr;
The 4th parameter is a 32-bit integer flag whose bits convey various
properties about the new function.  The original purpose of this
parameter was to specify the preferred text encoding for the function,
using one of the following constants:

 SQLITE_UTF8
 SQLITE_UTF16BE
 SQLITE_UTF16LE

All custom SQL functions will accept text in any encoding.  Encoding
conversions will happen automatically.  The preferred encoding merely
specifies the encoding for which the function implementation is optimized.
It is possible to specify multiple functions with the same name and the
same number of arguments, but different preferred encodings and different
callbacks used to implement the function, and SQLite will chose the
set of callbacks for which the input encodings most closely match the
preferred encoding.

The 4th parameter as more recently be extended with additional flag bits
to convey additional information about the function.  The additional
bits include:

 SQLITE_DETERMINISTIC
 SQLITE_DIRECTONLY
 SQLITE_INNOCUOUS
 SQLITE_SUBTYPE


Additional bits may be added in future versions of SQLite.

pApp &rarr;
The 5th parameter is an arbitrary pointer that is passed through
into the callback routines.  SQLite itself does nothing with this
pointer, except to make it available to the callbacks, and to pass
it into the destructor when the function is unregistered.


2.2. Multiple Calls To sqlite3_create_function() For The Same Function


It is common for an application to invoke sqlite3_create_function() multiple
times for the same SQL function.  For example, if an SQL function can take
either 2 or 3 arguments, then sqlite3_create_function() would be invoked
once for the 2-argument version and a second time for the 3-argument version.
The underlying implementation (the callbacks) can be different for both
variants.


An application can also register multiple SQL functions with the same name
and same number of arguments, but a different preferred text encoding.
In that case, SQLite will invoke the function using the callbacks for
the version whose preferred text encoding most closely matches the database
text encoding.  In this way, multiple implementations of the same function
can be provided that are optimized for UTF8 or UTF16.


If multiple calls to sqlite3_create_function() specify the same function name,
and the same number of arguments, and the same preferred text encoding, then
the callbacks and other parameters of the second call overwrite the first,
and the destructor callback from the first call (if it exists) is invoked.


2.3. Callbacks


SQLite evaluates an SQL function by invoking callback routines.

2.3.1. The Scalar Function Callback

Scalar SQL functions are implemented by a single callback in the
xFunc parameter to sqlite3_create_function().
The following code demonstrations the implementation of a "noop(X)"
scalar SQL function that merely returns its argument:

static void noopfunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( argc==1 );
  sqlite3_result_value(context, argv&#91;0&#93;);
}



The 1st parameter, context, is a pointer to an opaque object
that describes the content from which the SQL function was invoked.  This
context point becomes the first parameter to many other routines that
the function implement might to invoke, including:



sqlite3_aggregate_context
sqlite3_context_db_handle
sqlite3_get_auxdata
sqlite3_result_blob
sqlite3_result_blob64
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_error_code
sqlite3_result_error_nomem
sqlite3_result_error_toobig
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_pointer
sqlite3_result_subtype
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_text64
sqlite3_result_value
sqlite3_result_zeroblob
sqlite3_result_zeroblob64
sqlite3_set_auxdata
sqlite3_user_data




The sqlite3_result() family of functions are
used to specify the result of the scalar SQL function.  One or more of
these should be invoked by the callback to set the function return value.
If none of these routines are invoked for a specific callback, then the
return value will be NULL.

The sqlite3_user_data() routine returns a copy of the pArg
pointer that was given to sqlite3_create_function() when the SQL
function was created.

The sqlite3_context_db_handle() routine returns a pointer to the
database connection object.

The sqlite3_aggregate_context() routine is used only in the
implementations of aggregate and window functions.  Scalar functions
may not use sqlite3_aggregate_context().  The sqlite3_aggregate_context()
function is included in the interface list only for completeness.


The 2nd and 3rd arguments to the scalar SQL function implemenetation,
argc and argv, are
the number of arguments to the SQL function itself and the values for
each argument of the SQL function.
Argument values can be of any datatype and are thus stored in
instances of the sqlite3_value object.
Specific C-language values can be extracted from this object using
the sqlite3_value() family of interfaces.

2.3.2. The Aggregate Function Callbacks

Aggregate SQL functions are implemented by using two callback
functions, xStep and xFinal.  The xStep() function 
is called for each row of the aggregate and the xFinal() function
is invoked to compute the final answer at the end.
The following (slightly simplified) version of the built-in
count() function illustrates:

typedef struct CountCtx CountCtx;
struct CountCtx {
  i64 n;
};
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv}; hd_resolve_one {0}; hd_puts {)) && p ){
    p->n++;
  }
}   
static void countFinalize(sqlite3_context *context){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_int64(context, p ? p->n : 0);
}


Recall that there are two versions of the count() aggregate.
With zero arguments, count() returns a count of the number of rows.
With one argument, count() returns the number of times that the
argument was non-NULL.

The countStep() callback is invoked once for each row in the aggregate.
As you can see, the count is incremented if either there are no arguments,
or if the one argument is not NULL.

The step function for an aggregate should always begin with a call
to the sqlite3_aggregate_context() routine to fetch the persistent
state of the aggregate function.  On the first invocation of the step()
function, the aggregate context is initialized to a block of memory
that is N bytes in size, where N is the second parameter to
sqlite3_aggregate_context() and that memory is zeroed.  On all subsequent
calls to the step() function, the same block of memory is returned.
Except, sqlite3_aggregate_context() might return NULL in the case of
an out-of-memory error, so aggregate functions should be prepared to
deal with that case.

After all rows are processed the countFinalize() routine is called
exactly once.  This routine computes the final result and invokes
one of the sqlite3_result() family of functions
to set the final result.  The aggregate context will be freed automatically
by SQLite, though the xFinalize() routine must clean up any substructure
associated with the aggregate context before it returns.  If the xStep()
method is called one or more times, then SQLite guarantees thta the
xFinal() method will be called at once, even if the query aborts.

2.3.3. The Window Function Callbacks

Window functions use the same xStep() and xFinal() callbacks that
aggregate functions use, plus two others: xValue and xInverse.
See the documentation on
application-defined window functions for further details.

2.3.4. Examples

There are dozens and dozens of SQL function implementations scattered
throughout the SQLite source code that can be used as example applications.
The built-in SQL functions use the same interface as application-defined
SQL functions, so built-in functions can be used as examples too.
Search for "sqlite3_context" in the SQLite source code to find examples.



3. Security Implications


Application-defined SQL functions can become security vulnerabilities if
not carefully managed.  Suppose, for example, an application defines
a new "system(X)" SQL function that runs its argument X as a command and
returns the integer result code.  Perhaps the implementation is like this:

static void systemFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zCmd = (const char*)sqlite3_value_text(argv}; hd_resolve_one {0}; hd_puts {);
  if( zCmd!=0 ){
    int rc = system(zCmd);
    sqlite3_result_int(context, rc);
  }
}



This is a function with powerful side-effects.  Most programmers would
be naturally cautious about using it, but probably would not see the
harm in merely having it available.  But there is great risk in merely
defining such a function, even if the application itself never invokes
it!


Suppose the application normally does a query against table TAB1
when it starts up.  If an attacker can gain access to the database
file and modify the schema like this:

ALTER TABLE tab1 RENAME TO tab1_real;
CREATE VIEW tab1 AS SELECT * FROM tab1 WHERE system('rm -rf *') IS NOT NULL;



Then, when the application attempts to open the database, register the
system() function, then run an innocent query against the "tab1" table,
it instead deletes all the files in its working directory.  Yikes!


To prevent this kind of mischief, applications that create their own
custom SQL functions should take one or more of the following safety
precautions.  The more precautions taken the better:



Invoke sqlite3_db_config(db,SQLITE_DBCONFIG_TRUSTED_SCHEMA,0,0)
on each database connection as soon as it is opened.
This prevents application-defined functions from being used in places
where an attacker might be able to surreptiously invoke them by modifying
a database schema:

 In in VIEWs.
 In in TRIGGERSs.
 In CHECK constraints of a table definition.
 In DEFAULT constraints of a table definition.
 In the definitions of generated columns.
 In the expression part of an index on an expression.
 In the WHERE clause of a partial index.


To put it another way, this setting requires that application-defined
functions only be run directly by top-level SQL invoked from the application
itself, not as a consequence of doing some other innocent-looking query.


Use the PRAGMA trusted_schema=OFF SQL statement to disable trusted
schema.  This has the same effect as the previous bullet, but does not
require the use of C-code and hence can be performed in programs written
in another programming language and that do not have access SQLite
C-language APIs.


Compile SQLite using the -DSQLITE_TRUSTED_SCHEMA=0 compile-time option.
This make SQLite distrust application-defined functions inside of
the schema by default.


If any application-defined SQL functions have potentially dangerous
side-effects, or if they could potentially leak sensitive information
to an attacker if misused, then tag those functions using the
SQLITE_DIRECTONLY option on the "enc" parameter.  This means
that the function can never be run from schema-code even if the
trusted-schema option is on.


Never tag an application-defined SQL function with SQLITE_INNOCUOUS
unless you really need to and you have checked the implementation closely
and are certain that it can do no harm even if it falls under the
control of an attacker.


c2: How To Download Canonical SQLite Source Code
c5: getthecode.html
c4:
1. Introduction

Most programmers compile SQLite into their applications using
the amalgamation.  The amalgamation is C-code but it is not
"source code".  The amalgamation is generated from source code
by scripts.

This document describes how to obtain the canonical source code
for SQLite - the raw source files from which the amalgamation is
built.  See the How To Compile SQLite page for additional information
on what to do with the canonical source code once it is obtained.

2. Direct Downloads

Snapshots of official releases of SQLite source code can often
be obtained directly from the download page of the SQLite website.
Even if the specific version desired is not listed on the download page,
the naming conventions are fairly clear and so programmers can often
guess the name of an historical release and download it that way.

3. Obtaining Code Directly From the Version Control System

For any historical version of SQLite, the source tree can be obtained
from the Fossil version control system,
either downloading a tarball or ZIP archive for a specific version, or
by cloning the entire project history.

SQLite sources are maintained on three geographically dispersed
servers:


https://www.sqlite.org/cgi/src (Dallas)
https://www2.sqlite.org/cgi/src (Newark)
https://www3.sqlite.org/cgi/src (San Francisco)


The documentation is maintained in separate source repositories on
those same servers:


https://www.sqlite.org/cgi/docsrc (Dallas)
https://www2.sqlite.org/cgi/docsrc (Newark)
https://www3.sqlite.org/cgi/docsrc (San Francisco)


To download a specific historical version, first locate the specific
version desired by visiting the timeline page on one of these servers
(for example: http://www.sqlite.org/cgi/src/timeline).  If
you know the approximate date of the version you want to download, you
can add a query parameter like "c=YYYY-MM-DD" to the "timeline" URL to
see a timeline centered on that date.  For example, to see all the check-ins
that occurred around August 26, 2013, visit
http://www.sqlite.org/cgi/src/timeline?c=2013-08-26.
If you are looking for an official release, visit the
chronology page, click on the date to the left of the release
you are looking for, and that will take you immediately to the
check-in corresponding to the release.

Once you locate a specific version, click on the hyperlink for that
version to see the "Check-in Information Page".
Then click on either the "Tarball" link or the
"ZIP archive" link to download the complete source tree.



4. Cloning The Complete Development History

To clone the entire history of SQLite, first go to the
http://www.fossil-scm.org/download.html page and grab a precompiled binary
for the Fossil version control program.  Or get the source code on the
same page and compile it yourself.

As of 2017-03-12, you must use Fossil version
2.0 or later for the following instructions to work.  
The SQLite repository started using
artifacts named using SHA3 hashes instead of SHA1 hashes on that date,
and Fossil 2.0 or later is needed in order to understand the new SHA3
hashes.  To find out what version of Fossil you are running, 
type "fossil -v".

Fossil is a completely stand-alone
program, so install it simply by putting the "fossil" or "fossil.exe"
executable someplace on your $PATH or %PATH%.  After you have Fossil
installed, do this:

fossil clone http://www.sqlite.org/cgi/src sqlite.fossil


The command above
will make a copy of the complete development history of
SQLite into the "sqlite.fossil" file on your computer.  Making this copy
takes about a minute and uses about 32 megabytes of transfer.  After
making the copy, "open" the repository by typing:

fossil open sqlite.fossil


This second command will "checkout" the latest check-in from the SQLite
source tree into your current directory.  Subsequently, you can easily switch
to a different version by typing:

fossil update VERSION


Where VERSION can be a branch name (like "trunk" or "session") to get the
latest check-in on a specific branch, or VERSION can be a SHA1 hash or a
prefix of a SHA1 hash for a specific check-in, or VERSION can be a tag
such as "version-3.8.8".  Every time you run "fossil update" it will
automatically reach out to the original repository at
http://www.sqlite.org/cgi/src to obtain new check-ins that might have been
made by others since your previous update.


c2: The UNION Virtual Table
c5: unionvtab.html
c4:
The UNION virtual table (hereafter: "union-vtab")
is a virtual table that makes multiple independent
rowid tables tables look like a single large table.


The tables that participate in a union-vtab can be in the same 
database file, or they can be in separate databases files that
are ATTACH-ed to the same database connection.


The union-vtab is not built into SQLite.
Union-vtab is a loadable extension.
The source code for union-vtab is contained in a single file located at
ext/misc/unionvtab.c
in the SQLite source tree.


A new union-vtab instance is created as follows:


CREATE VIRTUAL TABLE temp.tabname USING unionvtab(query);



Every union-vtab must be in the TEMP namespace.  Hence, the "temp."
prior to tabname is required.  Only the union-vtab itself is required
to be in the TEMP namespace - the individual tables that are being unioned
can be any ATTACH-ed database.


The query in the CREATE VIRTUAL TABLE statement for a union-vtab 
must be a well-formed SQL query that returns four columns and an 
arbitrary number of rows.  Each row in the result of the query
represents a single table that is to participate in the union.


The first column is the schema name for the database that contains
the tables.  Examples:  "main", "zone512".

The second column is the name of the table.

The third column  is the minimum value for any rowid in the table.

The fourth column is the maximum value of any rowid in the table.



The query for the CREATE VIRTUAL TABLE statement of a union-vtab
can be either a SELECT statement or a VALUES clause.


The query is run once when the CREATE VIRTUAL TABLE statement is
first encountered and the results of that one run are used for all subsequent
access to the union-vtab.  If the results of query change, then
the union-vtab should be DROP-ed and recreated in order
to cause the query to be run again.


There must be no overlap in the bands of rowids for the various tables
in a union-vtab.


All tables that participate in a union-vtab must have identical
CREATE TABLE definitions, except that the names of the tables can be different.


All tables that participate in a union-vtab must be rowid tables.


The column names and definitions for tabname will be the same as
the underlying tables.  An application can access tabname just like
it was one of the real underlying tables.


No table in a union-vtab may contain entries that are outside of the
rowid bounds established by the query in the CREATE VIRTUAL TABLE
statement.


The union-vtab shall optimize access to the underlying real tables
when the constraints on the query are among forms shown below.
Other kinds of constraints may be optimized in the future, but only
these constraints are optimized in the initial implementation.

 rowid=$id
 rowid IN query-or-list
 rowid BETWEEN $lwr AND $upr


Other kinds of constraints may be used and will work, but other
constraints will be checked individually for each row and will not
be optimized (at least not initially). 
All constraint checking is completely automatic regardless of whether
or not optimization occurs.  The optimization referred to in this bullet point
is a performance consideration only.  The same result is obtained
regardless of whether or not the query is optimized.


The union-vtab is read-only.  Support for writing may be added at a later
time, but writing is not a part of the initial implementation.


Nota bene:
The sqlite3_blob_open() interface does not work for a union-vtab.
BLOB content must be read from the union-vtab using ordinary SQL statements.


c2: In-Memory Databases
c5: inmemorydb.html
c4:
In-Memory Databases

An SQLite database is normally stored in a single ordinary disk
file. However, in certain circumstances, the database might be stored in
memory.

The most common way to force an SQLite database to exist purely 
in memory is to open the database using the special filename
":memory:".  In other words, instead of passing the name of
a real disk file into one of the sqlite3_open(), sqlite3_open16(), or
sqlite3_open_v2() functions, pass in the string ":memory:".  For
example:


rc = sqlite3_open(":memory:", &amp;db);


When this is done, no disk file is opened.  
Instead, a new database is created
purely in memory.  The database ceases to exist as soon as the database
connection is closed.  Every :memory: database is distinct from every
other.  So, opening two database connections each with the filename
":memory:" will create two independent in-memory databases.

The special filename ":memory:" can be used anywhere that a database
filename is permitted.  For example, it can be used as the
filename in an ATTACH command:


ATTACH DATABASE ':memory:' AS aux1;


Note that in order for the special ":memory:" name to apply and to
create a pure in-memory database, there must be no additional text in the
filename.  Thus, a disk-based database can be created in a file by prepending
a pathname, like this:  "./:memory:".

The special ":memory:" filename also works when using URI filenames.
For example:


rc = sqlite3_open("file::memory:", &amp;db);


Or,


ATTACH DATABASE 'file::memory:' AS aux1;




In-memory Databases And Shared Cache

In-memory databases are allowed to use shared cache if they are
opened using a URI filename.  If the unadorned ":memory:" name is used
to specify the in-memory database, then that database always has a private
cache and is this only visible to the database connection that originally
opened it.  However, the same in-memory database can be opened by two or
more database connections as follows:


rc = sqlite3_open("file::memory:?cache=shared", &amp;db);


Or,


ATTACH DATABASE 'file::memory:?cache=shared' AS aux1;


This allows separate database connections to share the same
in-memory database.  Of course, all database connections sharing the
in-memory database need to be in the same process.  The database is
automatically deleted and memory is reclaimed when the last connection
to the database closes.

If two or more distinct but shareable in-memory databases are needed
in a single process, then the mode=memory query parameter can
be used with a URI filename to create a named in-memory database:


rc = sqlite3_open("file:memdb1?mode=memory&amp;cache=shared", &amp;db);


Or,


ATTACH DATABASE 'file:memdb1?mode=memory&amp;cache=shared' AS aux1;


When an in-memory database is named in this way, it will only share its
cache with another connection that uses exactly the same name.





Temporary Databases

When the name of the database file handed to sqlite3_open() or to
ATTACH is an empty string, then a new temporary file is created to hold
the database.


rc = sqlite3_open("", &amp;db);



ATTACH DATABASE '' AS aux2;


A different temporary file is created each time, so that just like as
with the special ":memory:" string, two database connections to temporary
databases each have their own private database.  Temporary databases are
automatically deleted when the connection that created them closes.

Even though a disk file is allocated for each temporary database, in
practice the temporary database usually resides in the in-memory pager
cache and hence is very little difference between a pure in-memory database
created by ":memory:" and a temporary database created by an empty filename.
The sole difference is that a ":memory:" database must remain in memory
at all times whereas parts of a temporary database might be flushed to
disk if database becomes large or if SQLite comes under memory pressure.

The previous paragraphs describe the behavior of temporary databases
under the default SQLite configuration.  An application can use the
temp_store pragma and the SQLITE_TEMP_STORE compile-time parameter to
force temporary databases to behave as pure in-memory databases, if desired.


c2: The COMPLETION() Table-Valued Function
c5: completion.html
c4:
1. Overview

The COMPLETION extension implements a table-valued function named
"completion" that can be used to suggest completions of partially entered
words during interactive SQL input.  The completion table can be
used to help implement tab-completion, for example.

2. Details

The designed query interface is:

SELECT DISTINCT candidate COLLATE nocase
  FROM completion($prefix, $wholeline)
 ORDER BY 1;


The query above will return suggestions for the whole input word that
begins with $prefix.  The $wholeline parameter is all text from the beginning
of the line up to the insertion point.  The $wholeline parameter is used
for context.

The $prefix parameter may be NULL, in which case the prefix is deduced
from $wholeline.  Or, the $wholeline parameter may be NULL or omitted if 
context information is unavailable or if context-aware completion is not
desired.

The completion table might return the same candidate more than once, and
it will return candidates in an arbitrary order.  The DISTINCT keyword and
the ORDER BY in the sample query above are added to make the answers unique
and in lexicographical order.

2.1. Example Usage

The completion table is used to implement tab-completion in the
command-line shell in conjunction with either the readline or linenoise
input line editing packages for unix.  See the
https://sqlite.org/src/file/src/shell.c.in source file for example
code.  Search for "FROM completion" to find the relevant code sections.

Because the completion table is built into the command-line shell in order
to provide for tab-completions, you can run test queries against the
completion table directly in the command-line shell.  Simply type a
query such as the example shown above, filling in appropriate values
for $prefix and $wholeline, and observe the output.

3. Limitations

The completion table is designed for interactive use.  It will return
answers at a speed appropriate for human typing.  No effort is made to
be unusually efficient, so long as the response time is nearly instantaneous
in a user interface.

As of this writing (2017-07-13), the completion virtual table only
looks for SQL keywords, and schema, table, and column names.  The
context contained in $wholeline is completely ignored.  Future enhancements
will try to return new completions taken from function and pragma names
and other sources, as well as consider more context.  The completion
table should be considered a work-in-progress.


c2: Deterministic SQL Functions
c5: deterministic.html
c4:
1. Overview


SQL functions in SQLite can be either "deterministic" or "non-deterministic".


A deterministic function always gives the same answer when it has
the same inputs.  Most built-in SQL functions in SQLite are
deterministic.  For example, the abs(X) function always returns
the same answer as long as its input X is the same.


Non-deterministic functions might give different answers on each
invocation, even if the arguments are always the same.  The following
are examples of non-deterministic functions:


 random()
 changes()
 last_insert_rowid()
 sqlite3_version()



The random() function is obviously non-deterministic because it gives
a different answer every time it is invoked.  The answers from changes()
and last_insert_rowid() depend on prior SQL statements, and so they
are also non-deterministic. The
sqlite3_version() function is mostly constant, but it can change when
SQLite is upgraded, and so even though it always returns the same answer
for any particular session, because it can change answers across sessions
it is still considered non-deterministic.


2. Restrictions on the use of non-deterministic functions


There are some contexts in SQLite that do not allow the use of
non-deterministic functions:


In the expression of a CHECK constraint.
In the WHERE clause of a partial index.
In an expression used as part of an expression index.
In the expression of a generated column.



In the cases above, the values returned by the function affects the
information stored in the database file.  The values of functions
in CHECK constraints determines which entries are valid for a table,
and functions in the WHERE clause of a partial index or in an index on
an expression compute values stored in the index b-tree.
If any of these functions later returns a different
value, then the database might no longer be well-formed.  
Hence, to avoid database corruption,
only deterministic functions can be used in the contexts
above.



3. Special-case Processing For Date/Time Functions


The built-in date and time functions of SQLite are a special case.
These functions are usually considered deterministic.  However, if
these functions use the string "now" as the date, or if they use
the localtime modifier or the utc modifier, then they are
considered non-deterministic.  Because the function inputs are
not necessarily known until run-time, the date/time functions will
throw an exception if they encounter any of the non-deterministic
features in a context where only deterministic functions are allowed.


Prior to SQLite 3.20.0 (2017-08-01) all date/time functions were
always considered non-deterministic.  The ability for date/time functions
to be deterministic sometimes and non-deterministic at other times,
depending on their arguments, was added for the 3.20.0 release.

4. Application-defined deterministic functions


By default, application-defined SQL functions are considered to
be non-deterministic.  However, if the 4th parameter to
sqlite3_create_function_v2() is OR-ed with 
SQLITE_DETERMINISTIC, then SQLite will treat that function as if it
were deterministic.


Note that if a non-deterministic function is tagged with
SQLITE_DETERMINISTIC and if that function ends up being used in
the WHERE clause of a partial index or in an
expression index, then when the function begins to return different
answers, the associated index may become corrupt.  If an SQL function
is nearly deterministic (which is to say, if it only rarely changes,
like sqlite_version()) and it is used in an index that becomes
corrupt, the corruption can be fixed by running REINDEX.


The interfaces necessary to construct a function that is sometimes
deterministic and sometimes non-deterministic depending on their
inputs, such as the built-in date/time functions, are not published.
Generic application-defined SQL functions must
be always deterministic or always non-deterministic.


c2: Floating Pointer Numbers
c5: floatingpoint.html
c4:
1. How SQLite Stores Numbers


SQLite stores integer values in the 64-bit 
twos-complement
format.
This gives a storage range of -9223372036854775808 to +9223372036854775807,
inclusive.  Integers within this range are exact.


So-called "REAL" or floating point values are stored in the
IEEE 754
Binary-64
format.
This gives a range of positive values between approximately
1.7976931348623157e+308 and 4.9406564584124654e-324 with an equivalent
range of negative values.  A binary64 can also be 0.0 (and -0.0), positive
and negative infinity and "NaN" or "Not-a-Number".  Floating point
values are approximate.


Pay close attention to the last sentence in the previous paragraph:

Floating point values are approximate &larr; Always remember this!



If you need an exact answer, you should not use binary64 floating-point
values, in SQLite or in any other product.  This is not an SQLite limitation.
It is a mathematical limitation inherent in the design of floating-point numbers.

1.1. Floating-Point Accuracy


SQLite promises to preserve the 15 most significant digits of a floating
point value.  However, it makes no guarantees about the accuracy of
computations on floating point values, as no such guarantees are possible.
Performing math on floating-point values introduces error.
For example, consider what happens if you attempt to subtract two floating-point
numbers of similar magnitude:



1152693165.1106291898
-1152693165.1106280772

0.0000011126



The result shown above (0.0000011126) is the correct answer.  But if you
do this computation using binary64 floating-point, the answer you get is
0.00000095367431640625 - an error of about 14%.  If you do many similar
computations as part of your program, the errors add up so that your final
result might be completely meaningless.

The error arises because only about the first 15 significant digits of
each number are stored accurately, and first the difference between the two numbers
being subtracted is in the 16th digit.  

1.2. Floating Point Numbers


The binary64 floating-point format uses 64 bits per number.  Hence there
are 1.845e+19 different possible floating point values.  On the other hand
there are infinitely many real numbers in the range of 
1.7977e+308 and 4.9407e-324.  It follows then that binary64 cannot possibly
represent all possible real numbers within that range.  Approximations are
required.


An IEEE 754 floating-point value is an integer multiplied by a power
of two:


M &times 2E


The M value is the "mantissa" and E is the "exponent".  Both
M and E are integers.

For Binary64, M is a 53-bit integer and E is an 11-bit integer that
offset so that represents a range of values between -1074 and +972, inclusive.

(NB:  The usual description of IEEE 754 is more complex, and it is important
to understand the added complexity if you really want to appreciate the details,
merits, and limitations of IEEE 754.  However, the integer description shown
here, while not exactly right, is easier to understand and is sufficient for
the purposes of this article.)

1.2.1. Unrepresentable numbers

Not ever decimal number with fewer than 16 significant digits can be
represented exactly as a binary64 number.  In fact, most decimal numbers
with digits to the right of the decimal point lack an exact binary64
equivalent.  For example, if you have a database column that is intended
to hold an item price in dollars and cents, the only cents value that
can be exactly represented are 0.00, 0.25, 0.50, and 0.75.  Any other
numbers to the right of the decimal point result in an approximation.
If you provide a "price" value of 47.49, that number will be represented
in binary64 as:


6683623321994527 &times; 2-47


Which works out to be:


47.49000000000000198951966012828052043914794921875


That number is very close to 47.49, but it is not exact.  It is a little
too big.  If we reduce M by one to 6683623321994526 so that we have the
next smaller possible binary64 value, we get:


47.4899999999999948840923025272786617279052734375




This second number is too small.
The first number is closer to the desired value of 47.49, so that is the
one that gets used.  But it is not exact.  Most decimal values work this
way in IEEE 754.  Remember the key point we made above:


Floating point values are approximate.


If you remember nothing else about floating-point values, 
please don't forget this one key idea.

1.2.2. Is it close enough?

The precision provided by IEEE 754 Binary64 is sufficient for most computations.
For example, if "47.49" represents a price and inflation is running
at 2% per year, then the price is going up by about 0.0000000301 dollars per
second.  The error in the recorded value of 47.49 represents about 66 nanoseconds
worth of inflation.  So if the 47.49 price is exact
when you enter it, then the effects of inflation will cause the true value to
exactly equal the value actually stored
(47.4900000000000019895196601282805204391479492187) in less than 
one ten-millionth of a second.
Surely that level of precision is sufficient for most purposes?

2. Extensions For Dealing With Floating Point Numbers



2.1. The ieee754.c Extension

The ieee754 extension converts a floating point number between its
binary64 representation and the M&times;2E format.
In other words in the expression:


F = M &times 2E


The ieee754 extension converts between F and (M,E) and back again.

The ieee754 extension is not part of the amalgamation, but it is included
by default in the CLI.  If you want to include the ieee754 extension in your
application, you will need to compile and load it separately.



2.1.1. The ieee754() function

The ieee754(F) SQL function takes a single floating-point argument
as its input and returns a string that looks like this:


'ieee754(M,E)'


Except that the M and E are replaced by the mantissa and exponent of the
floating point number.  For example:

sqlite> .mode box
sqlite> SELECT ieee754(47.49) AS x;
┌───────────────────────────────┐
│               x               │
├───────────────────────────────┤
│ ieee754(6683623321994527,-47) │
└───────────────────────────────┘



Going in the other direction, the 2-argument version of ieee754() takes
the M and E values and converts them into the corresponding F value:

sqlite> select ieee754(6683623321994527,-47) as x;
┌───────┐
│   x   │
├───────┤
│ 47.49 │
└───────┘




2.1.2. The ieee754_mantissa() and ieee754_exponent() functions

The text output of the one-argument form of ieee754() is great for human
readability, but it awkward to use as part of a larger expression.  Hence
The ieee754_mantissa() and ieee754_exponent() routines were added to return
the M and E values corresponding to their single argument F
value.
For example:

sqlite> .mode box
sqlite> SELECT ieee754_mantissa(47.49) AS M, ieee754_exponent(47.49) AS E;
┌──────────────────┬─────┐
│        M         │  E  │
├──────────────────┼─────┤
│ 6683623321994527 │ -47 │
└──────────────────┴─────┘




2.1.3. The ieee754_from_blob() and ieee754_to_blob() functions

The ieee754_to_blob(F) SQL function converts the floating point number F
into an 8-byte BLOB that is the big-endian binary64 encoding of that number.
The ieee754_from_blob(B) function goes the other way, converting an 8-byte
blob into the floating-point value that the binary64 encoding represents.

So, for example, if you read
on
Wikipedia that the encoding for the minimum positive binary64 value is
0x0000000000000001, then you can find the corresponding floating point value
like this:

sqlite> .mode box
sqlite> SELECT ieee754_from_blob(x'0000000000000001') AS F;
┌───────────────────────┐
│           F           │
├───────────────────────┤
│ 4.94065645841247e-324 │
└───────────────────────┘


Or go the other way:

sqlite> .mode box
sqlite> SELECT quote(ieee754_to_blob(4.94065645841247e-324)) AS binary64;
┌─────────────────────┐
│      binary64       │
├─────────────────────┤
│ X'0000000000000001' │
└─────────────────────┘




2.2. The decimal.c Extension

The decimal extension provides arbitrary-precision decimal arithmetic on
numbers stored as text strings.  Because the numbers are stored to arbitrary
precision and as text, no approximations are needed.  Computations can be
done exactly.

The decimal extension is not (currently) part of the SQLite amalgamation.
However, it is included in the CLI.

There are three math functions available:



 decimal_add(A,B)
 decimal_sub(A,B)
 decimal_mul(A,B)



These functions respectively add, subtract, and multiply their arguments
and return a new text string that is the decimal representation of the result.
There is no division operator at this time.

Use the decimal_cmp(A,B) to compare two decimal values.  The result will
be negative, zero, or positive if A is less than, equal to, or greater than B,
respectively.

The decimal_sum(X) function is an aggregate, like the built-in
sum() aggregate function, except that decimal_sum() computes its result
to arbitrary precision and is therefore precise.

Finally, the decimal extension provides the "decimal" collating sequences
that compares decimal text strings in numeric order.

3. Techniques


The following SQL illustrates how to use the ieee754 and decimal
extensions to compute the exact decimal equivalent
for a binary64 floating-point number.

-- The pow2 table will hold all the necessary powers of two.
CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
WITH RECURSIVE c(x,v) AS (
  VALUES(0,'1')
  UNION ALL
  SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1&lt;=971
) INSERT INTO pow2(x,v) SELECT x, v FROM c;
WITH RECURSIVE c(x,v) AS (
  VALUES(-1,'0.5')
  UNION ALL
  SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1&gt;=-1075
) INSERT INTO pow2(x,v) SELECT x, v FROM c;

-- This query finds the decimal representation of each value in the "c" table.
WITH c(n) AS (VALUES(47.49))
                 ----XXXXX----------- Replace with whatever you want
SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
  FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);


c2: Command Line Shell For SQLite
c5: cli.html
c4:
1. Getting Started

The SQLite project provides a simple command-line program named
sqlite3 (or sqlite3.exe on Windows)
that allows the user to manually enter and execute SQL
statements against an SQLite database or against a
ZIP archive.  This document provides a brief
introduction on how to use the sqlite3 program.

Start the sqlite3 program by typing "sqlite3" at the
command prompt, optionally followed 
by the name the file that holds the SQLite database
(or ZIP archive).  If the named
file does not exist, a new database file with the given name will be
created automatically.  If no database file is specified on the
command-line, a temporary database is created, then deleted when 
the "sqlite3" program exits.

On startup, the sqlite3 program will show a brief banner
message then prompt you to enter SQL.  Type in SQL statements (terminated
by a semicolon), press "Enter" and the SQL will be executed.

For example, to create a new SQLite database named "ex1" 
with a single table named "tbl1", you might do this:

$ sqlite3 ex1
SQLite version 3.28.0 2019-03-02 15:25:24
Enter ".help" for usage hints.
sqlite&gt; create table tbl1(one varchar(10), two smallint);
sqlite&gt; insert into tbl1 values('hello!',10);
sqlite&gt; insert into tbl1 values('goodbye', 20);
sqlite&gt; select * from tbl1;
hello!|10
goodbye|20
sqlite&gt;


Terminate the sqlite3 program by typing your system
End-Of-File character (usually a Control-D).  Use the interrupt
character (usually a Control-C) to stop a long-running SQL statement.

Make sure you type a semicolon at the end of each SQL command!
The sqlite3 program looks for a semicolon to know when your SQL command is
complete.  If you omit the semicolon, sqlite3 will give you a
continuation prompt and wait for you to enter more text to be
added to the current SQL command.  This feature allows you to
enter SQL commands that span multiple lines.  For example:


sqlite&gt; CREATE TABLE tbl2 (
   ...&gt;   f1 varchar(30) primary key,
   ...&gt;   f2 text,
   ...&gt;   f3 real
   ...&gt; );
sqlite&gt;




2. Double-click Startup On Windows

Windows users can double-click on the sqlite3.exe icon to cause
the command-line shell to pop-up a terminal window running SQLite.  However,
because double-clicking starts the sqlite3.exe without command-line arguments,
no database file will have been specified, so SQLite will use a temporary
database that is deleted when the session exits.
To use a persistent disk file as the database, enter the ".open" command
immediately after the terminal window starts up:

SQLite version 3.28.0 2019-03-02 15:25:24
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite&gt; .open ex1.db
sqlite&gt;


The example above causes the database file named "ex1.db" to be opened
and used.  The "ex1.db" file is created if it does not previously exist.
You might want to
use a full pathname to ensure that the file is in the directory that you
think it is in.  Use forward-slashes as the directory separator character.
In other words use "c:/work/ex1.db", not "c:\work\ex1.db".

Alternatively, you can create a new database using the default temporary
storage, then save that database into a disk file using the ".save" command:

SQLite version 3.28.0 2019-03-02 15:25:24
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite&gt; ... many SQL commands omitted ...
sqlite&gt; .save ex1.db
sqlite&gt;


Be careful when using the ".save" command as it will overwrite any
preexisting database files having the same name without prompting for
confirmation.  As with the ".open" command, you might want to use a
full pathname with forward-slash directory separators to avoid ambiguity.



3. Special commands to sqlite3 (dot-commands)


Most of the time, sqlite3 just reads lines of input and passes them
on to the SQLite library for execution.
But input lines that begin with a dot (".")
are intercepted and interpreted by the sqlite3 program itself.
These "dot commands" are typically used to change the output format
of queries, or to execute certain prepackaged query statements.
There were originally just a few dot commands, but over the years
many new features have accumulated so that today there over 60.



For a listing of the available dot commands, you can enter ".help" with
no arguments.  Or enter ".help TOPIC" for detailed information about TOPIC.
The list of available dot-commands follows:


sqlite&gt; .help
.archive ...             Manage SQL archives
.auth ON|OFF             Show authorizer callbacks
.backup ?DB? FILE        Backup DB (default "main") to FILE
.bail on|off             Stop after hitting an error.  Default OFF
.binary on|off           Turn binary output on or off.  Default OFF
.cd DIRECTORY            Change the working directory to DIRECTORY
.changes on|off          Show number of rows changed by SQL
.check GLOB              Fail if output since .testcase does not match
.clone NEWDB             Clone data into NEWDB from the existing database
.databases               List names and files of attached databases
.dbconfig ?op? ?val?     List or change sqlite3_db_config() options
.dbinfo ?DB?             Show status information about the database
.dump ?TABLE?            Render database content as SQL
.echo on|off             Turn command echo on or off
.eqp on|off|full|...     Enable or disable automatic EXPLAIN QUERY PLAN
.excel                   Display the output of next command in spreadsheet
.exit ?CODE?             Exit this program with return-code CODE
.expert                  EXPERIMENTAL. Suggest indexes for queries
.explain ?on|off|auto?   Change the EXPLAIN formatting mode.  Default: auto
.filectrl CMD ...        Run various sqlite3_file_control() operations
.fullschema ?--indent?   Show schema and the content of sqlite_stat tables
.headers on|off          Turn display of headers on or off
.help ?-all? ?PATTERN?   Show help text for PATTERN
.import FILE TABLE       Import data from FILE into TABLE
.imposter INDEX TABLE    Create imposter table TABLE on index INDEX
.indexes ?TABLE?         Show names of indexes
.limit ?LIMIT? ?VAL?     Display or change the value of an SQLITE_LIMIT
.lint OPTIONS            Report potential schema issues.
.load FILE ?ENTRY?       Load an extension library
.log FILE|off            Turn logging on or off.  FILE can be stderr/stdout
.mode MODE ?TABLE?       Set output mode
.nullvalue STRING        Use STRING in place of NULL values
.once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE
.open ?OPTIONS? ?FILE?   Close existing database and reopen FILE
.output ?FILE?           Send output to FILE or stdout if FILE is omitted
.parameter CMD ...       Manage SQL parameter bindings
.print STRING...         Print literal STRING
.progress N              Invoke progress handler after every N opcodes
.prompt MAIN CONTINUE    Replace the standard prompts
.quit                    Exit this program
.read FILE               Read input from FILE
.recover                 Recover as much data as possible from corrupt db.
.restore ?DB? FILE       Restore content of DB (default "main") from FILE
.save FILE               Write in-memory database into FILE
.scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off
.schema ?PATTERN?        Show the CREATE statements matching PATTERN
.selftest ?OPTIONS?      Run tests defined in the SELFTEST table
.separator COL ?ROW?     Change the column and row separators
.sha3sum ...             Compute a SHA3 hash of database content
.shell CMD ARGS...       Run CMD ARGS... in a system shell
.show                    Show the current values for various settings
.stats ?on|off?          Show stats or turn stats on or off
.system CMD ARGS...      Run CMD ARGS... in a system shell
.tables ?TABLE?          List names of tables matching LIKE pattern TABLE
.testcase NAME           Begin redirecting output to 'testcase-out.txt'
.testctrl CMD ...        Run various sqlite3_test_control() operations
.timeout MS              Try opening locked tables for MS milliseconds
.timer on|off            Turn SQL timer on or off
.trace ?OPTIONS?         Output each SQL statement as it is run
.vfsinfo ?AUX?           Information about the top-level VFS
.vfslist                 List all available VFSes
.vfsname ?AUX?           Print the name of the VFS stack
.width NUM1 NUM2 ...     Set minimum column widths for columnar output
sqlite&gt;




4. Rules for "dot-commands"

Ordinary SQL statements are free-form, and can be
spread across multiple lines, and can have whitespace and
comments anywhere.  Dot-commands are
more restrictive:


A dot-command must begin with the "." at the left margin
    with no preceding whitespace.
The dot-command must be entirely contained on a single input line.
A dot-command cannot occur in the middle of an ordinary SQL
    statement.  In other words, a dot-command cannot occur at a
    continuation prompt.
Dot-commands do not recognize comments.


The dot-commands
are interpreted by the sqlite3.exe command-line program, not by
SQLite itself.  So none of the dot-commands will work as an argument
to SQLite interfaces like sqlite3_prepare() or sqlite3_exec().



5. Changing Output Formats

The sqlite3 program is able to show the results of a query
in 14 different formats:


 ascii
 box
 csv
 column
 html
 insert
 json
 line
 list
 markdown
 quote
 table
 tabs
 tcl


You can use the ".mode" dot command to switch between these output
formats.
>The default output mode is "list".  In
list mode, each row of a query result is written on one line of
output and each column within that row is separated by a specific
separator string.  The default separator is a pipe symbol ("|").
List mode is especially useful when you are going to send the output
of a query to another program (such as AWK) for additional processing.

sqlite&gt; .mode list
sqlite&gt; select * from tbl1;
hello|10
goodbye|20
sqlite&gt;


Use the ".separator" dot command to change the separator.
For example, to change the separator to a comma and
a space, you could do this:

sqlite&gt; .separator ", "
sqlite&gt; select * from tbl1;
hello, 10
goodbye, 20
sqlite&gt;


The next ".mode" command will reset the ".separator" back to its default.
So you will need repeat the ".separator" command whenever you change
modes if you want to continue using a non-standard separator.



In "quote" mode, the output is formatted as SQL literals.  Strings are
enclosed in single-quotes and internal single-quotes are escaped by doubling.
Blobs are displayed in hexadecimal blob literal notation (Ex: x'abcd').
Numbers are displayed as ASCII text and NULL values are shown as "NULL".
All columns are separated from each other by a comma (or whatever alternative
character is selected using ".separator").

sqlite&gt; .mode quote
sqlite&gt; select * from tbl1;
'hello',10
'goodbye',20
sqlite&gt;


In "line" mode, each column in a row of the database
is shown on a line by itself.  Each line consists of the column
name, an equal sign and the column data.  Successive records are
separated by a blank line.  Here is an example of line mode
output:

sqlite&gt; .mode line
sqlite&gt; select * from tbl1;
one = hello
two = 10

one = goodbye
two = 20
sqlite&gt;


In column mode, each record is shown on a separate line with the
data aligned in columns.  For example:

sqlite&gt; .mode column
sqlite&gt; select * from tbl1;
one       two       
--------  ---
hello     10        
goodbye   20        
sqlite&gt;


In "column" mode (and also in "box", "table", and "markdown" modes)
the width of columns adjusts automatically.  But you can override this,
providing a minimum width for each column using the ".width" command.
The arguments to ".width" are integers which are the minimum number of
spaces to devote to each column.  Negative numbers mean right-justify.
Thus:

sqlite&gt; .width 12 -6
sqlite&gt; select * from tbl1;
one              two
------------  ------
hello!            10
goodbye           20
sqlite&gt;


A width of 0 means the column width is chosen automatically.
Unspecified columns widths to go zero.  Hence, the command
".width" with no arguments sets all columns widths to zero and
hence causes all column widths to be determine automatically.

The "column" mode is a tabular output format.  Other
tabular output formats as "box", "markdown", and "table":

sqlite&gt; .width
sqlite&gt; .mode markdown
sqlite&gt; select * from tbl1;
|   one   | two |
|---------|-----|
| hello!  | 10  |
| goodbye | 20  |
sqlite&gt; .mode table
sqlite&gt; select * from tbl1;
+---------+-----+
|   one   | two |
+---------+-----+
| hello!  | 10  |
| goodbye | 20  |
+---------+-----+
sqlite&gt; .mode box
sqlite&gt; select * from tbl1;
┌─────────┬─────┐
│   one   │ two │
├─────────┼─────┤
│ hello!  │ 10  │
│ goodbye │ 20  │
└─────────┴─────┘
sqlite&gt;


Another useful output mode is "insert".  In insert mode, the output
is formatted to look like SQL INSERT statements.  Use insert
mode to generate text that can later be used to input data into a 
different database.

When specifying insert mode, you have to give an extra argument
which is the name of the table to be inserted into.  For example:

sqlite&gt; .mode insert new_table
sqlite&gt; select * from tbl1;
INSERT INTO "new_table" VALUES('hello',10);
INSERT INTO "new_table" VALUES('goodbye',20);
sqlite&gt;



Other output modes include "html", "json", and "tcl".  Try these
yourself to see what they do.




6. Writing results to a file

By default, sqlite3 sends query results to standard output.  You
can change this using the ".output" and ".once" commands.  Just put 
the name of an output file as an argument to .output and all subsequent
query results will be written to that file.  Or use the .once command
instead of .output and output will only be redirected for the single next
command before reverting to the console.  Use .output with no arguments to
begin writing to standard output again.  For example:

sqlite&gt; .mode list
sqlite&gt; .separator |
sqlite&gt; .output test_file_1.txt
sqlite&gt; select * from tbl1;
sqlite&gt; .exit
$ cat test_file_1.txt
hello|10
goodbye|20
$


If the first character of the ".output" or ".once" filename is a pipe
symbol ("|") then the remaining characters are treated as a command and the
output is sent to that command.  This makes it easy to pipe the results
of a query into some other process.  For example, the 
"open -f" command on a Mac opens a text editor to display the content that
it reads from standard input.  So to see the results of a query
in a text editor, one could type:

sqlite3&gt; .once '|open -f'
sqlite3&gt; SELECT * FROM bigTable;


If the ".output" or ".once" commands have an argument of "-e" then
output is collected into a temporary file and the system text editor is
invoked on that text file.  Thus, the command ".once -e" achieves the
same result as ".once '|open -f'" but with the benefit of being portable
across all systems.

If the ".output" or ".once" commands have a "-x" argument, that causes
them to accumulate output as Comma-Separated-Values (CSV) in a temporary
file, then invoke the default system utility for viewing CSV files
(usually a spreadsheet program) on the result.  This is a quick way of
sending the result of a query to a spreadsheet for easy viewing:

sqlite3&gt; .once -x
sqlite3&gt; SELECT * FROM bigTable;




The ".excel" command is an alias for ".once -x".  It does exactly the same
thing.



6.1. File I/O Functions

The command-line shell adds two application-defined SQL functions that
facilitate reading content from a file into a table column, and writing the
content of a column into a file, respectively.

The readfile(X) SQL function reads the entire content of the file named
X and returns that content as a BLOB.  This can be used to load content into
a table.  For example:

sqlite&gt; CREATE TABLE images(name TEXT, type TEXT, img BLOB);
sqlite&gt; INSERT INTO images(name,type,img)
   ...&gt;   VALUES('icon','jpeg',readfile('icon.jpg'));


The writefile(X,Y) SQL function write the blob Y into the file named X
and returns the number of bytes written.  Use this function to extract
the content of a single table column into a file.  For example:

sqlite&gt; SELECT writefile('icon.jpg',img) FROM images WHERE name='icon';


Note that the readfile(X) and writefile(X,Y) functions are extension
functions and are not built into the core SQLite library.  These routines
are available as a loadable extension in the
ext/misc/fileio.c
source file in the SQLite source code repositories.



6.2. The edit() SQL function

The CLI has another build-in SQL function named edit().  Edit() takes
one or two arguments.  The first argument is a value - usually a large
multi-line string to be edited.  The second argument is the name of a
text editor.  If the second argument is omitted, the VISUAL environment
variable is used.  The edit() function writes its first argument into a
temporary file, invokes the editor on the temporary file, rereads the file
back into memory after the editor is done, then returns the edited text.

The edit() function can be used to make changes to large text
values.  For example:

sqlite&gt; UPDATE docs SET body=edit(body) WHERE name='report-15';


In this example, the content of the docs.body field for the entry where
docs.name is "report-15" will be sent to the editor.  After the editor returns,
the result will be written back into the docs.body field.

The default operation of edit() is to invoke a text editor.  But by using
an alternative edit program in the second argument, you can also get it to edit
images or other non-text resources.  For example, if you want to modify a JPEG
image that happens to be stored in a field of a table, you could run:

sqlite&gt; UPDATE pics SET img=edit(img,'gimp') WHERE id='pic-1542';


The edit program can also be used as a viewer, by simply ignoring the
return value.  For example, to merely look at the image above, you might run:

sqlite&gt; SELECT length(edit(img,'gimp')) WHERE id='pic-1542';





7. Querying the database schema

The sqlite3 program provides several convenience commands that
are useful for looking at the schema of the database.  There is
nothing that these commands do that cannot be done by some other
means.  These commands are provided purely as a shortcut.



For example, to see a list of the tables in the database, you
can enter ".tables".


sqlite&gt; .tables
tbl1
tbl2
sqlite&gt;



The ".tables" command is similar to setting list mode then
executing the following query:

SELECT name FROM sqlite_schema 
WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'
ORDER BY 1


But the ".tables" command does more.  It queries the sqlite_schema table
for all attached databases, not just the primary database.  And it arranges
its output into neat columns.

The ".indexes" command works in a similar way to list all of
the indexes. If the ".indexes" command is given an argument which is
the name of a table, then it shows just indexes on that table.



The ".schema" command shows the complete schema for the database,
or for a single table if an optional tablename argument is provided:

sqlite&gt; .schema
create table tbl1(one varchar(10), two smallint)
CREATE TABLE tbl2 (
  f1 varchar(30) primary key,
  f2 text,
  f3 real
)
sqlite&gt; .schema tbl2
CREATE TABLE tbl2 (
  f1 varchar(30) primary key,
  f2 text,
  f3 real
)
sqlite&gt;



The ".schema" command is roughly the same as setting
list mode, then entering the following query:

SELECT sql FROM sqlite_schema
ORDER BY tbl_name, type DESC, name


As with ".tables", the ".schema" command shows the schema for
all attached databases.  If you only want to see the schema for
a single database (perhaps "main") then you can add an argument
to ".schema" to restrict its output:

sqlite&gt; .schema main.*


The ".schema" command can be augmented with the "--indent" option,
in which case it tries to reformat the various CREATE statements of
the schema so that they are more easily readable by humans.

The ".databases" command shows a list of all databases open in
the current connection.  There will always be at least 2.  The first
one is "main", the original database opened.  The second is "temp",
the database used for temporary tables. There may be additional 
databases listed for databases attached using the ATTACH statement.
The first output column is the name the database is attached with, 
and the second column is the filename of the external file.

sqlite&gt; .databases




The ".fullschema" dot-command works like the ".schema" command in
that it displays the entire database schema.  But ".fullschema" also
includes dumps of the statistics tables "sqlite_stat1", "sqlite_stat3",
and "sqlite_stat4", if they exist.  The ".fullschema" command normally
provides all of the information needed to exactly recreate a query
plan for a specific query.  When reporting suspected problems with
the SQLite query planner to the SQLite development team, developers
are requested to provide the complete ".fullschema" output as part
of the trouble report.  Note that the sqlite_stat3 and sqlite_stat4
tables contain samples of index entries and so might contain sensitive
data, so do not send the ".fullschema" output of a proprietary database
over a public channel.



8. CSV Import

Use the ".import" command to import CSV (comma separated value) data into
an SQLite table.  The ".import" command takes two arguments which are the
name of the disk file from which CSV data is to be read and the name of the
SQLite table into which the CSV data is to be inserted.

Note that it is important to set the "mode" to "csv" before running the
 ".import" command.  This is necessary to prevent the command-line shell
from trying to interpret the input file text as some other format.

sqlite&gt; .import C:/work/somedata.csv tab1


There are two cases to consider:  (1) Table "tab1" does not previously
exist and (2) table "tab1" does already exist.

In the first case, when the table does not previously exist, the table is
automatically created and the content of the first row of the input CSV
file is used to determine the name of all the columns in the table.  In
other words, if the table does not previously exist, the first row of the
CSV file is interpreted to be column names and the actual data starts on
the second row of the CSV file.

For the second case, when the table already exists, every row of the
CSV file, including the first row, is assumed to be actual content.  If
the CSV file contains an initial row of column labels, you can cause
the .import command to skip that initial row using the "--skip 1" option.





9. CSV Export

To export an SQLite table (or part of a table) as CSV, simply set
the "mode" to "csv" and then run a query to extract the desired rows
of the table.

sqlite&gt; .headers on
sqlite&gt; .mode csv
sqlite&gt; .once c:/work/dataout.csv
sqlite&gt; SELECT * FROM tab1;
sqlite&gt; .system c:/work/dataout.csv


In the example above, the ".headers on" line causes column labels to
be printed as the first row of output.  This means that the first row of
the resulting CSV file will contain column labels.  If column labels are
not desired, set ".headers off" instead. (The ".headers off" setting is
the default and can be omitted if the headers have not been previously
turned on.)

The line ".once FILENAME" causes all query output to go into
the named file instead of being printed on the console.  In the example
above, that line causes the CSV content to be written into a file named
"C:/work/dataout.csv".

The final line of the example (the ".system c:/work/dataout.csv")
has the same effect as double-clicking on the c:/work/dataout.csv file
in windows.  This will typically bring up a spreadsheet program to display
the CSV file.

That command only works as written on Windows.  
The equivalent line on a Mac would be:

sqlite&gt; .system open dataout.csv


On Linux and other unix systems you will need to enter something like:


sqlite&gt; .system xdg-open dataout.csv




9.1.  Export to Excel 

To simplify export to a spreadsheet, the CLI provides the
".excel" command which captures the output of a single query and sends
that output to the default spreadsheet program on the host computer.
Use it like this:

sqlite&gt; .excel
sqlite&gt; SELECT * FROM tab;



The command above writes the output of the query as CSV into a temporary
file, invokes the default handler for CSV files (usually the preferred
spreadsheet program such as Excel or LibreOffice), then deletes the
temporary file.  This is essentially a short-hand method of doing
the sequence of ".csv", ".once", and ".system" commands described above.


The ".excel" command is really an alias for ".once -x".  The -x option
to .once causes it to writes results as CSV into a temporary file that
is named with a ".csv" suffix, then invoke the systems default handler
for CSV files.


There is also a ".once -e" command which works similarly, except that
it names the temporary file with a ".txt" suffix so that the default
text editor for the system will be invoked, instead of the default
spreadsheet.



10. Accessing ZIP Archives As Database Files

In addition to reading and writing SQLite database files,
the sqlite3 program will also read and write ZIP archives.
Simply specify a ZIP archive filename in place of an SQLite database
filename on the initial command line, or in the ".open" command,
and sqlite3 will automatically detect that the file is a
ZIP archive instead of an SQLite database and will open it as such.
This works regardless of file suffix.  So you can open JAR, DOCX,
and ODP files and any other file format that is really a ZIP
archive and SQLite will read it for you.

A ZIP archive appears to be a database containing a single table
with the following schema:

CREATE TABLE zip(
  name,     // Name of the file
  mode,     // Unix-style file permissions
  mtime,    // Timestamp, seconds since 1970
  sz,       // File size after decompression
  rawdata,  // Raw compressed file data
  data,     // Uncompressed file content
  method    // ZIP compression method code
);


So, for example, if you wanted to see the compression efficiency
(expressed as the size of the compressed content relative to the
original uncompressed file size) for all files in the ZIP archive,
sorted from most compressed to least compressed, you could run a
query like this:

sqlite&gt; SELECT name, (100.0*length(rawdata))/sz FROM zip ORDER BY 2;


Or using file I/O functions, you can extract elements of the
ZIP archive:

sqlite&gt; SELECT writefile(name,content) FROM zip
   ...&gt; WHERE name LIKE 'docProps/%';


10.1. How ZIP archive access is implemented

The command-line shell uses the Zipfile virtual table to
access ZIP archives.  You can see this by running the ".schema"
command when a ZIP archive is open:

sqlite&gt; .schema
CREATE VIRTUAL TABLE zip USING zipfile('document.docx')
/* zip(name,mode,mtime,sz,rawdata,data,method) */;


When opening a file, if the command-line client discovers that the
file is ZIP archive instead of an SQLite database, it actually opens
an in-memory database and then in that in-memory database it creates
an instance of the Zipfile virtual table that is attached to the
ZIP archive.

The special processing for opening ZIP archives is a trick of the
command-line shell, not the core SQLite library.  So if you want to
open a ZIP archive as a database in your application, you will need to
activate the Zipfile virtual table module then run an appropriate
CREATE VIRTUAL TABLE statement.




11. Converting An Entire Database To An ASCII Text File

Use the ".dump" command to convert the entire contents of a
database into a single ASCII text file.  This file can be converted
back into a database by piping it back into sqlite3.

A good way to make an archival copy of a database is this:


$ sqlite3 ex1 .dump | gzip -c &gt;ex1.dump.gz



This generates a file named ex1.dump.gz that contains everything
you need to reconstruct the database at a later time, or on another
machine.  To reconstruct the database, just type:


$ zcat ex1.dump.gz | sqlite3 ex2



The text format is pure SQL so you
can also use the .dump command to export an SQLite database
into other popular SQL database engines.  Like this:


$ createdb ex2
$ sqlite3 ex1 .dump | psql ex2




12. Recover Data From a Corrupted Database

Like the ".dump" command, ".recover" attempts to convert the entire 
contents of a database file to text. The difference is that instead of
reading data using the normal SQL database interface, ".recover"
attempts to reassemble the database based on data extracted directly from 
as many database pages as possible. If the database is corrupt, ".recover"
is usually able to recover data from all uncorrupted parts of the database,
whereas ".dump" stops when the first sign of corruption is encountered.

If the ".recover" command recovers one or more rows that it cannot 
attribute to any database table, the output script creates a "lost_and_found"
table to store the orphaned rows. The schema of the lost_and_found
table is as follows:

CREATE TABLE lost_and_found(
    rootpgno INTEGER,             -- root page of tree pgno is a part of
    pgno INTEGER,                 -- page number row was found on
    nfield INTEGER,               -- number of fields in row
    id INTEGER,                   -- value of rowid field, or NULL
    c0, c1, c2, c3...             -- columns for fields of row
);


The "lost_and_found" table contains one row for each orphaned row recovered
from the database. Additionally, there is one row for each recovered index
entry that cannot be attributed to any SQL index. This is because, in an
SQLite database, the same format is used to store SQL index entries and
WITHOUT ROWID table entries.


  ColumnContents
  rootpgno Even though it may not be possible to attribute the 
      row to a specific database table, it may be part of a tree structure
      within the database file. In this case, the root page number of that
      tree structure is stored in this column. Or, if the page the row was
      found on is not part of a tree structure, this column stores a copy of
      the value in column "pgno" - the page number of the page the row was
      found on. In many, although not all, cases, all rows in the
      lost_and_found table with the same value in this column belong to the
      same table.

  pgno The page number of the page on which this row was found.

  nfield The number of fields in this row.

  id If the row comes from a WITHOUT ROWID table, this column 
      contains NULL. Otherwise, it contains the 64-bit integer rowid value for
      the row.

  c0,&nbsp;c1,&nbsp;c2... The values for each column of the row
      are stored in these columns. The ".recover" command creates the
      lost_and_found table with as many columns as required by the longest
      orphaned row.


If the recovered database schema already contains a table named
"lost_and_found", the ".recover" command uses the name "lost_and_found0". If
the name "lost_and_found0" is also already taken, "lost_and_found1", and so
on. The default name "lost_and_found" may be overridden by invoking ".recover"
with the --lost-and-found switch. For example, to have the output script call
the table "orphaned_rows":

sqlite&gt; .recover --lost-and-found orphaned_rows




13. Loading Extensions

You can add new custom application-defined SQL functions,
collating sequences, virtual tables, and VFSes to the command-line
shell at run-time using the ".load" command.  First, convert the
extension in to a DLL or shared library (as described in the
Run-Time Loadable Extensions document) then type:

sqlite&gt; .load /path/to/my_extension


Note that SQLite automatically adds the appropriate extension suffix
(".dll" on windows, ".dylib" on Mac, ".so" on most other unixes) to the
extension filename.  It is generally a good idea to specify the full
pathname of the extension.

SQLite computes the entry point for the extension based on the extension
filename.  To override this choice, simply add the name of the extension
as a second argument to the ".load" command.

Source code for several useful extensions can be found in the
ext/misc
subdirectory of the SQLite source tree.  You can use these extensions
as-is, or as a basis for creating your own custom extensions to address
your own particular needs.




14. Cryptographic Hashes Of Database Content

The ".sha3sum" dot-command computes a
SHA3 hash of the content
of the database.  To be clear, the hash is computed over the database content,
not its representation on disk.  This means, for example, that a VACUUM
or similar data-preserving transformation does not change the hash.

The ".sha3sum" command supports options "--sha3-224", "--sha3-256", 
"--sha3-384", and "--sha3-512" to define which variety of SHA3 to use
for the hash.  The default is SHA3-256.

The database schema (in the sqlite_schema table) is not normally
included in the hash, but can be added by the "--schema" option.

The ".sha3sum" command takes a single optional argument which is a
LIKE pattern.  If this option is present, only tables whose names match
the LIKE pattern will be hashed.

The ".sha3sum" command is implemented with the help of the
extension function "sha3_query()"
that is included with the command-line shell.



15. Database Content Self-Tests

The ".selftest" command attempts to verify that a database is
intact and is not corrupt.  
The .selftest command looks for a table in schema named "selftest"
and defined as follows:

CREATE TABLE selftest(
  tno INTEGER PRIMARY KEY,  -- Test number
  op TEXT,                  -- 'run' or 'memo'
  cmd TEXT,                 -- SQL command to run, or text of "memo"
  ans TEXT                  -- Expected result of the SQL command
);


The .selftest command reads the rows of the selftest table in
selftest.tno order.
For each 'memo' row, it writes the text in 'cmd' to the output.  For
each 'run' row, it runs the 'cmd' text as SQL and compares the result
to the value in 'ans', and shows an error message if the results differ.

If there is no selftest table, the ".selftest" command runs
PRAGMA integrity_check.

The ".selftest --init" command creates the selftest table if it
does not already exists, then appends entries that check the SHA3
hash of the content of all tables.  Subsequent runs of ".selftest"
will verify that the database has not been changed in any way.  To
generates tests to verify that a subset of the tables are unchanged,
simply run ".selftest --init" then DELETE the selftest rows that
refer to tables that are not constant.  



16. SQLite Archive Support

The ".archive" dot-command and the "-A" command-line option
provide built-in support for the 
SQLite Archive format. The interface is similar to
that of the "tar" command on unix systems. Each invocation of the ".ar"
command must specify a single command option. The following commands
are available for ".archive":


  OptionLong&nbsp;OptionPurpose
  -c--createCreate a new archive containing specified files.
  -x--extractExtract specified files from archive.
  -i--insertAdd files to existing archive.
  -t--listList the files in the archive.
  -u--updateAdd files to existing archive if they have changed.


As well as the command option, each invocation of ".ar" may specify
one or more modifier options. Some modifier options require an argument,
some do not. The following modifier options are available:


  OptionLong&nbsp;OptionPurpose
  -v--verboseList each file as it is processed.
  -f FILE--file FILEIf specified, use file FILE as the
  archive. Otherwise, assume that the current "main" database is the 
  archive to be operated on.
  -a FILE--append FILELike --file, use file FILE as the
  archive, but open the file using the 
  apndvfs VFS so that
  the archive will be appended to the end of FILE if FILE already exists.
  -C DIR--directory DIRIf specified, interpret all relative
  paths as relative to DIR, instead of the current working directory.
  -n--dryrunShow the SQL that would be run to carry out the
                       archive operation, but do not actually change anything.
  ----All subsequent command line words are command arguments,
  not options.



For command-line usage, add the short style command-line options immediately
following the "-A", without an intervening space.  All subsequent arguments
are considered to be part of the .archive command.  For example, the following 
commands are equivalent:

sqlite3 new_archive.db -Acv file1 file2 file3
sqlite3 new_archive.db ".ar -cv file1 file2 file3"



Long and short style options may be mixed. For example, the following are
equivalent:

-- Two ways to create a new archive named "new_archive.db" containing
-- files "file1", "file2" and "file3".
.ar -c --file new_archive.db file1 file2 file3
.ar -f new_archive.db --create file1 file2 file3


Alternatively, the first argument following to ".ar" may be the concatenation
of the short form of all required options (without the "-" characters). In 
this case arguments for options requiring them are read from the command line
next, and any remaining words are considered command arguments. For example:

-- Create a new archive "new_archive.db" containing files "file1" and
-- "file2" from directory "dir1".
.ar cCf dir1 new_archive.db file1 file2 file3


16.1.  SQLite Archive Create Command 

Create a new archive, overwriting any existing archive (either in the current
"main" db or in the file specified by a --file option). Each argument following
the options is a file to add to the archive. Directories are imported
recursively. See above for examples.

16.2.  SQLite Archive Extract Command 

Extract files from the archive (either to the current working directory or
to the directory specified by a --directory option). If there are no arguments
following the options all files are extracted from the archive. Or, if there
are arguments, they are the names of files to extract from the archive. Any
specified directories are extracted recursively. It is an error if any
specified files are not part of the archive.

-- Extract all files from the archive in the current "main" db to the
-- current working directory. List files as they are extracted. 
.ar --extract --verbose

-- Extract file "file1" from archive "ar.db" to directory "dir1".
.ar fCx ar.db dir1 file1


16.3.  SQLite Archive List Command 

List the contents of the archive. If no arguments are specified, then all
files are listed. Otherwise, only those specified as arguments are. Currently,
the --verbose option does not change the behaviour of this command. That may
change in the future.

-- List contents of archive in current "main" db..
.ar --list




16.4.  SQLite Archive Insert And Update Commands 

 The --update and --insert commands work like --create command, except that 
they do not delete the current archive before commencing. New versions of
files silently replace existing files with the same names, but otherwise
the initial contents of the archive (if any) remain intact.

 For the --insert command, all files listed are inserted into the archive.
For the --update command, files are only inserted if they do not previously
exist in the archive, or if their "mtime" or "mode" is different from what
is currently in the archive.

 Compatibility node:  Prior to SQLite version 3.28.0 (2019-04-16) only
the --update option was supported but that option worked like --insert in that
it always reinserted every file regardless of whether or not it had changed.

16.5.  Operations On ZIP Archives 

If FILE is a ZIP archive rather than an SQLite Archive, the ".archive"
command and the "-A" command-line option still work.  This is accomplished
using of the zipfile extension.
Hence, the following commands are roughly equivalent,
differing only in output formatting:


  Traditional CommandEquivalent sqlite3.exe Command
  unzip archive.zipsqlite3 -Axf archive.zip
  unzip -l archive.zipsqlite3 -Atvf archive.zip
  zip -r archive2.zip dirsqlite3 -Acf archive2.zip dir


16.6.  SQL Used To Implement SQLite Archive Operations 

The various SQLite Archive Archive commands are implemented using SQL statements.
Application developers can easily add SQLite Archive Archive reading and writing
support to their own projects by running the appropriate SQL.

To see what SQL statements are used to implement an SQLite Archive
operation, add the --dryrun or -n option.  This causes the SQL to be
displayed but inhibits the execution of the SQL.

The SQL statements used to implement SQLite Archive operations make use of
various loadable extensions.  These extensions are all available in
the SQLite source tree in the
ext/misc/ subfolder.
The extensions needed for full SQLite Archive support include:



fileio.c &mdash;
This extension adds SQL functions readfile() and writefile() for
reading and writing content from files on disk.  The fileio.c
extension also includes fsdir() table-valued function for listing
the contents of a directory and the lsname() function for converting
numeric st_mode integers from the stat() system call into human-readable
strings after the fashion of the "ls -l" command.


sqlar.c &mdash;
This extension adds the sqlar_compress() and sqlar_uncompress()
functions that are needed to compress and uncompress file content
as it is insert and extracted from an SQLite Archive.


zipfile.c &mdash;
This extension implements the "zipfile(FILE)" table-valued function
which is used to read ZIP archives.  This extension is only needed
when reading ZIP archives instead of SQLite archives.


appendvfs.c &mdash;
This extension implements a new VFS that allows an SQLite database
to be appended to some other file, such as an executable.  This
extension is only needed if the --append option to the .archive
command is used.




17. SQL Parameters

SQLite allows bound parameters to appear in an SQL statement anywhere
that a literal value is allowed.  The values for these parameters are set
using the sqlite3_bind_...() family of APIs.

Parameters can be either named or unnamed.  An unnamed parameter is a single
question mark ("?").  Named parameters are a "?" followed immediately by a number
(ex: "?15" or "?123") or one of the characters "$", ":", or "@" followed by an
alphanumeric name (ex: "$var1", ":xyz", "@bingo").

This command-line shell leaves unnamed parameters unbound, meaning that they
will have a value of an SQL NULL, but named parameters might be assigned values.
If there exists a TEMP table named "sqlite_parameters" with a schema like this:

CREATE TEMP TABLE sqlite_parameters(
  key TEXT PRIMARY KEY,
  value ANY
) WITHOUT ROWID;


And if there is an entry in that table where the key column exactly matches
the name of parameter (including the initial "?", "$", ":", or "@" character)
then the parameter is assigned the value of the value column.  If no entry exists,
the parameter defaults to NULL.

The ".parameter" command exists to simplify managing this table.  The
".parameter init" command (often abbreviated as just ".param init") creates
the temp.sqlite_parameters table if it does not already exist.  The ".param list"
command shows all entries in the temp.sqlite_parameters table.  The ".param clear"
command drops the temp.sqlite_parameters table.  The ".param set KEY VALUE" and
".param unset KEY" commands create or delete entries from the 
temp.sqlite_parameters table.

The temp.sqlite_parameters table only provides values for parameters in the
command-line shell.  The temp.sqlite_parameter table has no effect on queries
that are run directly using the SQLite C-language API.  Individual applications
are expected to implement their own parameter binding.  You can search for 
"sqlite_parameters" in the 
command-line shell source code
to see how the command-line shell does parameter binding, and use that as
a hint for how to implement it yourself.



18. Index Recommendations (SQLite Expert)

Note: This command is experimental. It may be removed or the 
interface modified in incompatible ways at some point in the future.

For most non-trivial SQL databases, the key to performance is creating
the right SQL indexes. In this context "the right SQL indexes" means those
that cause the queries that an application needs to optimize run fast. The
".expert" command can assist with this by proposing indexes that might
assist with specific queries, were they present in the database.

The ".expert" command is issued first, followed by the SQL query 
on a separate line. For example, consider the following session:

sqlite&gt; CREATE TABLE x1(a, b, c);                  -- Create table in database 
sqlite&gt; .expert
sqlite&gt; SELECT * FROM x1 WHERE a=? AND b&gt;?;        -- Analyze this SELECT 
CREATE INDEX x1_idx_000123a7 ON x1(a, b);

0|0|0|SEARCH TABLE x1 USING INDEX x1_idx_000123a7 (a=? AND b&gt;?)

sqlite&gt; CREATE INDEX x1ab ON x1(a, b);             -- Create the recommended index 
sqlite&gt; .expert
sqlite&gt; SELECT * FROM x1 WHERE a=? AND b&gt;?;        -- Re-analyze the same SELECT 
(no new indexes)

0|0|0|SEARCH TABLE x1 USING INDEX x1ab (a=? AND b&gt;?)


In the above, the user creates the database schema (a single table - "x1"),
and then uses the ".expert" command to analyze a query, in this case 
"SELECT * FROM x1 WHERE a=? AND b&gt;?". The shell tool recommends that the
user create a new index (index "x1_idx_000123a7") and outputs the plan
that the query would use in EXPLAIN QUERY PLAN format. The user then creates
an index with an equivalent schema and runs the analysis on the same query
again. This time the shell tool does not recommend any new indexes, and 
outputs the plan that SQLite will use for the query given the existing 
indexes.

The ".expert" command accepts the following options:


 Option  Purpose
 --verbose 
     If present, output a more verbose report for each query analyzed.
 --sample&nbsp;PERCENT 
     By default, the ".expert" command recommends indexes based on the
         query and database schema alone. This is similar to the way the
         SQLite query planner selects indexes for queries if the user has not
         run the ANALYZE command on the database to generate data
         distribution statistics. 
         
         If this option is passed a non-zero argument, the ".expert" command
         generates similar data distribution statistics for all indexes
         considered based on PERCENT percent of the rows currently stored in
         each database table. For databases with unusual data distributions,
         this may lead to better index recommendations, particularly if the
         application intends to run ANALYZE.
         
         For small databases and modern CPUs, there is usually no reason not
         to pass "--sample 100". However, gathering data distribution
         statistics can be expensive for large database tables. If the
         operation is too slow, try passing a smaller value for the --sample
         option.


Th functionality described in this section may be integrated into other
applications or tools using the 

SQLite expert extension code.



19. Other Dot Commands

There are many other dot-commands available in the command-line
shell.  See the ".help" command for a complete list for any particular
version and build of SQLite.



20. Using sqlite3 in a shell script


One way to use sqlite3 in a shell script is to use "echo" or
"cat" to generate a sequence of commands in a file, then invoke sqlite3
while redirecting input from the generated command file.  This
works fine and is appropriate in many circumstances.  But as
an added convenience, sqlite3 allows a single SQL command to be
entered on the command line as a second argument after the
database name.  When the sqlite3 program is launched with two
arguments, the second argument is passed to the SQLite library
for processing, the query results are printed on standard output
in list mode, and the program exits.  This mechanism is designed
to make sqlite3 easy to use in conjunction with programs like
"awk".  For example:

$ sqlite3 ex1 'select * from tbl1' |
&gt;  awk '{printf "&lt;tr&gt;&lt;td&gt;%s&lt;td&gt;%s\n",$1,$2 }'
&lt;tr&gt;&lt;td&gt;hello&lt;td&gt;10
&lt;tr&gt;&lt;td&gt;goodbye&lt;td&gt;20
$




21. Ending shell commands


SQLite commands are normally terminated by a semicolon.  In the shell 
you can also use the word "GO" (case-insensitive) or a slash character 
"/" on a line by itself to end a command.  These are used by SQL Server 
and Oracle, respectively.  These won't work in sqlite3_exec(), 
because the shell translates these into a semicolon before passing them 
to that function.




22. Compiling the sqlite3 program from sources


To compile the command-line shell on unix systems and on Windows with MinGW,
the usual configure-make command works:

sh configure; make



The configure-make works whether your are building from the canonical sources
from the source tree, or from an amalgamated bundle.  There are few
dependencies.  When building from canonical sources, a working 
tclsh is required.
If using an amalgamation bundle, all the preprocessing work normally 
done by tclsh will have already been carried out and only normal build
tools are required.


A working zlib compression library is
needed in order for the .archive command to operate.


On Windows with MSVC, use nmake with the Makefile.msc:

nmake /f Makefile.msc



For correct operation of the .archive command, make a copy of the
zlib source code into the compat/zlib subdirectory 
of the source tree and compile this way:

nmake /f Makefile.msc USE_ZLIB=1


22.1.  Do-It-Yourself Builds 


The source code to the sqlite3 command line interface is in a single
file named "shell.c".  The shell.c source file is generated from other
sources, but most of the code for shell.c can be found in
src/shell.c.in.
(Regenerate shell.c by typing "make shell.c" from the canonical source tree.)
Compile the shell.c file (together
with the sqlite3 library source code) to generate
the executable.  For example:

gcc -o sqlite3 shell.c sqlite3.c -ldl -lpthread -lz -lm



The following additional compile-time options are recommended in order to
provide a full-featured command-line shell:


 -DSQLITE_THREADSAFE=0
 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
 -DSQLITE_HAVE_ZLIB
 -DSQLITE_INTROSPECTION_PRAGMAS
 -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
 -DSQLITE_ENABLE_STMTVTAB
 -DSQLITE_ENABLE_DBPAGE_VTAB
 -DSQLITE_ENABLE_DBSTAT_VTAB
 -DSQLITE_ENABLE_OFFSET_SQL_FUNC
 -DSQLITE_ENABLE_JSON1
 -DSQLITE_ENABLE_RTREE
 -DSQLITE_ENABLE_FTS4
 -DSQLITE_ENABLE_FTS5


c2: SQLite Copyright Release Template
c5: copyright-release.html
c4:
Copyright Release for
Contributions To SQLite



SQLite is software that implements an embeddable SQL database engine.
SQLite is available for free download from http://www.sqlite.org/.
The principal author and maintainer of SQLite has disclaimed all
copyright interest in his contributions to SQLite
and thus released his contributions into the public domain.
In order to keep the SQLite software unencumbered by copyright
claims, the principal author asks others who may from time to
time contribute changes and enhancements to likewise disclaim
their own individual copyright interest.



Because the SQLite software found at http://www.sqlite.org/ is in the
public domain, anyone is free to download the SQLite software
from that website, make changes to the software, use, distribute,
or sell the modified software, under either the original name or
under some new name, without any need to obtain permission, pay
royalties, acknowledge the original source of the software, or
in any other way compensate, identify, or notify the original authors.  
Nobody is in any way compelled to contribute their SQLite changes and 
enhancements back to the SQLite website.  This document concerns
only changes and enhancements to SQLite that are intentionally and
deliberately contributed back to the SQLite website.  



For the purposes of this document, "SQLite software" shall mean any
computer source code, documentation, makefiles, test scripts, or
other information that is published on the SQLite website, 
http://www.sqlite.org/.  Precompiled binaries are excluded from
the definition of "SQLite software" in this document because the
process of compiling the software may introduce information from
outside sources which is not properly a part of SQLite.



The header comments on the SQLite source files exhort the reader to
share freely and to never take more than one gives.
In the spirit of that exhortation I make the following declarations:




I dedicate to the public domain 
any and all copyright interest in the SQLite software that
was publicly available on the SQLite website (http://www.sqlite.org/) prior
to the date of the signature below and any changes or enhancements to
the SQLite software 
that I may cause to be published on that website in the future.
I make this dedication for the benefit of the public at large and
to the detriment of my heirs and successors.  I intend this
dedication to be an overt act of relinquishment in perpetuity of
all present and future rights to the SQLite software under copyright
law.



To the best of my knowledge and belief, the changes and enhancements that
I have contributed to SQLite are either originally written by me
or are derived from prior works which I have verified are also
in the public domain and are not subject to claims of copyright
by other parties.



To the best of my knowledge and belief, no individual, business, organization,
government, or other entity has any copyright interest
in the SQLite software as it existed on the
SQLite website as of the date on the signature line below.



I agree never to publish any additional information
to the SQLite website (by CVS, email, scp, FTP, or any other means) unless
that information is an original work of authorship by me or is derived from 
prior published versions of SQLite.
I agree never to copy and paste code into the SQLite code base from
other sources.
I agree never to publish on the SQLite website any information that
would violate a law or breach a contract.







Signature:
&nbsp;
&nbsp;
&nbsp;

Date:


Name (printed):


c2: The SQLite Query Optimizer Overview
c5: optoverview.html
c4:
1. Introduction

  This document provides an overview of how the query planner and optimizer
  for SQLite works.



  Given a single SQL statement, there might be dozens, hundreds, or even
  thousands of ways to implement that statement, depending on the complexity
  of the statement itself and of the underlying database schema.  The 
  task of the query planner is to select an algorithm from among the many
  choices that provides the answer with a minimum of disk I/O and CPU
  overhead.



  Additional background information is available in the
  indexing tutorial document.



  With release 3.8.0 (2013-08-26),
  the SQLite query planner was reimplemented as the
  Next Generation Query Planner or "NGQP".  All of the features, techniques,
  and algorithms described in this document are applicable to both the
  pre-3.8.0 legacy query planner and to the NGQP.  For further information on
  how the NGQP differs from the legacy query planner, see the 
  detailed description of the NGQP.






2. WHERE clause analysis


  The WHERE clause on a query is broken up into "terms" where each term
  is separated from the others by an AND operator.
  If the WHERE clause is composed of constraints separate by the OR
  operator then the entire clause is considered to be a single "term"
  to which the OR-clause optimization is applied.


  All terms of the WHERE clause are analyzed to see if they can be
  satisfied using indices.
  To be usable by an index a term must be of one of the following
  forms:


  column = expression
  column IS expression
  column &gt; expression
  column &gt;= expression
  column &lt; expression
  column &lt;= expression
  expression = column
  expression &gt; column
  expression &gt;= column
  expression &lt; column
  expression &lt;= column
  column IN (expression-list)
  column IN (subquery)
  column IS NULL



  If an index is created using a statement like this:

CREATE INDEX idx_ex1 ON ex1(a,b,c,d,e,...,y,z);



  Then the index might be used if the initial columns of the index
  (columns a, b, and so forth) appear in WHERE clause terms.
  The initial columns of the index must be used with
  the *=* or *IN* or *IS* operators.  
  The right-most column that is used can employ inequalities.  
  For the right-most
  column of an index that is used, there can be up to two inequalities
  that must sandwich the allowed values of the column between two extremes.


  It is not necessary for every column of an index to appear in a
  WHERE clause term in order for that index to be used. 
  But there cannot be gaps in the columns of the index that are used.
  Thus for the example index above, if there is no WHERE clause term
  that constraints column c, then terms that constrain columns a and b can
  be used with the index but not terms that constraint columns d through z.
  Similarly, index columns will not normally be used (for indexing purposes)
  if they are to the right of a 
  column that is constrained only by inequalities.
  (See the skip-scan optimization below for the exception.)


  In the case of indexes on expressions, whenever the word "column" is
  used in the foregoing text, one can substitute "indexed expression"
  (meaning a copy of the expression that appears in the CREATE INDEX
  statement) and everything will work the same.



2.1. Index term usage examples

  For the index above and WHERE clause like this:

... WHERE a=5 AND b IN (1,2,3) AND c IS NULL AND d='hello'


  The first four columns a, b, c, and d of the index would be usable since
  those four columns form a prefix of the index and are all bound by
  equality constraints.


  For the index above and WHERE clause like this:

... WHERE a=5 AND b IN (1,2,3) AND c>12 AND d='hello'


  Only columns a, b, and c of the index would be usable.  The d column
  would not be usable because it occurs to the right of c and c is
  constrained only by inequalities.


  For the index above and WHERE clause like this:

... WHERE a=5 AND b IN (1,2,3) AND d='hello'


  Only columns a and b of the index would be usable.  The d column
  would not be usable because column c is not constrained and there can
  be no gaps in the set of columns that usable by the index.


  For the index above and WHERE clause like this:

... WHERE b IN (1,2,3) AND c NOT NULL AND d='hello'


  The index is not usable at all because the left-most column of the
  index (column "a") is not constrained.  Assuming there are no other
  indices, the query above would result in a full table scan.


  For the index above and WHERE clause like this:

... WHERE a=5 OR b IN (1,2,3) OR c NOT NULL OR d='hello'


  The index is not usable because the WHERE clause terms are connected
  by OR instead of AND. This query would result in a full table scan.
  However, if three additional indices where added that contained columns
  b, c, and d as their left-most columns, then the
  OR-clause optimization might apply.




3. The BETWEEN optimization


  If a term of the WHERE clause is of the following form:


  expr1 BETWEEN expr2 AND expr3


  Then two "virtual" terms are added as follows:


  expr1 &gt;= expr2 AND expr1 &lt;= expr3


  Virtual terms are used for analysis only and do not cause any byte-code
  to be generated.
  If both virtual terms end up being used as constraints on an index,
  then the original BETWEEN term is omitted and the corresponding test
  is not performed on input rows.
  Thus if the BETWEEN term ends up being used as an index constraint
  no tests are ever performed on that term.
  On the other hand, the
  virtual terms themselves never causes tests to be performed on
  input rows.
  Thus if the BETWEEN term is not used as an index constraint and
  instead must be used to test input rows, the expr1 expression is
  only evaluated once.



4. OR optimizations


  WHERE clause constraints that are connected by OR instead of AND can
  be handled in two different ways.
  If a term consists of multiple subterms containing a common column
  name and separated by OR, like this:


  column = expr1 OR column = expr2 OR column = expr3 OR ...


  Then that term is rewritten as follows:


  column IN (expr1,expr2,expr3,...)


  The rewritten term then might go on to constrain an index using the
  normal rules for *IN* operators.  Note that column must be
  the same column in every OR-connected subterm,
  although the column can occur on either the left or the right side of
  the *=* operator.


  If and only if the previously described conversion of OR to an IN operator
  does not work, the second OR-clause optimization is attempted.
  Suppose the OR clause consists of multiple subterms as follows:


  expr1 OR expr2 OR expr3


  Individual subterms might be a single comparison expression like
  *a=5* or *x>y* or they can be LIKE or BETWEEN expressions, or a subterm
  can be a parenthesized list of AND-connected sub-subterms.
  Each subterm is analyzed as if it were itself the entire WHERE clause
  in order to see if the subterm is indexable by itself.
  If every subterm of an OR clause is separately indexable
  then the OR clause might be coded such that a separate index is used
  to evaluate each term of the OR clause.  One way to think about how
  SQLite uses separate indices for each OR clause term is to imagine
  that the WHERE clause where rewritten as follows:


  rowid IN (SELECT rowid FROM table WHERE expr1
            UNION SELECT rowid FROM table WHERE expr2
            UNION SELECT rowid FROM table WHERE expr3)


  The rewritten expression above is conceptual; WHERE clauses containing
  OR are not really rewritten this way.
  The actual implementation of the OR clause uses a mechanism that is
  more efficient and that works even for WITHOUT ROWID tables or 
  tables in which the "rowid" is inaccessible.
  But the essence of the implementation is captured by the statement
  above:  Separate indices are used to find candidate result rows
  from each OR clause term and the final result is the union of
  those rows.


  Note that in most cases, SQLite will only use a single index for each
  table in the FROM clause of a query.  The second OR-clause optimization
  described here is the exception to that rule.  With an OR-clause,
  a different index might be used for each subterm in the OR-clause.


  For any given query, the fact that the OR-clause optimization described
  here can be used does not guarantee that it will be used.
  SQLite uses a cost-based query planner that estimates the CPU and
  disk I/O costs of various competing query plans and chooses the plan
  that it thinks will be the fastest.  If there are many OR terms in
  the WHERE clause or if some of the indices on individual OR-clause 
  subterms are not very selective, then SQLite might decide that it is
  faster to use a different query algorithm, or even a full-table scan.
  Application developers can use the
  EXPLAIN QUERY PLAN prefix on a statement to get a
  high-level overview of the chosen query strategy.



5. The LIKE optimization


  A WHERE-clause term that uses the LIKE or GLOB operator
  can sometimes be used with an index to do a range search, 
  almost as if the LIKE or GLOB were an alternative to a BETWEEN
  operator.
  There are many conditions on this optimization:


  
  The right-hand side of the LIKE or GLOB must be either a string literal
      or a parameter bound to a string literal
      that does not begin with a wildcard character.
  It must not be possible to make the LIKE or GLOB operator true by
      having a numeric value (instead of a string or blob) on the
      left-hand side. This means that either:
      
       the left-hand side of the LIKE or GLOB operator is the name
           of an indexed column with TEXT affinity, or
       the right-hand side pattern argument does not begin with a
           minus sign ("-") or a digit.
      
      This constraint arises from the fact that numbers do not sort in
      lexicographical order.  For example: 9&lt;10 but '9'&gt;'10'.
  The built-in functions used to implement LIKE and GLOB must not
      have been overloaded using the sqlite3_create_function() API.
  For the GLOB operator, the column must be indexed using the 
      built-in BINARY collating sequence.
  For the LIKE operator, if case_sensitive_like mode is enabled then
      the column must indexed using BINARY collating sequence, or if
      case_sensitive_like mode is disabled then the column must indexed
      using built-in NOCASE collating sequence.
  If the ESCAPE option is used, the ESCAPE character must be ASCII,
      or a single-byte character in UTF-8.
  


  The LIKE operator has two modes that can be set by a
  pragma.  The
  default mode is for LIKE comparisons to be insensitive to differences
  of case for latin1 characters.  Thus, by default, the following
  expression is true:

'a' LIKE 'A'


  But if the case_sensitive_like pragma is enabled as follows:

PRAGMA case_sensitive_like=ON;


  Then the LIKE operator pays attention to case and the example above would
  evaluate to false.  Note that case insensitivity only applies to
  latin1 characters - basically the upper and lower case letters of English
  in the lower 127 byte codes of ASCII.  International character sets
  are case sensitive in SQLite unless an application-defined
  collating sequence and like() SQL function are provided that
  take non-ASCII characters into account.
  But if an application-defined collating sequence and/or like() SQL
  function are provided, the LIKE optimization described here will never
  be taken.


  The LIKE operator is case insensitive by default because this is what
  the SQL standard requires.  You can change the default behavior at
  compile time by using the SQLITE_CASE_SENSITIVE_LIKE command-line option
  to the compiler.


  The LIKE optimization might occur if the column named on the left of the
  operator is indexed using the built-in BINARY collating sequence and
  case_sensitive_like is turned on.  Or the optimization might occur if
  the column is indexed using the built-in NOCASE collating sequence and the 
  case_sensitive_like mode is off.  These are the only two combinations
  under which LIKE operators will be optimized.


  The GLOB operator is always case sensitive.  The column on the left side
  of the GLOB operator must always use the built-in BINARY collating sequence
  or no attempt will be made to optimize that operator with indices.


  The LIKE optimization will only be attempted if
  the right-hand side of the GLOB or LIKE operator is either
  literal string or a parameter that has been bound
  to a string literal.  The string literal must not
  begin with a wildcard; if the right-hand side begins with a wildcard
  character then this optimization is not attempted.  If the right-hand side 
  is a parameter that is bound to a string, then this optimization is
  only attempted if the prepared statement containing the expression
  was compiled with sqlite3_prepare_v2() or sqlite3_prepare16_v2().
  The LIKE optimization is not attempted if the
  right-hand side is a parameter and the statement was prepared using
  sqlite3_prepare() or sqlite3_prepare16().


  Suppose the initial sequence of non-wildcard characters on the right-hand
  side of the LIKE or GLOB operator is x.  We are using a single 
  character to denote this non-wildcard prefix but the reader should
  understand that the prefix can consist of more than 1 character.
  Let y be the smallest string that is the same length as /x/ but which
  compares greater than x.  For example, if x is *hello* then
  y would be *hellp*.
  The LIKE and GLOB optimizations consist of adding two virtual terms
  like this:


  column &gt;= x AND column &lt; y


  Under most circumstances, the original LIKE or GLOB operator is still
  tested against each input row even if the virtual terms are used to
  constrain an index.  This is because we do not know what additional
  constraints may be imposed by characters to the right
  of the x prefix.  However, if there is only a single
  global wildcard to the right of x, then the original LIKE or 
  GLOB test is disabled.
  In other words, if the pattern is like this:


  column LIKE x%
  column GLOB x*


  then the original LIKE or GLOB tests are disabled when the virtual
  terms constrain an index because in that case we know that all of the
  rows selected by the index will pass the LIKE or GLOB test.


  Note that when the right-hand side of a LIKE or GLOB operator is
  a parameter and the statement is prepared using sqlite3_prepare_v2()
  or sqlite3_prepare16_v2() then the statement is automatically reparsed
  and recompiled on the first sqlite3_step() call of each run if the binding
  to the right-hand side parameter has changed since the previous run.
  This reparse and recompile is essentially the same action that occurs
  following a schema change.  The recompile is necessary so that the query
  planner can examine the new value bound to the right-hand side of the
  LIKE or GLOB operator and determine whether or not to employ the
  optimization described above.



6. The Skip-Scan Optimization


  The general rule is that indexes are only useful if there are 
  WHERE-clause constraints on the left-most columns of the index.
  However, in some cases,
  SQLite is able to use an index even if the first few columns of
  the index are omitted from the WHERE clause but later columns 
  are included.



  Consider a table such as the following:

CREATE TABLE people(
  name TEXT PRIMARY KEY,
  role TEXT NOT NULL,
  height INT NOT NULL, -- in cm
  CHECK( role IN ('student','teacher') )
);
CREATE INDEX people_idx1 ON people(role, height);



  The people table has one entry for each person in a large
  organization.  Each person is either a "student" or a "teacher",
  as determined by the "role" field.  And we record the height in
  centimeters of each person.  The role and height are indexed.
  Notice that the left-most column of the index is not very
  selective - it only contains two possible values.



  Now consider a query to find the names of everyone in the
  organization that is 180cm tall or taller:


SELECT name FROM people WHERE height>=180;



  Because the left-most column of the index does not appear in the
  WHERE clause of the query, one is tempted to conclude that the
  index is not usable here.  But SQLite is able to use the index.
  Conceptually, SQLite uses the index as if the query were more
  like the following:


SELECT name FROM people
 WHERE role IN (SELECT DISTINCT role FROM people)
   AND height>=180;



  Or this:

SELECT name FROM people WHERE role='teacher' AND height>=180
UNION ALL
SELECT name FROM people WHERE role='student' AND height>=180;



  The alternative query formulations shown above are conceptual only.
  SQLite does not really transform the query. 
  The actual query plan is like this:
  SQLite locates the first possible value for "role", which it
  can do by rewinding the "people_idx1" index to the beginning and reading
  the first record.  SQLite stores this first "role" value in an
  internal variable that we will here call "$role".  Then SQLite
  runs a query like: "SELECT name FROM people WHERE role=$role AND height>=180".
  This query has an equality constraint on the left-most column of the
  index and so the index can be used to resolve that query.  Once
  that query is finished, SQLite then uses the "people_idx1" index to
  locate the next value of the "role" column, using code that is logically
  similar to "SELECT role FROM people WHERE role>$role LIMIT 1".
  This new "role" value overwrites the $role variable, and the process
  repeats until all possible values for "role" have been examined.


  We call this kind of index usage a "skip-scan" because the database
  engine is basically doing a full scan of the index but it optimizes the
  scan (making it less than "full") by occasionally skipping ahead to the
  next candidate value.


  SQLite might use a skip-scan on an index if it knows that the first
  one or more columns contain many duplication values.
  If there are too few duplicates
  in the left-most columns of the index, then it would
  be faster to simply step ahead to the next value, and thus do
  a full table scan, than to do a binary search on an index to locate
  the next left-column value.


  The only way that SQLite can know that the left-most columns of an index
  have many duplicate is if the ANALYZE command has been run
  on the database.
  Without the results of ANALYZE, SQLite has to guess at the "shape" of
  the data in the table, and the default guess is that there are an average
  of 10 duplicates for every value in the left-most column of the index.
  But skip-scan only becomes profitable (it only gets to be faster than
  a full table scan) when the number of duplicates is about 18 or more.
  Hence, a skip-scan is never used on a database that has not been analyzed.



7. Joins


  The ON and USING clauses of an inner join are converted into additional
  terms of the WHERE clause prior to WHERE clause analysis described
  above in paragraph 1.0.  Thus with SQLite, there is no computational
  advantage to use the newer SQL92 join syntax
  over the older SQL89 comma-join syntax.  They both end up accomplishing
  exactly the same thing on inner joins.


  For a LEFT OUTER JOIN the situation is more complex.  The following
  two queries are not equivalent:

SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.x=tab2.y;
SELECT * FROM tab1 LEFT JOIN tab2 WHERE tab1.x=tab2.y;


  For an inner join, the two queries above would be identical.  But
  special processing applies to the ON and USING clauses of an OUTER join:
  specifically, the constraints in an ON or USING clause do not apply if
  the right table of the join is on a null row, but the constraints do apply
  in the WHERE clause.  The net effect is that putting the ON or USING
  clause expressions for a LEFT JOIN in the WHERE clause effectively converts
  the query to an
  ordinary INNER JOIN - albeit an inner join that runs more slowly.



7.1. Order of tables in a join


  The current implementation of 
  SQLite uses only loop joins.  That is to say, joins are implemented as
  nested loops.


  The default order of the nested loops in a join is for the left-most
  table in the FROM clause to form the outer loop and the right-most
  table to form the inner loop.
  However, SQLite will nest the loops in a different order if doing so
  will help it to select better indices.


  Inner joins can be freely reordered.  However a left outer join is
  neither commutative nor associative and hence will not be reordered.
  Inner joins to the left and right of the outer join might be reordered
  if the optimizer thinks that is advantageous but the outer joins are
  always evaluated in the order in which they occur.


  SQLite treats the CROSS JOIN operator specially.
  The CROSS JOIN operator is commutative in theory.  But SQLite chooses to
  never reorder tables in a CROSS JOIN.  This provides a mechanism
  by which the programmer can force SQLite to choose a particular loop nesting
  order.  


  When selecting the order of tables in a join, SQLite uses an efficient
  polynomial-time algorithm.  Because of this,
  SQLite is able to plan queries with 50- or 60-way joins in a matter of
  microseconds


  Join reordering is automatic and usually works well enough that
  programmers do not have to think about it, especially if ANALYZE
  has been used to gather statistics about the available indices.
  But occasionally some hints from the programmer are needed.
  Consider, for example, the following schema:

CREATE TABLE node(
   id INTEGER PRIMARY KEY,
   name TEXT
);
CREATE INDEX node_idx ON node(name);
CREATE TABLE edge(
   orig INTEGER REFERENCES node,
   dest INTEGER REFERENCES node,
   PRIMARY KEY(orig, dest)
);
CREATE INDEX edge_idx ON edge(dest,orig);


  The schema above defines a directed graph with the ability to store a
  name at each node. Now consider a query against this schema:

SELECT *
  FROM edge AS e,
       node AS n1,
       node AS n2
 WHERE n1.name = 'alice'
   AND n2.name = 'bob'
   AND e.orig = n1.id
   AND e.dest = n2.id;


  This query asks for is all information about edges that go from
  nodes labeled "alice" to nodes labeled "bob".
  The query optimizer in SQLite has basically two choices on how to
  implement this query.  (There are actually six different choices, but
  we will only consider two of them here.)
  Pseudocode below demonstrating these two choices.



Option 1:
foreach n1 where n1.name='alice' do:
  foreach n2 where n2.name='bob' do:
    foreach e where e.orig=n1.id and e.dest=n2.id
      return n1.*, n2.*, e.*
    end
  end
end



Option 2:
foreach n1 where n1.name='alice' do:
  foreach e where e.orig=n1.id do:
    foreach n2 where n2.id=e.dest and n2.name='bob' do:
      return n1.*, n2.*, e.*
    end
  end
end


  The same indices are used to speed up every loop in both implementation
  options.
  The only difference in these two query plans is the order in which
  the loops are nested.


  So which query plan is better? It turns out that the answer depends on
  what kind of data is found in the node and edge tables.


  Let the number of alice nodes be M and the number of bob nodes be N.
  Consider two scenarios. In the first scenario, M and N are both 2 but
  there are thousands of edges on each node. In this case, option 1 is
  preferred. With option 1, the inner loop checks for the existence of
  an edge between a pair of nodes and outputs the result if found. 
  But because there are only 2 alice and bob nodes each, the inner loop
  only has to run 4 times and the query is very quick. Option 2 would
  take much longer here. The outer loop of option 2 only executes twice,
  but because there are a large number of edges leaving each alice node,
  the middle loop has to iterate many thousands of times. It will be
  much slower. So in the first scenario, we prefer to use option 1.


  Now consider the case where M and N are both 3500. Alice nodes are
  abundant. But suppose each of these nodes is connected by only one
  or two edges. In this case, option 2 is preferred. With option 2,
  the outer loop still has to run 3500 times, but the middle loop only
  runs once or twice for each outer loop and the inner loop will only
  run once for each middle loop, if at all. So the total number of
  iterations of the inner loop is around 7000. Option 1, on the other
  hand, has to run both its outer loop and its middle loop 3500 times
  each, resulting in 12 million iterations of the middle loop.
  Thus in the second scenario, option 2 is nearly 2000 times faster
  than option 1.


  So you can see that depending on how the data is structured in the table,
  either query plan 1 or query plan 2 might be better.  Which plan does
  SQLite choose by default?  As of version 3.6.18, without running ANALYZE,
  SQLite will choose option 2.
  But if the ANALYZE command is run in order to gather statistics,
  a different choice might be made if the statistics indicate that the
  alternative is likely to run faster.



7.2. Manual Control Of Query Plans Using SQLITE_STAT Tables


  SQLite provides the ability for advanced programmers to exercise control
  over the query plan chosen by the optimizer. One method for doing this
  is to fudge the ANALYZE results in the sqlite_stat1, 
  sqlite_stat3, and/or sqlite_stat4 tables.  That approach is not 
  recommended except for the one scenario described in the next paragraph.


  For a program that uses an SQLite database as its 
  application file-format,
  when a new database instance is first created the ANALYZE
  command is ineffective because the database contain no data from which
  to gather statistics.  In that case, one could construct a large prototype
  database containing typical data during development and run the 
  ANALYZE command on this prototype database to gather statistics,
  then save the prototype statistics as part of the application.
  After deployment, when the application goes to create a new database file,
  it can run the ANALYZE command in order to create the statistics
  tables, then copy the precomputed statistics obtained
  from the prototype database into these new statistics tables.
  In that way, statistics from large working data sets can be preloaded
  into newly created application files.



7.3. Manual Control Of Query Plans Using CROSS JOIN


  Programmers can force SQLite to use a particular loop nesting order
  for a join by using the CROSS JOIN operator instead of just JOIN, 
  INNER JOIN, NATURAL JOIN, or a "," join.  Though CROSS JOINs are
  commutative in theory, SQLite chooses to never reorder the tables in
  a CROSS JOIN.  Hence, the left table of a CROSS JOIN will always be
  in an outer loop relative to the right table.


  In the following query, the optimizer is free to reorder the 
  tables of FROM clause anyway it sees fit:

SELECT *
  FROM node AS n1,
       edge AS e,
       node AS n2
 WHERE n1.name = 'alice'
   AND n2.name = 'bob'
   AND e.orig = n1.id
   AND e.dest = n2.id;


  But in the following logically equivalent formulation of the same query,
  the substitution of "CROSS JOIN" for the "," means that the order
  of tables must be N1, E, N2.

SELECT *
  FROM node AS n1 CROSS JOIN
       edge AS e CROSS JOIN
       node AS n2
 WHERE n1.name = 'alice'
   AND n2.name = 'bob'
   AND e.orig = n1.id
   AND e.dest = n2.id;


  In the latter query, the query plan must be 
  option 2.  Note that
  you must use the keyword "CROSS" in order to disable the table reordering
  optimization; INNER JOIN, NATURAL JOIN, JOIN, and other similar
  combinations work just like a comma join in that the optimizer is
  free to reorder tables as it sees fit. (Table reordering is also
  disabled on an outer join, but that is because outer joins are not
  associative or commutative. Reordering tables in OUTER JOIN changes
  the result.)


  See "The Fossil NGQP Upgrade Case Study" for another real-world example
  of using CROSS JOIN to manually control the nesting order of a join.
  The query planner checklist found later in the same document provides
  further guidance on manual control of the query planner.



8. Choosing between multiple indices


  Each table in the FROM clause of a query can use at most one index
  (except when the OR-clause optimization comes into
  play)
  and SQLite strives to use at least one index on each table.  Sometimes,
  two or more indices might be candidates for use on a single table.
  For example:

CREATE TABLE ex2(x,y,z);
CREATE INDEX ex2i1 ON ex2(x);
CREATE INDEX ex2i2 ON ex2(y);
SELECT z FROM ex2 WHERE x=5 AND y=6;


  For the SELECT statement above, the optimizer can use the ex2i1 index
  to lookup rows of ex2 that contain x=5 and then test each row against
  the y=6 term.  Or it can use the ex2i2 index to lookup rows
  of ex2 that contain y=6 then test each of those rows against the
  x=5 term.


  When faced with a choice of two or more indices, SQLite tries to estimate
  the total amount of work needed to perform the query using each option.
  It then selects the option that gives the least estimated work.


  To help the optimizer get a more accurate estimate of the work involved
  in using various indices, the user may optionally run the ANALYZE command.
  The ANALYZE command scans all indices of database where there might
  be a choice between two or more indices and gathers statistics on the
  selectiveness of those indices.  The statistics gathered by
  this scan are stored in special database tables names shows names all
  begin with "sqlite_stat".
  The content of these tables is not updated as the database
  changes so after making significant changes it might be prudent to
  rerun ANALYZE.
  The results of an ANALYZE command are only available to database connections
  that are opened after the ANALYZE command completes.


  The various sqlite_statN tables contain information on how
  selective the various indices are.  For example, the sqlite_stat1
  table might indicate that an equality constraint on column x reduces the
  search space to 10 rows on average, whereas an equality constraint on
  column y reduces the search space to 3 rows on average.  In that case,
  SQLite would prefer to use index ex2i2 since that index is more selective.



8.1. Disqualifying WHERE Clause Terms Using Unary-"+"


  Terms of the WHERE clause can be manually disqualified for use with
  indices by prepending a unary *+* operator to the column name.  The
  unary *+* is a no-op and will not generate any byte code in the prepared
  statement.
  But the unary *+* operator will prevent the term from constraining an index.
  So, in the example above, if the query were rewritten as:

SELECT z FROM ex2 WHERE +x=5 AND y=6;


  The *+* operator on the *x* column will prevent that term from 
  constraining an index.  This would force the use of the ex2i2 index.


  Note that the unary *+* operator also removes 
  type affinity from
  an expression, and in some cases this can cause subtle changes in
  the meaning of an expression.
  In the example above,
  if column *x* has TEXT affinity
  then the comparison "x=5" will be done as text.  But the *+* operator
  removes the affinity.  So the comparison "+x=5" will compare the text
  in column *x* with the numeric value 5 and will always be false.



8.2. Range Queries


  Consider a slightly different scenario:

CREATE TABLE ex2(x,y,z);
CREATE INDEX ex2i1 ON ex2(x);
CREATE INDEX ex2i2 ON ex2(y);
SELECT z FROM ex2 WHERE x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100;


  Further suppose that column x contains values spread out
  between 0 and 1,000,000 and column y contains values
  that span between 0 and 1,000.  In that scenario,
  the range constraint on column x should reduce the search space by
  a factor of 10,000 whereas the range constraint on column y should
  reduce the search space by a factor of only 10.  So the ex2i1 index
  should be preferred.


  SQLite will make this determination, but only if it has been compiled
  with SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4.
  The SQLITE_ENABLE_STAT3 and SQLITE_ENABLE_STAT4 options causes
  the ANALYZE command to collect a histogram of column content in the
  sqlite_stat3 or sqlite_stat4 tables and to use this histogram to 
  make a better guess at the best query to use for range constraints
  such as the above.  The main difference between STAT3 and STAT4 is
  that STAT3 records histogram data for only the left-most column of
  an index whereas STAT4 records histogram data for all columns of an
  index.  For single-column indexes, STAT3 and STAT4 work the same.


  The histogram data is only useful if the right-hand side of the constraint
  is a simple compile-time constant or parameter and not an expression.


  Another limitation of the histogram data is that it only applies to the
  left-most column on an index.  Consider this scenario:

CREATE TABLE ex3(w,x,y,z);
CREATE INDEX ex3i1 ON ex2(w, x);
CREATE INDEX ex3i2 ON ex2(w, y);
SELECT z FROM ex3 WHERE w=5 AND x BETWEEN 1 AND 100 AND y BETWEEN 1 AND 100;


  Here the inequalities are on columns x and y which are not the
  left-most index columns.  Hence, the histogram data which is collected no
  left-most column of indices is useless in helping to choose between the
  range constraints on columns x and y.



9. Covering Indices


  When doing an indexed lookup of a row, the usual procedure is to
  do a binary search on the index to find the index entry, then extract
  the rowid from the index and use that rowid to do a binary search on
  the original table.  Thus a typical indexed lookup involves two
  binary searches.
  If, however, all columns that were to be fetched from the table are
  already available in the index itself, SQLite will use the values
  contained in the index and will never look up the original table
  row.  This saves one binary search for each row and can make many
  queries run twice as fast.


  When an index contains all of the data needed for a query and when the
  original table never needs to be consulted, we call that index a
  "covering index".



10. ORDER BY optimizations


  SQLite attempts to use an index to satisfy the ORDER BY clause of a
  query when possible.
  When faced with the choice of using an index to satisfy WHERE clause
  constraints or satisfying an ORDER BY clause, SQLite does the same
  cost analysis described above
  and chooses the index that it believes will result in the fastest answer.


  SQLite will also attempt to use indices to help satisfy GROUP BY clauses
  and the DISTINCT keyword.  If the nested loops of the join can be arranged
  such that rows that are equivalent for the GROUP BY or for the DISTINCT are
  consecutive, then the GROUP BY or DISTINCT logic can determine if the 
  current row is part of the same group or if the current row is distinct
  simply by comparing the current row to the previous row.
  This can be much faster than the alternative of comparing each row to
  all prior rows.



10.1. Partial ORDER BY Via Index


  If a query contains an ORDER BY clause with multiple terms, it might
  be that SQLite can use indices to cause rows to come out in the order
  of some prefix of the terms in the ORDER BY but that later terms in
  the ORDER BY are not satisfied.  In that case, SQLite does block sorting.
  Suppose the ORDER BY clause has four terms and the natural order of the
  query results in rows appearing in order of the first two terms.  As
  each row is output by the query engine and enters the sorter, the 
  outputs in the current row corresponding to the first two terms of 
  the ORDER BY are compared against the previous row.  If they have
  changed, the current sort is finished and output and a new sort is
  started.  This results in a slightly faster sort.  But the bigger
  advantages are that many fewer rows need to be held in memory,
  reducing memory requirements, and outputs can begin to appear before
  the core query has run to completion.



11. Subquery flattening


  When a subquery occurs in the FROM clause of a SELECT, the simplest
  behavior is to evaluate the subquery into a transient table, then run
  the outer SELECT against the transient table.  But such a plan
  can be suboptimal since the transient table will not have any indices
  and the outer query (which is likely a join) will be forced to do a
  full table scan on the transient table.


  To overcome this problem, SQLite attempts to flatten subqueries in
  the FROM clause of a SELECT.
  This involves inserting the FROM clause of the subquery into the
  FROM clause of the outer query and rewriting expressions in
  the outer query that refer to the result set of the subquery.
  For example:

  SELECT t1.a, t2.b FROM t2, (SELECT x+y AS a FROM t1 WHERE z5



  Would be rewritten using query flattening as:

  SELECT t1.x+t1.y AS a, t2.b FROM t2, t1 WHERE z5



  There is a long list of conditions that must all be met in order for
  query flattening to occur.  Some of the constraints are marked as 
  obsolete by italic text.  These extra constraints are retained in the
  documentation to preserve the numbering of the other constraints.


  Casual readers are not expected to understand all of these rules.
  A key take-away from this section is that the rules for determining
  when query flatting is safe and when it is unsafe are subtle and
  complex.  There have been multiple bugs over the years caused by
  over-aggressive query flattening.  On the other hand, performance
  of complex queries and/or queries involving views tends to suffer
  if query flattening is more conservative.


  
    (Obsolete.  Query flattening is no longer
                      attempted for aggregate subqueries.)

    (Obsolete.  Query flattening is no longer
                      attempted for aggregate subqueries.)

  
  If the subquery is the right operand of a LEFT JOIN then
    the subquery may not be a join, and
    the FROM clause of the subquery may
   not contain a virtual table, and
    the outer query may not be an aggregate.

    The subquery is not DISTINCT.

   (Subsumed into constraint 4)

   (Obsolete.  Query flattening is no longer
                      attempted for aggregate subqueries.)

  
  The subquery has a FROM clause.

  
  The subquery does not use LIMIT or the outer query is not a join.

  
  The subquery does not use LIMIT or the outer query does not use
  aggregates.

   (Restriction relaxed in 2005)

  
  The subquery and the outer query do not both have ORDER BY clauses.

   (Subsumed into constraint 3)

    The subquery and outer query do not both use LIMIT.

    The subquery does not use OFFSET.

  
  If the outer query is part of a compound select, then the
  subquery may not have a LIMIT clause.

  
  If the outer query is an aggregate, then the subquery may
  not contain ORDER BY. 

  
  If the sub-query is a compound SELECT, then
  
   all compound operators must be UNION ALL, and
   no terms with the subquery compound may be aggregate
       or DISTINCT, and
   every term within the subquery must have a FROM clause, and
   the outer query may not be an aggregate, DISTINCT query, or join.
  

  The parent and sub-query may contain WHERE clauses. Subject to
  rules (11), (12) and (13), they may also contain ORDER BY,
  LIMIT and OFFSET clauses.

  
  If the sub-query is a compound select, then all terms of the
  ORDER by clause of the parent must be simple references to 
  columns of the sub-query.

  
  If the subquery uses LIMIT then the outer query may not
  have a WHERE clause.

  
  If the sub-query is a compound select, then it must not use
   an ORDER BY clause.

  
  If the subquery uses LIMIT, then the outer query may not be
  DISTINCT.

   The subquery may not be a recursive CTE.

   (Subsumed into constraint 17d.)

   (Obsolete. Query flattening is no longer
                      attempted for aggregate subqueries.)
  


  The casual reader is not expected to understand or remember any part of
  the list above.  The point of this list is to demonstrate
  that the decision of whether or not to flatten a query is complex.


  Query flattening is an important optimization when views are used as
  each use of a view is translated into a subquery.



12. Subquery Co-routines


  Prior to SQLite 3.7.15 (2012-12-12),
  a subquery in the FROM clause would be
  either flattened into the outer query, or else the subquery would be run
  to completion
  before the outer query started, the result set from the subquery
  would be stored in a transient table,
  and then the transient table would be used in the outer query.  Newer
  versions of SQLite have a third option, which is to implement the subquery
  using a co-routine.


  A co-routine is like a subroutine in that it runs in the same thread
  as the caller and eventually returns control back to the caller.  The
  difference is that a co-routine also has the ability to return
  before it has finished, and then resume where it left off the next
  time it is called.


  When a subquery is implemented as a co-routine, byte-code is generated
  to implement the subquery as if it were a standalone query, except
  instead of returning rows of results back to the application, the
  co-routine yields control back to the caller after each row is computed.
  The caller can then use that one computed row as part of its computation,
  then invoke the co-routine again when it is ready for the next row.


  Co-routines are better than storing the complete result set of the subquery
  in a transient table because co-routines use less memory.  With a co-routine,
  only a single row of the result needs to be remembered, whereas all rows of
  the result must be stored for a transient table.  Also, because the
  co-routine does not need to run to completion before the outer query
  begins its work, the first rows of output can appear much sooner, and if
  the overall query is aborted, less work is done overall.


  On the other hand, if the result of the subquery must be scanned multiple
  times (because, for example, it is just one table in a join) then it
  is better to use a transient table to remember the entire result of the
  subquery, in order to avoid computing the subquery more than once.



12.1. Using Co-routines To Defer Work Until After The Sorting


  As of SQLite version 3.21.0 (2017-10-24), the query planner will
  always prefer to use a co-routine to implement FROM-clause subqueries 
  that contains an ORDER BY clause and that are not part of a join when
  the result set of the outer query is "complex".  This feature allows
  applications to shift expensive computations from before the
  sorter until after the sorter, which can result in faster operation.
  For example, consider this query:

SELECT expensive_function(a) FROM tab ORDER BY date DESC LIMIT 5;


  The goal of this query is to compute some value for the five most
  recent entries in the table.  But in the query above, the
  "expensive_function()" is invoked prior to the sort and thus is
  invoked on every row of the table, even
  rows that are ultimately omitted due to the LIMIT clause.
  A co-routine can be used to work around this:

SELECT expensive_function(a) FROM (
  SELECT a FROM tab ORDER BY date DESC LIMIT 5
);


  In the revised query, the subquery implemented by a co-routine computes
  the five most recent values for "a".  Those five values are passed from the
  co-routine up into the outer query where the "expensive_function()" is
  invoked on only the specific rows that the application cares about.


  The query planner in future versions of SQLite might grow smart enough
  to make transformations such as the above automatically, in both directions.
  That is to say, future versions of SQLite might transform queries of the
  first form into the second, or queries written the second way into the
  first.  As of SQLite version 3.22.0 (2018-01-22), the query planner
  will flatten the subquery if the outer query does not make use of any
  user-defined functions or subqueries in its result set.  For the examples
  shown above, however, SQLite implements each of the queries as
  written.



13. The MIN/MAX optimization


  Queries that contain a single MIN() or MAX() aggregate function whose
  argument is the left-most column of an index might be satisfied
  by doing a single index lookup rather than by scanning the entire table.
  Examples:

SELECT MIN(x) FROM table;
SELECT MAX(x)+1 FROM table;




14. Automatic Indexes


  When no indices are available to aid the evaluation of a query, SQLite
  might create an automatic index that lasts only for the duration
  of a single SQL statement.
  Since the cost of constructing the automatic index is
  O(NlogN) (where N is the number of entries in the table) and the cost of
  doing a full table scan is only O(N), an automatic index will
  only be created if SQLite expects that the lookup will be run more than
  logN times during the course of the SQL statement. Consider an example:

CREATE TABLE t1(a,b);
CREATE TABLE t2(c,d);
-- Insert many rows into both t1 and t2
SELECT * FROM t1, t2 WHERE a=c;


  In the query above, if both t1 and t2 have approximately N rows, then
  without any indices the query will require O(N*N) time.  On the other
  hand, creating an index on table t2 requires O(NlogN) time and then use
  that index to evaluate the query requires an additional O(NlogN) time.
  In the absence of ANALYZE information, SQLite guesses that N is one
  million and hence it believes that constructing the automatic index will
  be the cheaper approach.


  An automatic index might also be used for a subquery:

CREATE TABLE t1(a,b);
CREATE TABLE t2(c,d);
-- Insert many rows into both t1 and t2
SELECT a, (SELECT d FROM t2 WHERE c=b) FROM t1;


  In this example, the t2 table is used in a subquery to translate values
  of the t1.b column.  If each table contains N rows, SQLite expects that
  the subquery will run N times, and hence it will believe it is faster
  to construct an automatic, transient index on t2 first and then use
  that index to satisfy the N instances of the subquery.


  The automatic indexing capability can be disabled at run-time using
  the automatic_index pragma.  Automatic indexing is turned on by
  default, but this can be changed so that automatic indexing is off
  by default using the SQLITE_DEFAULT_AUTOMATIC_INDEX compile-time option.
  The ability to create automatic indices can be completely disabled by
  compiling with the SQLITE_OMIT_AUTOMATIC_INDEX compile-time option.


  In SQLite version 3.8.0 (2013-08-26) and later, 
  an SQLITE_WARNING_AUTOINDEX message is sent
  to the error log every time a statement is prepared that uses an
  automatic index.  Application developers can and should use these warnings
  to identify the need for new persistent indices in the schema.


  Do not confuse automatic indexes with the internal indexes (having names
  like "sqlite_autoindex_table_N") that are sometimes
  created to implement a PRIMARY KEY constraint or UNIQUE constraint.
  The automatic indexes described here exist only for the duration of a
  single query, are never persisted to disk, and are only visible to a
  single database connection.  Internal indexes are part of the implementation
  of PRIMARY KEY and UNIQUE constraints, are long-lasting and persisted
  to disk, and are visible to all database connections.  The term "autoindex"
  appears in the names of internal indexes for legacy reasons and does
  not indicate that internal indexes and automatic indexes are related.



15. The Push-Down Optimization


  If a subquery cannot be flattened into the outer query, it might
  still be possible to enhance performance by "pushing down" WHERE clause
  terms from the outer query into the subquery.  Consider an example:

CREATE TABLE t1(a INT, b INT);
CREATE TABLE t2(x INT, y INT);
CREATE VIEW v1(a,b) AS SELECT DISTINCT a, b FROM t1;

SELECT x, y, b
  FROM t2 JOIN v1 ON (x=a)
 WHERE b BETWEEN 10 AND 20;



  The view v1 cannot be flattened because it is DISTINCT.  It must
  instead be run as a subquery with the results being stored in a
  transient table, then the join is performed between t2 and the
  transient table.  The push-down optimization pushes down the
  "b BETWEEN 10 AND 20" term into the view.  This makes the transient
  table smaller, and helps the subquery to run faster if there
  is an index on t1.b.  The resulting evaluation is like this:

SELECT x, y, b
  FROM t2
  JOIN (SELECT DISTINCT a, b FROM t1 WHERE b BETWEEN 10 AND 20)
 WHERE b BETWEEN 10 AND 20;



  The push-down optimization cannot always be used.  For example,
  if the subquery contains a LIMIT, then pushing down any part of
  the WHERE clause from the outer query could change the result of
  the inner query.  There are other restrictions, explained in a
  comment in the source code on the pushDownWhereTerms() routine
  that implements this optimization.



16. The LEFT JOIN Strength Reduction Optimization


  Sometimes a LEFT JOIN can be converted into an ordinary JOIN,
  if there are terms in the WHERE clause that guarantee that the
  two joins will give identical results.  In particular, if any
  column in the right-hand table of the LEFT JOIN must be non-NULL
  in order for the WHERE clause to be true, then the LEFT JOIN is
  demoted to an ordinary JOIN.


  The prover that determines whether any column of the right-hand
  table of a LEFT JOIN must be non-NULL in the WHERE clause is
  imperfect.  It sometimes returns a false negative.  In other words,
  it sometimes fails to reduce the strength of a LEFT JOIN when doing
  so was in fact possible.  For example, the prover does not know
  the datetime() SQL function will always return NULL if its first
  argument is NULL, and so it will not recognize that the LEFT JOIN
  in the following query could be strength-reduced:

SELECT urls.url
  FROM urls
  LEFT JOIN
    (SELECT *
      FROM (SELECT url_id AS uid, max(retrieval_time) AS rtime
              FROM lookups GROUP BY 1 ORDER BY 1)
      WHERE uid IN (358341,358341,358341)
    ) recent
    ON u.source_seed_id = recent.xyz OR u.url_id = recent.xyz
 WHERE
     DATETIME(recent.rtime) > DATETIME('now', '-5 days');



  It is possible that future enhancements to the prover might enable it
  to recognize that NULL inputs to certain built-in functions
  always result in a NULL answer.  But not all built-in
  functions have that property (for example coalesce()) and, of
  course, the prover will never be able to reason about
  application-defined SQL functions.




17. The Omit LEFT JOIN Optimization


  Sometimes a LEFT JOIN can be completely omitted from a query without
  changing the result.  This can happen if all of the following are
  true:


  
   The query is not an aggregate
   Either the query is DISTINCT or else the ON or USING clause
       on the LEFT JOIN constrains the join such that it matches
       only a single row
   The right-hand table of the LEFT JOIN is not be used anywhere
       in the query outside of its own USING or ON clause.
  


  LEFT JOIN elimination often comes up when LEFT JOINs are used
  inside of views, and then the view is used in such as way that
  none of the columns of the right-hand table of the LEFT JOIN are
  referenced.


  Here is a simple example of omitting a LEFT JOIN:

CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);

SELECT v1, v3 FROM t1 
  LEFT JOIN t2 USING (t1.ipk=t2.ipk)
  LEFT JOIN t3 USING (t1.ipk=t3.ipk)



  The t2 table is completely unused in the query above, and so the
  query planner is able to implement the query as if it were written:

SELECT v1, v3 FROM t1 
  LEFT JOIN t3 USING (t1.ipk=t3.ipk)


c2: SQLite Pro Support
c5: prosupport.html
c4:
Professional Support &amp; Extension Products




Support
(details below)



1.Public Forum. 
  Help and advice from a world-wide community of experts.

Free
More Info
Recent Posts

2.Annual Maintenance Subscription. 
  Private, expert email advice from the developers of SQLite.

$1500/year
More Info
Buy Now!

3.Technical Support. 
  High-priority email and phone support directly from the SQLite developers.
  Guaranteed response time available as an option.

$8K-50K/year
More Info
Request A Quote

4.SQLite Consortium Membership. 
  Premium enterprise support including on-site visits and
  access to all proprietary extensions and test suites.

$85K/year
More Info
Request A Quote





Public Forum. 
  Help and advice from a world-wide community of experts.

Cost: Free
More Info
Recent Posts


Annual Maintenance Subscription. 
  Private, expert email advice from the developers of SQLite.

Cost: $1500/year
More Info
Buy Now!


Technical Support. 
  High-priority email and phone support directly from the SQLite developers.
  Guaranteed response time available as an option.

Cost: $8K-50K/year
More Info
Request A Quote


SQLite Consortium Membership. 
  Premium enterprise support including on-site visits and
  access to all proprietary extensions and test suites.

Cost: $85K/year
More Info
Request A Quote




Licenses
(details below)



5.SQLite License. 
  Warranty of title and perpetual right-to-use for the SQLite source code. 

$6000 one time fee
More Info
Buy Now!

6.SQLite Encryption Extension (SEE). 
   A drop-in replacement for public-domain SQLite source code that has 
   the added ability to read/write AES-encrypted databases. 

$2000 one time fee
More Info
Buy Now!

7.Compressed And Encrypted Read-Only Database (CEROD). 
   A drop-in replacement for public-domain SQLite source code
   that has the added ability to read database that has been both 
   compressed and encrypted. 

$2000 one time fee
More Info
Buy Now!

8.The ZIPVFS Read/Write Compressed Database Extension. 
   The ZIPVFS extension automatically compresses and encrypts
   your data as it is written to disk, and decompressed and decrypts
   it while reading.

$4000 one time fee
More Info
Buy Now!





SQLite License. 
  Warranty of title and perpetual right-to-use for the SQLite source code. 

Cost: $6000 one time fee
More Info
Buy Now!


SQLite Encryption Extension (SEE). 
   A drop-in replacement for public-domain SQLite source code that has 
   the added ability to read/write AES-encrypted databases. 

Cost: $2000 one time fee
More Info
Buy Now!


Compressed And Encrypted Read-Only Database (CEROD). 
   A drop-in replacement for public-domain SQLite source code
   that has the added ability to read database that has been both 
   compressed and encrypted. 

Cost: $2000 one time fee
More Info
Buy Now!


The ZIPVFS Read/Write Compressed Database Extension. 
   The ZIPVFS extension automatically compresses and encrypts
   your data as it is written to disk, and decompressed and decrypts
   it while reading.

Cost: $4000 one time fee
More Info
Buy Now!




Special Services
(details below)



9.TH3 Testing Support. 
  The TH3 test harness
  is an aviation-grade test suite for SQLite. SQLite developers 
  can run TH3 on specialized hardware and/or using specialized
  compile-time options, according to customer specification, 
  either remotely or on customer premises. Pricing for this 
  services is on a case-by-case basis depending on requirements.

call
More Info
Request A Quote





TH3 Testing Support. 
  The TH3 test harness
  is an aviation-grade test suite for SQLite. SQLite developers 
  can run TH3 on specialized hardware and/or using specialized
  compile-time options, according to customer specification, 
  either remotely or on customer premises. Pricing for this 
  services is on a case-by-case basis depending on requirements.

Cost: call
More Info
Request A Quote





Further Information

SQLite is free and works great.
Most people use SQLite without
any kind of license or support.

Free support for SQLite is available on the public
SQLite Forum.
The forum is monitored by a large
community of experts, including the core SQLite development team,
who are able to resolve just about
any problems with SQLite that you are likely to have.

If you do not want to discuss your issues on a public and open forum, an
Annual Maintenance 
Subscription or "AMS" might
serve your needs better.
An AMS entitles you to private email support directly from the developers of
SQLite.  The level of support with an AMS is similar to the support one
gets from the public forum except that an AMS includes a unilateral 
promise of non-disclosure, so with an AMS you can discuss your issues
with the SQLite developers in private, without the whole world watching.
An AMS costs $1500 per year.

Users with more advanced support needs can opt for a
Technical Support
Agreement.
Technical support agreements are customized to the needs of each
individual client, but generally include direct telephone support
and priority handling of issues and bugs.  Guaranteed response time
is available as an option.  The cost of
technical support varies but is generally
in the range of $8000 to $35000 per year.

If SQLite is "mission critical" to your company, then you may
want to become an 
SQLite Consortium 
Member.  The SQLite
Consortium is a collaboration of companies who sponsor ongoing development
of SQLite in exchange for enterprise-level technical support, on-site
visits from the SQLite developers, unlimited access to all licensed
products, and strong guarantees that SQLite will remain in the public
domain, free and independent, and will not come under the control of
a competitor.


Software Licenses

The SQLite source code is in the 
public domain,
and is free for use
by anyone and for any purpose.  No license is required.  However, some
users desire a license so that they can have warranty of title, or just
because their company lawyers say they need one.  A
perpetual license 
and warranty
of title for the core SQLite source code is available for this purpose.

The 
SQLite Encryption
Extension (SEE),
the ZIPVFS Extension,
and the Compressed and
Encrypted ReadOnly Database (CEROD) extension are enhanced versions 
of SQLite that handle encrypted
and/or compressed databases.  SEE can read and write encrypted databases.
SEE encrypts all database content, including metadata, so that the database
file appears as white noise.  ZIPVFS 
compresses the database on-the-fly using application-supplied 
compression and decompression functions.
CEROD reads a compressed database that is
also optionally encrypted.  All of SEE, ZIPVFS, and CEROD are 
supplied in source code form only; the licensee is responsible for 
compiling the products for their chosen platform.  It is not difficult 
to compile any of these extension.  All products come in the form of an
amalgamated source file
named "sqlite3.c".  So compiling SEE, ZIPVFS, or CEROD into an application 
is simply a matter of substituting the SEE-, ZIPVFS-, or CEROD-enabled sqlite3.c 
source file in place of the public-domain sqlite3.c source file and recompiling.
Licenses for SEE, ZIPVFS, and CEROD are perpetual.
All three extension can read and write ordinary,
uncompressed and unencrypted database files.


Testing Services

The Test Harness #3 (TH3) is 
a suite of test cases for SQLite that provide 100% branch test coverage
(and 100% modified condition/decision coverage) for the core SQLite in
an as-deployed configuration using only published and documented interfaces.
TH3 is designed for use with embedded devices, and is compatible with
DO-178B.  Every release of the public-domain SQLite is tested using TH3,
and so all users benefit from the TH3 tests.  But the TH3 tests are not
themselves public.  Hardware or system manufactures who want to have
TH3 test run on their systems can negotiate a service agreement to have
the SQLite Developers run those tests.

About The SQLite Team

Paid support options and products are provided by
Hipp, Wyrick &amp; Company, Inc., (Hwaci), a 
Georgia
corporation 
with headquarters in

Charlotte, North Carolina and has been in business since
1992.
Hwaci has an international team of
employees and associates representing the best available talent.  
We are a 100% engineering company.  There is
no sales staff.
Our goal is to provide outstanding service and honest advice
without spin or sales-talk.

Hwaci is a small company but it is
also closely held and debt-free and has low
fixed costs, which means that it is largely immune to buy-outs,
take-overs, and market down-turns.  Hwaci intends to 
continue operating in its current form, and at roughly its current 
size until at least the year 2050.
We expect to be here when you need us,
even if that need is many years in the future.


c2: The JSON1 Extension
c5: json1.html
c4:
1. Overview

The json1 extension is a loadable extension that
implements fifteen application-defined SQL functions and
two table-valued functions that are useful for
managing JSON content stored in an SQLite database.
There are thirteen scalar functions:



json(json)



json_array(value1,value2,...)



json_array_length(json)json_array_length(json,path)



json_extract(json,path,...)



json_insert(json,path,value,...)



json_object(label1,value1,...)



json_patch(json1,json2)



json_remove(json,path,...)



json_replace(json,path,value,...)



json_set(json,path,value,...)



json_type(json)json_type(json,path)



json_valid(json)



json_quote(value)





There are two aggregate SQL functions:



json_group_array(value)



json_group_object(name,value)





The two table-valued functions are:



json_each(json)json_each(json,path)



json_tree(json)json_tree(json,path)












2. Compiling the JSON1 Extension


The loadable extensions documentation describes
how to compile loadable extensions as shared libraries.  The
techniques described there work fine for the json1 module.


The json1 source code is included with the SQLite amalgamation, though
it is disabled by default.  Add the -DSQLITE_ENABLE_JSON1 compile-time
option to enable the json1 extension that is built into the amalgamation.
The standard makefiles include -DSQLITE_ENABLE_JSON1 when building the
command-line shell and some of the test utilities so this extension is
normally available in the command-line shell.

3. Interface Overview


The json1 extension (currently) stores JSON as ordinary text.


Backwards compatibility constraints mean that SQLite is only able to
store values that are NULL, integers, floating-point numbers, text,
and BLOBs.  It is not possible to add a sixth "JSON" type.


The json1 extension does not (currently) support a binary encoding
of JSON.  Experiments have been unable to find a binary encoding
that is significantly smaller or faster than a plain text encoding.
(The present implementation parses JSON text at over 1 GB/s.)
All json1 functions currently throw an error if any of their
arguments are BLOBs because BLOBs are reserved
for a future enhancement in which BLOBs will store the binary encoding
for JSON.


The "1" at the end of the name for the json1 extension is deliberate.
The designers anticipate that there will be future incompatible JSON
extensions building upon the lessons learned from json1.
Once sufficient experience is gained, some kind of
JSON extension might be folded into the SQLite core.  For now,
JSON support remains an extension.

3.1. JSON arguments


For functions that accept JSON as their first argument, that argument
can be a JSON object, array, number, string, or null.  SQLite numeric
values and NULL values are interpreted as JSON numbers and nulls, respectively.
SQLite text values can be understood as JSON objects, arrays, or strings.
If an SQLite text value that is not a well-formed JSON object, array, or
string is passed into json1 function, that function will usually throw
an error.  (Exceptions to this rule are json_valid() and
json_quote().)


For the purposes of determining validity, leading and trailing whitespace
on JSON inputs is ignored.  Interior whitespace is also ignored, in accordance
with the JSON spec.  These routines accept exactly the 
rfc-7159 JSON syntax
&mdash; no more and no less.



3.2. PATH arguments


For functions that accept PATH arguments, that PATH must be well-formed or
else the function will throw an error.
A well-formed PATH is a text value that begins with exactly one
'$' character followed by zero or more instances
of ".objectlabel" or "&#91;arrayindex&#93;".


The arrayindex is usually a non-negative integer N.  In
that case, the array element selected is the N-th element
of the array, starting with zero on the left.
The arrayindex can also be of the form "#-N"
in which case the element selected is the N-th from the
right.  The last element of the array is "#-1".  Think of
the "#" characters as the "number of elements in the array".  Then
the expression "#-1" evaluates is the integer that corresponds to 
the last entry in the array.

3.3. VALUE arguments


For functions that accept "value" arguments (also shown as
"value1" and "value2"),
those arguments is usually understood
to be a literal strings that are quoted and becomes JSON string values
in the result.  Even if the input value strings look like 
well-formed JSON, they are still interpreted as literal strings in the
result.


However, if a value argument come directly from the result of another
json1 function, then the argument is understood to be actual JSON and
the complete JSON is inserted rather than a quoted string.


For example, in the following call to json_object(), the value
argument looks like a well-formed JSON array.  However, because it is just
ordinary SQL text, it is interpreted as a literal string and added to the
result as a quoted string:


json_object('ex','[52,3.14159]')
&rarr; '{"ex":"[52,3.14159]"}'





But if the value argument in the outer json_object() call is the
result of another json1 function like json() or json_array(), then
the value is understood to be actual JSON and is inserted as such:


json_object('ex',json('[52,3.14159]'))
&rarr; '{"ex":[52,3.14159]}'

json_object('ex',json_array(52,3.14159))
&rarr; '{"ex":[52,3.14159]}'





To be clear: "json" arguments are always interpreted as JSON
regardless of where the value for that argument comes from.  But
"value" arguments are only interpreted as JSON if those arguments
come directly from another json1 function.

3.4. Compatibility


The json1 extension uses the sqlite3_value_subtype() and
sqlite3_result_subtype() interfaces that were introduced with
SQLite version 3.9.0 (2015-10-14)
The json1 extension will not work
in earlier versions of SQLite.


The current implementation of this JSON library uses a recursive descent
parser.  In order to avoid using excess stack space, any JSON input that has
more than 2000 levels of nesting is considered invalid.   Limits on nesting
depth are allowed for compatible implementations of JSON by
RFC-7159 section 9.


4. Function Details

The following sections provide additional detail on the operation of
the various functions that are part of the json1 extension.



4.1. The json() function

The json(X) function verifies that its argument X is a valid
JSON string and returns a minified version of that JSON string
(with all unnecessary whitespace removed).  If X is not a well-formed
JSON string, then this routine throws an error.

If the argument X to json(X) contains JSON objects with duplicate
labels, then it is undefined whether or not the duplicates are
preserved.  The current implementation preserves duplicates.
However, future enhancements
to this routine may choose to silently remove duplicates.


Example:


json(' { "this" : "is", "a": [ "test" ] } ')
&rarr; '{"this":"is","a":["test"]}'






4.2. The json_array() function

The json_array() SQL function accepts zero or more arguments and
returns a well-formed JSON array that is composed from those arguments.
If any argument to json_array() is a BLOB then an error is thrown.

An argument with SQL type TEXT it is normally converted into a quoted 
JSON string.  However, if the argument is the output from another json1
function, then it is stored as JSON.  This allows calls to json_array()
and json_object() to be nested.  The json() function can also
be used to force strings to be recognized as JSON.

Examples:


json_array(1,2,'3',4)
&rarr; '[1,2,"3",4]'

json_array('[1,2]')
&rarr; '["[1,2]"]'

json_array(json_array(1,2))
&rarr; '[[1,2]]'

json_array(1,null,'3','[4,5]','{"six":7.7}')
&rarr; '[1,null,"3","[4,5]","{\"six\":7.7}"]'

json_array(1,null,'3',json('[4,5]'),json('{"six":7.7}'))
&rarr; '[1,null,"3",[4,5],{"six":7.7}]'







4.3. The json_array_length() function

The json_array_length(X) function returns the number of elements
in the JSON array X, or 0 if X is some kind of JSON value other
than an array.  The json_array_length(X,P) locates the array at path P
within X and returns the length of that array, or 0 if path P locates
an element or X other than a JSON array, and NULL if path P does not
locate any element of X.  Errors are thrown if either X is not 
well-formed JSON or if P is not a well-formed path.

Examples:


json_array_length('[1,2,3,4]')
&rarr; 4

json_array_length('[1,2,3,4]', '$')
&rarr; 4

json_array_length('[1,2,3,4]', '$[2]')
&rarr; 0

json_array_length('{"one":[1,2,3]}')
&rarr; 0

json_array_length('{"one":[1,2,3]}', '$.one')
&rarr; 3

json_array_length('{"one":[1,2,3]}', '$.two')
&rarr; NULL







4.4. The json_extract() function

The json_extract(X,P1,P2,...) extracts and returns one or more 
values from the
well-formed JSON at X.  If only a single path P1 is provided, then the
SQL datatype of the result is NULL for a JSON null, INTEGER or REAL
for a JSON numeric value, an INTEGER zero for a JSON false value,
an INTEGER one for a JSON true value, the dequoted text for a 
JSON string value, and a text representation for JSON object and array values.
If there are multiple path arguments (P1, P2, and so forth) then this
routine returns SQLite text which is a well-formed JSON array holding
the various values.

Examples:


json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$')
&rarr; '{"a":2,"c":[4,5,{"f":7}]}'

json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c')
&rarr; '[4,5,{"f":7}]'

json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]')
&rarr; '{"f":7}'

json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f')
&rarr; 7

json_extract('{"a":2,"c":[4,5],"f":7}','$.c','$.a')
&rarr; '[[4,5],2]'

json_extract('{"a":2,"c":[4,5],"f":7}','$.c[#-1]')
&rarr; 5

json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x')
&rarr; NULL

json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x', '$.a')
&rarr; '[null,2]'


  







4.5. The json_insert(), json_replace, and json_set() functions

The json_insert(), json_replace, and json_set() functions all take
a single JSON value as their first argument followed by zero or more
pairs of path and value arguments, and return a new JSON string formed
by updating the input JSON by the path/value pairs.  The functions
differ only in how they deal with creating new values and overwriting
preexisting values.




FunctionOverwrite if already exists?Create if does not exist?

json_insert()NoYes

json_replace()YesNo

json_set()YesYes


The json_insert(), json_replace(), and json_set() functions always
take an odd number of arguments.  The first argument is always the original
JSON to be edited.  Subsequent arguments occur in pairs with the first
element of each pair being a path and the second element being the value
to insert or replace or set on that path.

Edits occurs sequentially from left to right.  Changes caused by
prior edits can affect the path search for subsequent edits.

If the value of a path/value pair is an SQLite TEXT value, then it
is normally inserted as a quoted JSON string, even if the string looks
like valid JSON.  However, if the value is the result of another
json1 function (such as json() or json_array() or json_object())
then it is interpreted as JSON and is inserted as JSON retaining all
of its substructure.

These routines throw an error if the first JSON argument is not
well-formed or if any PATH argument is not well-formed or if any
argument is a BLOB.

To append an element onto the end of an array, using json_insert()
with an array index of "#".  Examples:


json_insert('[1,2,3,4]','$[#]',99)
&rarr; '[1,2,3,4,99]'

json_insert('[1,[2,3],4]','$[1][#]',99)
&rarr; '[1,[2,3,99],4]'




Other examples:


json_insert('{"a":2,"c":4}', '$.a', 99)
&rarr; '{"a":2,"c":4}'

json_insert('{"a":2,"c":4}', '$.e', 99)
&rarr; '{"a":2,"c":4,"e":99}'

json_replace('{"a":2,"c":4}', '$.a', 99)
&rarr; '{"a":99,"c":4}'

json_replace('{"a":2,"c":4}', '$.e', 99)
&rarr; '{"a":2,"c":4}'

json_set('{"a":2,"c":4}', '$.a', 99)
&rarr; '{"a":99,"c":4}'

json_set('{"a":2,"c":4}', '$.e', 99)
&rarr; '{"a":2,"c":4,"e":99}'

json_set('{"a":2,"c":4}', '$.c', '[97,96]')
&rarr; '{"a":2,"c":"[97,96]"}'

json_set('{"a":2,"c":4}', '$.c', json('[97,96]'))
&rarr; '{"a":2,"c":[97,96]}'

json_set('{"a":2,"c":4}', '$.c', json_array(97,96))
&rarr; '{"a":2,"c":[97,96]}'






4.6. The json_object() function

The json_object() SQL function accepts zero or more pairs of arguments
and returns a well-formed JSON object that is composed from those arguments.
The first argument of each pair is the label and the second argument of
each pair is the value.
If any argument to json_object() is a BLOB then an error is thrown.

The json_object() function currently allows duplicate labels without
complaint, though this might change in a future enhancement.

An argument with SQL type TEXT it is normally converted into a quoted 
JSON string even if the input text is well-formed JSON.  
However, if the argument is the direct result from another json1
function, then it is treated as JSON and all of its JSON type information
and substructure is preserved.  This allows calls to json_object()
and json_array() to be nested.  The json() function can also
be used to force strings to be recognized as JSON.

Examples:


json_object('a',2,'c',4)
&rarr; '{"a":2,"c":4}'

json_object('a',2,'c','{e:5}')
&rarr; '{"a":2,"c":"{e:5}"}'

json_object('a',2,'c',json_object('e',5))
&rarr; '{"a":2,"c":{"e":5}}'






4.7. The json_patch() function

The json_patch(T,P) SQL function runs the
RFC-7396 MergePatch algorithm
to apply patch P against input T.  The patched copy of T is returned.

MergePatch can add, modify, or delete elements of a JSON Object,
and so for JSON Objects, the json_patch() routine is a generalized
replacement for json_set() and json_remove().  However, MergePatch
treats JSON Array objects as atomic.  MergePatch cannot append to an
Array nor modify individual elements of an Array.  It can only insert,
replace, or delete the whole Array as a single unit.  Hence, json_patch()
is not as useful when dealing with JSON that includes Arrays,
especially Arrays with lots of substructure.

Examples:


json_patch('{"a":1,"b":2}','{"c":3,"d":4}')
&rarr; '{"a":1,"b":2,"c":3,"d":4}'

json_patch('{"a":[1,2],"b":2}','{"a":9}')
&rarr; '{"a":9,"b":2}'

json_patch('{"a":[1,2],"b":2}','{"a":null}')
&rarr; '{"b":2}'

json_patch('{"a":1,"b":2}','{"a":9,"b":null,"c":8}')
&rarr; '{"a":9,"c":8}'

json_patch('{"a":{"x":1,"y":2},"b":3}','{"a":{"y":9},"c":8}')
&rarr; '{"a":{"x":1,"y":9},"b":3,"c":8}'






4.8. The json_remove() function

The json_remove(X,P,...) function takes a single JSON value as its
first argument followed by zero or more path arguments.
The json_remove(X,P,...) function returns
a new JSON value that is the X with all the elements 
identified by path arguments removed.  Paths that select elements
not found in X are silently ignored.

Removals occurs sequentially from left to right.  Changes caused by
prior removals can affect the path search for subsequent arguments.

If the json_remove(X) function is called with no path arguments,
then it returns the input X reformatted, with excess whitespace
removed.

The json_remove() function throws an error if the first argument
is not well-formed JSON or if any later argument is not a well-formed
path, or if any argument is a BLOB.

Examples:


json_remove('[0,1,2,3,4]','$[2]')
&rarr; '[0,1,3,4]'

json_remove('[0,1,2,3,4]','$[2]','$[0]')
&rarr; '[1,3,4]'

json_remove('[0,1,2,3,4]','$[0]','$[2]')
&rarr; '[1,2,4]'

json_remove('[0,1,2,3,4]','$[#-1]','$[0]')
&rarr; '[1,2,3]'

json_remove('{"x":25,"y":42}')
&rarr; '{"x":25,"y":42}'

json_remove('{"x":25,"y":42}','$.z')
&rarr; '{"x":25,"y":42}'

json_remove('{"x":25,"y":42}','$.y')
&rarr; '{"x":25}'

json_remove('{"x":25,"y":42}','$')
&rarr; NULL






4.9. The json_type() function

The json_type(X) function returns the "type" of the outermost element
of X.  The json_type(X,P) function returns the "type" of the element
in X that is selected by path P.  The "type" returned by json_type() is
one of the following an SQL text values:
'null', 'true', 'false', 'integer', 'real', 'text', 'array', or 'object'.
If the path P in json_type(X,P) selects an element that does not exist
in X, then this function returns NULL.

The json_type() function throws an error if any of its arguments are
not well-formed or is a BLOB.

Examples:


json_type('{"a":[2,3.5,true,false,null,"x"]}')
&rarr; 'object'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$')
&rarr; 'object'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a')
&rarr; 'array'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]')
&rarr; 'integer'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]')
&rarr; 'real'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]')
&rarr; 'true'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]')
&rarr; 'false'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]')
&rarr; 'null'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]')
&rarr; 'text'

json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]')
&rarr; NULL






4.10. The json_valid() function

The json_valid(X) function return 1 if the argument X is well-formed
JSON and return 0 if the argument X is not well-formed JSON.

Examples:


json_valid('{"x":35}')
&rarr; 1

json_valid('{"x":35')
&rarr; 0






4.11. The json_quote() function

The json_quote(X) function converts the SQL value X (a number or a
string) into its corresponding JSON representation. 

Examples:


json_quote(3.14159)
&rarr; 3.14159

json_quote('verdant')
&rarr; "verdant"







4.12. The json_group_array() and json_group_object()
aggregate SQL functions

The json_group_array(X) function is an 
aggregate SQL function that returns a JSON array
comprised of all X values in the aggregation.
Similarly, the json_group_object(NAME,VALUE) function returns a JSON object
comprised of all NAME/VALUE pairs in the aggregation.






4.13. The json_each() and json_tree() table-valued functions

The json_each(X) and json_tree(X) table-valued functions walk the
JSON value provided as their first argument and return one row for each
element.  The json_each(X) function only walks the immediate children
of the top-level array or object or 
or just the top-level element itself if the top-level
element is a primitive value.
The json_tree(X) function recursively walks through the
JSON substructure starting with the top-level element.  

The json_each(X,P) and json_tree(X,P) functions work just like
their one-argument counterparts except that they treat the element
identified by path P as the top-level element.

The schema for the table returned by json_each() and json_tree() is
as follows:


CREATE TABLE json_tree(
    key ANY,             -- key for current element relative to its parent
    value ANY,           -- value for the current element
    type TEXT,           -- 'object','array','string','integer', etc.
    atom ANY,            -- value for primitive types, null for array & object
    id INTEGER,          -- integer ID for this element
    parent INTEGER,      -- integer ID for the parent of this element
    fullkey TEXT,        -- full path describing the current element
    path TEXT,           -- path to the container of the current row
    json JSON HIDDEN,    -- 1st input parameter: the raw JSON
    root TEXT HIDDEN     -- 2nd input parameter: the PATH at which to start
);



The "key" column is the integer array index for elements of a JSON array 
and the text label for elements of a JSON object.  The key column is
NULL in all other cases.


The "atom" column is the SQL value corresponding to primitive elements - 
elements other than JSON arrays and objects.  The "atom" column is NULL
for a JSON array or object.  The "value" column is the same as the
"atom" column for primitive JSON elements but takes on the text JSON value
for arrays and objects.


The "type" column is an SQL text value taken from ('null', 'true', 'false',
'integer', 'real', 'text', 'array', 'object') according to the type of
the current JSON element.


The "id" column is an integer that identifies a specific JSON element
within the complete JSON string.  The "id" integer is an internal housekeeping
number, the computation of which might change in future releases.  The
only guarantee is that the "id" column will be different for every row.


The "parent" column is always NULL for json_each().
For json_tree(),
the "parent" column is the "id" integer for the parent of the current
element, or NULL for the top-level JSON element or the element identified
by the root path in the second argument.


The "fullkey" column is a text path that uniquely identifies the current
row element within the original JSON string.  The complete key to the
true top-level element is returned even if an alternative starting point
is provided by the "root" argument.


The "path" column is the path to the array or object container the holds 
the current row, or the path to the current row in the case where the 
iteration starts on a primitive type and thus only provides a single
row of output.

4.13.1. Examples using json_each() and json_tree()

Suppose the table "CREATE TABLE user(name,phone)" stores zero or
more phone numbers as a JSON array object in the user.phone field.
To find all users who have any phone number with a 704 area code:


SELECT DISTINCT user.name
  FROM user, json_each(user.phone)
 WHERE json_each.value LIKE '704-%';


Now suppose the user.phone field contains plain text if the user
has only a single phone number and a JSON array if the user has multiple
phone numbers.  The same question is posed: "Which users have a phone number
in the 704 area code?"  But now the json_each() function can only be called
for those users that have two or more phone numbers since json_each()
requires well-formed JSON as its first argument:


SELECT name FROM user WHERE phone LIKE '704-%'
UNION
SELECT user.name
  FROM user, json_each(user.phone)
 WHERE json_valid(user.phone)
   AND json_each.value LIKE '704-%';


Consider a different database with "CREATE TABLE big(json JSON)".
To see a complete line-by-line decomposition of the data:


SELECT big.rowid, fullkey, value
  FROM big, json_tree(big.json)
 WHERE json_tree.type NOT IN ('object','array');


In the previous, the "type NOT IN ('object','array')" term of the
WHERE clause suppresses containers and only lets through leaf elements.
The same effect could be achieved this way:


SELECT big.rowid, fullkey, atom
  FROM big, json_tree(big.json)
 WHERE atom IS NOT NULL;


Suppose each entry in the BIG table is a JSON object 
with a '$.id' field that is a unique identifier
and a '$.partlist' field that can be a deeply nested object.
You want to find the id of every entry that contains one
or more references to uuid '6fa5181e-5721-11e5-a04e-57f3d7b32808' anywhere
in its '$.partlist'.


SELECT DISTINCT json_extract(big.json,'$.id')
  FROM big, json_tree(big.json, '$.partlist')
 WHERE json_tree.key='uuid'
   AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';


