RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
Описание SQLite Bytecode

1. Обзор

SQLite работает, переводя SQL-операторы на bytecode и затем управляя этим bytecode в виртуальной машине. Этот документ описывает, как bytecode работает.

Этот документ описывает внутренности SQLite. Информация, предоставленная здесь, не необходима для обычной разработки приложений, используя SQLite. Этот документ предназначается для людей, которые хотят копаться более глубоко во внутренней структуре SQLite.

bytecode не API SQLite. Детали о bytecode изменяются от одного выпуска SQLite к следующему. Запросы, которые используют SQLite, не должны зависеть ни от одной из деталей, найденных в этом документе.

2. Введение

SQLite работает, переводя каждый SQL-оператор на bytecode и затем управляя этим bytecode. A Подготовленный запрос в SQLite главным образом просто bytecode, который должен был осуществить соответствующий SQL. sqlite3_prepare_v2() это компилятор, который переводит SQL на bytecode. sqlite3_step() это виртуальная машина, которая управляет bytecode в рамках подготовленного запроса.

Программисты, которые хотят понять, как SQLite работает внутренне, должны быть знакомы с bytecode-движком.

Исторически, bytecode-движок в SQLite известен как "Virtual DataBase Engine" или "VDBE". Этот веб-сайт использует термины "bytecode engine", "VDBE", "virtual machine" и "bytecode virtual machine" попеременно, поскольку они все имеют в виду то же самое.

Эта статья также использует термины "bytecode-программа" и "подготовленный запрос" попеременно, поскольку они главным образом то же самое.

2.1. Исходный текст VDBE

Исходный текст bytecode-движка находится в файле vdbe.c. Определения кода операции в этом документе получены на основании комментариев в том исходном файле. Комментарии исходного кода это канонический источник информации о bytecode. Когда сомневаетесь, обратитесь к исходному коду.

В дополнение к основному файлу исходного кода vdbe.c в исходном дереве есть другие кодовые файлы-помощники, чьи имена начинаются с "vdbe", сокращение от "Virtual DataBase Engine".

Помните, что имена и значения кодов операции часто изменяются от одного выпуска SQLite к следующему. Таким образом, если вы изучаете вывод EXPLAIN в SQLite, необходимо сослаться на версию этого документа (или исходный код vdbe.c), который соответствует версии SQLite, который управлял EXPLAIN. Иначе описание кодов операции может не быть точным. Этот документ получен из SQLite version 3.44.0 17129ba1ff7f0 dated 2023-11-01.

2.2. Формат инструкций

bytecode в SQLite состоит из одной или более инструкций. У каждой инструкции есть код операции и пять операндов по имени P1, P2 P3, P4 и P5. P1, P2 и P3 это 32-битные целые числа со знаком. Эти операнды часто обращаются к регистрам. Для инструкций, которые воздействуют на курсоры b-дерева, операнд P1 обычно номер курсора. Для команд перехода P2 обычно место назначения. P4 может быть 32-битным целым числом со знаком, 64-битным целым числом со знаком, 64-битным значением с плавающей точкой, строковым литералом, Blob, указателем на функцию сравнения последовательности сопоставления, указателем на внедрение определенной применением функции SQL или чем-то еще. P5 это 16-битное целое без знака, обычно хранит флаги. Части флага P5 могут иногда затрагивать код операции тонкими способами. Например, если SQLITE_NULLEQ (0x0080) часть операнда P5 установлен на коде операции Eq, NULL выдерживают сравнение равенства друг другу. Иначе NULL считаются отличающимися друг от друга.

Некоторые коды операции используют все пять операндов. Некоторые коды операции используют один или два. Некоторые коды операции не используют ни один из операндов.

bytecode начинает выполнение на инструкции номер 0. Выполнение продолжается, пока инструкция Halt не замечена, пока счетчик команд не становится больше, чем адрес последней инструкции или пока нет ошибки. Когда bytecode останавливается, вся память, которую он ассигновал, освобождена, закрываются все курсоры базы данных, которые он, возможно, открыл. Если выполнение остановилось из-за ошибки, любые отложенные транзакции закончены, и изменения, внесенные в базу данных, отменены.

Код операции ResultRow заставляет bytecode делать паузу, и соответствующие sqlite3_step() вернут SQLITE_ROW. Прежде, чем вызвать ResultRow, bytecode загрузит результаты для единственноой строки запроса в ряд регистров. C API, такой как sqlite3_column_int() или sqlite3_column_text(), извлекает результаты запроса из тех регистров. bytecode возобновляется со следующей инструкцией после ResultRow на следующем вызове sqlite3_step().

2.3. Регистры

У каждой bytecode-программы есть фиксированное (но потенциально большое) количество регистров. Единственный регистр может содержать множество объектов:

Регистр может также быть "Undefined", что подразумевает, что он не содержит значение вообще. Неопределенный отличается от NULL. В зависимости от вариантов времени компиляции попытка прочитать неопределенный регистр будет обычно вызывать ошибку периода выполнения. Если генератор кода (sqlite3_prepare_v2()) когда-нибудь производит подготовленный запрос, который читает неопределенный регистр, это является ошибкой в генераторе кода.

Регистры пронумерованы, начав с 0. Большинство кодов операции обращается по крайней мере к одному регистру.

Количество регистров в единственном подготовленном запросе фиксируется во время компиляции. Содержание всех регистров очищено, когда подготовленный запрос сбрасывается или закрывается.

Внутренняя объектно-ориентированная память Mem хранит значение для единственного регистра. Абстрактный объект sqlite3_value, который выставляется в API, является действительно просто объектом Mem или регистром.

2.4. Курсоры B-Tree

Подготовленный запрос может иметь нуль или более открытых курсоров. Каждый курсор определяется маленьким целым числом, которое обычно является параметром P1 к коду операции, который использует курсор. Могут быть многократные курсоры, открытые на том же самом индексе или таблице. Все курсоры работают независимо, даже курсоры, указывающие на те же самые индексы или таблицы. Единственный путь к виртуальной машине, чтобы взаимодействовать с файлом базы данных, это через курсор. Инструкции в виртуальной машине могут создать новый курсор (OpenRead или OpenWrite), читать данные из курсора (Column), сдвинуть курсор к другому входу в таблице (Next или Prev) и т.д. Все курсоры автоматически закрываются, когда подготовленный запрос сброшен или закрыт.

2.5. Подпрограммы

bytecode не имеет стека, в котором можно сохранить обратный адрес подпрограммы. Обратные адреса должны быть сохранены в регистрах.

Код операции Gosub сохранит текущий счетчик команд в регистр P1, затем переходит на адрес в P2. Return переходит на адрес в P1+1. Следовательно, каждая подпрограмма связана с двумя целыми числами: адрес точки входа в подпрограмму и номер регистра, который используется, чтобы хранить обратный адрес.

Код операции Yield меняет значение счетчика команд с целочисленным значением в регистре P1. Этот код операции используется, чтобы осуществить подпрограммы, они часто используются, чтобы осуществить подвопросы, из которых содержание вынимают по мере необходимости.

Триггеры должны быть поточно-безопасны. Так так подпрограммы bytecode не поточно-безопасны, различный механизм должен использоваться, чтобы осуществить триггеры. Каждый триггер осуществляется, используя отдельную bytecode-программу с ее собственными кодами операции, счетчиком команд и набором регистров. Код операции Program вызывает триггер. Program ассигнует и инициализирует новый набор регистров для каждого вызова подпрограммы, таким образом, подпрограммы могут быть поточно-безопасны и рекурсивны. Код операции Param используется подпрограммами, чтобы получить доступ к содержанию в регистрах запроса bytecode-программы.

2.6. Самоизменение кода

Некоторые коды операции самоизменяются. Например, код операции Init (который всегда является первым кодом операции в каждой bytecode-программе) увеличивает свой операнд P1. Последующий Once сравнивают свои операнды P1 со значением P1 для Init, чтобы определить, должен ли одноразовый код инициализации, который следует, быть пропущен. Другой пример это код операции String8, который преобразовывает его операнд P4 из UTF-8 в правильное кодирование последовательности базы данных, затем преобразовывает себя в код операции String.

3. Просмотр Bytecode

Каждый SQL-оператор SQLite интерпретирует в программе для виртуальной машины. Но если SQL-оператор начнется с ключевого слова EXPLAIN, то виртуальная машина не выполнит программу. Вместо этого инструкции программы будут возвращены, одна инструкция на строку, как результат запроса. Эта особенность полезна для отладки и для изучения, как виртуальная машина работает. Например:

$ sqlite3 ex1.db
sqlite> explain delete from tbl1 where two<20;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     12    0                    00  Start at 12
1     Null           0     1     0                    00  r[1]=NULL
2     OpenWrite      0     2     0     3              00  root=2 iDb=0; tbl1
3     Rewind         0     10    0                    00
4     Column         0     1     2                    00  r[2]=tbl1.two
5     Ge             3     9     2     (BINARY)       51  if r[2]>=r[3] goto 9
6     Rowid          0     4     0                    00  r[4]=rowid
7     Once           0     8     0                    00
8     Delete         0     1     0     tbl1           02
9     Next           0     4     0                    01
10    Noop           0     0     0                    00
11    Halt           0     0     0                    00
12    Transaction    0     1     1     0              01  usesStmtJournal=0
13    TableLock      0     2     1     tbl1           00  iDb=0 root=2 write=1
14    Integer        20    3     0                    00  r[3]=20
15    Goto           0     1     0                    00

Любое применение может управлять EXPLAIN, который выдаст подобное вышеупомянутому. Оболочка командной строки содержит дополнительную логику для того, чтобы определить циклы. Кроме того, колонка "комментария" в выводе EXPLAIN предоставлена только, если SQLite собран с -DSQLITE_ENABLE_EXPLAIN_COMMENTS.

Когда SQLite собран с выбором времени компиляции SQLITE_DEBUG, команды PRAGMA доступны, которые полезны для отладки и для исследования операции VDBE. Например, vdbe_trace pragma можно заставить выполнить разборку каждого кода операции VDBE с печатью на стандартном выводе, поскольку код операции выполняется. Отладочные pragma включают:

4. Коды операции

В настоящее время есть 187 кодов операции, определенных виртуальной машиной. Все в настоящее время определяемые коды операции описаны в приведенной ниже таблице. Она была произведена автоматически, сканируя исходный код из файла vdbe.c.

Помните: коды операции VDBE не часть интерфейсного определения для SQLite. Количество кодов операции и их имен и значений изменяется от одного выпуска SQLite к следующему. Коды операции, показанные в приведенной ниже таблице, действительны для SQLite version 3.44.0 17129ba1ff7f0 dated 2023-11-01.

Имя OpcodeОписание
Abortable Проверьте, что аварийное прекращение работы может произойти, проверяет могло ли бы аварийное прекращение работы в этом пункте вызвать повреждение базы данных. Этот код операции появляется только в отладочной сборке.

Abort безопасно если не было записей или если есть активный журнал.

Add Добавьте значение в регистре P1 к значению в регистре P2 и сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
AddImm Добавьте постоянную P2 к значению в регистре P1. Результат всегда целое число.

Чтобы вынудить любой регистр быть целым числом, просто добавьте 0.

Affinity Примените близость к диапазону регистров P2, начиная с P1.

P4 это строка, которая имеет длину в P2 символов. N-й символ указывает на близость колонки, которая должна использоваться для N-го элемента памяти в диапазоне.

AggFinal P1 это ячейка памяти, которая является сумматором для функции окна или совокупности. Выполните функцию finalizer на совокупности и сохраните результат в P1.

P2 это количество аргументов, которое ступенчатая функция берет, а P4 это указатель на FuncDef для этой функции. Аргумент P2 не используется этим кодом операции. Это только чтобы снять неоднозначность функций, которые могут взять переменное число аргументов. Аргумент P4 необходим только для случая, где ступенчатую функцию ранее не вызывали.

AggInverse Выполнить функцию xInverse для совокупности. У функции есть аргументы P5. P4 указатель на структуру FuncDef, которая определяет функцию. Регистр P3 является сумматором.

Аргументы P5 взяты из регистра P2 и его преемников.

AggStep Выполните функцию xStep для совокупности. У функции есть аргументы P5. P4 указатель на структуру FuncDef, которая определяет функцию. Регистр P3 является сумматором.

Аргументы P5 взяты из регистра P2 и его преемников.

AggStep1 Выполнить xStep (если P1=0) или xInverse (если P1!=0) для совокупности. Аргументы P5 взяты из регистра P2 и его преемников. У функции есть аргументы P5. P4 указатель на структуру FuncDef, которая определяет функцию. Регистр P3 является сумматором.

