sqlite3intck.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. /*
  2. ** 2024-02-08
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. */
  13. #include "sqlite3intck.h"
  14. #include <string.h>
  15. #include <assert.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. /*
  19. ** nKeyVal:
  20. ** The number of values that make up the 'key' for the current pCheck
  21. ** statement.
  22. **
  23. ** rc:
  24. ** Error code returned by most recent sqlite3_intck_step() or
  25. ** sqlite3_intck_unlock() call. This is set to SQLITE_DONE when
  26. ** the integrity-check operation is finished.
  27. **
  28. ** zErr:
  29. ** If the object has entered the error state, this is the error message.
  30. ** Is freed using sqlite3_free() when the object is deleted.
  31. **
  32. ** zTestSql:
  33. ** The value returned by the most recent call to sqlite3_intck_testsql().
  34. ** Each call to testsql() frees the previous zTestSql value (using
  35. ** sqlite3_free()) and replaces it with the new value it will return.
  36. */
  37. struct sqlite3_intck {
  38. sqlite3 *db;
  39. const char *zDb; /* Copy of zDb parameter to _open() */
  40. char *zObj; /* Current object. Or NULL. */
  41. sqlite3_stmt *pCheck; /* Current check statement */
  42. char *zKey;
  43. int nKeyVal;
  44. char *zMessage;
  45. int bCorruptSchema;
  46. int rc; /* Error code */
  47. char *zErr; /* Error message */
  48. char *zTestSql; /* Returned by sqlite3_intck_test_sql() */
  49. };
  50. /*
  51. ** Some error has occurred while using database p->db. Save the error message
  52. ** and error code currently held by the database handle in p->rc and p->zErr.
  53. */
  54. static void intckSaveErrmsg(sqlite3_intck *p){
  55. p->rc = sqlite3_errcode(p->db);
  56. sqlite3_free(p->zErr);
  57. p->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
  58. }
  59. /*
  60. ** If the handle passed as the first argument is already in the error state,
  61. ** then this function is a no-op (returns NULL immediately). Otherwise, if an
  62. ** error occurs within this function, it leaves an error in said handle.
  63. **
  64. ** Otherwise, this function attempts to prepare SQL statement zSql and
  65. ** return the resulting statement handle to the user.
  66. */
  67. static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zSql){
  68. sqlite3_stmt *pRet = 0;
  69. if( p->rc==SQLITE_OK ){
  70. p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0);
  71. if( p->rc!=SQLITE_OK ){
  72. intckSaveErrmsg(p);
  73. assert( pRet==0 );
  74. }
  75. }
  76. return pRet;
  77. }
  78. /*
  79. ** If the handle passed as the first argument is already in the error state,
  80. ** then this function is a no-op (returns NULL immediately). Otherwise, if an
  81. ** error occurs within this function, it leaves an error in said handle.
  82. **
  83. ** Otherwise, this function treats argument zFmt as a printf() style format
  84. ** string. It formats it according to the trailing arguments and then
  85. ** attempts to prepare the results and return the resulting prepared
  86. ** statement.
  87. */
  88. static sqlite3_stmt *intckPrepareFmt(sqlite3_intck *p, const char *zFmt, ...){
  89. sqlite3_stmt *pRet = 0;
  90. va_list ap;
  91. char *zSql = 0;
  92. va_start(ap, zFmt);
  93. zSql = sqlite3_vmprintf(zFmt, ap);
  94. if( p->rc==SQLITE_OK && zSql==0 ){
  95. p->rc = SQLITE_NOMEM;
  96. }
  97. pRet = intckPrepare(p, zSql);
  98. sqlite3_free(zSql);
  99. va_end(ap);
  100. return pRet;
  101. }
  102. /*
  103. ** Finalize SQL statement pStmt. If an error occurs and the handle passed
  104. ** as the first argument does not already contain an error, store the
  105. ** error in the handle.
  106. */
  107. static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
  108. int rc = sqlite3_finalize(pStmt);
  109. if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
  110. intckSaveErrmsg(p);
  111. }
  112. }
  113. /*
  114. ** If there is already an error in handle p, return it. Otherwise, call
  115. ** sqlite3_step() on the statement handle and return that value.
  116. */
  117. static int intckStep(sqlite3_intck *p, sqlite3_stmt *pStmt){
  118. if( p->rc ) return p->rc;
  119. return sqlite3_step(pStmt);
  120. }
  121. /*
  122. ** Execute SQL statement zSql. There is no way to obtain any results
  123. ** returned by the statement. This function uses the sqlite3_intck error
  124. ** code convention.
  125. */
  126. static void intckExec(sqlite3_intck *p, const char *zSql){
  127. sqlite3_stmt *pStmt = 0;
  128. pStmt = intckPrepare(p, zSql);
  129. intckStep(p, pStmt);
  130. intckFinalize(p, pStmt);
  131. }
  132. /*
  133. ** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error
  134. ** code convention.
  135. */
  136. static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){
  137. va_list ap;
  138. char *zRet = 0;
  139. va_start(ap, zFmt);
  140. zRet = sqlite3_vmprintf(zFmt, ap);
  141. if( p->rc==SQLITE_OK ){
  142. if( zRet==0 ){
  143. p->rc = SQLITE_NOMEM;
  144. }
  145. }else{
  146. sqlite3_free(zRet);
  147. zRet = 0;
  148. }
  149. return zRet;
  150. }
  151. /*
  152. ** This is used by sqlite3_intck_unlock() to save the vector key value
  153. ** required to restart the current pCheck query as a nul-terminated string
  154. ** in p->zKey.
  155. */
  156. static void intckSaveKey(sqlite3_intck *p){
  157. int ii;
  158. char *zSql = 0;
  159. sqlite3_stmt *pStmt = 0;
  160. sqlite3_stmt *pXinfo = 0;
  161. const char *zDir = 0;
  162. assert( p->pCheck );
  163. assert( p->zKey==0 );
  164. pXinfo = intckPrepareFmt(p,
  165. "SELECT group_concat(desc, '') FROM %Q.sqlite_schema s, "
  166. "pragma_index_xinfo(%Q, %Q) "
  167. "WHERE s.type='index' AND s.name=%Q",
  168. p->zDb, p->zObj, p->zDb, p->zObj
  169. );
  170. if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXinfo) ){
  171. zDir = (const char*)sqlite3_column_text(pXinfo, 0);
  172. }
  173. if( zDir==0 ){
  174. /* Object is a table, not an index. This is the easy case,as there are
  175. ** no DESC columns or NULL values in a primary key. */
  176. const char *zSep = "SELECT '(' || ";
  177. for(ii=0; ii<p->nKeyVal; ii++){
  178. zSql = intckMprintf(p, "%z%squote(?)", zSql, zSep);
  179. zSep = " || ', ' || ";
  180. }
  181. zSql = intckMprintf(p, "%z || ')'", zSql);
  182. }else{
  183. /* Object is an index. */
  184. assert( p->nKeyVal>1 );
  185. for(ii=p->nKeyVal; ii>0; ii--){
  186. int bLastIsDesc = zDir[ii-1]=='1';
  187. int bLastIsNull = sqlite3_column_type(p->pCheck, ii)==SQLITE_NULL;
  188. const char *zLast = sqlite3_column_name(p->pCheck, ii);
  189. char *zLhs = 0;
  190. char *zRhs = 0;
  191. char *zWhere = 0;
  192. if( bLastIsNull ){
  193. if( bLastIsDesc ) continue;
  194. zWhere = intckMprintf(p, "'%s IS NOT NULL'", zLast);
  195. }else{
  196. const char *zOp = bLastIsDesc ? "<" : ">";
  197. zWhere = intckMprintf(p, "'%s %s ' || quote(?%d)", zLast, zOp, ii);
  198. }
  199. if( ii>1 ){
  200. const char *zLhsSep = "";
  201. const char *zRhsSep = "";
  202. int jj;
  203. for(jj=0; jj<ii-1; jj++){
  204. const char *zAlias = (const char*)sqlite3_column_name(p->pCheck,jj+1);
  205. zLhs = intckMprintf(p, "%z%s%s", zLhs, zLhsSep, zAlias);
  206. zRhs = intckMprintf(p, "%z%squote(?%d)", zRhs, zRhsSep, jj+1);
  207. zLhsSep = ",";
  208. zRhsSep = " || ',' || ";
  209. }
  210. zWhere = intckMprintf(p,
  211. "'(%z) IS (' || %z || ') AND ' || %z",
  212. zLhs, zRhs, zWhere);
  213. }
  214. zWhere = intckMprintf(p, "'WHERE ' || %z", zWhere);
  215. zSql = intckMprintf(p, "%z%s(quote( %z ) )",
  216. zSql,
  217. (zSql==0 ? "VALUES" : ",\n "),
  218. zWhere
  219. );
  220. }
  221. zSql = intckMprintf(p,
  222. "WITH wc(q) AS (\n%z\n)"
  223. "SELECT 'VALUES' || group_concat('(' || q || ')', ',\n ') FROM wc"
  224. , zSql
  225. );
  226. }
  227. pStmt = intckPrepare(p, zSql);
  228. if( p->rc==SQLITE_OK ){
  229. for(ii=0; ii<p->nKeyVal; ii++){
  230. sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1));
  231. }
  232. if( SQLITE_ROW==sqlite3_step(pStmt) ){
  233. p->zKey = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0));
  234. }
  235. intckFinalize(p, pStmt);
  236. }
  237. sqlite3_free(zSql);
  238. intckFinalize(p, pXinfo);
  239. }
  240. /*
  241. ** Find the next database object (table or index) to check. If successful,
  242. ** set sqlite3_intck.zObj to point to a nul-terminated buffer containing
  243. ** the object's name before returning.
  244. */
  245. static void intckFindObject(sqlite3_intck *p){
  246. sqlite3_stmt *pStmt = 0;
  247. char *zPrev = p->zObj;
  248. p->zObj = 0;
  249. assert( p->rc==SQLITE_OK );
  250. assert( p->pCheck==0 );
  251. pStmt = intckPrepareFmt(p,
  252. "WITH tables(table_name) AS ("
  253. " SELECT name"
  254. " FROM %Q.sqlite_schema WHERE (type='table' OR type='index') AND rootpage"
  255. " UNION ALL "
  256. " SELECT 'sqlite_schema'"
  257. ")"
  258. "SELECT table_name FROM tables "
  259. "WHERE ?1 IS NULL OR table_name%s?1 "
  260. "ORDER BY 1"
  261. , p->zDb, (p->zKey ? ">=" : ">")
  262. );
  263. if( p->rc==SQLITE_OK ){
  264. sqlite3_bind_text(pStmt, 1, zPrev, -1, SQLITE_TRANSIENT);
  265. if( sqlite3_step(pStmt)==SQLITE_ROW ){
  266. p->zObj = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0));
  267. }
  268. }
  269. intckFinalize(p, pStmt);
  270. /* If this is a new object, ensure the previous key value is cleared. */
  271. if( sqlite3_stricmp(p->zObj, zPrev) ){
  272. sqlite3_free(p->zKey);
  273. p->zKey = 0;
  274. }
  275. sqlite3_free(zPrev);
  276. }
  277. /*
  278. ** Return the size in bytes of the first token in nul-terminated buffer z.
  279. ** For the purposes of this call, a token is either:
  280. **
  281. ** * a quoted SQL string,
  282. * * a contiguous series of ascii alphabet characters, or
  283. * * any other single byte.
  284. */
  285. static int intckGetToken(const char *z){
  286. char c = z[0];
  287. int iRet = 1;
  288. if( c=='\'' || c=='"' || c=='`' ){
  289. while( 1 ){
  290. if( z[iRet]==c ){
  291. iRet++;
  292. if( z[iRet]!=c ) break;
  293. }
  294. iRet++;
  295. }
  296. }
  297. else if( c=='[' ){
  298. while( z[iRet++]!=']' && z[iRet] );
  299. }
  300. else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){
  301. while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){
  302. iRet++;
  303. }
  304. }
  305. return iRet;
  306. }
  307. /*
  308. ** Return true if argument c is an ascii whitespace character.
  309. */
  310. static int intckIsSpace(char c){
  311. return (c==' ' || c=='\t' || c=='\n' || c=='\r');
  312. }
  313. /*
  314. ** Argument z points to the text of a CREATE INDEX statement. This function
  315. ** identifies the part of the text that contains either the index WHERE
  316. ** clause (if iCol<0) or the iCol'th column of the index.
  317. **
  318. ** If (iCol<0), the identified fragment does not include the "WHERE" keyword,
  319. ** only the expression that follows it. If (iCol>=0) then the identified
  320. ** fragment does not include any trailing sort-order keywords - "ASC" or
  321. ** "DESC".
  322. **
  323. ** If the CREATE INDEX statement does not contain the requested field or
  324. ** clause, NULL is returned and (*pnByte) is set to 0. Otherwise, a pointer to
  325. ** the identified fragment is returned and output parameter (*pnByte) set
  326. ** to its size in bytes.
  327. */
  328. static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){
  329. int iOff = 0;
  330. int iThisCol = 0;
  331. int iStart = 0;
  332. int nOpen = 0;
  333. const char *zRet = 0;
  334. int nRet = 0;
  335. int iEndOfCol = 0;
  336. /* Skip forward until the first "(" token */
  337. while( z[iOff]!='(' ){
  338. iOff += intckGetToken(&z[iOff]);
  339. if( z[iOff]=='\0' ) return 0;
  340. }
  341. assert( z[iOff]=='(' );
  342. nOpen = 1;
  343. iOff++;
  344. iStart = iOff;
  345. while( z[iOff] ){
  346. const char *zToken = &z[iOff];
  347. int nToken = 0;
  348. /* Check if this is the end of the current column - either a "," or ")"
  349. ** when nOpen==1. */
  350. if( nOpen==1 ){
  351. if( z[iOff]==',' || z[iOff]==')' ){
  352. if( iCol==iThisCol ){
  353. int iEnd = iEndOfCol ? iEndOfCol : iOff;
  354. nRet = (iEnd - iStart);
  355. zRet = &z[iStart];
  356. break;
  357. }
  358. iStart = iOff+1;
  359. while( intckIsSpace(z[iStart]) ) iStart++;
  360. iThisCol++;
  361. }
  362. if( z[iOff]==')' ) break;
  363. }
  364. if( z[iOff]=='(' ) nOpen++;
  365. if( z[iOff]==')' ) nOpen--;
  366. nToken = intckGetToken(zToken);
  367. if( (nToken==3 && 0==sqlite3_strnicmp(zToken, "ASC", nToken))
  368. || (nToken==4 && 0==sqlite3_strnicmp(zToken, "DESC", nToken))
  369. ){
  370. iEndOfCol = iOff;
  371. }else if( 0==intckIsSpace(zToken[0]) ){
  372. iEndOfCol = 0;
  373. }
  374. iOff += nToken;
  375. }
  376. /* iStart is now the byte offset of 1 byte passed the final ')' in the
  377. ** CREATE INDEX statement. Try to find a WHERE clause to return. */
  378. while( zRet==0 && z[iOff] ){
  379. int n = intckGetToken(&z[iOff]);
  380. if( n==5 && 0==sqlite3_strnicmp(&z[iOff], "where", 5) ){
  381. zRet = &z[iOff+5];
  382. nRet = (int)strlen(zRet);
  383. }
  384. iOff += n;
  385. }
  386. /* Trim any whitespace from the start and end of the returned string. */
  387. if( zRet ){
  388. while( intckIsSpace(zRet[0]) ){
  389. nRet--;
  390. zRet++;
  391. }
  392. while( nRet>0 && intckIsSpace(zRet[nRet-1]) ) nRet--;
  393. }
  394. *pnByte = nRet;
  395. return zRet;
  396. }
  397. /*
  398. ** User-defined SQL function wrapper for intckParseCreateIndex():
  399. **
  400. ** SELECT parse_create_index(<sql>, <icol>);
  401. */
  402. static void intckParseCreateIndexFunc(
  403. sqlite3_context *pCtx,
  404. int nVal,
  405. sqlite3_value **apVal
  406. ){
  407. const char *zSql = (const char*)sqlite3_value_text(apVal[0]);
  408. int idx = sqlite3_value_int(apVal[1]);
  409. const char *zRes = 0;
  410. int nRes = 0;
  411. assert( nVal==2 );
  412. if( zSql ){
  413. zRes = intckParseCreateIndex(zSql, idx, &nRes);
  414. }
  415. sqlite3_result_text(pCtx, zRes, nRes, SQLITE_TRANSIENT);
  416. }
  417. /*
  418. ** Return true if sqlite3_intck.db has automatic indexes enabled, false
  419. ** otherwise.
  420. */
  421. static int intckGetAutoIndex(sqlite3_intck *p){
  422. int bRet = 0;
  423. sqlite3_stmt *pStmt = 0;
  424. pStmt = intckPrepare(p, "PRAGMA automatic_index");
  425. if( SQLITE_ROW==intckStep(p, pStmt) ){
  426. bRet = sqlite3_column_int(pStmt, 0);
  427. }
  428. intckFinalize(p, pStmt);
  429. return bRet;
  430. }
  431. /*
  432. ** Return true if zObj is an index, or false otherwise.
  433. */
  434. static int intckIsIndex(sqlite3_intck *p, const char *zObj){
  435. int bRet = 0;
  436. sqlite3_stmt *pStmt = 0;
  437. pStmt = intckPrepareFmt(p,
  438. "SELECT 1 FROM %Q.sqlite_schema WHERE name=%Q AND type='index'",
  439. p->zDb, zObj
  440. );
  441. if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
  442. bRet = 1;
  443. }
  444. intckFinalize(p, pStmt);
  445. return bRet;
  446. }
  447. /*
  448. ** Return a pointer to a nul-terminated buffer containing the SQL statement
  449. ** used to check database object zObj (a table or index) for corruption.
  450. ** If parameter zPrev is not NULL, then it must be a string containing the
  451. ** vector key required to restart the check where it left off last time.
  452. ** If pnKeyVal is not NULL, then (*pnKeyVal) is set to the number of
  453. ** columns in the vector key value for the specified object.
  454. **
  455. ** This function uses the sqlite3_intck error code convention.
  456. */
  457. static char *intckCheckObjectSql(
  458. sqlite3_intck *p, /* Integrity check object */
  459. const char *zObj, /* Object (table or index) to scan */
  460. const char *zPrev, /* Restart key vector, if any */
  461. int *pnKeyVal /* OUT: Number of key-values for this scan */
  462. ){
  463. char *zRet = 0;
  464. sqlite3_stmt *pStmt = 0;
  465. int bAutoIndex = 0;
  466. int bIsIndex = 0;
  467. const char *zCommon =
  468. /* Relation without_rowid also contains just one row. Column "b" is
  469. ** set to true if the table being examined is a WITHOUT ROWID table,
  470. ** or false otherwise. */
  471. ", without_rowid(b) AS ("
  472. " SELECT EXISTS ("
  473. " SELECT 1 FROM tabname, pragma_index_list(tab, db) AS l"
  474. " WHERE origin='pk' "
  475. " AND NOT EXISTS (SELECT 1 FROM sqlite_schema WHERE name=l.name)"
  476. " )"
  477. ")"
  478. ""
  479. /* Table idx_cols contains 1 row for each column in each index on the
  480. ** table being checked. Columns are:
  481. **
  482. ** idx_name: Name of the index.
  483. ** idx_ispk: True if this index is the PK of a WITHOUT ROWID table.
  484. ** col_name: Name of indexed column, or NULL for index on expression.
  485. ** col_expr: Indexed expression, including COLLATE clause.
  486. ** col_alias: Alias used for column in 'intck_wrapper' table.
  487. */
  488. ", idx_cols(idx_name, idx_ispk, col_name, col_expr, col_alias) AS ("
  489. " SELECT l.name, (l.origin=='pk' AND w.b), i.name, COALESCE(("
  490. " SELECT parse_create_index(sql, i.seqno) FROM "
  491. " sqlite_schema WHERE name = l.name"
  492. " ), format('\"%w\"', i.name) || ' COLLATE ' || quote(i.coll)),"
  493. " 'c' || row_number() OVER ()"
  494. " FROM "
  495. " tabname t,"
  496. " without_rowid w,"
  497. " pragma_index_list(t.tab, t.db) l,"
  498. " pragma_index_xinfo(l.name) i"
  499. " WHERE i.key"
  500. " UNION ALL"
  501. " SELECT '', 1, '_rowid_', '_rowid_', 'r1' FROM without_rowid WHERE b=0"
  502. ")"
  503. ""
  504. ""
  505. /*
  506. ** For a PK declared as "PRIMARY KEY(a, b) ... WITHOUT ROWID", where
  507. ** the intck_wrapper aliases of "a" and "b" are "c1" and "c2":
  508. **
  509. ** o_pk: "o.c1, o.c2"
  510. ** i_pk: "i.'a', i.'b'"
  511. ** ...
  512. ** n_pk: 2
  513. */
  514. ", tabpk(db, tab, idx, o_pk, i_pk, q_pk, eq_pk, ps_pk, pk_pk, n_pk) AS ("
  515. " WITH pkfields(f, a) AS ("
  516. " SELECT i.col_name, i.col_alias FROM idx_cols i WHERE i.idx_ispk"
  517. " )"
  518. " SELECT t.db, t.tab, t.idx, "
  519. " group_concat(a, ', '), "
  520. " group_concat('i.'||quote(f), ', '), "
  521. " group_concat('quote(o.'||a||')', ' || '','' || '), "
  522. " format('(%s)==(%s)',"
  523. " group_concat('o.'||a, ', '), "
  524. " group_concat(format('\"%w\"', f), ', ')"
  525. " ),"
  526. " group_concat('%s', ','),"
  527. " group_concat('quote('||a||')', ', '), "
  528. " count(*)"
  529. " FROM tabname t, pkfields"
  530. ")"
  531. ""
  532. ", idx(name, match_expr, partial, partial_alias, idx_ps, idx_idx) AS ("
  533. " SELECT idx_name,"
  534. " format('(%s,%s) IS (%s,%s)', "
  535. " group_concat(i.col_expr, ', '), i_pk,"
  536. " group_concat('o.'||i.col_alias, ', '), o_pk"
  537. " ), "
  538. " parse_create_index("
  539. " (SELECT sql FROM sqlite_schema WHERE name=idx_name), -1"
  540. " ),"
  541. " 'cond' || row_number() OVER ()"
  542. " , group_concat('%s', ',')"
  543. " , group_concat('quote('||i.col_alias||')', ', ')"
  544. " FROM tabpk t, "
  545. " without_rowid w,"
  546. " idx_cols i"
  547. " WHERE i.idx_ispk==0 "
  548. " GROUP BY idx_name"
  549. ")"
  550. ""
  551. ", wrapper_with(s) AS ("
  552. " SELECT 'intck_wrapper AS (\n SELECT\n ' || ("
  553. " WITH f(a, b) AS ("
  554. " SELECT col_expr, col_alias FROM idx_cols"
  555. " UNION ALL "
  556. " SELECT partial, partial_alias FROM idx WHERE partial IS NOT NULL"
  557. " )"
  558. " SELECT group_concat(format('%s AS %s', a, b), ',\n ') FROM f"
  559. " )"
  560. " || format('\n FROM %Q.%Q ', t.db, t.tab)"
  561. /* If the object being checked is a table, append "NOT INDEXED".
  562. ** Otherwise, append "INDEXED BY <index>", and then, if the index
  563. ** is a partial index " WHERE <condition>". */
  564. " || CASE WHEN t.idx IS NULL THEN "
  565. " 'NOT INDEXED'"
  566. " ELSE"
  567. " format('INDEXED BY %Q%s', t.idx, ' WHERE '||i.partial)"
  568. " END"
  569. " || '\n)'"
  570. " FROM tabname t LEFT JOIN idx i ON (i.name=t.idx)"
  571. ")"
  572. ""
  573. ;
  574. bAutoIndex = intckGetAutoIndex(p);
  575. if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 0");
  576. bIsIndex = intckIsIndex(p, zObj);
  577. if( bIsIndex ){
  578. pStmt = intckPrepareFmt(p,
  579. /* Table idxname contains a single row. The first column, "db", contains
  580. ** the name of the db containing the table (e.g. "main") and the second,
  581. ** "tab", the name of the table itself. */
  582. "WITH tabname(db, tab, idx) AS ("
  583. " SELECT %Q, (SELECT tbl_name FROM %Q.sqlite_schema WHERE name=%Q), %Q "
  584. ")"
  585. ""
  586. ", whereclause(w_c) AS (%s)"
  587. ""
  588. "%s" /* zCommon */
  589. ""
  590. ", case_statement(c) AS ("
  591. " SELECT "
  592. " 'CASE WHEN (' || group_concat(col_alias, ', ') || ', 1) IS (\n' "
  593. " || ' SELECT ' || group_concat(col_expr, ', ') || ', 1 FROM '"
  594. " || format('%%Q.%%Q NOT INDEXED WHERE %%s\n', t.db, t.tab, p.eq_pk)"
  595. " || ' )\n THEN NULL\n '"
  596. " || 'ELSE format(''surplus entry ('"
  597. " || group_concat('%%s', ',') || ',' || p.ps_pk"
  598. " || ') in index ' || t.idx || ''', ' "
  599. " || group_concat('quote('||i.col_alias||')', ', ') || ', ' || p.pk_pk"
  600. " || ')'"
  601. " || '\n END AS error_message'"
  602. " FROM tabname t, tabpk p, idx_cols i WHERE i.idx_name=t.idx"
  603. ")"
  604. ""
  605. ", thiskey(k, n) AS ("
  606. " SELECT group_concat(i.col_alias, ', ') || ', ' || p.o_pk, "
  607. " count(*) + p.n_pk "
  608. " FROM tabpk p, idx_cols i WHERE i.idx_name=p.idx"
  609. ")"
  610. ""
  611. ", main_select(m, n) AS ("
  612. " SELECT format("
  613. " 'WITH %%s\n' ||"
  614. " ', idx_checker AS (\n' ||"
  615. " ' SELECT %%s,\n' ||"
  616. " ' %%s\n' || "
  617. " ' FROM intck_wrapper AS o\n' ||"
  618. " ')\n',"
  619. " ww.s, c, t.k"
  620. " ), t.n"
  621. " FROM case_statement, wrapper_with ww, thiskey t"
  622. ")"
  623. "SELECT m || "
  624. " group_concat('SELECT * FROM idx_checker ' || w_c, ' UNION ALL '), n"
  625. " FROM "
  626. "main_select, whereclause "
  627. , p->zDb, p->zDb, zObj, zObj
  628. , zPrev ? zPrev : "VALUES('')", zCommon
  629. );
  630. }else{
  631. pStmt = intckPrepareFmt(p,
  632. /* Table tabname contains a single row. The first column, "db", contains
  633. ** the name of the db containing the table (e.g. "main") and the second,
  634. ** "tab", the name of the table itself. */
  635. "WITH tabname(db, tab, idx, prev) AS (SELECT %Q, %Q, NULL, %Q)"
  636. ""
  637. "%s" /* zCommon */
  638. /* expr(e) contains one row for each index on table zObj. Value e
  639. ** is set to an expression that evaluates to NULL if the required
  640. ** entry is present in the index, or an error message otherwise. */
  641. ", expr(e, p) AS ("
  642. " SELECT format('CASE WHEN EXISTS \n"
  643. " (SELECT 1 FROM %%Q.%%Q AS i INDEXED BY %%Q WHERE %%s%%s)\n"
  644. " THEN NULL\n"
  645. " ELSE format(''entry (%%s,%%s) missing from index %%s'', %%s, %%s)\n"
  646. " END\n'"
  647. " , t.db, t.tab, i.name, i.match_expr, ' AND (' || partial || ')',"
  648. " i.idx_ps, t.ps_pk, i.name, i.idx_idx, t.pk_pk),"
  649. " CASE WHEN partial IS NULL THEN NULL ELSE i.partial_alias END"
  650. " FROM tabpk t, idx i"
  651. ")"
  652. ", numbered(ii, cond, e) AS ("
  653. " SELECT 0, 'n.ii=0', 'NULL'"
  654. " UNION ALL "
  655. " SELECT row_number() OVER (),"
  656. " '(n.ii='||row_number() OVER ()||COALESCE(' AND '||p||')', ')'), e"
  657. " FROM expr"
  658. ")"
  659. ", counter_with(w) AS ("
  660. " SELECT 'WITH intck_counter(ii) AS (\n ' || "
  661. " group_concat('SELECT '||ii, ' UNION ALL\n ') "
  662. " || '\n)' FROM numbered"
  663. ")"
  664. ""
  665. ", case_statement(c) AS ("
  666. " SELECT 'CASE ' || "
  667. " group_concat(format('\n WHEN %%s THEN (%%s)', cond, e), '') ||"
  668. " '\nEND AS error_message'"
  669. " FROM numbered"
  670. ")"
  671. ""
  672. /* This table contains a single row consisting of a single value -
  673. ** the text of an SQL expression that may be used by the main SQL
  674. ** statement to output an SQL literal that can be used to resume
  675. ** the scan if it is suspended. e.g. for a rowid table, an expression
  676. ** like:
  677. **
  678. ** format('(%d,%d)', _rowid_, n.ii)
  679. */
  680. ", thiskey(k, n) AS ("
  681. " SELECT o_pk || ', ii', n_pk+1 FROM tabpk"
  682. ")"
  683. ""
  684. ", whereclause(w_c) AS ("
  685. " SELECT CASE WHEN prev!='' THEN "
  686. " '\nWHERE (' || o_pk ||', n.ii) > ' || prev"
  687. " ELSE ''"
  688. " END"
  689. " FROM tabpk, tabname"
  690. ")"
  691. ""
  692. ", main_select(m, n) AS ("
  693. " SELECT format("
  694. " '%%s, %%s\nSELECT %%s,\n%%s\nFROM intck_wrapper AS o"
  695. ", intck_counter AS n%%s\nORDER BY %%s', "
  696. " w, ww.s, c, thiskey.k, whereclause.w_c, t.o_pk"
  697. " ), thiskey.n"
  698. " FROM case_statement, tabpk t, counter_with, "
  699. " wrapper_with ww, thiskey, whereclause"
  700. ")"
  701. "SELECT m, n FROM main_select",
  702. p->zDb, zObj, zPrev, zCommon
  703. );
  704. }
  705. while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
  706. zRet = intckMprintf(p, "%s", (const char*)sqlite3_column_text(pStmt, 0));
  707. if( pnKeyVal ){
  708. *pnKeyVal = sqlite3_column_int(pStmt, 1);
  709. }
  710. }
  711. intckFinalize(p, pStmt);
  712. if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1");
  713. return zRet;
  714. }
  715. /*
  716. ** Open a new integrity-check object.
  717. */
  718. int sqlite3_intck_open(
  719. sqlite3 *db, /* Database handle to operate on */
  720. const char *zDbArg, /* "main", "temp" etc. */
  721. sqlite3_intck **ppOut /* OUT: New integrity-check handle */
  722. ){
  723. sqlite3_intck *pNew = 0;
  724. int rc = SQLITE_OK;
  725. const char *zDb = zDbArg ? zDbArg : "main";
  726. int nDb = (int)strlen(zDb);
  727. pNew = (sqlite3_intck*)sqlite3_malloc(sizeof(*pNew) + nDb + 1);
  728. if( pNew==0 ){
  729. rc = SQLITE_NOMEM;
  730. }else{
  731. memset(pNew, 0, sizeof(*pNew));
  732. pNew->db = db;
  733. pNew->zDb = (const char*)&pNew[1];
  734. memcpy(&pNew[1], zDb, nDb+1);
  735. rc = sqlite3_create_function(db, "parse_create_index",
  736. 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0
  737. );
  738. if( rc!=SQLITE_OK ){
  739. sqlite3_intck_close(pNew);
  740. pNew = 0;
  741. }
  742. }
  743. *ppOut = pNew;
  744. return rc;
  745. }
  746. /*
  747. ** Free the integrity-check object.
  748. */
  749. void sqlite3_intck_close(sqlite3_intck *p){
  750. if( p ){
  751. sqlite3_finalize(p->pCheck);
  752. sqlite3_create_function(
  753. p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
  754. );
  755. sqlite3_free(p->zObj);
  756. sqlite3_free(p->zKey);
  757. sqlite3_free(p->zTestSql);
  758. sqlite3_free(p->zErr);
  759. sqlite3_free(p->zMessage);
  760. sqlite3_free(p);
  761. }
  762. }
  763. /*
  764. ** Step the integrity-check object.
  765. */
  766. int sqlite3_intck_step(sqlite3_intck *p){
  767. if( p->rc==SQLITE_OK ){
  768. if( p->zMessage ){
  769. sqlite3_free(p->zMessage);
  770. p->zMessage = 0;
  771. }
  772. if( p->bCorruptSchema ){
  773. p->rc = SQLITE_DONE;
  774. }else
  775. if( p->pCheck==0 ){
  776. intckFindObject(p);
  777. if( p->rc==SQLITE_OK ){
  778. if( p->zObj ){
  779. char *zSql = 0;
  780. zSql = intckCheckObjectSql(p, p->zObj, p->zKey, &p->nKeyVal);
  781. p->pCheck = intckPrepare(p, zSql);
  782. sqlite3_free(zSql);
  783. sqlite3_free(p->zKey);
  784. p->zKey = 0;
  785. }else{
  786. p->rc = SQLITE_DONE;
  787. }
  788. }else if( p->rc==SQLITE_CORRUPT ){
  789. p->rc = SQLITE_OK;
  790. p->zMessage = intckMprintf(p, "%s",
  791. "corruption found while reading database schema"
  792. );
  793. p->bCorruptSchema = 1;
  794. }
  795. }
  796. if( p->pCheck ){
  797. assert( p->rc==SQLITE_OK );
  798. if( sqlite3_step(p->pCheck)==SQLITE_ROW ){
  799. /* Normal case, do nothing. */
  800. }else{
  801. intckFinalize(p, p->pCheck);
  802. p->pCheck = 0;
  803. p->nKeyVal = 0;
  804. if( p->rc==SQLITE_CORRUPT ){
  805. p->rc = SQLITE_OK;
  806. p->zMessage = intckMprintf(p,
  807. "corruption found while scanning database object %s", p->zObj
  808. );
  809. }
  810. }
  811. }
  812. }
  813. return p->rc;
  814. }
  815. /*
  816. ** Return a message describing the corruption encountered by the most recent
  817. ** call to sqlite3_intck_step(), or NULL if no corruption was encountered.
  818. */
  819. const char *sqlite3_intck_message(sqlite3_intck *p){
  820. assert( p->pCheck==0 || p->zMessage==0 );
  821. if( p->zMessage ){
  822. return p->zMessage;
  823. }
  824. if( p->pCheck ){
  825. return (const char*)sqlite3_column_text(p->pCheck, 0);
  826. }
  827. return 0;
  828. }
  829. /*
  830. ** Return the error code and message.
  831. */
  832. int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){
  833. if( pzErr ) *pzErr = p->zErr;
  834. return (p->rc==SQLITE_DONE ? SQLITE_OK : p->rc);
  835. }
  836. /*
  837. ** Close any read transaction the integrity-check object is holding open
  838. ** on the database.
  839. */
  840. int sqlite3_intck_unlock(sqlite3_intck *p){
  841. if( p->rc==SQLITE_OK && p->pCheck ){
  842. assert( p->zKey==0 && p->nKeyVal>0 );
  843. intckSaveKey(p);
  844. intckFinalize(p, p->pCheck);
  845. p->pCheck = 0;
  846. }
  847. return p->rc;
  848. }
  849. /*
  850. ** Return the SQL statement used to check object zObj. Or, if zObj is
  851. ** NULL, the current SQL statement.
  852. */
  853. const char *sqlite3_intck_test_sql(sqlite3_intck *p, const char *zObj){
  854. sqlite3_free(p->zTestSql);
  855. if( zObj ){
  856. p->zTestSql = intckCheckObjectSql(p, zObj, 0, 0);
  857. }else{
  858. if( p->zObj ){
  859. p->zTestSql = intckCheckObjectSql(p, p->zObj, p->zKey, 0);
  860. }else{
  861. sqlite3_free(p->zTestSql);
  862. p->zTestSql = 0;
  863. }
  864. }
  865. return p->zTestSql;
  866. }