DBD-SQLeet
view release on metacpan or search on metacpan
SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*);
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
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 *zMaster);
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*, int*, int flags);
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(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
SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
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, int*);
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 extentions 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
if( rc==SQLITE_OK && bCommit ){
rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
}
if( !pPager->exclusiveMode
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
){
rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
pPager->changeCountDone = 0;
}
pPager->eState = PAGER_READER;
pPager->setMaster = 0;
return (rc==SQLITE_OK?rc2:rc);
}
/*
** 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);
}
}
pager_unlock(pPager);
}
/*
** Parameter aData must point to a buffer of pPager->pageSize bytes
** of data. Compute and return a checksum based ont 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;
}
/*
** Report the current page size and number of reserved bytes back
** to the codec.
*/
#ifdef SQLITE_HAS_CODEC
static void pagerReportSize(Pager *pPager){
if( pPager->xCodecSizeChng ){
pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
(int)pPager->nReserve);
}
}
#else
# define pagerReportSize(X) /* No-op if we do not support a codec */
#endif
#ifdef SQLITE_HAS_CODEC
/*
** Make sure the number of reserved bits is the same in the destination
** pager as it is in the source. This comes up when a VACUUM changes the
** number of reserved bits to the "optimal" amount.
*/
SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
if( pDest->nReserve!=pSrc->nReserve ){
pDest->nReserve = pSrc->nReserve;
pagerReportSize(pDest);
}
}
#endif
/*
** 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.
**
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
#define YYNSTATE 521
#define YYNRULE 367
#define YYNTOKEN 155
#define YY_MAX_SHIFT 520
#define YY_MIN_SHIFTREDUCE 756
#define YY_MAX_SHIFTREDUCE 1122
#define YY_ERROR_ACTION 1123
#define YY_ACCEPT_ACTION 1124
#define YY_NO_ACTION 1125
#define YY_MIN_REDUCE 1126
#define YY_MAX_REDUCE 1492
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
/* 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
/* 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 (2009)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 368, 105, 102, 197, 105, 102, 197, 515, 1124, 1,
/* 10 */ 1, 520, 2, 1128, 515, 1192, 1171, 1456, 275, 370,
/* 20 */ 127, 1389, 1197, 1197, 1192, 1166, 178, 1205, 64, 64,
/* 30 */ 477, 887, 322, 428, 348, 37, 37, 808, 362, 888,
/* 40 */ 509, 509, 509, 112, 113, 103, 1100, 1100, 953, 956,
/* 50 */ 946, 946, 110, 110, 111, 111, 111, 111, 365, 252,
/* 60 */ 252, 515, 252, 252, 497, 515, 309, 515, 459, 515,
/* 70 */ 1079, 491, 512, 478, 6, 512, 809, 134, 498, 228,
/* 80 */ 194, 428, 37, 37, 515, 208, 64, 64, 64, 64,
/* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107,
/* 100 */ 107, 106, 401, 258, 381, 13, 13, 398, 397, 428,
/* 110 */ 252, 252, 370, 476, 405, 1104, 1079, 1080, 1081, 386,
/* 120 */ 1106, 390, 497, 512, 497, 1423, 1419, 304, 1105, 307,
/* 130 */ 1256, 496, 370, 499, 16, 16, 112, 113, 103, 1100,
/* 140 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
/* 150 */ 111, 262, 1107, 495, 1107, 401, 112, 113, 103, 1100,
/* 160 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
/* 170 */ 111, 129, 1425, 343, 1420, 339, 1059, 492, 1057, 263,
/* 180 */ 73, 105, 102, 197, 994, 109, 109, 109, 109, 108,
/* 190 */ 108, 107, 107, 107, 106, 401, 370, 111, 111, 111,
/* 200 */ 111, 104, 492, 89, 1432, 109, 109, 109, 109, 108,
/* 210 */ 108, 107, 107, 107, 106, 401, 111, 111, 111, 111,
/* 220 */ 112, 113, 103, 1100, 1100, 953, 956, 946, 946, 110,
/* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108,
/* 240 */ 108, 107, 107, 107, 106, 401, 114, 108, 108, 107,
/* 250 */ 107, 107, 106, 401, 109, 109, 109, 109, 108, 108,
/* 260 */ 107, 107, 107, 106, 401, 152, 399, 399, 399, 109,
/* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
/* 280 */ 178, 493, 1412, 434, 1037, 1486, 1079, 515, 1486, 370,
/* 290 */ 421, 297, 357, 412, 74, 1079, 109, 109, 109, 109,
/* 300 */ 108, 108, 107, 107, 107, 106, 401, 1413, 37, 37,
/* 310 */ 1431, 274, 506, 112, 113, 103, 1100, 1100, 953, 956,
/* 320 */ 946, 946, 110, 110, 111, 111, 111, 111, 1436, 520,
/* 330 */ 2, 1128, 1079, 1080, 1081, 430, 275, 1079, 127, 366,
/* 340 */ 933, 1079, 1080, 1081, 220, 1205, 913, 458, 455, 454,
/* 350 */ 392, 167, 515, 1035, 152, 445, 924, 453, 152, 874,
/* 360 */ 923, 289, 109, 109, 109, 109, 108, 108, 107, 107,
/* 370 */ 107, 106, 401, 13, 13, 261, 853, 252, 252, 227,
/* 380 */ 106, 401, 370, 1079, 1080, 1081, 311, 388, 1079, 296,
/* 390 */ 512, 923, 923, 925, 231, 323, 1255, 1388, 1423, 490,
/* 400 */ 274, 506, 12, 208, 274, 506, 112, 113, 103, 1100,
/* 410 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
int nIndex; /* Number of aux. indexes on table zTbl */
/* Statements created by rbuObjIterPrepareAll() */
int nCol; /* Number of columns in current object */
sqlite3_stmt *pSelect; /* Source data */
sqlite3_stmt *pInsert; /* Statement for INSERT operations */
sqlite3_stmt *pDelete; /* Statement for DELETE ops */
sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
/* Last UPDATE used (for PK b-tree updates only), or NULL. */
RbuUpdateStmt *pRbuUpdate;
};
/*
** Values for RbuObjIter.eType
**
** 0: Table does not exist (error)
** 1: Table has an implicit rowid.
** 2: Table has an explicit IPK column.
** 3: Table has an external PK index.
** 4: Table is WITHOUT ROWID.
** 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;
};
/*
** 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 */
int 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;
/* 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;
int pgsz;
u8 *aBuf;
#define sqlite3Fts5ParserCTX_PARAM
#define sqlite3Fts5ParserCTX_FETCH
#define sqlite3Fts5ParserCTX_STORE
#define fts5YYNSTATE 35
#define fts5YYNRULE 28
#define fts5YYNFTS5TOKEN 16
#define fts5YY_MAX_SHIFT 34
#define fts5YY_MIN_SHIFTREDUCE 52
#define fts5YY_MAX_SHIFTREDUCE 79
#define fts5YY_ERROR_ACTION 80
#define fts5YY_ACCEPT_ACTION 81
#define fts5YY_NO_ACTION 82
#define fts5YY_MIN_REDUCE 83
#define fts5YY_MAX_REDUCE 110
/************* End control #defines *******************************************/
#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])))
/* 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
/* 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 = 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 */
int 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_malloc(nByte);
if( p==0 ){
rc = SQLITE_NOMEM;
}else{
memset(p, 0, 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);
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 mimimum 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 = SQLITE_OK; /* 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 the BM25 score for the current row. */
for(i=0; rc==SQLITE_OK && i<pData->nPhrase; i++){
score += pData->aIDF[i] * (
( aFreq[i] * (k1 + 1.0) ) /
( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
);
}
/* If no error has occurred, return the calculated score. Otherwise,
** throw an SQL exception. */
if( rc==SQLITE_OK ){
sqlite3_result_double(pCtx, -1.0 * score);
}else{
sqlite3_result_error_code(pCtx, rc);
}
}
static int sqlite3Fts5AuxInit(fts5_api *pApi){
struct Builtin {
const char *zFunc; /* Function name (nul-terminated) */
void *pUserData; /* User-data pointer */
fts5_extension_function xFunc;/* Callback function */
void (*xDestroy)(void*); /* Destructor function */
} aBuiltin [] = {
{ "snippet", 0, fts5SnippetFunction, 0 },
{ "highlight", 0, fts5HighlightFunction, 0 },
{ "bm25", 0, fts5Bm25Function, 0 },
};
( run in 0.942 second using v1.01-cache-2.11-cpan-870870ed90f )