Этот код операции первоначально закодирован как OP_AggStep0. На первой оценке FuncDef, сохраненный в P4, преобразовывается в sqlite3_context и код операции изменяется. Таким образом инициализация sqlite3_context происходит только однажды, а не при каждом обращении к ступенчатой функции.

AggValue Вызовите xValue() и сохраните результат в регистре P3.

P2 это число аргументов, что ступенчатая функция берет, и P4 указатель на FuncDef для этой функции. Аргумент P2 не используется этим кодом операции. Это только чтобы снять неоднозначность функций, которые могут взять переменное число аргументов. Аргумент P4 необходим только для случая, где ступенчатую функцию ранее не вызывали.

And Возьмите логический AND значений в P1 и P2 и напишите результат в регистр P3.

Если P1 или P2 = 0 (false), результат 0, даже если другой вход NULL. NULL и true или 2 NULL всегда дадут NULL.

AutoCommit Установите флаг auto-commit базы данных в P1 (1 или 0). Если P2 = true, отмените любые в настоящее время активные btree-транзакции. Если есть какие-либо активные VM (кроме этой), то ROLLBACK терпит неудачу. COMMIT терпит неудачу, если есть активная запись VM или активный VM, использующая общий кэш.

Эта инструкция заставляет VM останавливаться.

BeginSubrtn Отметьте начало подпрограммы, которая может быть введена, или это можно вызвать, используя Gosub. Подпрограмма должна быть закончена инструкцией Return, у которой есть операнд P1, который совпадает с операндом P2 к этому коду операции, и у этого есть P3 = 1. Если подпрограмма будет введена напрямую, то Return просто провалится. Но если подпрограмма будет введена, используя Gosub, Return перейдет назад к первой инструкции после Gosub.

Это работает, загружая NULL в регистр P2. Когда регистр обратного адреса содержит NULL, инструкция Return не делает ничего, просто проваливается к следующей инструкции (предполагая, что у кода операции Return P3 = 1). Таким образом, если подпрограмма будет введена напрямую, Return заставит действующее выполнение продолжаться. Но если подпрограмма будет введена через Gosub, Return вызовет возвращение к адресу после Gosub.

Этот код операции идентичен Null. У этого есть другое имя только, чтобы заставить легче прочитать и проверить.

BitAnd Возьмите поразрядный AND значений в регистрах P1 и P2 и сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
BitNot Интерпретируйте содержание регистра P1 как целое число. Сохраните поразрядное дополнение до единицы значения P1 в регистр P2. Если P1 хранит NULL, пишите NULL в P2.
BitOr Возьмите битовое OR значений в регистрах P1 и P2 и сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
Blob P4 указывает на blob P1 байт длиной. Сохраните blob в P2. Если P4 = NULL, постройте заполненный нолем blob P1 байтов длиной в P2.
Cast Вынудите значение в регистре P1 быть типом, определенным P2.

  • P2='A' → BLOB
  • P2='B' → TEXT
  • P2='C' → NUMERIC
  • P2='D' → INTEGER
  • P2='E' → REAL

NULL не изменяется этим установленным порядком. Это остается NULL.

Checkpoint Контрольная точка базы данных P1. Не делает ничего, если P1 не в режиме WAL. P2 один из SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART или TRUNCATE. Запишите 1 или 0 в mem[P3], если контрольная точка возвращает SQLITE_BUSY или нет, соответственно. Напишите число страниц в WAL после контрольной точки в mem[P3+1] и число страниц в WAL, которые были обработаны после того, как контрольная точка заканчивает, в mem[P3+2]. Однако, на ошибке, mem[P3+1] и mem[P3+2] = -1.
Clear Удалите все содержание таблицы базы данных или индекса, страница корня которого в файле базы данных дана как P1. Но, в отличие от Destroy, не удаляйте таблицу или индекс из файла базы данных.

Очищаемая таблица находится в главном файле базы данных если P2 = 0. Если P2 = 1, тогда таблица находится во вспомогательном файле базы данных, который используется для хранения таблиц из CREATE TEMPORARY TABLE.

Если P3 не 0, количество изменения строки увеличено количеством строк в очищаемой таблице. Если P3 больше, чем ноль, то значение, сохраненное в регистре P3, также увеличено количеством строк в очищаемой таблице.

См. также: Destroy

Close Закройте курсор, ранее открытый как P1. Если P1 в настоящее время не открыт, эта инструкция ничего не делает.
ClrSubtype Очистите подтип из регистра P1.
CollSeq P4 указатель на объект CollSeq. Если следующее вызов к функции пользователя или совокупности вызовет sqlite3GetFuncCollSeq(), эта сортирующая последовательность будет возвращена. Это используется встроенными min(), max() и nullif().

Если P1 не 0, то это регистр, который последующую совокупность min() или max() установит в 1, если текущая строка не будет минимумом или максимумом. Регистр P1 инициализируется к 0 этой инструкцией.

Интерфейс, используемый внедрением вышеупомянутых функций, чтобы восстановить сортирующую последовательность, установленную этим кодом операции, не доступен публично. Только у встроенных функций есть доступ к этой особенности.

Column Интерпретируйте данные, на которые указывает курсор P1, как структуру, построенную использованием инструкции MakeRecord. См. подробности в MakeRecord. Извлеките P2-ю колонку из этого записи. Если есть меньше, чем (P2+1) значений в записи, извлекают NULL.

Извлеченное значение сохранено в регистре P3.

Если запись содержит меньше, чем P2 полей, верните NULL. Ксли аргумент P4 это P4_MEM, примените значение аргумента P4 как результат.

Если бит OPFLAG_LENGTHARG установлен в P5, результат, как гарантируют, будет использоваться только length() или эквивалентом. Содержание больших blob не загружается, таким образом экономя циклы CPU. Если бит OPFLAG_TYPEOFARG установлен, результат будет использоваться только typeof(), операторами IS NULL, IS NOT NULL или аналогами. В этом случае весь загруженный контент может быть опущен.

ColumnsUsed Этот код операции (который существует только, если SQLite был собран с SQLITE_ENABLE_COLUMN_USED_MASK) определяет, какие колонки таблицы или индекса для курсора P1 используются. P4 это 64-битное целое число (P4_INT64), в котором первые 63 бита по одному для каждой из первых 63 колонок таблицы или индекса, которые на самом деле используются курсором. Старший бит установлен, если какая-либо колонка после 64-й используется.
Compare Сравните два вектора регистров в reg(P1)..reg(P1+P3-1) (это vector "A") и в reg(P2)..reg(P2+P3-1) ("B"). Сохраните результат сравнения для использования следующим Jump.

Если P5 имеет установленный бит OPFLAG_PERMUTE, порядок сравнения определяется новым оператором Permutation. Если бит OPFLAG_PERMUTE очищен, регистры сравнены в последовательном порядке.

P4 это структура KeyInfo, которая определяет последовательности сопоставления и порядки сортировки для сравнения. Перестановка относится только к регистрам. Элементы KeyInfo используются последовательно.

Сравнение это сортированное сравнение, так что NULL считаются равными, NULL меньше, чем числа, числа меньше, чем последовательности, а последовательности меньше, чем blob.

Этот код операции должен немедленно сопровождаться кодом операции Jump.

Concat Добавьте текст в регистре P1 в конец текста в регистре P2 и сохраните результат в регистре P3. Если P1 или P2 = NULL, тогда сохраните NULL в P3.

P3 = P2 || P1

Незаконно для P1 и P3 быть тем же самым регистром. Иногда, если P3 тот же самый регистр как P2, внедрение в состоянии обойти memcpy().

Copy Сделайте копию регистров P1.. P1+P3 в регистры P2.. P2+P3.

Если бит 0x0002 в P5 установлен, также очищают флаг MEM_Subtype в месте назначения. Бит 0x0001 в P5 указывает, что этот код операции Copy не может быть слит. Бит 0x0001 используется планировщиком запроса и не играет роли во время выполнения запросов.

Эта инструкция делает глубокую копию из значения. Дубликат сделан из любой последовательности или постоянного blob. См. также SCopy.

Count Сохраните количество записей (целочисленное значение) в таблице или индексе, открытом курсором P1 в регистре P2.

Если P3=0, точное количество получено, которое включает посещение каждой btree-страницы таблицы. Но если P3 отличный от нуля, оценка возвращена на основе текущей позиции курсора.

CreateBtree Ассигнуйте новое b-дерево в главном файле базы данных, если P1 = 0, в файле базы данных TEMP, если P1 = 1 или в приложенной базе данных, если P1> 1. Аргумент P3 должен быть 1 (BTREE_INTKEY) для rowid-таблицы, 2 (BTREE_BLOBKEY) для индекса или таблицы WITHOUT ROWID. Номер страницы корня нового b-дерева сохранен в регистре P2.
CursorHint Предоставьте намек курсору P1, что он только должен возвратить строки, которые удовлетворяют Expr в P4. Термины TK_REGISTER в выражении P4 относятся к значениям, в настоящее время проводимым в регистрах. Термины TK_COLUMN в выражении P4 относятся к колонкам в b-дереве, на которое указывает курсор P1.
CursorLock Захватите btree, на который указывает курсор P1 так, чтобы btree не мог быть написан другим курсором.
CursorUnlock Разблокируйте btree, на который указывает курсор P1 так, чтобы это могло быть написано другими курсорами.
DecrJumpZero Регистр P1 должен содержать целое число. Уменьшите значение в P1 и перейдите к P2, если новое значение точно ноль.
DeferredSeek P1 открытый курсор индекса, P3 курсор на соответствующей таблице. Этот код операции делает отсроченный поиск курсора таблицы P3 в строке, которая соответствует текущей строке P1.

Это отсроченный поиск. Ничего на самом деле не происходит, пока курсор не используется, чтобы прочитать запись. Если не происходит чтение, никакого ненужного I/O не происходит.

P4 может быть массивом integers (тип P4_INTARRAY), содержащим один вход для каждой колонки в таблице P3. Если запись массива a(i) отличная от нуля, то чтение колонки a(i)-1 от курсора P3 эквивалентно выполнению отсроченного поиска и затем чтение колонки i от P1. Эта информация хранится в P3 и используется, чтобы перенаправить чтение из P3 в P1, таким образом возможно избегая потребности искать и прочитать курсор P3.

Delete Удалите запись, на которую в настоящее время указывает курсор P1.

Если бит OPFLAG_SAVEPOSITION в P5 установлен, курсор будет указывающим налево в следующей или в предыдущей записи в таблице. Если это будет указывающим налево в следующей записи, то следующая инструкция Next ничего не делает. В результате в этом случае нормально удалять запись в цикле Next. Если бит OPFLAG_SAVEPOSITION = 0 в P5, курсор оставят в неопределенном статусе.

Если OPFLAG_AUXDELETE = 1 в P5, указывает, что это удаляет одну из нескольких связанных с удалением строки таблицы строк и всех ее связанных элементов индекса. Точно одно из тех удалений "primary". Все другие на курсорах OPFLAG_FORDELETE или иначе отмечены флагом AUXDELETE.

Если флаг OPFLAG_NCHANGE (0x01) в P2 (P2 НЕ P5) = 1, тогда количество изменения строки увеличено (иначе нет).

Если флаг OPFLAG_ISNOOP (0x40) в P2 (НЕ в P5!) = 1, перехватчик pre-update для удалений выполняется, но btree в других отношениях неизменен. Это происходит, когда Delete должно вскоре сопровождаться Insert с тем же самым ключом, заставляя вход btree быть переписанным.

P1 не должен быть псевдотаблицей. Это должна быть реальная таблица с многократными строкими.

Если P4 не NULL, это указывает на объект таблицы. В этом случае перехватчик update, pre-update или оба может быть вызван. Курсор P1 должен быть позиционирован, используя NotFound до вызова этого кода операции в этом случае. Определенно, если вы настраиваете pre-update вызван, если P4 не NULL. update-hook вызван, если P4 не NULL, и флаг OPFLAG_NCHANGE установлен в P2.

Если флаг OPFLAG_ISUPDATE установлен в P2, P3 содержит адрес элемента памяти, который содержит значение, что rowid строки будет установлен обновлением.

Destroy Удалите всю таблицу базы данных или индекс, страница корня которого в файле базы данных дана в P1.

Таблица находится в главном файле базы данных если P3 = 0. Если P3 = 1, тогда эта таблица находится во вспомогательном файле базы данных, который используется для хранения таблиц, созданных CREATE TEMPORARY TABLE.

Если AUTOVACUUM позволен, тогда возможно, что другая страница корня могла бы быть перемещена в недавно удаленную страницу корня, чтобы сохранять все страницы корня смежными в начале базы данных. Бывшее значение страницы корня, которая переместилась (ее значение перед перемещением) сохранено в регистре P2. Если никакое движение страницы не требовалось (потому что удаляемая таблица уже была последней в базе данных), ноль сохранен в регистре P2. Если AUTOVACUUM выключен, ноль сохранен в регистре P2.

