closure.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. /*
  2. ** 2013-04-16
  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. ** This file contains code for a virtual table that finds the transitive
  14. ** closure of a parent/child relationship in a real table. The virtual
  15. ** table is called "transitive_closure".
  16. **
  17. ** A transitive_closure virtual table is created like this:
  18. **
  19. ** CREATE VIRTUAL TABLE x USING transitive_closure(
  20. ** tablename=<tablename>, -- T
  21. ** idcolumn=<columnname>, -- X
  22. ** parentcolumn=<columnname> -- P
  23. ** );
  24. **
  25. ** When it is created, the new transitive_closure table may be supplied
  26. ** with default values for the name of a table T and columns T.X and T.P.
  27. ** The T.X and T.P columns must contain integers. The ideal case is for
  28. ** T.X to be the INTEGER PRIMARY KEY. The T.P column should reference
  29. ** the T.X column. The row referenced by T.P is the parent of the current row.
  30. **
  31. ** The tablename, idcolumn, and parentcolumn supplied by the CREATE VIRTUAL
  32. ** TABLE statement may be overridden in individual queries by including
  33. ** terms like tablename='newtable', idcolumn='id2', or
  34. ** parentcolumn='parent3' in the WHERE clause of the query.
  35. **
  36. ** For efficiency, it is essential that there be an index on the P column:
  37. **
  38. ** CREATE Tidx1 ON T(P)
  39. **
  40. ** Suppose a specific instance of the closure table is as follows:
  41. **
  42. ** CREATE VIRTUAL TABLE ct1 USING transitive_closure(
  43. ** tablename='group',
  44. ** idcolumn='groupId',
  45. ** parentcolumn='parentId'
  46. ** );
  47. **
  48. ** Such an instance of the transitive_closure virtual table would be
  49. ** appropriate for walking a tree defined using a table like this, for example:
  50. **
  51. ** CREATE TABLE group(
  52. ** groupId INTEGER PRIMARY KEY,
  53. ** parentId INTEGER REFERENCES group
  54. ** );
  55. ** CREATE INDEX group_idx1 ON group(parentId);
  56. **
  57. ** The group table above would presumably have other application-specific
  58. ** fields. The key point here is that rows of the group table form a
  59. ** tree. The purpose of the ct1 virtual table is to easily extract
  60. ** branches of that tree.
  61. **
  62. ** Once it has been created, the ct1 virtual table can be queried
  63. ** as follows:
  64. **
  65. ** SELECT * FROM element
  66. ** WHERE element.groupId IN (SELECT id FROM ct1 WHERE root=?1);
  67. **
  68. ** The above query will return all elements that are part of group ?1
  69. ** or children of group ?1 or grand-children of ?1 and so forth for all
  70. ** descendents of group ?1. The same query can be formulated as a join:
  71. **
  72. ** SELECT element.* FROM element, ct1
  73. ** WHERE element.groupid=ct1.id
  74. ** AND ct1.root=?1;
  75. **
  76. ** The depth of the transitive_closure (the number of generations of
  77. ** parent/child relations to follow) can be limited by setting "depth"
  78. ** column in the WHERE clause. So, for example, the following query
  79. ** finds only children and grandchildren but no further descendents:
  80. **
  81. ** SELECT element.* FROM element, ct1
  82. ** WHERE element.groupid=ct1.id
  83. ** AND ct1.root=?1
  84. ** AND ct1.depth<=2;
  85. **
  86. ** The "ct1.depth<=2" term could be a strict equality "ct1.depth=2" in
  87. ** order to find only the grandchildren of ?1, not ?1 itself or the
  88. ** children of ?1.
  89. **
  90. ** The root=?1 term must be supplied in WHERE clause or else the query
  91. ** of the ct1 virtual table will return an empty set. The tablename,
  92. ** idcolumn, and parentcolumn attributes can be overridden in the WHERE
  93. ** clause if desired. So, for example, the ct1 table could be repurposed
  94. ** to find ancestors rather than descendents by inverting the roles of
  95. ** the idcolumn and parentcolumn:
  96. **
  97. ** SELECT element.* FROM element, ct1
  98. ** WHERE element.groupid=ct1.id
  99. ** AND ct1.root=?1
  100. ** AND ct1.idcolumn='parentId'
  101. ** AND ct1.parentcolumn='groupId';
  102. **
  103. ** Multiple calls to ct1 could be combined. For example, the following
  104. ** query finds all elements that "cousins" of groupId ?1. That is to say
  105. ** elements where the groupId is a grandchild of the grandparent of ?1.
  106. ** (This definition of "cousins" also includes siblings and self.)
  107. **
  108. ** SELECT element.* FROM element, ct1
  109. ** WHERE element.groupId=ct1.id
  110. ** AND ct1.depth=2
  111. ** AND ct1.root IN (SELECT id FROM ct1
  112. ** WHERE root=?1
  113. ** AND depth=2
  114. ** AND idcolumn='parentId'
  115. ** AND parentcolumn='groupId');
  116. **
  117. ** In our example, the group.groupId column is unique and thus the
  118. ** subquery will return exactly one row. For that reason, the IN
  119. ** operator could be replaced by "=" to get the same result. But
  120. ** in the general case where the idcolumn is not unique, an IN operator
  121. ** would be required for this kind of query.
  122. **
  123. ** Note that because the tablename, idcolumn, and parentcolumn can
  124. ** all be specified in the query, it is possible for an application
  125. ** to define a single transitive_closure virtual table for use on lots
  126. ** of different hierarchy tables. One might say:
  127. **
  128. ** CREATE VIRTUAL TABLE temp.closure USING transitive_closure;
  129. **
  130. ** As each database connection is being opened. Then the application
  131. ** would always have a "closure" virtual table handy to use for querying.
  132. **
  133. ** SELECT element.* FROM element, closure
  134. ** WHERE element.groupid=ct1.id
  135. ** AND closure.root=?1
  136. ** AND closure.tablename='group'
  137. ** AND closure.idname='groupId'
  138. ** AND closure.parentname='parentId';
  139. **
  140. ** See the documentation at http://www.sqlite.org/loadext.html for information
  141. ** on how to compile and use loadable extensions such as this one.
  142. */
  143. #include "sqlite3ext.h"
  144. SQLITE_EXTENSION_INIT1
  145. #include <stdlib.h>
  146. #include <string.h>
  147. #include <assert.h>
  148. #include <stdio.h>
  149. #include <ctype.h>
  150. #ifndef SQLITE_OMIT_VIRTUALTABLE
  151. /*
  152. ** Forward declaration of objects used by this implementation
  153. */
  154. typedef struct closure_vtab closure_vtab;
  155. typedef struct closure_cursor closure_cursor;
  156. typedef struct closure_queue closure_queue;
  157. typedef struct closure_avl closure_avl;
  158. /*****************************************************************************
  159. ** AVL Tree implementation
  160. */
  161. /*
  162. ** Objects that want to be members of the AVL tree should embedded an
  163. ** instance of this structure.
  164. */
  165. struct closure_avl {
  166. sqlite3_int64 id; /* Id of this entry in the table */
  167. int iGeneration; /* Which generation is this entry part of */
  168. closure_avl *pList; /* A linked list of nodes */
  169. closure_avl *pBefore; /* Other elements less than id */
  170. closure_avl *pAfter; /* Other elements greater than id */
  171. closure_avl *pUp; /* Parent element */
  172. short int height; /* Height of this node. Leaf==1 */
  173. short int imbalance; /* Height difference between pBefore and pAfter */
  174. };
  175. /* Recompute the closure_avl.height and closure_avl.imbalance fields for p.
  176. ** Assume that the children of p have correct heights.
  177. */
  178. static void closureAvlRecomputeHeight(closure_avl *p){
  179. short int hBefore = p->pBefore ? p->pBefore->height : 0;
  180. short int hAfter = p->pAfter ? p->pAfter->height : 0;
  181. p->imbalance = hBefore - hAfter; /* -: pAfter higher. +: pBefore higher */
  182. p->height = (hBefore>hAfter ? hBefore : hAfter)+1;
  183. }
  184. /*
  185. ** P B
  186. ** / \ / \
  187. ** B Z ==> X P
  188. ** / \ / \
  189. ** X Y Y Z
  190. **
  191. */
  192. static closure_avl *closureAvlRotateBefore(closure_avl *pP){
  193. closure_avl *pB = pP->pBefore;
  194. closure_avl *pY = pB->pAfter;
  195. pB->pUp = pP->pUp;
  196. pB->pAfter = pP;
  197. pP->pUp = pB;
  198. pP->pBefore = pY;
  199. if( pY ) pY->pUp = pP;
  200. closureAvlRecomputeHeight(pP);
  201. closureAvlRecomputeHeight(pB);
  202. return pB;
  203. }
  204. /*
  205. ** P A
  206. ** / \ / \
  207. ** X A ==> P Z
  208. ** / \ / \
  209. ** Y Z X Y
  210. **
  211. */
  212. static closure_avl *closureAvlRotateAfter(closure_avl *pP){
  213. closure_avl *pA = pP->pAfter;
  214. closure_avl *pY = pA->pBefore;
  215. pA->pUp = pP->pUp;
  216. pA->pBefore = pP;
  217. pP->pUp = pA;
  218. pP->pAfter = pY;
  219. if( pY ) pY->pUp = pP;
  220. closureAvlRecomputeHeight(pP);
  221. closureAvlRecomputeHeight(pA);
  222. return pA;
  223. }
  224. /*
  225. ** Return a pointer to the pBefore or pAfter pointer in the parent
  226. ** of p that points to p. Or if p is the root node, return pp.
  227. */
  228. static closure_avl **closureAvlFromPtr(closure_avl *p, closure_avl **pp){
  229. closure_avl *pUp = p->pUp;
  230. if( pUp==0 ) return pp;
  231. if( pUp->pAfter==p ) return &pUp->pAfter;
  232. return &pUp->pBefore;
  233. }
  234. /*
  235. ** Rebalance all nodes starting with p and working up to the root.
  236. ** Return the new root.
  237. */
  238. static closure_avl *closureAvlBalance(closure_avl *p){
  239. closure_avl *pTop = p;
  240. closure_avl **pp;
  241. while( p ){
  242. closureAvlRecomputeHeight(p);
  243. if( p->imbalance>=2 ){
  244. closure_avl *pB = p->pBefore;
  245. if( pB->imbalance<0 ) p->pBefore = closureAvlRotateAfter(pB);
  246. pp = closureAvlFromPtr(p,&p);
  247. p = *pp = closureAvlRotateBefore(p);
  248. }else if( p->imbalance<=(-2) ){
  249. closure_avl *pA = p->pAfter;
  250. if( pA->imbalance>0 ) p->pAfter = closureAvlRotateBefore(pA);
  251. pp = closureAvlFromPtr(p,&p);
  252. p = *pp = closureAvlRotateAfter(p);
  253. }
  254. pTop = p;
  255. p = p->pUp;
  256. }
  257. return pTop;
  258. }
  259. /* Search the tree rooted at p for an entry with id. Return a pointer
  260. ** to the entry or return NULL.
  261. */
  262. static closure_avl *closureAvlSearch(closure_avl *p, sqlite3_int64 id){
  263. while( p && id!=p->id ){
  264. p = (id<p->id) ? p->pBefore : p->pAfter;
  265. }
  266. return p;
  267. }
  268. /* Find the first node (the one with the smallest key).
  269. */
  270. static closure_avl *closureAvlFirst(closure_avl *p){
  271. if( p ) while( p->pBefore ) p = p->pBefore;
  272. return p;
  273. }
  274. /* Return the node with the next larger key after p.
  275. */
  276. closure_avl *closureAvlNext(closure_avl *p){
  277. closure_avl *pPrev = 0;
  278. while( p && p->pAfter==pPrev ){
  279. pPrev = p;
  280. p = p->pUp;
  281. }
  282. if( p && pPrev==0 ){
  283. p = closureAvlFirst(p->pAfter);
  284. }
  285. return p;
  286. }
  287. /* Insert a new node pNew. Return NULL on success. If the key is not
  288. ** unique, then do not perform the insert but instead leave pNew unchanged
  289. ** and return a pointer to an existing node with the same key.
  290. */
  291. static closure_avl *closureAvlInsert(
  292. closure_avl **ppHead, /* Head of the tree */
  293. closure_avl *pNew /* New node to be inserted */
  294. ){
  295. closure_avl *p = *ppHead;
  296. if( p==0 ){
  297. p = pNew;
  298. pNew->pUp = 0;
  299. }else{
  300. while( p ){
  301. if( pNew->id<p->id ){
  302. if( p->pBefore ){
  303. p = p->pBefore;
  304. }else{
  305. p->pBefore = pNew;
  306. pNew->pUp = p;
  307. break;
  308. }
  309. }else if( pNew->id>p->id ){
  310. if( p->pAfter ){
  311. p = p->pAfter;
  312. }else{
  313. p->pAfter = pNew;
  314. pNew->pUp = p;
  315. break;
  316. }
  317. }else{
  318. return p;
  319. }
  320. }
  321. }
  322. pNew->pBefore = 0;
  323. pNew->pAfter = 0;
  324. pNew->height = 1;
  325. pNew->imbalance = 0;
  326. *ppHead = closureAvlBalance(p);
  327. return 0;
  328. }
  329. /* Walk the tree can call xDestroy on each node
  330. */
  331. static void closureAvlDestroy(closure_avl *p, void (*xDestroy)(closure_avl*)){
  332. if( p ){
  333. closureAvlDestroy(p->pBefore, xDestroy);
  334. closureAvlDestroy(p->pAfter, xDestroy);
  335. xDestroy(p);
  336. }
  337. }
  338. /*
  339. ** End of the AVL Tree implementation
  340. ******************************************************************************/
  341. /*
  342. ** A closure virtual-table object
  343. */
  344. struct closure_vtab {
  345. sqlite3_vtab base; /* Base class - must be first */
  346. char *zDb; /* Name of database. (ex: "main") */
  347. char *zSelf; /* Name of this virtual table */
  348. char *zTableName; /* Name of table holding parent/child relation */
  349. char *zIdColumn; /* Name of ID column of zTableName */
  350. char *zParentColumn; /* Name of PARENT column in zTableName */
  351. sqlite3 *db; /* The database connection */
  352. int nCursor; /* Number of pending cursors */
  353. };
  354. /* A closure cursor object */
  355. struct closure_cursor {
  356. sqlite3_vtab_cursor base; /* Base class - must be first */
  357. closure_vtab *pVtab; /* The virtual table this cursor belongs to */
  358. char *zTableName; /* Name of table holding parent/child relation */
  359. char *zIdColumn; /* Name of ID column of zTableName */
  360. char *zParentColumn; /* Name of PARENT column in zTableName */
  361. closure_avl *pCurrent; /* Current element of output */
  362. closure_avl *pClosure; /* The complete closure tree */
  363. };
  364. /* A queue of AVL nodes */
  365. struct closure_queue {
  366. closure_avl *pFirst; /* Oldest node on the queue */
  367. closure_avl *pLast; /* Youngest node on the queue */
  368. };
  369. /*
  370. ** Add a node to the end of the queue
  371. */
  372. static void queuePush(closure_queue *pQueue, closure_avl *pNode){
  373. pNode->pList = 0;
  374. if( pQueue->pLast ){
  375. pQueue->pLast->pList = pNode;
  376. }else{
  377. pQueue->pFirst = pNode;
  378. }
  379. pQueue->pLast = pNode;
  380. }
  381. /*
  382. ** Extract the oldest element (the front element) from the queue.
  383. */
  384. static closure_avl *queuePull(closure_queue *pQueue){
  385. closure_avl *p = pQueue->pFirst;
  386. if( p ){
  387. pQueue->pFirst = p->pList;
  388. if( pQueue->pFirst==0 ) pQueue->pLast = 0;
  389. }
  390. return p;
  391. }
  392. /*
  393. ** This function converts an SQL quoted string into an unquoted string
  394. ** and returns a pointer to a buffer allocated using sqlite3_malloc()
  395. ** containing the result. The caller should eventually free this buffer
  396. ** using sqlite3_free.
  397. **
  398. ** Examples:
  399. **
  400. ** "abc" becomes abc
  401. ** 'xyz' becomes xyz
  402. ** [pqr] becomes pqr
  403. ** `mno` becomes mno
  404. */
  405. static char *closureDequote(const char *zIn){
  406. int nIn; /* Size of input string, in bytes */
  407. char *zOut; /* Output (dequoted) string */
  408. nIn = (int)strlen(zIn);
  409. zOut = sqlite3_malloc(nIn+1);
  410. if( zOut ){
  411. char q = zIn[0]; /* Quote character (if any ) */
  412. if( q!='[' && q!= '\'' && q!='"' && q!='`' ){
  413. memcpy(zOut, zIn, nIn+1);
  414. }else{
  415. int iOut = 0; /* Index of next byte to write to output */
  416. int iIn; /* Index of next byte to read from input */
  417. if( q=='[' ) q = ']';
  418. for(iIn=1; iIn<nIn; iIn++){
  419. if( zIn[iIn]==q ) iIn++;
  420. zOut[iOut++] = zIn[iIn];
  421. }
  422. }
  423. assert( (int)strlen(zOut)<=nIn );
  424. }
  425. return zOut;
  426. }
  427. /*
  428. ** Deallocate an closure_vtab object
  429. */
  430. static void closureFree(closure_vtab *p){
  431. if( p ){
  432. sqlite3_free(p->zDb);
  433. sqlite3_free(p->zSelf);
  434. sqlite3_free(p->zTableName);
  435. sqlite3_free(p->zIdColumn);
  436. sqlite3_free(p->zParentColumn);
  437. memset(p, 0, sizeof(*p));
  438. sqlite3_free(p);
  439. }
  440. }
  441. /*
  442. ** xDisconnect/xDestroy method for the closure module.
  443. */
  444. static int closureDisconnect(sqlite3_vtab *pVtab){
  445. closure_vtab *p = (closure_vtab*)pVtab;
  446. assert( p->nCursor==0 );
  447. closureFree(p);
  448. return SQLITE_OK;
  449. }
  450. /*
  451. ** Check to see if the argument is of the form:
  452. **
  453. ** KEY = VALUE
  454. **
  455. ** If it is, return a pointer to the first character of VALUE.
  456. ** If not, return NULL. Spaces around the = are ignored.
  457. */
  458. static const char *closureValueOfKey(const char *zKey, const char *zStr){
  459. int nKey = (int)strlen(zKey);
  460. int nStr = (int)strlen(zStr);
  461. int i;
  462. if( nStr<nKey+1 ) return 0;
  463. if( memcmp(zStr, zKey, nKey)!=0 ) return 0;
  464. for(i=nKey; isspace(zStr[i]); i++){}
  465. if( zStr[i]!='=' ) return 0;
  466. i++;
  467. while( isspace(zStr[i]) ){ i++; }
  468. return zStr+i;
  469. }
  470. /*
  471. ** xConnect/xCreate method for the closure module. Arguments are:
  472. **
  473. ** argv[0] -> module name ("transitive_closure")
  474. ** argv[1] -> database name
  475. ** argv[2] -> table name
  476. ** argv[3...] -> arguments
  477. */
  478. static int closureConnect(
  479. sqlite3 *db,
  480. void *pAux,
  481. int argc, const char *const*argv,
  482. sqlite3_vtab **ppVtab,
  483. char **pzErr
  484. ){
  485. int rc = SQLITE_OK; /* Return code */
  486. closure_vtab *pNew = 0; /* New virtual table */
  487. const char *zDb = argv[1];
  488. const char *zVal;
  489. int i;
  490. (void)pAux;
  491. *ppVtab = 0;
  492. pNew = sqlite3_malloc( sizeof(*pNew) );
  493. if( pNew==0 ) return SQLITE_NOMEM;
  494. rc = SQLITE_NOMEM;
  495. memset(pNew, 0, sizeof(*pNew));
  496. pNew->db = db;
  497. pNew->zDb = sqlite3_mprintf("%s", zDb);
  498. if( pNew->zDb==0 ) goto closureConnectError;
  499. pNew->zSelf = sqlite3_mprintf("%s", argv[2]);
  500. if( pNew->zSelf==0 ) goto closureConnectError;
  501. for(i=3; i<argc; i++){
  502. zVal = closureValueOfKey("tablename", argv[i]);
  503. if( zVal ){
  504. sqlite3_free(pNew->zTableName);
  505. pNew->zTableName = closureDequote(zVal);
  506. if( pNew->zTableName==0 ) goto closureConnectError;
  507. continue;
  508. }
  509. zVal = closureValueOfKey("idcolumn", argv[i]);
  510. if( zVal ){
  511. sqlite3_free(pNew->zIdColumn);
  512. pNew->zIdColumn = closureDequote(zVal);
  513. if( pNew->zIdColumn==0 ) goto closureConnectError;
  514. continue;
  515. }
  516. zVal = closureValueOfKey("parentcolumn", argv[i]);
  517. if( zVal ){
  518. sqlite3_free(pNew->zParentColumn);
  519. pNew->zParentColumn = closureDequote(zVal);
  520. if( pNew->zParentColumn==0 ) goto closureConnectError;
  521. continue;
  522. }
  523. *pzErr = sqlite3_mprintf("unrecognized argument: [%s]\n", argv[i]);
  524. closureFree(pNew);
  525. *ppVtab = 0;
  526. return SQLITE_ERROR;
  527. }
  528. rc = sqlite3_declare_vtab(db,
  529. "CREATE TABLE x(id,depth,root HIDDEN,tablename HIDDEN,"
  530. "idcolumn HIDDEN,parentcolumn HIDDEN)"
  531. );
  532. #define CLOSURE_COL_ID 0
  533. #define CLOSURE_COL_DEPTH 1
  534. #define CLOSURE_COL_ROOT 2
  535. #define CLOSURE_COL_TABLENAME 3
  536. #define CLOSURE_COL_IDCOLUMN 4
  537. #define CLOSURE_COL_PARENTCOLUMN 5
  538. if( rc!=SQLITE_OK ){
  539. closureFree(pNew);
  540. }
  541. *ppVtab = &pNew->base;
  542. return rc;
  543. closureConnectError:
  544. closureFree(pNew);
  545. return rc;
  546. }
  547. /*
  548. ** Open a new closure cursor.
  549. */
  550. static int closureOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  551. closure_vtab *p = (closure_vtab*)pVTab;
  552. closure_cursor *pCur;
  553. pCur = sqlite3_malloc( sizeof(*pCur) );
  554. if( pCur==0 ) return SQLITE_NOMEM;
  555. memset(pCur, 0, sizeof(*pCur));
  556. pCur->pVtab = p;
  557. *ppCursor = &pCur->base;
  558. p->nCursor++;
  559. return SQLITE_OK;
  560. }
  561. /*
  562. ** Free up all the memory allocated by a cursor. Set it rLimit to 0
  563. ** to indicate that it is at EOF.
  564. */
  565. static void closureClearCursor(closure_cursor *pCur){
  566. closureAvlDestroy(pCur->pClosure, (void(*)(closure_avl*))sqlite3_free);
  567. sqlite3_free(pCur->zTableName);
  568. sqlite3_free(pCur->zIdColumn);
  569. sqlite3_free(pCur->zParentColumn);
  570. pCur->zTableName = 0;
  571. pCur->zIdColumn = 0;
  572. pCur->zParentColumn = 0;
  573. pCur->pCurrent = 0;
  574. pCur->pClosure = 0;
  575. }
  576. /*
  577. ** Close a closure cursor.
  578. */
  579. static int closureClose(sqlite3_vtab_cursor *cur){
  580. closure_cursor *pCur = (closure_cursor *)cur;
  581. closureClearCursor(pCur);
  582. pCur->pVtab->nCursor--;
  583. sqlite3_free(pCur);
  584. return SQLITE_OK;
  585. }
  586. /*
  587. ** Advance a cursor to its next row of output
  588. */
  589. static int closureNext(sqlite3_vtab_cursor *cur){
  590. closure_cursor *pCur = (closure_cursor*)cur;
  591. pCur->pCurrent = closureAvlNext(pCur->pCurrent);
  592. return SQLITE_OK;
  593. }
  594. /*
  595. ** Allocate and insert a node
  596. */
  597. static int closureInsertNode(
  598. closure_queue *pQueue, /* Add new node to this queue */
  599. closure_cursor *pCur, /* The cursor into which to add the node */
  600. sqlite3_int64 id, /* The node ID */
  601. int iGeneration /* The generation number for this node */
  602. ){
  603. closure_avl *pNew = sqlite3_malloc( sizeof(*pNew) );
  604. if( pNew==0 ) return SQLITE_NOMEM;
  605. memset(pNew, 0, sizeof(*pNew));
  606. pNew->id = id;
  607. pNew->iGeneration = iGeneration;
  608. closureAvlInsert(&pCur->pClosure, pNew);
  609. queuePush(pQueue, pNew);
  610. return SQLITE_OK;
  611. }
  612. /*
  613. ** Called to "rewind" a cursor back to the beginning so that
  614. ** it starts its output over again. Always called at least once
  615. ** prior to any closureColumn, closureRowid, or closureEof call.
  616. **
  617. ** This routine actually computes the closure.
  618. **
  619. ** See the comment at the beginning of closureBestIndex() for a
  620. ** description of the meaning of idxNum. The idxStr parameter is
  621. ** not used.
  622. */
  623. static int closureFilter(
  624. sqlite3_vtab_cursor *pVtabCursor,
  625. int idxNum, const char *idxStr,
  626. int argc, sqlite3_value **argv
  627. ){
  628. closure_cursor *pCur = (closure_cursor *)pVtabCursor;
  629. closure_vtab *pVtab = pCur->pVtab;
  630. sqlite3_int64 iRoot;
  631. int mxGen = 999999999;
  632. char *zSql;
  633. sqlite3_stmt *pStmt;
  634. closure_avl *pAvl;
  635. int rc = SQLITE_OK;
  636. const char *zTableName = pVtab->zTableName;
  637. const char *zIdColumn = pVtab->zIdColumn;
  638. const char *zParentColumn = pVtab->zParentColumn;
  639. closure_queue sQueue;
  640. (void)idxStr; /* Unused parameter */
  641. (void)argc; /* Unused parameter */
  642. closureClearCursor(pCur);
  643. memset(&sQueue, 0, sizeof(sQueue));
  644. if( (idxNum & 1)==0 ){
  645. /* No root=$root in the WHERE clause. Return an empty set */
  646. return SQLITE_OK;
  647. }
  648. iRoot = sqlite3_value_int64(argv[0]);
  649. if( (idxNum & 0x000f0)!=0 ){
  650. mxGen = sqlite3_value_int(argv[(idxNum>>4)&0x0f]);
  651. if( (idxNum & 0x00002)!=0 ) mxGen--;
  652. }
  653. if( (idxNum & 0x00f00)!=0 ){
  654. zTableName = (const char*)sqlite3_value_text(argv[(idxNum>>8)&0x0f]);
  655. pCur->zTableName = sqlite3_mprintf("%s", zTableName);
  656. }
  657. if( (idxNum & 0x0f000)!=0 ){
  658. zIdColumn = (const char*)sqlite3_value_text(argv[(idxNum>>12)&0x0f]);
  659. pCur->zIdColumn = sqlite3_mprintf("%s", zIdColumn);
  660. }
  661. if( (idxNum & 0x0f0000)!=0 ){
  662. zParentColumn = (const char*)sqlite3_value_text(argv[(idxNum>>16)&0x0f]);
  663. pCur->zParentColumn = sqlite3_mprintf("%s", zParentColumn);
  664. }
  665. zSql = sqlite3_mprintf(
  666. "SELECT \"%w\".\"%w\" FROM \"%w\" WHERE \"%w\".\"%w\"=?1",
  667. zTableName, zIdColumn, zTableName, zTableName, zParentColumn);
  668. if( zSql==0 ){
  669. return SQLITE_NOMEM;
  670. }else{
  671. rc = sqlite3_prepare_v2(pVtab->db, zSql, -1, &pStmt, 0);
  672. sqlite3_free(zSql);
  673. if( rc ){
  674. sqlite3_free(pVtab->base.zErrMsg);
  675. pVtab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pVtab->db));
  676. return rc;
  677. }
  678. }
  679. if( rc==SQLITE_OK ){
  680. rc = closureInsertNode(&sQueue, pCur, iRoot, 0);
  681. }
  682. while( (pAvl = queuePull(&sQueue))!=0 ){
  683. if( pAvl->iGeneration>=mxGen ) continue;
  684. sqlite3_bind_int64(pStmt, 1, pAvl->id);
  685. while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
  686. if( sqlite3_column_type(pStmt,0)==SQLITE_INTEGER ){
  687. sqlite3_int64 iNew = sqlite3_column_int64(pStmt, 0);
  688. if( closureAvlSearch(pCur->pClosure, iNew)==0 ){
  689. rc = closureInsertNode(&sQueue, pCur, iNew, pAvl->iGeneration+1);
  690. }
  691. }
  692. }
  693. sqlite3_reset(pStmt);
  694. }
  695. sqlite3_finalize(pStmt);
  696. if( rc==SQLITE_OK ){
  697. pCur->pCurrent = closureAvlFirst(pCur->pClosure);
  698. }
  699. return rc;
  700. }
  701. /*
  702. ** Only the word and distance columns have values. All other columns
  703. ** return NULL
  704. */
  705. static int closureColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  706. closure_cursor *pCur = (closure_cursor*)cur;
  707. switch( i ){
  708. case CLOSURE_COL_ID: {
  709. sqlite3_result_int64(ctx, pCur->pCurrent->id);
  710. break;
  711. }
  712. case CLOSURE_COL_DEPTH: {
  713. sqlite3_result_int(ctx, pCur->pCurrent->iGeneration);
  714. break;
  715. }
  716. case CLOSURE_COL_ROOT: {
  717. sqlite3_result_null(ctx);
  718. break;
  719. }
  720. case CLOSURE_COL_TABLENAME: {
  721. sqlite3_result_text(ctx,
  722. pCur->zTableName ? pCur->zTableName : pCur->pVtab->zTableName,
  723. -1, SQLITE_TRANSIENT);
  724. break;
  725. }
  726. case CLOSURE_COL_IDCOLUMN: {
  727. sqlite3_result_text(ctx,
  728. pCur->zIdColumn ? pCur->zIdColumn : pCur->pVtab->zIdColumn,
  729. -1, SQLITE_TRANSIENT);
  730. break;
  731. }
  732. case CLOSURE_COL_PARENTCOLUMN: {
  733. sqlite3_result_text(ctx,
  734. pCur->zParentColumn ? pCur->zParentColumn : pCur->pVtab->zParentColumn,
  735. -1, SQLITE_TRANSIENT);
  736. break;
  737. }
  738. }
  739. return SQLITE_OK;
  740. }
  741. /*
  742. ** The rowid. For the closure table, this is the same as the "id" column.
  743. */
  744. static int closureRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  745. closure_cursor *pCur = (closure_cursor*)cur;
  746. *pRowid = pCur->pCurrent->id;
  747. return SQLITE_OK;
  748. }
  749. /*
  750. ** EOF indicator
  751. */
  752. static int closureEof(sqlite3_vtab_cursor *cur){
  753. closure_cursor *pCur = (closure_cursor*)cur;
  754. return pCur->pCurrent==0;
  755. }
  756. /*
  757. ** Search for terms of these forms:
  758. **
  759. ** (A) root = $root
  760. ** (B1) depth < $depth
  761. ** (B2) depth <= $depth
  762. ** (B3) depth = $depth
  763. ** (C) tablename = $tablename
  764. ** (D) idcolumn = $idcolumn
  765. ** (E) parentcolumn = $parentcolumn
  766. **
  767. **
  768. **
  769. ** idxNum meaning
  770. ** ---------- ------------------------------------------------------
  771. ** 0x00000001 Term of the form (A) found
  772. ** 0x00000002 The term of bit-2 is like (B1)
  773. ** 0x000000f0 Index in filter.argv[] of $depth. 0 if not used.
  774. ** 0x00000f00 Index in filter.argv[] of $tablename. 0 if not used.
  775. ** 0x0000f000 Index in filter.argv[] of $idcolumn. 0 if not used
  776. ** 0x000f0000 Index in filter.argv[] of $parentcolumn. 0 if not used.
  777. **
  778. ** There must be a term of type (A). If there is not, then the index type
  779. ** is 0 and the query will return an empty set.
  780. */
  781. static int closureBestIndex(
  782. sqlite3_vtab *pTab, /* The virtual table */
  783. sqlite3_index_info *pIdxInfo /* Information about the query */
  784. ){
  785. int iPlan = 0;
  786. int i;
  787. int idx = 1;
  788. int seenMatch = 0;
  789. const struct sqlite3_index_constraint *pConstraint;
  790. closure_vtab *pVtab = (closure_vtab*)pTab;
  791. double rCost = 10000000.0;
  792. pConstraint = pIdxInfo->aConstraint;
  793. for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
  794. if( pConstraint->iColumn==CLOSURE_COL_ROOT
  795. && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
  796. seenMatch = 1;
  797. }
  798. if( pConstraint->usable==0 ) continue;
  799. if( (iPlan & 1)==0
  800. && pConstraint->iColumn==CLOSURE_COL_ROOT
  801. && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
  802. ){
  803. iPlan |= 1;
  804. pIdxInfo->aConstraintUsage[i].argvIndex = 1;
  805. pIdxInfo->aConstraintUsage[i].omit = 1;
  806. rCost /= 100.0;
  807. }
  808. if( (iPlan & 0x0000f0)==0
  809. && pConstraint->iColumn==CLOSURE_COL_DEPTH
  810. && (pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT
  811. || pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE
  812. || pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ)
  813. ){
  814. iPlan |= idx<<4;
  815. pIdxInfo->aConstraintUsage[i].argvIndex = ++idx;
  816. if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ) iPlan |= 0x000002;
  817. rCost /= 5.0;
  818. }
  819. if( (iPlan & 0x000f00)==0
  820. && pConstraint->iColumn==CLOSURE_COL_TABLENAME
  821. && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
  822. ){
  823. iPlan |= idx<<8;
  824. pIdxInfo->aConstraintUsage[i].argvIndex = ++idx;
  825. pIdxInfo->aConstraintUsage[i].omit = 1;
  826. rCost /= 5.0;
  827. }
  828. if( (iPlan & 0x00f000)==0
  829. && pConstraint->iColumn==CLOSURE_COL_IDCOLUMN
  830. && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
  831. ){
  832. iPlan |= idx<<12;
  833. pIdxInfo->aConstraintUsage[i].argvIndex = ++idx;
  834. pIdxInfo->aConstraintUsage[i].omit = 1;
  835. }
  836. if( (iPlan & 0x0f0000)==0
  837. && pConstraint->iColumn==CLOSURE_COL_PARENTCOLUMN
  838. && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
  839. ){
  840. iPlan |= idx<<16;
  841. pIdxInfo->aConstraintUsage[i].argvIndex = ++idx;
  842. pIdxInfo->aConstraintUsage[i].omit = 1;
  843. }
  844. }
  845. if( (pVtab->zTableName==0 && (iPlan & 0x000f00)==0)
  846. || (pVtab->zIdColumn==0 && (iPlan & 0x00f000)==0)
  847. || (pVtab->zParentColumn==0 && (iPlan & 0x0f0000)==0)
  848. ){
  849. /* All of tablename, idcolumn, and parentcolumn must be specified
  850. ** in either the CREATE VIRTUAL TABLE or in the WHERE clause constraints
  851. ** or else the result is an empty set. */
  852. iPlan = 0;
  853. }
  854. pIdxInfo->idxNum = iPlan;
  855. if( pIdxInfo->nOrderBy==1
  856. && pIdxInfo->aOrderBy[0].iColumn==CLOSURE_COL_ID
  857. && pIdxInfo->aOrderBy[0].desc==0
  858. ){
  859. pIdxInfo->orderByConsumed = 1;
  860. }
  861. if( seenMatch && (iPlan&1)==0 ) rCost *= 1e30;
  862. pIdxInfo->estimatedCost = rCost;
  863. return SQLITE_OK;
  864. }
  865. /*
  866. ** A virtual table module that implements the "transitive_closure".
  867. */
  868. static sqlite3_module closureModule = {
  869. 0, /* iVersion */
  870. closureConnect, /* xCreate */
  871. closureConnect, /* xConnect */
  872. closureBestIndex, /* xBestIndex */
  873. closureDisconnect, /* xDisconnect */
  874. closureDisconnect, /* xDestroy */
  875. closureOpen, /* xOpen - open a cursor */
  876. closureClose, /* xClose - close a cursor */
  877. closureFilter, /* xFilter - configure scan constraints */
  878. closureNext, /* xNext - advance a cursor */
  879. closureEof, /* xEof - check for end of scan */
  880. closureColumn, /* xColumn - read data */
  881. closureRowid, /* xRowid - read data */
  882. 0, /* xUpdate */
  883. 0, /* xBegin */
  884. 0, /* xSync */
  885. 0, /* xCommit */
  886. 0, /* xRollback */
  887. 0, /* xFindMethod */
  888. 0, /* xRename */
  889. 0, /* xSavepoint */
  890. 0, /* xRelease */
  891. 0 /* xRollbackTo */
  892. };
  893. #endif /* SQLITE_OMIT_VIRTUALTABLE */
  894. /*
  895. ** Register the closure virtual table
  896. */
  897. #ifdef _WIN32
  898. __declspec(dllexport)
  899. #endif
  900. int sqlite3_closure_init(
  901. sqlite3 *db,
  902. char **pzErrMsg,
  903. const sqlite3_api_routines *pApi
  904. ){
  905. int rc = SQLITE_OK;
  906. SQLITE_EXTENSION_INIT2(pApi);
  907. (void)pzErrMsg;
  908. #ifndef SQLITE_OMIT_VIRTUALTABLE
  909. rc = sqlite3_create_module(db, "transitive_closure", &closureModule, 0);
  910. #endif /* SQLITE_OMIT_VIRTUALTABLE */
  911. return rc;
  912. }