DBD-SQLite
view release on metacpan or search on metacpan
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char*);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int);
SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags);
SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
#ifndef SQLITE_OMIT_SHARED_CACHE
SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
#endif
/* Savepoints are named, nestable SQL transactions mostly implemented */
/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */
SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
/* "Checkpoint" only refers to WAL. See https://sqlite.org/wal.html#ckpt */
#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
#endif
SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
** of the flags shown below.
**
** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With
** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL
** indices.)
*/
#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
#define BTREE_BLOBKEY 2 /* Table has keys only - no data */
SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, i64*);
SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int);
SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
/*
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
** should be one of the following values. The integer values are assigned
** to constants so that the offset of the corresponding field in an
** SQLite database header may be found using the following formula:
**
** offset = 36 + (idx * 4)
**
** For example, the free-page-count field is located at byte offset 36 of
** the database file header. The incr-vacuum-flag field is located at
** byte offset 64 (== 36+4*7).
**
** The BTREE_DATA_VERSION value is not really a value stored in the header.
** It is a read-only number computed by the pager. But we merge it with
** the header value access routines since its access pattern is the same.
** Call it a "virtual meta value".
*/
#define BTREE_FREE_PAGE_COUNT 0
#define BTREE_SCHEMA_VERSION 1
#define BTREE_FILE_FORMAT 2
#define BTREE_DEFAULT_CACHE_SIZE 3
#define BTREE_LARGEST_ROOT_PAGE 4
#define BTREE_TEXT_ENCODING 5
#define BTREE_USER_VERSION 6
#define BTREE_INCR_VACUUM 7
#define BTREE_APPLICATION_ID 8
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
/*
** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
** interface.
**
** BTREE_HINT_RANGE (arguments: Expr*, Mem*)
**
** The first argument is an Expr* (which is guaranteed to be constant for
** the lifetime of the cursor) that defines constraints on which rows
** might be fetched with this cursor. The Expr* tree may contain
** TK_REGISTER nodes that refer to values stored in the array of registers
** passed as the second parameter. In other words, if Expr.op==TK_REGISTER
** then the value of the node is the value in Mem[pExpr.iTable]. Any
** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th
** column of the b-tree of the cursor. The Expr tree will not contain
** any function calls nor subqueries nor references to b-trees other than
** the cursor being hinted.
**
** The design of the _RANGE hint is aid b-tree implementations that try
** to prefetch content from remote machines - to provide those
** implementations with limits on what needs to be prefetched and thereby
** reduce network bandwidth.
**
** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
** standard SQLite. The other hints are provided for extensions that use
** the SQLite parser and code generator but substitute their own storage
** engine.
*/
#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
/*
** Values that may be OR'd together to form the argument to the
** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
**
** The BTREE_BULKLOAD flag is set on index cursors when the index is going
** to be filled with content that is already in sorted order.
**
** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or
/* Forward reference */
static int pager_playback(Pager *pPager, int isHot);
/*
** Execute a rollback if a transaction is active and unlock the
** database file.
**
** If the pager has already entered the ERROR state, do not attempt
** the rollback at this time. Instead, pager_unlock() is called. The
** call to pager_unlock() will discard all in-memory pages, unlock
** the database file and move the pager back to OPEN state. If this
** means that there is a hot-journal left in the file-system, the next
** connection to obtain a shared lock on the pager (which may be this one)
** will roll it back.
**
** If the pager has not already entered the ERROR state, but an IO or
** malloc error occurs during a rollback, then this will itself cause
** the pager to enter the ERROR state. Which will be cleared by the
** call to pager_unlock(), as described above.
*/
static void pagerUnlockAndRollback(Pager *pPager){
if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
assert( assert_pager_state(pPager) );
if( pPager->eState>=PAGER_WRITER_LOCKED ){
sqlite3BeginBenignMalloc();
sqlite3PagerRollback(pPager);
sqlite3EndBenignMalloc();
}else if( !pPager->exclusiveMode ){
assert( pPager->eState==PAGER_READER );
pager_end_transaction(pPager, 0, 0);
}
}else if( pPager->eState==PAGER_ERROR
&& pPager->journalMode==PAGER_JOURNALMODE_MEMORY
&& isOpen(pPager->jfd)
){
/* Special case for a ROLLBACK due to I/O error with an in-memory
** journal: We have to rollback immediately, before the journal is
** closed, because once it is closed, all content is forgotten. */
int errCode = pPager->errCode;
u8 eLock = pPager->eLock;
pPager->eState = PAGER_OPEN;
pPager->errCode = SQLITE_OK;
pPager->eLock = EXCLUSIVE_LOCK;
pager_playback(pPager, 1);
pPager->errCode = errCode;
pPager->eLock = eLock;
}
pager_unlock(pPager);
}
/*
** Parameter aData must point to a buffer of pPager->pageSize bytes
** of data. Compute and return a checksum based on the contents of the
** page of data and the current value of pPager->cksumInit.
**
** This is not a real checksum. It is really just the sum of the
** random initial value (pPager->cksumInit) and every 200th byte
** of the page data, starting with byte offset (pPager->pageSize%200).
** Each byte is interpreted as an 8-bit unsigned integer.
**
** Changing the formula used to compute this checksum results in an
** incompatible journal file format.
**
** If journal corruption occurs due to a power failure, the most likely
** scenario is that one end or the other of the record will be changed.
** It is much less likely that the two ends of the journal record will be
** correct and the middle be corrupt. Thus, this "checksum" scheme,
** though fast and simple, catches the mostly likely kind of corruption.
*/
static u32 pager_cksum(Pager *pPager, const u8 *aData){
u32 cksum = pPager->cksumInit; /* Checksum value to return */
int i = pPager->pageSize-200; /* Loop counter */
while( i>0 ){
cksum += aData[i];
i -= 200;
}
return cksum;
}
/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
** The page begins at offset *pOffset into the file. The *pOffset
** value is increased to the start of the next page in the journal.
**
** The main rollback journal uses checksums - the statement journal does
** not.
**
** If the page number of the page record read from the (sub-)journal file
** is greater than the current value of Pager.dbSize, then playback is
** skipped and SQLITE_OK is returned.
**
** If pDone is not NULL, then it is a record of pages that have already
** been played back. If the page at *pOffset has already been played back
** (if the corresponding pDone bit is set) then skip the playback.
** Make sure the pDone bit corresponding to the *pOffset page is set
** prior to returning.
**
** If the page record is successfully read from the (sub-)journal file
** and played back, then SQLITE_OK is returned. If an IO error occurs
** while reading the record from the (sub-)journal file or while writing
** to the database file, then the IO error code is returned. If data
** is successfully read from the (sub-)journal file but appears to be
** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
** two circumstances:
**
** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
** * If the record is being rolled back from the main journal file
** and the checksum field does not match the record content.
**
** Neither of these two scenarios are possible during a savepoint rollback.
**
** If this is a savepoint rollback, then memory may have to be dynamically
** allocated by this function. If this is the case and an allocation fails,
** SQLITE_NOMEM is returned.
*/
static int pager_playback_one_page(
Pager *pPager, /* The pager being played back */
i64 *pOffset, /* Offset of record to playback */
Bitvec *pDone, /* Bitvec of pages already played back */
int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */
/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
** Applications can choose to define yytestcase() in the %include section
** to a macro that can assist in verifying code coverage. For production
** code the yytestcase() macro should be turned off. But it is useful
** for testing.
*/
#ifndef yytestcase
# define yytestcase(X)
#endif
/* Macro to determine if stack space has the ability to grow using
** heap memory.
*/
#if YYSTACKDEPTH<=0 || YYDYNSTACK
# define YYGROWABLESTACK 1
#else
# define YYGROWABLESTACK 0
#endif
/* Guarantee a minimum number of initial stack slots.
*/
#if YYSTACKDEPTH<=0
# undef YYSTACKDEPTH
# define YYSTACKDEPTH 2 /* Need a minimum stack size */
#endif
/* Next are the tables used to determine what action to take based on the
** current state and lookahead token. These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.
**
** Suppose the action integer is N. Then the action is determined as
** follows
**
** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
** N == YY_ERROR_ACTION A syntax error has occurred.
**
** N == YY_ACCEPT_ACTION The parser accepts its input.
**
** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
** and YY_MAX_REDUCE
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = yy_action[ yy_shift_ofst[S] + X ]
** (B) N = yy_default[S]
**
** The (A) formula is preferred. The B formula is used instead if
** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X.
**
** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
** the yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
** yy_action[] A single table containing all actions.
** yy_lookahead[] A table containing the lookahead for each entry in
** yy_action. Used to detect hash collisions.
** yy_shift_ofst[] For each state, the offset into yy_action for
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (2207)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289,
/* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413,
/* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82,
/* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984,
/* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063,
/* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413,
/* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130,
/* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290,
/* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063,
/* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296,
/* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132,
/* 110 */ 132, 132, 131, 128, 451, 451, 1050, 1050, 1064, 1067,
/* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174,
/* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 481, 1341,
/* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132,
/* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 498, 1228,
/* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136,
/* 170 */ 136, 1204, 862, 1281, 288, 288, 283, 288, 288, 523,
/* 180 */ 523, 1250, 139, 578, 7, 578, 1345, 573, 1169, 562,
/* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 573, 547,
/* 200 */ 562, 1169, 245, 1541, 1169, 245, 133, 133, 132, 132,
/* 210 */ 132, 131, 128, 451, 302, 134, 134, 134, 134, 133,
/* 220 */ 133, 132, 132, 132, 131, 128, 451, 1575, 1204, 1205,
/* 230 */ 1204, 7, 470, 550, 455, 413, 550, 455, 130, 127,
/* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132,
/* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 483, 137,
/* 260 */ 138, 91, 1019, 1228, 1228, 1063, 1066, 1053, 1053, 135,
/* 270 */ 135, 136, 136, 136, 136, 1085, 576, 1204, 132, 132,
/* 280 */ 132, 131, 128, 451, 93, 214, 134, 134, 134, 134,
/* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 401, 19,
/* 300 */ 19, 134, 134, 134, 134, 133, 133, 132, 132, 132,
/* 310 */ 131, 128, 451, 1498, 426, 267, 344, 467, 332, 134,
/* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128,
/* 330 */ 451, 1281, 576, 6, 1204, 1205, 1204, 257, 576, 413,
/* 340 */ 511, 508, 507, 1279, 94, 1019, 464, 1204, 551, 551,
/* 350 */ 506, 1224, 1571, 44, 38, 51, 51, 411, 576, 413,
/* 360 */ 45, 51, 51, 137, 138, 91, 530, 1228, 1228, 1063,
/* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 398,
/* 380 */ 1148, 82, 82, 137, 138, 91, 39, 1228, 1228, 1063,
/* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 344,
/* 400 */ 44, 288, 288, 375, 1204, 1205, 1204, 209, 1204, 1224,
/* 410 */ 320, 567, 471, 576, 573, 576, 562, 576, 316, 264,
** 5: Table is a virtual table.
*/
#define RBU_PK_NOTABLE 0
#define RBU_PK_NONE 1
#define RBU_PK_IPK 2
#define RBU_PK_EXTERNAL 3
#define RBU_PK_WITHOUT_ROWID 4
#define RBU_PK_VTAB 5
/*
** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs
** one of the following operations.
*/
#define RBU_INSERT 1 /* Insert on a main table b-tree */
#define RBU_DELETE 2 /* Delete a row from a main table b-tree */
#define RBU_REPLACE 3 /* Delete and then insert a row */
#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */
#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */
#define RBU_UPDATE 6 /* Update a row in a main table b-tree */
/*
** A single step of an incremental checkpoint - frame iWalFrame of the wal
** file should be copied to page iDbPage of the database file.
*/
struct RbuFrame {
u32 iDbPage;
u32 iWalFrame;
};
#ifndef UNUSED_PARAMETER
/*
** The following macros are used to suppress compiler warnings and to
** make it clear to human readers when a function parameter is deliberately
** left unused within the body of a function. This usually happens when
** a function is called via a function pointer. For example the
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,
** if it knows that this is enforced elsewhere.
**
** When a function parameter is not used at all within the body of a function,
** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
** However, these macros may also be used to suppress warnings related to
** parameters that may or may not be used depending on compilation options.
** For example those parameters only used in assert() statements. In these
** cases the parameters are named as per the usual conventions.
*/
#define UNUSED_PARAMETER(x) (void)(x)
#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
#endif
/*
** RBU handle.
**
** nPhaseOneStep:
** If the RBU database contains an rbu_count table, this value is set to
** a running estimate of the number of b-tree operations required to
** finish populating the *-oal file. This allows the sqlite3_bp_progress()
** API to calculate the permyriadage progress of populating the *-oal file
** using the formula:
**
** permyriadage = (10000 * nProgress) / nPhaseOneStep
**
** nPhaseOneStep is initialized to the sum of:
**
** nRow * (nIndex + 1)
**
** for all source tables in the RBU database, where nRow is the number
** of rows in the source table and nIndex the number of indexes on the
** corresponding target database table.
**
** This estimate is accurate if the RBU update consists entirely of
** INSERT operations. However, it is inaccurate if:
**
** * the RBU update contains any UPDATE operations. If the PK specified
** for an UPDATE operation does not exist in the target table, then
** no b-tree operations are required on index b-trees. Or if the
** specified PK does exist, then (nIndex*2) such operations are
** required (one delete and one insert on each index b-tree).
**
** * the RBU update contains any DELETE operations for which the specified
** PK does not exist. In this case no operations are required on index
** b-trees.
**
** * the RBU update contains REPLACE operations. These are similar to
** UPDATE operations.
**
** nPhaseOneStep is updated to account for the conditions above during the
** first pass of each source table. The updated nPhaseOneStep value is
** stored in the rbu_state table if the RBU update is suspended.
*/
struct sqlite3rbu {
int eStage; /* Value of RBU_STATE_STAGE field */
sqlite3 *dbMain; /* target database handle */
sqlite3 *dbRbu; /* rbu database handle */
char *zTarget; /* Path to target db */
char *zRbu; /* Path to rbu db */
char *zState; /* Path to state db (or NULL if zRbu) */
char zStateDb[5]; /* Db name for state ("stat" or "main") */
int rc; /* Value returned by last rbu_step() call */
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
int nStep; /* Rows processed for current object */
sqlite3_int64 nProgress; /* Rows processed for all objects */
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
const char *zVfsName; /* Name of automatically created rbu vfs */
rbu_file *pTargetFd; /* File handle open on target db */
int nPagePerSector; /* Pages per sector for pTargetFd */
i64 iOalSz;
i64 nPhaseOneStep;
void *pRenameArg;
int (*xRename)(void*, const char*, const char*);
/* The following state variables are used as part of the incremental
** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
** function rbuSetupCheckpoint() for details. */
u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */
u32 mLock;
int nFrame; /* Entries in aFrame[] array */
int nFrameAlloc; /* Allocated size of aFrame[] array */
RbuFrame *aFrame;
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
** Applications can choose to define fts5yytestcase() in the %include section
** to a macro that can assist in verifying code coverage. For production
** code the fts5yytestcase() macro should be turned off. But it is useful
** for testing.
*/
#ifndef fts5yytestcase
# define fts5yytestcase(X)
#endif
/* Macro to determine if stack space has the ability to grow using
** heap memory.
*/
#if fts5YYSTACKDEPTH<=0 || fts5YYDYNSTACK
# define fts5YYGROWABLESTACK 1
#else
# define fts5YYGROWABLESTACK 0
#endif
/* Guarantee a minimum number of initial stack slots.
*/
#if fts5YYSTACKDEPTH<=0
# undef fts5YYSTACKDEPTH
# define fts5YYSTACKDEPTH 2 /* Need a minimum stack size */
#endif
/* Next are the tables used to determine what action to take based on the
** current state and lookahead token. These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.
**
** Suppose the action integer is N. Then the action is determined as
** follows
**
** 0 <= N <= fts5YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
**
** N == fts5YY_ERROR_ACTION A syntax error has occurred.
**
** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
**
** N == fts5YY_NO_ACTION No such action. Denotes unused
** slots in the fts5yy_action[] table.
**
** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
** and fts5YY_MAX_REDUCE
**
** The action table is constructed as a single large table named fts5yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
** (B) N = fts5yy_default[S]
**
** The (A) formula is preferred. The B formula is used instead if
** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X.
**
** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
** the fts5yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
** fts5yy_action[] A single table containing all actions.
** fts5yy_lookahead[] A table containing the lookahead for each entry in
** fts5yy_action. Used to detect hash collisions.
** fts5yy_shift_ofst[] For each state, the offset into fts5yy_action for
** shifting terminals.
** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for
** shifting non-terminals after a reduce.
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
#define fts5YY_ACTTAB_COUNT (105)
static const fts5YYACTIONTYPE fts5yy_action[] = {
/* 0 */ 81, 20, 96, 6, 28, 99, 98, 26, 26, 18,
/* 10 */ 96, 6, 28, 17, 98, 56, 26, 19, 96, 6,
/* 20 */ 28, 14, 98, 14, 26, 31, 92, 96, 6, 28,
/* 30 */ 108, 98, 25, 26, 21, 96, 6, 28, 78, 98,
/* 40 */ 58, 26, 29, 96, 6, 28, 107, 98, 22, 26,
/* 50 */ 24, 16, 12, 11, 1, 13, 13, 24, 16, 23,
/* 60 */ 11, 33, 34, 13, 97, 8, 27, 32, 98, 7,
/* 70 */ 26, 3, 4, 5, 3, 4, 5, 3, 83, 4,
/* 80 */ 5, 3, 63, 5, 3, 62, 12, 2, 86, 13,
/* 90 */ 9, 30, 10, 10, 54, 57, 75, 78, 78, 53,
/* 100 */ 57, 15, 82, 82, 71,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
/* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
/* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
/* 20 */ 20, 9, 22, 9, 24, 13, 17, 18, 19, 20,
/* 30 */ 26, 22, 24, 24, 17, 18, 19, 20, 15, 22,
/* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24,
/* 50 */ 6, 7, 9, 9, 10, 12, 12, 6, 7, 21,
/* 60 */ 9, 24, 25, 12, 18, 5, 20, 14, 22, 5,
/* 70 */ 24, 3, 1, 2, 3, 1, 2, 3, 0, 1,
/* 80 */ 2, 3, 11, 2, 3, 11, 9, 10, 5, 12,
/* 90 */ 23, 24, 10, 10, 8, 9, 9, 15, 15, 8,
/* 100 */ 9, 9, 27, 27, 11, 27, 27, 27, 27, 27,
/* 110 */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 120 */ 27,
};
#define fts5YY_SHIFT_COUNT (34)
#define fts5YY_SHIFT_MIN (0)
#define fts5YY_SHIFT_MAX (93)
static const unsigned char fts5yy_shift_ofst[] = {
/* 0 */ 44, 44, 44, 44, 44, 44, 51, 77, 43, 12,
/* 10 */ 14, 83, 82, 14, 23, 23, 31, 31, 71, 74,
/* 20 */ 78, 81, 86, 91, 6, 53, 53, 60, 64, 68,
/* 30 */ 53, 87, 92, 53, 93,
};
#define fts5YY_REDUCE_COUNT (17)
#define fts5YY_REDUCE_MIN (-17)
#define fts5YY_REDUCE_MAX (67)
static const signed char fts5yy_reduce_ofst[] = {
/* 0 */ -16, -8, 0, 9, 17, 25, 46, -17, -17, 37,
/* 10 */ 67, 4, 4, 8, 4, 20, 27, 38,
** Callback used by fts5Bm25GetData() to count the number of rows in the
** table matched by each individual phrase within the query.
*/
static int fts5CountCb(
const Fts5ExtensionApi *pApi,
Fts5Context *pFts,
void *pUserData /* Pointer to sqlite3_int64 variable */
){
sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
UNUSED_PARAM2(pApi, pFts);
(*pn)++;
return SQLITE_OK;
}
/*
** Set *ppData to point to the Fts5Bm25Data object for the current query.
** If the object has not already been allocated, allocate and populate it
** now.
*/
static int fts5Bm25GetData(
const Fts5ExtensionApi *pApi,
Fts5Context *pFts,
Fts5Bm25Data **ppData /* OUT: bm25-data object for this query */
){
int rc = SQLITE_OK; /* Return code */
Fts5Bm25Data *p; /* Object to return */
p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0);
if( p==0 ){
int nPhrase; /* Number of phrases in query */
sqlite3_int64 nRow = 0; /* Number of rows in table */
sqlite3_int64 nToken = 0; /* Number of tokens in table */
sqlite3_int64 nByte; /* Bytes of space to allocate */
int i;
/* Allocate the Fts5Bm25Data object */
nPhrase = pApi->xPhraseCount(pFts);
nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
p = (Fts5Bm25Data*)sqlite3_malloc64(nByte);
if( p==0 ){
rc = SQLITE_NOMEM;
}else{
memset(p, 0, (size_t)nByte);
p->nPhrase = nPhrase;
p->aIDF = (double*)&p[1];
p->aFreq = &p->aIDF[nPhrase];
}
/* Calculate the average document length for this FTS5 table */
if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
assert( rc!=SQLITE_OK || nRow>0 );
if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
/* Calculate an IDF for each phrase in the query */
for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
sqlite3_int64 nHit = 0;
rc = pApi->xQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb);
if( rc==SQLITE_OK ){
/* Calculate the IDF (Inverse Document Frequency) for phrase i.
** This is done using the standard BM25 formula as found on wikipedia:
**
** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) )
**
** where "N" is the total number of documents in the set and nHit
** is the number that contain at least one instance of the phrase
** under consideration.
**
** The problem with this is that if (N < 2*nHit), the IDF is
** negative. Which is undesirable. So the minimum allowable IDF is
** (1e-6) - roughly the same as a term that appears in just over
** half of set of 5,000,000 documents. */
double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) );
if( idf<=0.0 ) idf = 1e-6;
p->aIDF[i] = idf;
}
}
if( rc!=SQLITE_OK ){
sqlite3_free(p);
}else{
rc = pApi->xSetAuxdata(pFts, p, sqlite3_free);
}
if( rc!=SQLITE_OK ) p = 0;
}
*ppData = p;
return rc;
}
/*
** Implementation of bm25() function.
*/
static void fts5Bm25Function(
const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
Fts5Context *pFts, /* First arg to pass to pApi functions */
sqlite3_context *pCtx, /* Context for returning result/error */
int nVal, /* Number of values in apVal[] array */
sqlite3_value **apVal /* Array of trailing arguments */
){
const double k1 = 1.2; /* Constant "k1" from BM25 formula */
const double b = 0.75; /* Constant "b" from BM25 formula */
int rc; /* Error code */
double score = 0.0; /* SQL function return value */
Fts5Bm25Data *pData; /* Values allocated/calculated once only */
int i; /* Iterator variable */
int nInst = 0; /* Value returned by xInstCount() */
double D = 0.0; /* Total number of tokens in row */
double *aFreq = 0; /* Array of phrase freq. for current row */
/* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation)
** for each phrase in the query for the current row. */
rc = fts5Bm25GetData(pApi, pFts, &pData);
if( rc==SQLITE_OK ){
aFreq = pData->aFreq;
memset(aFreq, 0, sizeof(double) * pData->nPhrase);
rc = pApi->xInstCount(pFts, &nInst);
}
for(i=0; rc==SQLITE_OK && i<nInst; i++){
int ip; int ic; int io;
rc = pApi->xInst(pFts, i, &ip, &ic, &io);
if( rc==SQLITE_OK ){
double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0;
aFreq[ip] += w;
}
}
/* Figure out the total size of the current row in tokens. */
if( rc==SQLITE_OK ){
int nTok;
rc = pApi->xColumnSize(pFts, -1, &nTok);
D = (double)nTok;
}
/* Determine and return the BM25 score for the current row. Or, if an
** error has occurred, throw an exception. */
if( rc==SQLITE_OK ){
for(i=0; i<pData->nPhrase; i++){
score += pData->aIDF[i] * (
( aFreq[i] * (k1 + 1.0) ) /
( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
);
}
sqlite3_result_double(pCtx, -1.0 * score);
}else{
sqlite3_result_error_code(pCtx, rc);
}
}
/*
** Implementation of fts5_get_locale() function.
*/
static void fts5GetLocaleFunction(
const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
Fts5Context *pFts, /* First arg to pass to pApi functions */
sqlite3_context *pCtx, /* Context for returning result/error */
int nVal, /* Number of values in apVal[] array */
sqlite3_value **apVal /* Array of trailing arguments */
){
int iCol = 0;
int eType = 0;
int rc = SQLITE_OK;
( run in 1.943 second using v1.01-cache-2.11-cpan-13bb782fe5a )