Этот код операции бросает ошибку, если есть какой-либо активный читатель VM, когда это вызвано. Это сделано, чтобы избежать трудности, связанной с обновлением существующих курсоров, когда страница корня перемещена в базу данных AUTOVACUUM. Эта ошибка брошена, даже если база данных не AUTOVACUUM db, чтобы избежать вводить несовместимость между неавтовакуумными режимами и автовакуумом.

См. также: Clear

Divide Разделите значение регистра P1 на значение в регистре P2 и сохраните результат в регистре P3 (P3=P2/P1). Если значение в регистре P1 ноль, то результат NULL. Если любой вход NULL, результат NULL.
DropIndex Удалите внутренние структуры данных (в памяти), которые описывают индекс по имени P4 в базе данных P1. Это вызывают после того, как индекс удален с диска (через Destroy), чтобы сохранять внутреннее представление схемы согласовывающимся с тем, что находится на диске.
DropTable Удалите внутренние структуры данных (в памяти), которые описывают таблицу по имени P4 в базе данных P1. Это вызывают после того, как таблица удалена с диска (через Destroy), чтобы сохранять внутреннее представление схемы согласовывающимся с тем, что находится на диске.
DropTrigger Удалите внутренние структуры данных (в памяти), которые описывают триггер по имени P4 в базе данных P1. Это вызывают после того, как таблица удалена с диска (через Destroy), чтобы сохранять внутреннее представление схемы согласовывающимся с тем, что находится на диске.
ElseEq Этот код операции должен следовать за оператором сравнения Lt или Gt. Может быть ноль или больше кодов OP_ReleaseReg, но никаким другим кодам операции не позволяют произойти между этой инструкцией и предыдущим Lt или Gt.

Если результат сравнения Eq на тех же самых двух операндах как предшествующий Lt или Gt был бы верен, то переходите к P2. Если результат сравнения Eq на двух предыдущих операндах был бы ложным или NULL, то проваливается.

EndCoroutine Инструкцией по адресу в регистре P1 является Yield. Jump на параметр P2 Yield. После перехода P1 становится неопределенным.

См. также: InitCoroutine

Eq Сравните значения в регистрах P1 и P3. Если reg(P3)=reg(P1), перейдите на адрес в P2.

Часть SQLITE_AFF_MASK в P5 должна быть символом близости: SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER и т.д. Попытка предпринята, чтобы привести оба входа согласно этой близости, прежде чем сравнение будет сделано. Если SQLITE_AFF_MASK = 0x00, то числовая близость используется. Обратите внимание на то, что преобразования близости сохранены назад во входные регистры P1 и P3. Таким образом, этот код операции может вызвать постоянные изменения регистров P1 и P3.

Как только любые преобразования произошли, и никакое значение не NULL, значения сравнены. Если оба значения blob, используется memcmp(), чтобы определить результаты сравнения. Если оба значения текст, то соответствующая функция сопоставления, определенная в P4, используется, чтобы сделать сравнение. Если P4 не определяется, тогда используется memcmp(), чтобы сравнить текстовые строки. Если оба значения числовые, то числовое сравнение используется. Если два значения имеют различные типы, то числа считают меньше, чем последовательности, а последовательности считают меньше, чем blob.

Если установлен SQLITE_NULLEQ в P5, результат сравнения всегда true или false, но не NULL. Если оба операнда NULL, результат сравнения true. Если любой операнд NULL, результат false. Если никакой операнд не NULL, результат совпадает с тем, что было бы, если бы флаг SQLITE_NULLEQ был опущен в P5.

Этот код операции сохранит результат сравнения для использования новым кодом операции Jump.

Expire Заставьте предварительно собранные запросы истекать. Когда запрос с истекшим сроком будет выполнен, используя sqlite3_step() он автоматически повторно подготовится (если он был первоначально создан, используя sqlite3_prepare_v2()) или потерпит неудачу с SQLITE_SCHEMA.

Если P1 = 0, то все SQL-операторы становятся с истекшим сроком. Если P1 отличный от нуля, то только в настоящее время выполняющийся запрос истекает.

Если P2 = 0, то SQL-операторы немедленно истекают. Если P2 = 1, работающим SQL-операторам позволяют продолжить работу до завершения. Случай P2 = 1 происходит, когда CREATE INDEX или подобное изменение схемы происходят, которое могло бы помочь запросу, которым управляют быть быстрее, но это не затрагивает правильность операции.

Filter Вычислите хэш на ключе в регистре P4, начиная с r[P3]. Проверьте, чтобы видеть, найден ли хэш в фильтре bloom в регистре P1. Если это не присутствует там, возможно, перейдите на P2. Иначе провалитесь.

Ложные отрицательные стороны безопасны. Всегда безопасно провалиться, даже если значение находится в фильтре bloom. Ложное отрицание заставляет больше циклов CPU использоваться, но оно должно все еще привести к правильному ответу. Однако, неправильный ответ может явиться результатом ложного положительного, если переход сделан, когда это должно провалиться.

FilterAdd Вычислите хэш в P4, начиная с r[P3] и добавьте хэш к фильтру bloom в r[P1].
FinishSeek Если курсор P1 был ранее перемещен через DeferredSeek, закончите поисковые действия сейчас без дополнительной задержки. Если поиск курсора уже выполнен, эта инструкция не делает ничего.
FkCheck Остановка с ошибкой SQLITE_CONSTRAINT, если есть какие-либо нерешенные ограничительные нарушения внешнего ключа. Если нет никаких ограничительных нарушений внешнего ключа, это не делает ничего.

Ограничительные нарушения FK также проверяются, когда подготовленный запрос выходит. Этот код операции используется, чтобы поднять ограничительные ошибки внешнего ключа до возвращения результатов, таких как количество изменения строки или результат пункта RETURNING.

FkCounter Увеличьте "ограничительный счетчик" на P2 (P2 может быть отрицательным или положительным). Если P1 отличный от нуля, ограничительный счетчик базы данных увеличен (отсроченные ограничения внешнего ключа). Иначе, если P1 = 0, счетчик запроса увеличен (непосредственные ограничения внешнего ключа).
FkIfZero Этот код операции проверяет, является ли ограничительный счетчик внешнего ключа в настоящее время нолем. Если так, перейдите на инструкцию в P2. Иначе перейдите к следующей инструкции.

Если P1 отличный от нуля, то переход сделан, если ограничительный счетчик базы данных = 0 (тот, который считает отсроченные ограничительные нарушения). Если P1 = 0, переход сделан, если ограничительный счетчик запроса = 0 (непосредственные ограничительные нарушения внешнего ключа).

Found Если P4 = 0, тогда регистр P3 хранит blob, созданный MakeRecord. Если P4>0, P3 первый из регистров P4, которые формируют распакованную запись.

Курсор P1 находится на индексе btree. Если запись, определенная P3 и P4, является префиксом какого-либо входа в P1, сделан переход к P2, и P1 указывает налево при соответствующем входе.

Эта операция оставляет курсор в состоянии, где это может быть продвинуто в передовом направлении. Next будет работать, но Prev нет.

См. также: NotFound, NoConflict, NotExists. SeekGe

Function Вызовите функцию пользователя (P4 это указатель на объект sqlite3_context, который содержит указатель на функцию, которой будут управлять), с аргументами, взятыми из регистра P2. Количество аргументов находится в объекте sqlite3_context, на который указывает P4. Результат функции сохранен в регистре P3. Регистр P3 не должен быть одним из входов функции.

P1 это 32-bit bitmask, указывающий, был ли каждый аргумент функции постоянным во время компиляции. Если первый аргумент был постоянным, тогда бит 0 в P1 установлен. Это используется, чтобы определить, могут ли метаданные, связанные с аргументом функции пользователя, используя sqlite3_set_auxdata() API быть безопасно сохранены до следующего вызова этого кода операции.

См. также: AggStep, AggFinal, PureFunc

Ge Это работает точно так же, как код операции Lt за исключением того, что переход сделан, если содержание регистра P3 больше или равно содержанию регистра P1. См. код операции Lt.
Gosub Напишите текущий адрес в P1 и затем перейдите на адрес в P2.
Goto Безусловный переход на адрес в P2. Следующая выполненная инструкция будет той, у которой индекс в P2 с начала программы.

P1 на самом деле не используется этим кодом операции. Однако, это иногда устанавливается в 1 вместо 0 как намек оболочке командной строки, что этот Goto основание цикла и что строки от P2 вниз к текущей строке должны быть показаны для вывода EXPLAIN.

Gt Это работает точно так же, как код операции Lt за исключением того, что переход сделан, если содержание регистра P3 больше содержания регистра P1. См. код операции Lt.
Halt Выйдите немедленно. Все открытые курсоры и т.д. закрываются автоматически.

P1 это код результата, возвращенный sqlite3_exec(), sqlite3_reset() или sqlite3_finalize(). Для нормальной остановки это должно быть SQLITE_OK (0). Для ошибок это может быть некоторое другое значение. Если P1!=0, тогда P2 определит, действительно ли отменяется текущая транзакция. Не делайте обратной перемотки, если P2 = OE_Fail. Сделайте обратную перемотку, если P2 = OE_Rollback. Если P2 = OE_Abort, то отмените все изменения, которые произошли во время этого выполнения VDBE, но не делайте отмены транзакции.

Если P4 не null, это последовательность сообщения об ошибке.

P5 это значение от 0 до 4, включительно, которое изменяет последовательность P4.

0: (без изменений) 1: ограничение NOT NULL потерпело неудачу: P4 2: Ограничение UNIQUE потерпело неудачу: P4 3: Ограничение CHECK потерпело неудачу: P4 4: ограничение FOREIGN KEY потерпело неудачу: P4

Если P5 не 0 и P4 = NULL, все после ":" пропустить.

Есть подразумеваемая инструкция "Halt 0 0 0", вставленная в самом конце каждой программы. Таким образом, переход мимо последней инструкции программы совпадает с Halt.

HaltIfNull Проверьте значение в регистре P3. Если это NULL, тогда Halt, используя параметры P1, P2 и P4, как будто это было инструкцией Halt. Если P3 не NULL, ничего не делает. P5 должен быть 1.
IdxDelete Содержание регистров P3, начиная с P2, формирует распакованный ключ индекса. Этот код операции удаляет тот вход из индекса, открытого курсором P1.

Если P5 не 0, поднимите ошибку SQLITE_CORRUPT_INDEX, если никакой элемент индекса соответствия не найден. Это происходит, управляя UPDATE или оператором удаления, и элемент индекса, который будет обновлен или удален, не найден. Для некоторого использования IdxDelete (например: оператор EXCEPT) не имеет значения, что никакой вход соответствия не найден. Для тех случаев P5 = 0. Кроме того, не поднимайте эту (самокорректирующаяся и некритическая) ошибку, если в режиме writable_schema.

IdxGE Значения регистра P4, начиная с P3, формируют распакованный ключ индекса, который опускает PRIMARY KEY. Compare это значение ключа с индексом, на который P1 в настоящее время указывает, игнорируя PRIMARY KEY или области ROWID в конце.

Если элемент индекса P1 больше или равен значению ключа, тогда перейдите на P2. Иначе провалитесь к следующей инструкции.

IdxGT Значения регистра P4, начинающиеся с P3, формируют распакованный ключ индекса, который опускает PRIMARY KEY. Compare это значение ключа с индексом, на который P1 в настоящее время указывает, игнорируя PRIMARY KEY или области ROWID в конце.

Если элемент индекса P1 больше, чем значение ключа, тогда перейдите на P2. Иначе провалитесь к следующей инструкции.

IdxInsert P2 хранит ключ индекса SQL, созданный MakeRecord. Этот код операции пишет ключ в индекс P1. Данные для входа nil.

Если P4 не 0, то это количество значений в распакованном ключе reg(P2). В этом случае P3 это индекс первого регистра для распакованного ключа. Доступность распакованного ключа может иногда быть оптимизацией.

Если P5 имеет установленный бит OPFLAG_APPEND, это является намеком к слою b-дерева, что эта вставка, вероятно, будет приложением.

Если P5 имеет установленный бит OPFLAG_NCHANGE, то счетчик изменения увеличен этой инструкцией. Если бит OPFLAG_NCHANGE очищен, то счетчик изменения не изменен.

Если P5 имеет установленный бит OPFLAG_USESEEKRESULT, внедрение могло бы работать быстрее, избегая ненужного поиска на курсоре P1. Однако, флаг OPFLAG_USESEEKRESULT должен быть установлен только, если там не было предшествующих поисков на курсоре или если новые поиски используют ключевой эквивалент P2.

