1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Fix further missing comments and other minor issues in the session module code.

FossilOrigin-Name: 99f0f35092b0b78b7016b21c242da263ab64b77b
This commit is contained in:
dan
2011-04-18 15:47:08 +00:00
parent 798693b2b1
commit 77fc1d5bb4
3 changed files with 126 additions and 59 deletions

View File

@ -645,20 +645,25 @@ static int sessionMergeUpdate(
return 1; return 1;
} }
static void sessionPreupdateEqual( /*
sqlite3 *db, ** This function is only called from within a pre-update-hook callback.
SessionTable *pTab, ** It determines if the current pre-update-hook change affects the same row
SessionChange *pChange, ** as the change stored in argument pChange. If so, it returns true. Otherwise
int bNew, ** if the pre-update-hook does not affect the same row as pChange, it returns
int *pbEqual ** false.
*/
static int sessionPreupdateEqual(
sqlite3 *db, /* Database handle */
SessionTable *pTab, /* Table associated with change */
SessionChange *pChange, /* Change to compare to */
int op /* Current pre-update operation */
){ ){
int i; int iCol; /* Used to iterate through columns */
u8 *a = pChange->aRecord; u8 *a = pChange->aRecord; /* Cursor used to scan change record */
*pbEqual = 0; assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
for(iCol=0; iCol<pTab->nCol; iCol++){
for(i=0; i<pTab->nCol; i++){ if( !pTab->abPK[iCol] ){
if( !pTab->abPK[i] ){
a += sessionSerialLen(a); a += sessionSerialLen(a);
}else{ }else{
sqlite3_value *pVal; /* Value returned by preupdate_new/old */ sqlite3_value *pVal; /* Value returned by preupdate_new/old */
@ -670,15 +675,15 @@ static void sessionPreupdateEqual(
** time control flows to here they have already been called once from ** time control flows to here they have already been called once from
** within sessionPreupdateHash(). The first two asserts below verify ** within sessionPreupdateHash(). The first two asserts below verify
** this (that the method has already been called). */ ** this (that the method has already been called). */
if( bNew ){ if( op==SQLITE_INSERT ){
assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew );
rc = sqlite3_preupdate_new(db, i, &pVal); rc = sqlite3_preupdate_new(db, iCol, &pVal);
}else{ }else{
assert( db->pPreUpdate->pUnpacked ); assert( db->pPreUpdate->pUnpacked );
rc = sqlite3_preupdate_old(db, i, &pVal); rc = sqlite3_preupdate_old(db, iCol, &pVal);
} }
assert( rc==SQLITE_OK ); assert( rc==SQLITE_OK );
if( sqlite3_value_type(pVal)!=eType ) return; if( sqlite3_value_type(pVal)!=eType ) return 0;
/* A SessionChange object never has a NULL value in a PK column */ /* A SessionChange object never has a NULL value in a PK column */
assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
@ -689,32 +694,31 @@ static void sessionPreupdateEqual(
i64 iVal = sessionGetI64(a); i64 iVal = sessionGetI64(a);
a += 8; a += 8;
if( eType==SQLITE_INTEGER ){ if( eType==SQLITE_INTEGER ){
if( sqlite3_value_int64(pVal)!=iVal ) return; if( sqlite3_value_int64(pVal)!=iVal ) return 0;
}else{ }else{
double rVal; double rVal;
assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
memcpy(&rVal, &iVal, 8); memcpy(&rVal, &iVal, 8);
if( sqlite3_value_double(pVal)!=rVal ) return; if( sqlite3_value_double(pVal)!=rVal ) return 0;
} }
}else{ }else{
int n; int n;
const u8 *z; const u8 *z;
a += sessionVarintGet(a, &n); a += sessionVarintGet(a, &n);
if( sqlite3_value_bytes(pVal)!=n ) return; if( sqlite3_value_bytes(pVal)!=n ) return 0;
if( eType==SQLITE_TEXT ){ if( eType==SQLITE_TEXT ){
z = sqlite3_value_text(pVal); z = sqlite3_value_text(pVal);
}else{ }else{
z = sqlite3_value_blob(pVal); z = sqlite3_value_blob(pVal);
} }
if( memcmp(a, z, n) ) return; if( memcmp(a, z, n) ) return 0;
a += n; a += n;
break; break;
} }
} }
} }
*pbEqual = 1; return 1;
return;
} }
/* /*
@ -768,7 +772,8 @@ static int sessionGrowHash(SessionTable *pTab){
** not, SQLITE_SCHEMA is returned and none of the output variables are ** not, SQLITE_SCHEMA is returned and none of the output variables are
** populated. ** populated.
** **
** Otherwise, if it is not NULL, variable *pzTab is set to point to a ** Otherwise, if they are not NULL, variable *pnCol is set to the number
** of columns in the database table and variable *pzTab is set to point to a
** nul-terminated copy of the table name. *pazCol (if not NULL) is set to ** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
** point to an array of pointers to column names. And *pabPK (again, if not ** point to an array of pointers to column names. And *pabPK (again, if not
** NULL) is set to point to an array of booleans - true if the corresponding ** NULL) is set to point to an array of booleans - true if the corresponding
@ -778,8 +783,9 @@ static int sessionGrowHash(SessionTable *pTab){
** **
** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); ** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
** **
** Then the three output variables are populated as follows: ** Then the four output variables are populated as follows:
** **
** *pnCol = 4
** *pzTab = "tbl1" ** *pzTab = "tbl1"
** *pazCol = {"w", "x", "y", "z"} ** *pazCol = {"w", "x", "y", "z"}
** *pabPK = {1, 0, 0, 1} ** *pabPK = {1, 0, 0, 1}
@ -908,10 +914,18 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
return pSession->rc; return pSession->rc;
} }
/*
** This function is only called from with a pre-update-hook reporting a
** change on table pTab (attached to session pSession). The type of change
** (UPDATE, INSERT, DELETE) is specified by the first argument.
**
** Unless one is already present or an error occurs, an entry is added
** to the changed-rows hash table associated with table pTab.
*/
static void sessionPreupdateOneChange( static void sessionPreupdateOneChange(
int op, int op, /* One of SQLITE_UPDATE, INSERT, DELETE */
sqlite3_session *pSession, sqlite3_session *pSession, /* Session object pTab is attached to */
SessionTable *pTab SessionTable *pTab /* Table that change applies to */
){ ){
sqlite3 *db = pSession->db; sqlite3 *db = pSession->db;
int iHash; int iHash;
@ -939,9 +953,7 @@ static void sessionPreupdateOneChange(
/* Search the hash table for an existing record for this row. */ /* Search the hash table for an existing record for this row. */
SessionChange *pC; SessionChange *pC;
for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
int bEqual; if( sessionPreupdateEqual(db, pTab, pC, op) ) break;
sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual);
if( bEqual ) break;
} }
if( pC==0 ){ if( pC==0 ){
@ -1109,6 +1121,10 @@ int sqlite3session_create(
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Free the list of table objects passed as the first argument. The contents
** of the changed-rows hash tables are also deleted.
*/
void sessionDeleteTable(SessionTable *pList){ void sessionDeleteTable(SessionTable *pList){
SessionTable *pNext; SessionTable *pNext;
SessionTable *pTab; SessionTable *pTab;
@ -1492,14 +1508,20 @@ static int sessionAppendUpdate(
return rc; return rc;
} }
/*
** Formulate and prepare a SELECT statement to retrieve a row from table
** zTab in database zDb based on its primary key. i.e.
**
** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ...
*/
static int sessionSelectStmt( static int sessionSelectStmt(
sqlite3 *db, /* Database handle */ sqlite3 *db, /* Database handle */
const char *zDb, /* Database name */ const char *zDb, /* Database name */
const char *zTab, /* Table name */ const char *zTab, /* Table name */
int nCol, int nCol, /* Number of columns in table */
const char **azCol, const char **azCol, /* Names of table columns */
u8 *abPK, u8 *abPK, /* PRIMARY KEY array */
sqlite3_stmt **ppStmt sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){ ){
int rc = SQLITE_OK; int rc = SQLITE_OK;
int i; int i;
@ -1527,11 +1549,19 @@ static int sessionSelectStmt(
return rc; return rc;
} }
/*
** Bind the PRIMARY KEY values from the change passed in argument pChange
** to the SELECT statement passed as the first argument. The SELECT statement
** is as prepared by function sessionSelectStmt().
**
** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
** error code (e.g. SQLITE_NOMEM) otherwise.
*/
static int sessionSelectBind( static int sessionSelectBind(
sqlite3_stmt *pSelect, sqlite3_stmt *pSelect, /* SELECT from sessionSelectStmt() */
int nCol, int nCol, /* Number of columns in table */
u8 *abPK, u8 *abPK, /* PRIMARY KEY array */
SessionChange *pChange SessionChange *pChange /* Change structure */
){ ){
int i; int i;
int rc = SQLITE_OK; int rc = SQLITE_OK;
@ -1592,6 +1622,12 @@ static int sessionSelectBind(
return rc; return rc;
} }
/*
** This function is a no-op if *pRc is set to other than SQLITE_OK when it
** is called. Otherwise, append a serialized table header (part of the binary
** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
** SQLite error code before returning.
*/
static void sessionAppendTableHdr( static void sessionAppendTableHdr(
SessionBuffer *pBuf, SessionBuffer *pBuf,
SessionTable *pTab, SessionTable *pTab,
@ -1832,10 +1868,26 @@ static int sessionReadRecord(
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Advance the changeset iterator to the next change.
**
** If both paRec and pnRec are NULL, then this function works like the public
** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
** sqlite3changeset_new() and old() APIs may be used to query for values.
**
** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
** record is written to *paRec before returning and the number of bytes in
** the record to *pnRec.
**
** Either way, this function returns SQLITE_ROW if the iterator is
** successfully advanced to the next change in the changeset, an SQLite
** error code if an error occurs, or SQLITE_DONE if there are no further
** changes in the changeset.
*/
static int sessionChangesetNext( static int sessionChangesetNext(
sqlite3_changeset_iter *p, sqlite3_changeset_iter *p, /* Changeset iterator */
u8 **paRec, u8 **paRec, /* If non-NULL, store record pointer here */
int *pnRec int *pnRec /* If non-NULL, store size of record here */
){ ){
u8 *aChange; u8 *aChange;
int i; int i;
@ -1918,7 +1970,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){
/* /*
** The following function extracts information on the current change ** The following function extracts information on the current change
** from a changeset iterator. They may only be called after changeset_next() ** from a changeset iterator. It may only be called after changeset_next()
** has returned SQLITE_ROW. ** has returned SQLITE_ROW.
*/ */
int sqlite3changeset_op( int sqlite3changeset_op(
@ -1935,6 +1987,12 @@ int sqlite3changeset_op(
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Return information regarding the PRIMARY KEY and number of columns in
** the database table affected by the change that pIter currently points
** to. This function may only be called after changeset_next() returns
** SQLITE_ROW.
*/
int sqlite3changeset_pk( int sqlite3changeset_pk(
sqlite3_changeset_iter *pIter, /* Iterator object */ sqlite3_changeset_iter *pIter, /* Iterator object */
unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
@ -2828,14 +2886,19 @@ int sqlite3changeset_apply(
return rc; return rc;
} }
/*
** This function is called to merge two changes to the same row together as
** part of an sqlite3changeset_concat() operation. A new change object is
** allocated and a pointer to it stored in *ppNew.
*/
static int sessionChangeMerge( static int sessionChangeMerge(
SessionTable *pTab, SessionTable *pTab, /* Table structure */
SessionChange *pExist, SessionChange *pExist, /* Existing change */
int op2, int op2, /* Second change operation */
int bIndirect, int bIndirect, /* True if second change is indirect */
u8 *aRec, u8 *aRec, /* Second change record */
int nRec, int nRec, /* Number of bytes in aRec */
SessionChange **ppNew SessionChange **ppNew /* OUT: Merged change */
){ ){
SessionChange *pNew = 0; SessionChange *pNew = 0;
@ -2929,10 +2992,14 @@ static int sessionChangeMerge(
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Add all changes in the changeset passed via the first two arguments to
** hash tables.
*/
int sessionConcatChangeset( int sessionConcatChangeset(
int nChangeset, int nChangeset, /* Number of bytes in pChangeset */
void *pChangeset, void *pChangeset, /* Changeset buffer */
SessionTable **ppTabList SessionTable **ppTabList /* IN/OUT: List of table objects */
){ ){
u8 *aRec; u8 *aRec;
int nRec; int nRec;

View File

@ -1,5 +1,5 @@
C Fix\ssome\smissing\scomments\sand\sother\sissues\swith\ssession\smodule\scode. C Fix\sfurther\smissing\scomments\sand\sother\sminor\sissues\sin\sthe\ssession\smodule\scode.
D 2011-04-18T12:05:03.122 D 2011-04-18T15:47:08.694
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -106,7 +106,7 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478
F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5
F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180
F ext/session/sqlite3session.c 04a5065d5b64f43f120113df170e96bb8db8e229 F ext/session/sqlite3session.c 26de50c3e34d89ae62e97024ad07e772e1c52db2
F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf
F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388 F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 69a01c708bf044eacf21a8951fe9e7d9fb4332c5 P 20d7c280235201e519f296372f269e7cecda24da
R b92955ca865aafd93c0b967b180f7cc1 R 22fa2c52781f892ef560f2c8f63b1707
U dan U dan
Z 3095f8afd486ad0b7645eeb6cb4cbdcc Z e6f0d0d675f579cb5b46b0fe2c73f457

View File

@ -1 +1 @@
20d7c280235201e519f296372f269e7cecda24da 99f0f35092b0b78b7016b21c242da263ab64b77b