Эта инструкция работает только на индексах. Эквивалентная инструкция для таблиц Insert.

IdxLE Значение регистра P4, начиная с P3, формирует распакованный ключ индекса, который опускает PRIMARY KEY или ROWID. Compare это значение ключа с индексом, на который P1 в настоящее время указывает, игнорируя PRIMARY KEY или ROWID на индексе P1.

Если элемент индекса P1 меньше или равен значению ключа, тогда перейдите к P2. Иначе провалитесь к следующей инструкции.

IdxLT Значения регистра P4, начинающиеся с P3, формируют распакованный ключ индекса, который опускает PRIMARY KEY или ROWID. Compare это значение ключа с индексом, на который P1 в настоящее время указывает, игнорируя PRIMARY KEY или ROWID на индексе P1.

Если элемент индекса P1 меньше, чем значение ключа тогда перейдите к P2. Иначе провалитесь к следующей инструкции.

IdxRowid Напишите в регистр P2 целое число, которое является последним входом в записи в конце ключа индекса, на который указывает курсор P1. Это целое число должно быть rowid записи таблицы, на которую указывает этот элемент индекса.

См. также: Rowid, MakeRecord.

If Перейдите к P2, если значение в регистре P1 true. Значение считают true, если это числовое и отличное от нуля. Если значение в P1 NULL, тогда переход выполняют, если и только если P3 отличный от нуля.
IfNoHope Регистр P3 первый из регистров в P4, которые формируют распакованный запись. Курсор P1 это индекс btree. P2 место назначения перехода. Другими словами, операнды к этому коду операции совпадают с операндами NotFound и IdxGT.

Этот код операции только попытка оптимизации. Если этот код операции всегда проваливается, правильный ответ все еще получен, но дополнительная работа выполняется.

Значение N в seekHit флаге курсора P1 означает, что там существует ключ P3:N, который будет соответствовать некоторой записи в индексе. Мы хотим знать, возможно ли для записи P3:P4 соответствовать некоторой записи в индексе. Если это невозможно, мы можем пропустить некоторую работу. Таким образом, если seekHit меньше P4, делается попытка узнать, возможно ли соответствие, управляя NotFound.

Этот код операции используется в обработке пункта IN для многостолбцового ключа. Если пункт IN присоединен к элементу ключа кроме крайнего левого элемента, и при отсутствии совпадений на новом поиске по целому ключу, то могло бы случиться так, что один из элементов ключа слева запрещает совпадение и следовательно нет никакой надежды ни на какое соответствие независимо от того, сколько элементов пункта IN проверяется. В таком случае мы оставляем поиск пункта IN рано, используя этот код операции. Название кода операции происходит от того, что переход сделан, если нет никакой надежды на достижение соответствия.

См. также: NotFound, SeekHit

IfNot Перейдите к P2, если значение в регистре P1 False. Значение считают false, если у него есть числовое значение ноля. Если значение в P1 NULL, тогда переход делают, если и только если P3 отличный от нуля.
IfNotOpen Если курсор P1 не открыт или если P1 установлен в NULL, используя NullRow, перейдите на P2. Иначе провалиться.
IfNotZero Регистр P1 должен содержать целое число. Если содержание регистра P1 первоначально больше, чем ноль, то уменьшите значение в регистре P1. Если это отличное от нуля (отрицательное или положительное), перейдите к P2. Если регистр P1 первоначально ноль, оставьте его без изменений и проваливатесь.
IfNullRow Проверьте курсор P1, чтобы видеть, указывает ли он в настоящее время на NULL. Если да, установите регистр P3 к NULL и немедленно перейдите на P2. Если P1 не NULL, то провалитесь, не внося изменений.

Если P1 не открытый курсор, то этот код операции ничего не делает.

IfPos Регистр P1 должен содержать целое число. Если значение регистра P1 равняется 1 или больше, вычтите P3 из значения в P1 и перейдите к P2.

Если начальное значение регистра P1 меньше 1, значение неизменно, и контроль проходит к следующей инструкции.

IfSmaller Оцените количество строк в таблице P1. Перейдите на P2, если та оценка меньше, чем приблизительно 2**(0.1*P3).
IncrVacuum Выполните единственный шаг возрастающей вакуумной процедуры по базе данных P1. Если вакуум закончился, выполните переход на инструкцию в P2. Иначе провалитесь к следующей инструкции.
Init Программы содержат единственный случай этого кода операции как самый первый код операции.

Если отслеживание позволено (через интерфейс sqlite3_trace()), то последовательность UTF-8, содержавшаяся в P4, выдается на отзыве трассировки. Или если P4 чист, используйте последовательность, возвращенную sqlite3_sql().

Если P2 не ноль, выполните переход на инструкцию P2.

Увеличьте значение P1 так, чтобы Once перешел в первый раз, когда он оценен для этого.

Если P3 не ноль, то это адрес, чтобы перейти, если с ошибкой SQLITE_CORRUPT сталкиваются.

InitCoroutine Настройте регистр P1 так, чтобы это выполнило код по адресу в P3.

Если P2!=0, внедрение немедленно следует этому коду операции. Поэтому перепрыгните через внедрение, чтобы обратиться к P2.

См. также: EndCoroutine

Insert Напишите вход в таблицу курсора P1. Новый вход создается, если он не существует, или данные для существующего входа переписаны. Данные это значение MEM_Blob, сохраненное в регистре номер P2. Ключ сохранен в регистре P3. Ключ должен быть MEM_Int.

Если флаг OPFLAG_NCHANGE в P5 = 1, количество изменения строки увеличено (иначе нет). Если флаг OPFLAG_LASTROWID в P5 = 1, rowid сохранен для последующего возвращения sqlite3_last_insert_rowid() (иначе это не изменяется).

Если флаг OPFLAG_USESEEKRESULT в P5 = 1, внедрение могло бы работать быстрее, избегая ненужного поиска на курсоре P1. Однако, флаг OPFLAG_USESEEKRESULT должен быть установлен только, если там не было предшествующих поисков на курсоре или если новые поиски использовали ключ, равный P3.

Если установлен OPFLAG_ISUPDATE, то этот код операции часть операции UPDATE. Иначе (если флаг не установлен), этот код операции часть операции INSERT. Различие важно только для перехватчика обновления.

Параметр P4 может указать на структуру таблицы или может быть NULL. Если это не NULL, то перехватчик обновления (sqlite3.xUpdateCallback) вызван после успешной вставки.

Если P1 псевдокурсор, и P2 динамично ассигнуется, то владелец P2 передается псевдокурсору и регистр P2 становится эфемерным. Если курсор будет изменен, значение регистра P2 изменится. Удостоверьтесь, что это не вызывает проблем.

Эта инструкция работает только с таблицами. Эквивалентная инструкция для индексов IdxInsert.

Int64 P4 указатель на 64-bit integer. Напишите это значение в регистр P2.
IntCopy Передайте целочисленное значение, проводимое в регистре P1, в регистр P2.

Это оптимизированная версия SCopy, которая работает только на целочисленных значениях.

Integer 32-bit integer в P1 записывается в P2.
IntegrityCk Сделайте анализ в настоящее время открытой базы данных. Сохраните в регистре P1 текст сообщения об ошибке, описывающего любые проблемы. Если никакие проблемы не найдены, сохраните NULL в регистре P1.

Регистр P3 содержит на единицу меньше, чем максимальное количество позволенных ошибок. В большей части reg(P3) ошибки будет сообщаться. Другими словами, анализ останавливается, как только замечено reg(P1) ошибок. Reg(P1) обновляется с количеством остающихся ошибок.

Номера страниц корня всех столов в базе данных это целые числа, сохраненные в аргументе P4_INTARRAY.

Если P5 не ноль, проверка сделана на вспомогательном файле базы данных, не на главном файле базы данных.

Этот код операции используется, чтобы осуществить integrity_check pragma.

IsNull Перейдите к P2, если значением в регистре P1 является NULL.
IsTrue Этот код операции осуществляет IS TRUE, IS FALSE, IS NOT TRUE и IS NOT FALSE.

Интерпретируйте значение в регистре P1 как булево значение. Сохраните boolean (0 или 1) в P2. Или если значение в регистре, P1 = NULL, то P3 сохранен в регистре P2. Инвертируйте ответ, если P4 равняется 1.

Логика в итоге как это:

  • If P3=0 and P4=0 then r[P2] := r[P1] IS TRUE
  • If P3=1 and P4=1 then r[P2] := r[P1] IS FALSE
  • If P3=0 and P4=1 then r[P2] := r[P1] IS NOT TRUE
  • If P3=1 and P4=0 then r[P2] := r[P1] IS NOT FALSE
IsType Перейдите к P2, если тип колонки в btree один из типов, определенных битовой маской P5.

P1 обычно курсор на btree, для которого строка расшифрованный кэш действителен через, по крайней мере, колонку P3. Другими словами, должна была быть предшествующая Column для колонки P3 или больше. Если курсор не действителен, то этот код операции мог бы дать поддельные результаты. У btree-строки есть меньше, чем P3 колонок, затем используйте P4 в качестве типа данных.

Если P1 = -1, P3 это номер регистра, и тип данных взят от значения в том регистре.

P5 это битовая маска типов данных. SQLITE_INTEGER это младший значащий бит (0x01). SQLITE_FLOAT бит 0x02. SQLITE_TEXT 0x04. SQLITE_BLOB 0x08. SQLITE_NULL 0x10.

Этот код операции достоверно не различает NULL и REAL, когда P1>=0. Если база данных будет содержать значение NaN, этот код операции будет думать, что тип данных REAL, когда это должен быть NULL. Когда P1 <0 и значение уже сохранено в регистре P3, тогда этот код операции действительно достоверно различает NULL и REAL. Проблема возникает только когда P1> =0.

Выполните переход на адрес в P2, если и только если тип данных значения, определенного P1 и P3, соответствует одному из битов в битовой маске P5.

JournalMode Измените режим журнала базы данных P1 на P3. P3 должен быть одним из значений PAGER_JOURNALMODE_XXX. Изменяясь между различными режимами (delete, truncate, persist, off и memory), это простая операция. Никакой IO не требуется.

Изменяя режим WAL WAL процедура более сложна.

Напишите последовательность, содержащую заключительный режим журнала, в P2.

Jump Перейдите к инструкции по адресу P1, P2 или P3 в зависимости от того, P1 меньше, равен или больше P2 соответственно.

Этот код операции должен немедленно следовать за Compare.

Last Следующее использование Rowid, Column или Prev для P1 будет относиться к последнему входу в таблице базы данных или индексе. Если таблица или индекс пусты и P2> 0, то перейдите немедленно к P2. Если P2 = 0 или если таблица или индекс не пусты, провалитесь к следующим инструкциям.

Этот код операции оставляет курсор настроенным, чтобы переместиться в обратном порядке от конца к началу. Другими словами, курсор формируется, чтобы использовать Prev, но не Next.

Le Это работает точно так же, как код операции Lt за исключением того, что переход сделан, если содержание регистра P3 меньше или равно содержанию регистра P1.
LoadAnalysis Прочитайте таблицу sqlite_stat1 для базы данных P1 и загрузите содержание той таблицы во внутреннюю хэш-таблицу индекса. Это заставит анализ использоваться, готовя все последующие запросы.
Lt Сравните значения в регистрах P1 и P3. Если reg(P3)<reg(P1), перейдите к адресу в P2.

Если бит SQLITE_JUMPIFNULL в P5 = 1 и reg(P1) или reg(P3) = NULL, выполните переход. Если бит SQLITE_JUMPIFNULL = 0, тогда проваливаются, если любой операнд NULL.

Часть SQLITE_AFF_MASK в P5 должна быть символом близости: SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER и т.д. Попытка предпринята, чтобы принудить оба входа согласно этой близости, прежде чем сравнение будет сделано. Если SQLITE_AFF_MASK = 0x00, то числовая близость используется. Обратите внимание на то, что преобразования близости сохранены назад во входные регистры P1 и P3. Таким образом, этот код операции может вызвать постоянные изменения регистров P1 и P3.

Как только любые преобразования произошли, и никакое значение не NULL, значения сравнены. Если оба значения blob, memcmp() используется, чтобы определить результаты сравнения. Если оба значения текст, то соответствующая функция сопоставления, определенная в P4, используется, чтобы сделать сравнение. Если P4 не определяется, тогда используется memcmp(), чтобы сравнить текстовую строку. Если оба значения числовые, то числовое сравнение используется. Если два значения имеют различные типы, то числа считают меньше, чем последовательности, а последовательности считают меньше, чем blob.

Этот код операции сохранит результат сравнения для использования новым кодом операции Jump.

MakeRecord Преобразуйте регистр P2, начиная с P1, в формат записи, используемый в качестве записи данных в таблице базы данных или как ключ в индексе. Код операции Column может расшифровать запись позже.

P4 может быть последовательностью, которая имеет длину P2 символов. N-й символ строки указывает на близость колонки, которая должна использоваться для N-го поля ключа индекса.

Отображение от символа до близости дано макросом SQLITE_AFF_, определенным в sqliteInt.h.

Если P4 = NULL, у всех полей индекса есть близость BLOB.

Значение P5 зависит от того, позволен ли выбор времени компиляции SQLITE_ENABLE_NULL_TRIM:

Если включен SQLITE_ENABLE_NULL_TRIM, P5 это индекс самой правой таблицы, который может быть урезан пустым указателем.

Если выключен SQLITE_ENABLE_NULL_TRIM, P5 имеет значение OPFLAG_NOCHNG_MAGIC, если коду операции MakeRecord позволяют принять записи без изменений с serial_type 10. Это значение используется только в assert() и не затрагивает конечный результат.

MaxPgcnt Попытайтесь установить максимальный счетчик страниц для базы данных P1 в значение в P3. Не позволяйте максимальному количеству страниц падать ниже текущей страницы и не меняйте максимальное значение количества страниц, если P3 = 0.

Сохраните максимальное количество страниц после изменения в регистре P2.

MemMax P1 это регистр в структуре корня этой VM (структура корня отличается от текущей структуры, если эта инструкция выполняется в рамках подпрограммы). Установите значение регистра P1 к максимуму его текущего значения и значения в регистре P2.

Эта инструкция бросает ошибку, если элемент памяти первоначально не целое число.

Move Переместите значения P3 из регистров P1..P1+P3-1 в регистры P2..P2+P3-1. Регистры P1..P1+P3-1 после этого будут содержать NULL. Ошибка для диапазонов регистра P1.. P1+P3-1 и P2.. P2+P3-1 накладываться. Ошибка, если P3 меньше 1.
Multiply Умножьте значение в регистре P1 на значение в P2 и сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
MustBeInt Вынудите значение в регистре P1 быть целым числом. Если значение в P1 не целое число и не может быть преобразовано в целое число без потери данных, то немедленно перейдите в P2, или если P2=0 поднимите исключение SQLITE_MISMATCH.
Ne Это работает точно так же, как код операции Eq за исключением того, что переход сделан, если операнды в регистрах P1 и P3 не равны.
NewRowid Получите новое число integer записи ("rowid"), используемое в качестве ключа к таблице. Рекордное число ранее не используется в качестве ключа в таблице базы данных, на которую указывает курсор P1. Новое рекордное число написано в P2.

Если P3>0, P3 это регистр в структуре корня этой VDBE, который содержит самое большое ранее произведенное рекордное число. Никаким новым рекордным числам не позволяют быть меньше, чем это значение. Когда это значение достигает своего максимума, ошибка SQLITE_FULL произведена. Регистр P3 обновляется произведенным рекордным числом. Этот механизм P3 используется, чтобы помочь реализовать опцию AUTOINCREMENT.

Next Установите курсор P1 так, чтобы это указало на следующую пару ключа/данных в его таблице или индексе. Если больше нет пар ключ/значение, тогда проваливаются к следующим инструкциям. Но если прогресс курсора был успешен, перейдите немедленно к P2.

Next действителен только после SeekGT, SeekGE или Rewind, который раньше помещал курсор. Next не может следовать за SeekLT, SeekLE или Last.

Курсор P1 должен быть для реальной таблицы, не псевдотаблицы. P1 должен быть открыт до этого кода операции, или программа будет segfault.

Значение P3 это намек к btree-внедрению. Если P3=1, значит P1 является индексом SQL, а эта инструкция, возможно, была опущена, если бы тот индекс был уникален. P3 обычно 0. P3 всегда 0 или 1.

Если P5 положительный, и переход сделан, то счетчик события номер P5-1 в подготовленном запросе увеличен.

См. также: Prev

NoConflict Если P4=0, P3 хранит blob, созданный MakeRecord. Если P4>0, P3 первый из регистров P4, которые формируют распакованную запись.

Курсор P1 находится на индексе btree. Если запись, определенная P3 и P4, содержит какой-либо NULL, перейдите немедленно к P2. Если все термины записи не NULL, проверка сделана, чтобы определить, есть ли у какой-либо строки в индексе P1 btree соответствующий ключевой префикс. Если нет никаких соответствий, немедленно перейдите к P2. Если есть совпадение, провалитесь и оставьте курсор P1, указывающий на соответствующую строку.

Этот код операции подобен NotFound за исключениями, что отделение всегда берется, если какая-либо часть входного ключа поиска NULL.

Эта операция оставляет курсор в статусе, где это не может быть продвинуто ни в одном направлении. Другими словами, Next и Prev не работают после этой операции.

См. также: NotFound, Found, NotExists

Noop Ничего не делает. Эта инструкция часто полезна как место назначения перехода.
Not Интерпретируйте значение в регистре P1 как булево значение. Сохраните булево дополнение в регистре P2. Если значение в регистре P1 NULL, то NULL сохранен в P2.
NotExists P1 это индекс курсора, открытого на таблице SQL btree (с ключами целого числа). P3 это целое число rowid. Если P1 не содержит запись с rowid P3, тогда немедленно перейдите на P2. Если P2 = 0, поднимите ошибку SQLITE_CORRUPT. Если P1 действительно содержит запись с rowid P3, тогда оставляют курсор, указывающий на эту запись и проваливаются к следующей инструкции.

SeekRowid выполняет ту же самую операцию, но также позволяет регистру P3 содержать значение нецелого числа, в этом случае переход всегда делается. Этот код операции требует, чтобы P3 всегда содержал целое число.

NotFound выполняет ту же самую операцию на индексе btree (с произвольными ключами).

Этот код операции оставляет курсор в состоянии, где это не может быть продвинуто ни в одном направлении. Другими словами, Next и Prev не будут работать после этого кода операции.

См. также: Found, NotFound, NoConflict, SeekRowid

NotFound Если P4=0, регистр P3 хранит blob, созданный MakeRecord. Если P4>0, P3 первый из регистров P4, которые формируют распакованную запись.

Курсор P1 находится на индексе btree. Если запись, определенная P3 и P4, не является префиксом никакого входа в P1, переход сделан на P2. Если P1 действительно содержит вход, префикс которого соответствует записи P3/P4, управление проваливается к следующей инструкции, и P1 указывает налево при соответствующем входе.

Эта операция оставляет курсор в состоянии, где это не может быть продвинуто ни в одном направлении. Другими словами, Next и Prev не работают после этой операции.

См. также: Found, NotExists, NoConflict, IfNoHope

NotNull Перейдите на P2, если значение P1 не NULL.
Null Напишите NULL в P2. Если P3 больше P2, также напишите NULL в P3 и в каждый регистр между P2 и P3. Если P3 меньше P2 (обычно P3 = 0), только P2 установлен в NULL.

Если P1 не 0, то также установите флаг MEM_Cleared так, чтобы NULL не сравнивались как равные, даже если SQLITE_NULLEQ будет установлен в Ne или Eq.

NullRow Переместите курсор P1 в пустую строку. Любые операции Column, которые происходят, в то время как курсор находится на пустой строке, будут всегда писать NULL.

Если курсор P1 ранее не открыт, откройте его теперь для специального псевдокурсора, который всегда возвращает NULL для каждой колонки.

Offset Сохраните в регистр r[P3] байтовое смещение в файле базы данных, которое является началом полезной нагрузки для записи, на которую в настоящее время указывает тот курсор P1.

P2 это номер столбца для аргумента sqlite_offset(). Этот код операции не использует сам P2, но значение P2 используется генератором кода. P1, P2 и P3 к этому коду операции совпадают с Column.

Этот код операции доступен только, если SQLite собран с -DSQLITE_ENABLE_OFFSET_SQL_FUNC.

OffsetLimit Этот код операции выполняет обычно используемое вычисление, связанное с обработкой OFFSET и LIMIT. r[P1] содержит счетчик предела. r[P3] содержит счетчик смещения. Код операции вычисляет общее значение LIMIT и OFFSET и хранит его в r[P2]. Вычисленное значение r[P2] является общим количеством строк, которое надо будут посетить, чтобы закончить запрос.

Если r[P3] ноль или меньше нуля, значит нет никакого OFFSET, а r[P2] собирается быть значением LIMIT, r[P1].

Если r[P1] ноль или меньше нуля, значит нет никакого LIMIT, и r[P2] установлен в -1.

Иначе r[P2] это сумма r[P1] и r[P3].

Once Провалитесь к следующей инструкции в первый раз, когда с этим кодом операции сталкиваются на каждом вызове программы байт-кода. Jump на P2 на втором и всех последующих столкновениях во время той же самого вызова.

Программы верхнего уровня определяют первый вызов, сравнивая операнд P1 с операндом P1 на коде операции Init в начале программы. Если значения P1 отличаются, то проваливаются и делают P1 этого кода операции равным P1 из Init. Если значения P1 то же самое, тогда выполняют переход.

Для подпрограмм есть битовая маска в VdbeFrame, которая определяет, должен ли переход быть сделан. Битовая маска необходима, потому что самоизменяющаяся кодовая уловка не работает на рекурсивные триггеры.

OpenAutoindex Этот код операции работает аналогично OpenEphemeral. У этого есть другое имя, чтобы отличить его использование. Таблицы, созданные этим кодом, будут использоваться для автоматически созданных переходных индексов в соединениях.
OpenDup Откройте новый курсор P1, который указывает на ту же самую таблицу, как курсор P2. Курсор P2 должен быть открыт предшествующим кодом операции OpenEphemeral. Только эфемерные курсоры могут быть дублированы.

Двойные эфемерные курсоры используются для самосоединений осуществленных обзорами.

OpenEphemeral Откройте новый курсор P1 для переходной таблицы. Курсор всегда открывается на чтение-запись, даже если главная база данных только для чтения. Эфемерная таблица удалена автоматически, когда курсор закрывается.

Если курсор P1 уже открыт на эфемерной таблице, она очищена (все содержание стерто).

P2 это количество колонок в эфемерной таблице. Курсор указывает на таблицу BTree, если P4=0 или на индекс BTree, если P4 не 0. Если P4 не NULL, он указывает на структуру KeyInfo, которая определяет формат ключей в индексе.

P5 может быть маской флагов BTREE_*, определенных в btree.h. Эти флаги управляют аспектами операции btree. Флаги BTREE_OMIT_JOURNAL и BTREE_SINGLE добавляются автоматически.

Если P3 положительный, reg[P3] изменяется немного так, чтобы это могло использоваться в качестве данных нулевой длины для Insert. Это оптимизация, которая избегает дополнительного кода операции Blob, чтобы инициализировать тот регистр.

OpenPseudo Откройте новый курсор, который указывает на поддельную таблицу, которая содержит единственную строку данных. Содержание этой строки это содержание регистра памяти P2. Другими словами, курсор P1 становится псевдонимом для содержания MEM_Blob, содержавшегося в регистре P2.

Псевдотаблица, созданная этим кодом операции, используется, чтобы поддержать единственный вывод строки от сортировщика так, чтобы строка могла разделиться на отдельные столбцы, используя код операции Column. Код операции Column это единственный код операции курсора, который работает с псевдотаблицей.

P3 это количество областей в записях, которые будут сохранены псевдотаблицей.

OpenRead Откройте курсор read-only для таблицы базы данных, страница корня которой задана P2 в файле базы данных. Файл базы данных определяется P3. P3 = 0 означает главную базу данных, P3 = 1 означает базу данных, используемую для временных таблиц, P3>1 означает соответствующую приложенную базу данных. Дайте новому курсору идентификатор P1. Значения P1 не должны быть смежными, но все значения P1 должны быть маленькими целыми числами. Ошибка, если P1 отрицательный.

Биты P5:

  • 0x02 OPFLAG_SEEKEQ: Этот курсор будет использоваться только для поисков равенства (осуществлено как пара кодов операции SeekGE/IdxGT и SeekLE/IdxLT )

P4 может быть целым числом (P4_INT32) или указателем на структуру KeyInfo (P4_KEYINFO). Если это указатель на объект KeyInfo, то открываемая таблица должна быть index b-tree, где объект KeyInfo определяет содержание и последовательность сопоставления того b-дерева индекса. Иначе, если P4 целочисленное значение, то открываемая таблица должна быть table b-tree с числом колонок не меньше значения P4.

См. также: OpenWrite, ReopenIdx

OpenWrite Откройте курсор чтения-записи по имени P1 на таблице или индексе, страница корня которого P2 (или чья страница корня хранится в регистре P2, если бит OPFLAG_P2ISREG установлен в P5, см. посмотрите ниже).

Значение P4 может быть integer (P4_INT32) или указателем на структуру KeyInfo (P4_KEYINFO). Если это указатель на объект KeyInfo, то открываемая таблица должна быть index b-tree, где объект KeyInfo определяет содержание и последовательность сопоставления того b-дерева индекса. Иначе, если P4 целочисленное значение, то открываемая таблица должна быть table b-tree с числом колонок не меньше P4.

Допустимые биты P5:

  • 0x02 OPFLAG_SEEKEQ: Этот курсор будет использоваться только для поисков равенства (осуществлено как пара кодов операции SeekGE/IdxGT SeekLE/IdxLT).
  • 0x08 OPFLAG_FORDELETE: Этот курсор используется только, чтобы искать и впоследствии удалить записи в индексе btree. Это намек движку хранения, что ему позволяют проигнорировать. Намек не используется официальным SQLite b*tree, но используется COMDB2.
  • 0x10 OPFLAG_P2ISREG: Используйте содержание регистра P2 как страницу корня, не значение самого P2.

Эта инструкция работает как OpenRead за исключением того, что это открывает курсор в режиме read/write.

См. также: OpenRead, ReopenIdx

Or Выполните логгический OR значений в регистрах P1 и P2, сохраните ответ в регистре P3.

Если P1 или P2 отличные от нуля (true), результат 1 (true) даже если другой вход NULL. NULL и false или два NULL дают на выходе NULL.

Pagecount Напишите текущее число страниц в базе данных P1 к элементу памяти P2.
Param Этот код операции когда-либо присутствует только в подпрограммах, вызванных с помощью инструкции Program. Copy значение, в настоящее время хранимое в элементе памяти вызывающей (родительской) структуры в элемент P2 в адресном пространстве текущей структуры. Это используется триггерами, чтобы получить доступ к знаениям new.* и old.*.

Адрес клетки в родительской структуре определяется, добавляя значение аргумента P1 к значению аргумента P1 инструкции Program.

ParseSchema Прочитайте и разберите все записи от таблицы схемы базы данных P1, которые соответствуют оператору Where P4. Если P4 = NULL, то вся схема для P1 повторно размечена.

Этот код операции вызывает анализатор, чтобы создать новую виртуальную машину, затем управляет новой виртуальной машиной.

Permutation Установите перестановку, используемую Compare в следующей инструкции. Перестановка сохранена в операнде P4.

Перестановка действительна только для следующего кода операции, который должен быть Compare, у которого есть установленный бит OPFLAG_PERMUTE в P5.

Первое целое число во множестве целого числа P4 это длина множества и не является частью перестановки.

Prev Передвиньте курсор P1 так, чтобы он указал на предыдущую пару ключа/данных в таблице или индексе. Если нет никаких предыдущих пар ключ/значение, тогда перейдите к следующим инструкциям. Но если перемещение курсора успешно, перейдите немедленно к P2.

Prev действителен только после SeekLT, SeekLE или Last, которыми раньше двигали курсор. Prev не позволен после SeekGT, SeekGE или Rewind.

Курсор P1 должен быть открыт для реальной таблицы, не псевдотаблицы. Если P1 не открыт, поведение не определено.

Значение P3 это намек btree-внедрению. Если P3 = 1, это означает, что P1 является индексом SQL и эта инструкция, возможно, была опущена, если бы тот индекс был уникален. P3 обычно 0. P3 всегда 0 или 1.

Если P5 положительный, и переход сделан, то счетчик события номер P5-1 в подготовленном запросе увеличен.

Program Выполните триггер, переданный как P4 (тип P4_SUBPROGRAM).

P1 содержит адрес элемента памяти, который содержит первый элемент памяти во множестве значений, используемых в качестве аргументов подпрограммы. P2 содержит адрес, чтобы перейти к тому, если подпрограмма бросает исключение IGNORE, используя RAISE(). Регистр P3 содержит адрес элемента памяти в этой (родительской) VM, который используется, чтобы ассигновать память, требуемую sub-vdbe во время выполнения.

P4 указатель на VM, содержащую триггер.

Если P5 не 0, вызов рекурсивной программы позволен.

PureFunc Вызовите функцию пользователя (P4 указатель на объект sqlite3_context, который содержит указатель на функцию, которой будут управлять), с аргументами, взятыми из регистра P2. Количество аргументов находится в объекте sqlite3_context. Результат функции сохранен в регистре P3. Регистр P3 не должен быть одним из входов функции.

P1 это 32-bit bitmask, указывающая, был ли каждый аргумент функции летерминирован как постоянный во время компиляции. Если первый аргумент был постоянным, тогда бит 0 в P1 установлен. Это используется, чтобы определить, могут ли метаданные, связанные с аргументом функции пользователя, используя sqlite3_set_auxdata() API, быть безопасно сохранены до следующего вызова этого кода операции.

Этот код операции работает точно как Function. Единственная разница в имени. Этот код операции используется в местах, где функция должна быть чисто недетерминирована. Некоторые встроенные функции даты/времени могут быть детерминированы или нет в зависимости от их аргументов. Когда те функции используются недетерминированным способом, они проверят, чтобы видеть, вызвали ли их, используя PureFunc вместо Function и если это так, они бросают ошибку.

См. также: AggStep, AggFinal, Function

ReadCookie Прочитайте куки номер P3 от базы данных P1 и напишите его в регистр P2. P3 = 1 является версией схемы. P3=2 является форматом базы данных. P3=3 является рекомендуемым размером кэша страниц и т.д. P1=0 является главным файлом базы данных, P1 = 1 является файлом базы данных, используемым, чтобы сохранить временные таблицы.

Должна быть блокировка чтения на базе данных (транзакция должна быть начата или должен быть открытый курсор) прежде, чем выполнить эту инструкцию.

Real P4 это указатель на 64-битное значение с плавающей точкой. Напишите это значение в регистр P2.
RealAffinity Если регистр P1 содержит целое число, преобразовывает его в действительное значение.

Этот код операции используется, извлекая информацию из колонки, у которой есть близость REAL. Такие значения столбцов могут все еще быть сохранены как целые числа для эффективности, но после извлечения мы хотим, чтобы у них было только действительное значение.

ReleaseReg Освободить регистры. Любое содержание, которое было в регистрах, ненадежно после того, как этот код операции заканчивает работу.

Очищаемые регистры будут регистрами P2, начиная с P1, но если бит ii в P3 установлен, то не очищается P1+ii. Другими словами, P3 это маска регистров, чтобы сохранить.

Сброс регистра очищает указатель Mem.pScopyFrom. Это означает, что, если содержание регистра было установлено, используя SCopy, изменение значения исходного регистра для SCopy больше не будет производить ошибку утверждения в sqlite3VdbeMemAboutToChange().

Если установлен P5, то всем очищенным регистрам установили их тип в MEM_Undefined так, чтобы любая последующая попытка прочитать такой регистр (прежде чем это будет повторно инициализировано) произвела ошибку утверждения.

P5 должен быть установлен на каждом вызове к этому коду операции. Однако, есть места в генераторе кода, которые очищают регистры, прежде чем их использовать под (действительным) предположением, что регистры не будут перераспределены для некоторой другой цели, прежде чем они будут использоваться и следовательно это безопасно.

Этот код операции доступен только в тестировании и отладке. Это не произведено для сборок конечных версий. Цель этого кода операции состоит в том, чтобы помочь утвердить произведенный bytecode. Этот код операции на самом деле не способствует вычислению ответа.

Remainder Вычислите остаток после деления P2 на P1 и сохраните результат в регистре P3. Если значение P1 = 0, результат NULL. Если любой операнд NULL, результат NULL.
ReopenIdx ReopenIdx работает аналогично OpenRead за исключением того, что это сначала проверяет, чтобы видеть, открыт ли курсор на P1 уже на том же самом b-дереве и если это так, этот код операции не делает ничего. Другими словами, если курсор уже открыт, не откройте его вновь.

ReopenIdx может использоваться только с P5=0 или P5=OPFLAG_SEEKEQ и с P4, являющимся объектом P4_KEYINFO. Кроме того, значение P3 должно совпасть с любым ReopenIdx или OpenRead для того же самого номера курсора.

Допустимве биты P5:

  • 0x02 OPFLAG_SEEKEQ: Этот курсор будет только использоваться для поисков равенства (осуществлено как пара кодов операции SeekGE/IdxGT SeekLE/ IdxLT)

См. также: OpenRead, OpenWrite

ResetCount Значение счетчика изменения копируется к счетчику изменения дескриптора базы данных (возвращенного последующими запросами sqlite3_changes()). Тогда внутренний счетчик изменения VM сброшен к 0. Это используется триггерами.
ResetSorter Удалите все содержание из эфемерной таблицы или сортировщика, который открыт на курсоре P1.

Этот код операции работает только на курсорах, используемых для сортировки и открытых с OpenEphemeral или SorterOpen.

ResultRow Регистры с P1 по P1+P2-1 содержат единственную строку результатов. Этот код операции вызывает sqlite3_step(), чтобы закончиться с кодом возврата SQLITE_ROW, и это настраивает структуру sqlite3_stmt, чтобы обеспечить доступ к r(P1)..r(P1+P2-1) как к строке результата.
Return Перейдите к адресу, сохраненному в регистре P1. Если P1 регистр обратного адреса, то это достигает возвращения из подпрограммы.

Если P3 = 1, то переход будет только, если регистр P1 хранит integer, иначе выполнение проваливается к следующему коду операции, и Return ничего не делает. Если P3 = 0, P1 должен содержать целое число, иначе поднято assert(). P3 должен быть установлен в 1, когда этот код операции используется в сочетании с BeginSubrtn, или в 0 иначе.

Значение в регистре P1 неизменно этим кодом операции.

P2 не используется движком байт-кода. Однако, если P2 будет положительным и меньше, чем текущий адрес, то средство форматирования вывода "EXPLAIN" в CLI упорядочит все коды операции из кода операции P2, чтобы не включать текущий Return. P2 должен быть первым кодом операции в подпрограмме, из которой возвращается этот код операции. Таким образом, значение P2 это намек углубления кода байта. Посмотрите tag-20220407a в wherecode.c и shell.c.

Rewind Следующее использование Rowid, Column или Next для P1 будет относиться к первому входу в таблице базы данных или индексе. Если таблица или индекс пусты, перейдите немедленно к P2. Если таблица или индекс не пусты, провалитесь к следующим инструкциям.

Если P2 = 0, это является утверждением, что таблица P1 никогда не пуста, и следовательно переход никогда сделан не будет.

Этот код операции оставляет курсор формируемым, чтобы переместиться в передовой порядок с начала к концу. Другими словами, курсор формируется, чтобы использовать Next, но не Prev.

RowCell P1 и P2 оба открытые курсоры. Оба должны быть открыты на том же самом типе таблицы: intkey или index. Этот код операции используется в качестве части копирования текущей строки от P2 в P1. Если курсоры открыты на intkey-таблицах, P3 содержит rowid, чтобы использовать с новой записью в P1. Если они открыты на индексах, P3 не используется.

Этот код операции должен сопровождаться кодом операции Insert или InsertIdx с установленным флагом OPFLAG_PREFORMAT, чтобы закончить операцию по вставке.

RowData Напишите в регистр P2 полное содержание строки для строки, на которую в настоящее время указывает курсор P1. Нет никакой интерпретации данных. Это просто копируется в регистр P2 точно как это найдено в файле базы данных.

Если курсор P1 индекс, то содержание ключ строки. Если курсор P2 таблица, то извлеченное содержание является данными.

Если курсор P1 должен указывать на действительную строку (не NULL) реальной таблицы, не псевдотаблицы.

Если P3!=0, тогда этим кодам операции позволяют превратить эфемерный указатель в страницу базы данных. Это означает, что содержание выходного регистра будет лишено законной силы, как только курсор перемещается, включая шаги, вызванные другими курсорами, которые сохраняют текущее положение курсоров, чтобы они могли написать ту же самую таблицу. Если P3 = 0, копия данных сделана в памяти. P3!=0 быстрей, но P3=0 надежней.

Если P3!=0, содержание регистра P2 неподходящее для использования в OP_Result, и любой OP_Result лишит законной силы содержание регистра P2. Содержание регистра P2 лишено законной силы такими кодами операции, как Function или любым использованием другого курсора, указывающего на ту же самую таблицу.

Rowid Сохранить в регистре P2 целое число, которое является ключом записи таблицы, к которой P1 в настоящее время указателем.

P1 может быть обычной или виртуальной таблицей. Раньше был отдельный код операции OP_VRowid для использования с виртуальными таблицами, но этот код операции теперь работает на оба типа таблицы.

RowSetAdd Вставьте целочисленное значение, проводимое регистром P2 в объект RowSet в регистре P1.

Утверждение терпит неудачу, если P2 не целое число.

RowSetRead Извлеките самое маленькое значение из объекта RowSet в P1 и поместите то значение в регистр P3. Или, если объект RowSet P1 первоначально пуст, оставьте без изменений P3 и перейдите на инструкцию в P2.
RowSetTest Регистр P3, как предполагается, содержит 64-битное целочисленное значение. Если регистр P1 содержит объект RowSet и объект RowSet содержит значение в P3, перейдите на P2. Иначе вставьте целое число в P3 в RowSet и продвиньтесь к следующему коду операции.

Объект RowSet оптимизирован для случая, где наборы целых чисел вставляются в отличные фазы, причем каждый набор не содержит дубликатов. Каждый набор определяется уникальным значением P4. У первого набора должно быть P4=0, у заключительного набора должен быть P4 =-1, для всех других наборов должен быть P4>0.

Это позволяет оптимизацию: (a) когда P4=0 нет никакой потребности проверить объект RowSet на P3, поскольку это, как гарантируют, не будет содержать его, (b), когда P4 = -1 там не будет никакой потребности вставить значение, поскольку это никогда не будет проверяться, (c) когда значение, которое является частью набора X, вставляется, нет никакой потребности искать, чтобы видеть, было ли то же самое значение ранее вставлено как часть набора X (только если это было ранее вставлено как часть некоторого другого набора).

Savepoint Откройте, освободите или отмените точку сохранения, названную параметром P4, в зависимости от значения P1. Чтобы открыть новую точку сохранения устанавливают P1=0 (SAVEPOINT_BEGIN). Чтобы освободить (commit) существующую точку сохранения ставят P1=1 (SAVEPOINT_RELEASE). Для отмены существующей точки сохранения установиите P1=2 (SAVEPOINT_ROLLBACK).
SCopy Сделайте копию регистра P1 в регистр P2.

Эта инструкция делает мелкую копию из значения. Если значение последовательность или blob, копия только указатель на оригинал, следовательно если оригинал меняется, копия тоже. Хуже, если оригинал освобожден, копия становится недействительной. Таким образом программа должна гарантировать, что оригинал не изменится в течение целой жизни копии. Используйте Copy, чтобы сделать полную копию.

SeekEnd Курсор P1 передвиньте в конец btree в целях добавления нового входа в btree.

Предполагается, что курсор используется только для добавления и поэтому если курсор действителен, то курсор должен уже указывать в конец btree и таким образом, никакие изменения не внесены в курсор.

SeekGE Если курсор P1 относится к таблице SQL (B-дерево, которое использует ключи целого числа), используйте значение в регистре P3 как ключ. Если курсор P1 относится к индексу SQL, то P3 первый во множестве регистров P4, которые используются в качестве распакованного ключа индекса.

Курсор P1 сдвигается так, чтобы это указало на самый маленький вход, который больше или равен значению ключа. Если нет никаких записей, больше или равных ключу, и P2 не ноль, то перейдите к P2.

Если курсор P1 был открыт, используя флаг OPFLAG_SEEKEQ, то этот код операции приземлится на запись, которая точно соответствует ключу, или иначе это вызовет переход в P2. Когда курсор OPFLAG_SEEKEQ, этот код операции должен сопровождаться кодом операции IdxLE с теми же самыми аргументами. Код операции IdxGT будет пропущен, если этот код операции достигнет цели, но код операции IdxGT будет использоваться на последующих повторениях цикла. Флаг OPFLAG_SEEKEQ это намек слою btree, чтобы сказать, что это поиск равенства.

Этот код операции оставляет курсор формируемым, чтобы переместиться в передовой порядок с начала к концу. Другими словами, курсор формируется, чтобы использовать Next, но не Prev.

См. также: Found, NotFound, SeekLt, SeekGt, SeekLe

SeekGT Если курсор P1 относится к таблице SQL (B-дерево, которое использует ключи целого числа), используйте значение в регистре P3 как ключ. Если курсор P1 относится к индексу SQL, то P3 первый во множестве регистров P4, которые используются в качестве распакованного ключа индекса.

Курсор P1 сдвигается так, чтобы это указало на самый маленький вход, который больше, чем значение ключа. Если нет никаких записей, больше, чем ключ и P2 не ноль, то перейдите к P2.

Этот код операции оставляет курсор формируемым, чтобы переместиться в передовой порядок с начала к концу. Другими словами, курсор формируется, чтобы использовать Next, но не Prev.

См. также: Found, NotFound, SeekLt, SeekGe, SeekLe

SeekHit Увеличьте или уменьшите значение seekHit для курсора P1 при необходимости так, чтобы это было не меньше, чем P2 и не больше, чем P3.

seekHit представляет максимум условий в индексе, для которого известно по крайней мере одно совпадение. Если значение seekHit меньше, чем общее количество условий равенства в поиске индекса, то код операции IfNoHope мог бы работать, чтобы видеть, может ли цикл IN быть оставлен рано, таким образом экономя работу. Это часть оптимизации IN-early-out.

P1 должен быть действительным курсором b-дерева.

SeekLE Если курсор P1 относится к таблице SQL (B-дерево, которое использует ключи целого числа), используйте значение в регистре P3 как ключ. Если курсор P1 относится к индексу SQL, то P3 первый во множестве регистров P4, которые используются в качестве распакованного ключа индекса.

Курсор P1 сдвигается так, чтобы это указало на самый большой вход, который меньше или равен значению ключа. Если нет никаких записей, меньше или равных ключу, и P2 не ноль, то перейдите к P2.

Этот код операции оставляет курсор формируемым, чтобы переместиться в обратном порядке от конца к началу. Другими словами, курсор формируется, чтобы использовать Prev, но не Next.

Если курсор P1 был открыт, используя флаг OPFLAG_SEEKEQ, то этот код операции приземлится на запись, которая точно соответствует ключу, или иначе это вызовет переход в P2. Когда курсор OPFLAG_SEEKEQ, этот код операции должен сопровождаться кодом операции IdxLE с теми же самыми аргументами. Код операции IdxGE будет пропущен, если этот код операции достигнет цели, но код операции IdxGE будет использоваться на последующих повторениях цикла. Флаг OPFLAG_SEEKEQ это намек слою btree, чтобы сказать, что это поиск равенства.

См. также: Found, NotFound, SeekGt, SeekGe, SeekLt

SeekLT Если курсор P1 относится к таблице SQL (B-дерево, которое использует ключи целого числа), используйте значение в регистре P3 как ключ. Если курсор P1 относится к индексу SQL, то P3 первый во множестве регистров P4, которые используются в качестве распакованного ключа индекса.

Курсор P1 сдвигается так, чтобы это указало на самый большой вход, который является меньше, чем значение ключа. Если нет никаких записей меньше, чем ключ и P2 не ноль, то перейдите к P2.

Этот код операции оставляет курсор формируемым, чтобы переместиться в обратном порядке от конца к началу. Другими словами, курсор формируется, чтобы использовать Prev, но не Next.

См. также: Found, NotFound, SeekGt, SeekGe, SeekLe

SeekRowid P1 это индекс курсора, открытого на таблице SQL btree (с ключами целого числа). Если регистр P3 не содержит целое число или если P1 не содержит запись с rowid P3, немедленно перейдите на P2. Или, если P2 = 0, поднимите ошибку SQLITE_CORRUPT. Если P1 действительно содержит запись с rowid P3, тогда оставляют курсор, указывающий на ту запись, и проваливаются к следующей инструкции.

NotExists выполняет ту же самую операцию, но с NotExists регистр P3, как должны гарантировать, будет содержать целочисленное значение. С этим кодом операции P3 не мог бы содержать целое число.

NotFound выполняет ту же самую операцию на индексе btrees (с произвольными ключами).

Этот код операции оставляет курсор в состоянии, где это не может быть продвинуто ни в одном направлении. Другими словами, Next и Prev не будут работать после этого кода операции.

См. также: Found, NotFound, NoConflict, SeekRowid

SeekScan Этот код операции это код операции префикса к SeekGE. Другими словами, этот код операции должен немедленно сопровождаться SeekGE. Это ограничение проверяется assert().

Этот код операции использует операнды P1-P4 последующего SeekGE. В тексте, который следует, операнды последующего кода операции SeekGE обозначены как SeekOP.P1-SeekOP.P4. Только операнды P1, P2 и P5 этого кода операции также используют и называют This.P1, This.P2 и This.P5.

Этот код операции помогает оптимизировать операторов IN на многостолбцовом индексе, где оператор IN в более поздних отношениях индекса, избегает ненужных поисков в btree, заменяя их переходами к следующей строке b-дерева вместо этого. Правильный ответ получен, если этот код операции опущен или не делает ничего.

SeekGE.P3 и SeekGE.P4 определяют распакованный ключ, который является желаемым входом, на который мы хотим, чтобы курсор SeekGE.P1 указал. Назовите эту строку SeekGE.P3/P4 "target".

Если курсор SeekGE.P1 в настоящее время не указывает на действительную строку, то этот код операции не работает, и контроль проходит в SeekGE.

Если курсор SeekGE.P1 указывает на действительную строку, то он мог бы быть целевой строкой, или это могло бы быть строкой и немного перед целевой строкой, или это могло бы быть после целевой строки. Если курсор в настоящее время перед целевой строкой, то этот код операции пытается поместить курсор на целевую строку или после нее вызовом sqlite3BtreeStep() на курсоре между 1 и This.P1 раз.

This.P5 это флаг, который указывает, что сделать, если курсор заканчивает тем, что указал на действительную строку, которая проходит целевую. Если This.P5 = false (0), переход сделан на SeekGE.P2. Если This.P5 = true (не 0), переход сделан к This.P2. Ситуация P5=0 происходит, когда нет никаких ограничений неравенства направо от ограничения IN. Переход на SeekGE.P2 заканчивает цикл. Ситуация P5!=0 происходит, когда есть ограничения неравенства направо от оператора IN. В этом случае This.P2 укажет непосредственно на или код установки до кода операции IdxGT или IdxGE, который проверяет на конец цикла.

Возможные исходы из этого кода операции:

  1. Если курсор первоначально не указывает ни на какую действительную строку, то провалитесь в последующий код операции SeekGE.

  2. Если курсор указывает на левый край строки, которая перед целевой строкой, даже после создания минимум This.P1 вызовов sqlite3BtreeNext(), также провалитесь в SeekGE.

  3. Если курсор указывает на левый край целевой строки, это было в начале целевой строке или один или несколько вызовов sqlite3BtreeNext() переместили курсор в целевую строку, перейдите на This.P2.

  4. Если курсор был перед целевой строкой и вызовом to sqlite3BtreeNext() передвинут от конца индекса (указание, что целевая строка определенно не существует в btree), тогда перейдите на SeekGE.P2, заканчивая цикл.

  5. Если курсор заканчивается на действительной строке, которая после целевой (указание, что целевая строка не существует в btree), тогда перейдите на SeekOP.P2, если This.P5=0 или на This.P2, если This.P5>0.
Sequence Найдите следующий доступный порядковый номер для курсора P1. Напишите порядковый номер в регистр P2. Порядковый номер на курсоре увеличен после этой инструкции.
SequenceTest P1 это курсор сортировщика. Если счетчик последовательности в настоящее время ноль, выполните переход на P2. Независимо от того, сделан ли переход, увеличьте значение последовательности.
SetCookie Напишите целочисленное значение P3 в cookie номер P2 БД P1. P2=1 является версией схемы. P2=2 является форматом базы данных. P2=3 является рекомендуемым размером кэша страницы и т.д. P1=0 является главным файлом базы данных, P1=1 является файлом базы данных, используемым, чтобы сохранить временные таблицы.

Транзакция должна быть начата прежде, чем выполнить этот код операции.

Если P2 это SCHEMA_VERSION cookie (cookie номер 1), внутренняя версия схемы установлена в P3-P5. "PRAGMA schema_version=N" имеет P5 = 1, чтобы внутренняя версия схемы отличалась от версии схемы базы данных, приводя к сбросу схемы.

ShiftLeft Переместите целочисленное значение в регистре P2 налево на число битов, определенных целым числом в регистре P1. Сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
ShiftRight Переместите целочисленное значение в регистре P2 направо на число битов, определенных целым числом в регистре P1. Сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
SoftNull Установите регистр P1, чтобы иметь значение NULL, как указано MakeRecord, но не освобождайте последовательности или blob, связанные с регистром, чтобы, если значение было последовательностью или blob, который был ранее скопирован, используя SCopy, копии продолжили быть действительными.
Sort Этот код операции делает точно то же самое, как Rewind за исключением того, что это увеличивает недокументированную глобальную переменную, используемую для тестирования.

Сортировка достигается, записывая элементы в индекс сортировки, затем делается перемотка того индекса и воспроизведение его с начала до конца. Мы используем код операции Sort вместо Rewind, чтобы сделать перемотку так, чтобы глобальная переменная была увеличена, и регрессионные тесты могут определить, оптимизирует ли оптимизатор правильно сортировки.

SorterCompare P1 это курсор сортировщика. Эта инструкция сравнивает префикс blob в регистре P3 против префикса входа, на который в настоящее время указывает курсор сортировщика. Только первые P4 поля r[P3] и записи сортировщика сравнены.

Если P3 или сортировщик содержат NULL в одной из их значительных областей (не считая области P4 в конце, которые проигнорированы), сравнение, как предполагается, равно.

Провалитесь к следующей инструкции, если две записи выдерживают сравнение равенства друг другу. Jump на P2, если они отличаются.

SorterData Напишите в регистр P2 текущие данные сортировщика для курсора P1 сортировщика. Затем очистите кэш заголовка столбца на курсоре P3.

Этот код операции обычно используется, чтобы переместить запись из сортировщика в регистр, который является источником для курсора псевдотаблицы, созданной, используя OpenPseudo. Тот курсор псевдотаблицы, это тот, который определяется параметром P3. Очищение кэша колонки P3 как часть этого кода операции спасает нас от необходимости в отдельной инструкции NullRow, чтобы очистить тот кэш.

SorterInsert Регистрир P2 хранит ключ индекса SQL, сделанный использованием инструкций MakeRecord. Этот код операции пишет ключ в сортировщик P1. Данные для входа nil.
SorterNext Этот код операции работает точно так же, как Next за исключением того, что P1 должен быть объектом сортировщика, для которого был вызван код операции SorterSort . Этот код операции продвигает курсор к следующей сортированной записи или переходит на P2, если больше нет сортированных записей.
SorterOpen Этот код операции работает как OpenEphemeral за исключением того, что это открывает переходный индекс, который специально предназначен, чтобы привести в порядок большие таблицы, используя внешний алгоритм сортировки слиянием.

Если аргумент P3 не 0, это указывает, что сортировщик может предположить стабильную сортировку, рассматривая первые P3 полей каждого ключа, чтобы прийти к необходимым результатам.

SorterSort После того, как все записи были вставлены в объект Sorter, определенный P1, вызовите этот код операции, чтобы на самом деле сделать сортировку. Jump на P2 при отсутствии записей, которые будут сортированы.

Этот код операции псевдоним для Sort и Rewind, который используется для объектов Sorter.

SqlExec Управляйте SQL-оператором или запросами, определенными в последовательности P4. Отключите отзывы Auth и Trace в то время, как те запросы работают, если P1 = true.
String Значение последовательности P4 длиной P1 байт сохранено в регистре P2.

Если P3 не 0 и содержание регистра P3 = P5, тип данных регистра P2 преобразовывается в BLOB. Содержание та же самая последовательность байтов, это просто интерпретируется как BLOB вместо последовательности, как будто это был CAST. Другими словами:

if (P3!=0 and reg[P3]=P5) reg[P2] := CAST(reg[P2] as BLOB)

String8 P4 указывает на nul-законченную последовательность UTF-8. Этот код операции преобразовывается в код операции String прежде, чем он будет выполнен впервые. Во время этого преобразования длина последовательности P4 вычислена и сохранена как параметр P1.
Subtract Вычтите значение в регистре P1 из значения в регистре P2 и сохраните результат в регистре P3. Если любой вход NULL, результат NULL.
TableLock Получите блокировку на конкретной таблице. Эта инструкция используется только, когда опция общего кэша активирована.

P1 этоиндекс базы данных в sqlite3.aDb[] базы данных, на которой приобретена блокировка. Блокировка чтения получена, если P3 = 0 или блокировка записи получена, если P3=1.

P2 содержит страницу корня таблицы, чтобы блокировать.

P4 содержит указатель на название блокируемой таблицы. Это используется только, чтобы произвести сообщение об ошибке, если блокировка не может быть получена.

Trace Напишите P4 в вывод трассировки запроса, если отслеживание запроса позволено.

Операнд P1 должен быть 0x7fffffff, P2 должен быть положительным.

Transaction Начните транзакцию на базе данных P1, если транзакция еще не активна. Если P2 отличный от нуля, то транзакция записи начата, или если транзакция чтения уже активна, это модернизировано до транзакции записи. Если P2 = 0, то транзакция чтения начата. Если P2 равняется 2 или больше, тогда начата исключительная транзакция.

P1 это индекс файла базы данных, на котором начата транзакция. Индекс 0 это главный файл базы данных, индекс 1 файл, используемый для временных таблиц. Индексы 2 или больше используются для приложенных баз данных.

Если транзакция записи начата, и флаг Vdbe.usesStmtJournal = true (этот флаг установлен, если Vdbe может изменить больше, чем одну строку и может бросить исключение ABORT), транзакция запроса может также быть открыта. Более определенно транзакция запроса открыта, если соединение с базой данных в настоящее время находится не в режиме autocommit или если есть другие активные запросы. Транзакция запроса позволяет изменениям, внесенным этим VDBE быть отмененными после ошибки, не имея необходимости отменять всю транзакцию. Если ни с какой ошибкой не столкнутся, транзакция запроса автоматически передастся, когда VDBE остановится.

Если P5!=0, тогда этот код также сравнивают cookie схемы с P3 и счетчик поколения схемы с P4. Здесь cookie изменяет свою значение каждый раз, когда схема базы данных изменяется. Эта операция используется, чтобы обнаружить изменение cookie и понять, что текущий процесс должен перечитать схему. Если cookie схемы в P3 отличается от cookie схемы в заголовке базы данных или если счетчик поколения схемы в P4 отличается от текущего счетчика поколения, то ошибка SQLITE_SCHEMA поднята и выполнение остановлено. Функция обертки sqlite3_step() могла бы тогда повторно подготовить запрос и запустить повторно его с начала.

TypeCheck Примените близость к диапазону регистров P2, начиная с P1. Возьмите близость от объекта таблицы в P4. Если какое-либо значение не может быть приведено в правильный тип, то поднимите ошибку.

Этот код операции подобен Affinity за исключением того, что этот код операции принудительно приводит тип регистра к типу столбца таблицы. Это используется, чтобы осуществить "strict affinity".

Столбцы GENERATED ALWAYS AS ... STATIC проверяются только если P3 = 0. Когда P3 отличный от нуля, никакая проверка типа не происходит для статических произведенных колонок. Виртуальные колонки вычисляются во время выполнения запроса и таким образом они никогда не проверяются.

Предварительные условия:

  • P2 должен быть количеством невиртуальных колонок в таблице P4.
  • Таблица P4 должна быть таблицей STRICT.

Если какое-либо предварительное условие ложное, ошибка утверждения происходит.

Vacuum Пропылесосьте всю базу данных P1. P1 = 0 для "main", 2 или больше для приложенной базы данных. База данных "temp" не может вакуумироваться.

Если P2 не 0, то это регистр, содержащий последовательность, которая является файлом, в который должен быть написан результат вакуума. Когда P2 = 0, вакуум переписывает оригинальную базу данных.

Variable Передайте значения связанного параметра P1 в регистр P2.

Если параметр называют, то его имя появляется в P4. Значение P4 используется sqlite3_bind_parameter_name().

VBegin P4 может быть указателем на структуру sqlite3_vtab. Если это так, вызовите метод xBegin для этой таблицы.

Кроме того, установлен ли P4, проверьте, что это не вызывают из отзыва к методу xSync() виртуальной таблицы. Если это будет так, код ошибки будет установлен в SQLITE_LOCKED.

VCheck P4 указатель на объект таблицы, который является виртуальной таблицей в схеме P1, которая поддерживает метод xIntegrity(). Этот код операции управляет методом xIntegrity() для той виртуальной таблицы, используя P3 в качестве целочисленного аргумента. Если ошибка сообщена, имя таблицы предваряется сообщением об ошибке, и то сообщение хранится в P2. Если никакие ошибки не замечены, регистр P2 = NULL.
VColumn Сохраните в регистре P3 значение P2-й колонки текущей строки виртуальной таблицы курсора P1.

Если VColumn используется, чтобы принести значение неизменной колонки во время операции UPDATE, то значение P5 = OPFLAG_NOCHNG. Это заставит функцию sqlite3_vtab_nochange() возвращать true в методе xColumn виртуального внедрения таблицы. Колонка P5 могла бы также содержать другие биты (OPFLAG_LENGTHARG или OPFLAG_TYPEOFARG), но те биты не использованы VColumn.

VCreate P2 содержит название виртуальной таблицы в базе данных P1. Вызовите метод xCreate для той таблицы.
VDestroy P4 название виртуальной таблицы в базе данных P1. Вызовите метод xDestroy для той таблицы.
VFilter P1 это открытый курсор, применяемый VOpen. P2 это адрес, чтобы перейти, если фильтрованный набор результатов пуст.

P4 NULL или последовательность, которая была произведена методом xBestIndex модуля. Интерпретацию последовательности P4 оставляют внедрению модуля.

Этот код операции вызывает метод xFilter на виртуальной таблице, определенный P1. Параметр плана запросов целого числа для xFilter сохранен в регистре P3. Регистр P3+1 хранит параметр argc, который будет передан к методу xFilter. Регистры P3+2..P3+1+argc это дополнительные argc параметров, которые передаются к xFilter как argv. Регистр P3+2 становится argv[0], когда передано к xFilter.

Переход сделан к P2, если бы набор результатов после фильтрации был бы пуст.

VInitIn Установите регистр P2, чтобы быть указателем на объект ValueList для курсора P1 с кэшем регистра P3 и выходным регистром P3+1. Объект ValueList может использоваться в качестве первого аргумента sqlite3_vtab_in_first() и sqlite3_vtab_in_next(), чтобы извлечь все значения, сохраненные в курсоре P1. Регистр P3 используется, чтобы хранить значения, возвращенные sqlite3_vtab_in_first() и sqlite3_vtab_in_next().
VNext Продвиньте виртуальную таблицу P1 к следующей строке в наборе результатов и перейдите на инструкцию P2. Или, если виртуальная таблица достигла конца своего набора результатов, то проваливается к следующей инструкции.
VOpen P4 указатель на виртуальный объект таблицы, структуру sqlite3_vtab. P1 это номер курсора. Этот код операции открывает курсор для виртуальной таблицы и хранит тот курсор в P1.
VRename P4 это указатель на виртуальный объект таблицы, структуру sqlite3_vtab. Этот код операции вызывает соответствующий метод xRename. Значение в регистре P1 передается как аргумент zName методу xRename.
VUpdate P4 это указатель на виртуальный объект таблицы, структуру sqlite3_vtab. Этот код операции вызывает соответствующий метод xUpdate. Значения P2 это смежные элементы памяти, начиная в P3 для передачи вызову xUpdate. Значение в регистре (P3+P2-1) соответствует элементу p2 множества argv, переданного xUpdate.

Метод xUpdate сделает DELETE или INSERT или оба. Элемент argv[0] (который соответствует элементу памяти P3) является rowid строки, чтобы удалить. Если argv[0] = NULL, никакое удаление не происходит. Элемент argv[1] это rowid новой строки. Это может быть NULL, чтобы виртуальная таблица выбрала новый rowid для себя. Последующие элементы во множестве это значения колонок в новой строке.

Если P2=1, никакая вставка не выполняется. argv[0] это rowid строки, чтобы удалить.

P1 это флаг boolean. Если это установлено в true и xUpdate успешен, значение, возвращенное sqlite3_last_insert_rowid(), установлено к значению rowid для вставленной строки.

P5 это ошибочные действия (OE_Replace, OE_Fail, OE_Ignore), чтобы применить в случае ограничительной неудачи для вставки или обновления.

Yield Обменяйте счетчик команд со значением в регистре P1. Это имеет эффект уступки.

Если подпрограмма, которая начата этой инструкцией, закончит с Yield или Return, перейдите к следующей инструкции. Но если она закончит с EndCoroutine, перейдите на P2 вместо того, чтобы продолжить следующую инструкцию.

См. также: InitCoroutine

ZeroOrNull Если оба регистра P1 и P3 NOT NULL, то сохраните ноль в регистре P2. Если регистр P1 или P3 NULL, поместите NULL в регистр P2.