Check-in [faf09dc7ae]
Not logged in
Overview

SHA1 Hash:faf09dc7ae5417fd4a8b09cc67c7c6ef9c9793a9
Date: 2009-01-22 01:53:04
User: drh
Comment:Define a "leaf" as a check-in with no children in the same branch. The is_a_leaf() function does some complicated SQL to figure this out.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/checkin.c from [daf07ead77] to [dbcea16417].

@@ -346,26 +346,45 @@
     g.aCommitFile[ii-2] = 0;
   }
 }
 
 /*
-** Return true if the check-in with RID=rid has no child
-** check-ins which are not tagged with "newbranch".  In other words,
-** return true if the check-in is a leaf.
+** Return true if the check-in with RID=rid is a leaf.
+**
+** A leaf has no children in the same branch.  For the purposes of
+** this definition, a two check-ins are in same branch they have the
+** same set of propagated symbolic tags.
 */
 int is_a_leaf(int rid){
-  return !db_exists(
-    "SELECT 1 FROM plink"
-    " WHERE pid=%d"
-      " AND NOT EXISTS("
-                     "SELECT 1 FROM tagxref"
-                     " WHERE tagxref.rid=plink.cid"
-                     "   AND tagxref.tagid=%d"
-                     "   AND tagxref.tagtype=1"
-               ")",
-    rid, TAG_NEWBRANCH
-  );
+
+  /* This query selects all children in the same branch as rid */
+  static const char zSql[] =
+    @ SELECT cid FROM plink
+    @  WHERE pid=:rid
+    @    AND (SELECT group_concat(x) FROM (
+    @           SELECT tag.tagid AS x FROM tagxref, tag
+    @            WHERE tagxref.rid=:rid AND tagxref.tagtype=2
+    @              AND tag.tagid=tagxref.tagid AND tagxref.srcid=0
+    @              AND tag.tagname GLOB 'sym-*'
+    @            ORDER BY 1)
+    @        ) ==
+    @        (SELECT group_concat(x) FROM (
+    @           SELECT tag.tagid AS x FROM tagxref, tag
+    @            WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2
+    @              AND tag.tagid=tagxref.tagid
+    @              AND tag.tagname GLOB 'sym-*'
+    @            ORDER BY 1)
+    @        )
+  ;
+  Stmt q;    /* The prepared statement */
+  int rc;    /* Return code from stepping the prepared statement */
+
+  db_prepare(&q, zSql);
+  db_bind_int(&q, ":rid", rid);
+  rc = db_step(&q);
+  db_finalize(&q);
+  return rc==SQLITE_DONE;
 }
 
 /*
 ** COMMAND: ci
 ** COMMAND: commit

Modified src/descendants.c from [cba21fd744] to [c48bc9acc2].

@@ -62,11 +62,10 @@
 */
 void compute_leaves(int iBase, int closeMode){
   Bag seen;       /* Descendants seen */
   Bag pending;    /* Unpropagated descendants */
   Stmt q1;        /* Query to find children of a check-in */
-  Stmt q2;        /* Query to detect if a merge is across branches */
   Stmt isBr;      /* Query to check to see if a check-in starts a new branch */
   Stmt ins;       /* INSERT statement for a new record */
 
   /* Create the LEAVES table if it does not already exist.  Make sure
   ** it is empty.
@@ -92,32 +91,10 @@
   bag_init(&pending);
   bag_insert(&pending, iBase);
 
   /* This query returns all non-merge children of check-in :rid */
   db_prepare(&q1, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
-
-  /* This query returns all merge children of check-in :rid where
-  ** the child and parent are on same branch.  The child and
-  ** parent are assumed to be on same branch if they have
-  ** the same set of propagated symbolic tags.
-  */
-  db_prepare(&q2,
-     "SELECT cid FROM plink"
-     " WHERE pid=:rid AND NOT isprim"
-     "   AND (SELECT group_concat(x) FROM ("
-     "          SELECT tag.tagid AS x FROM tagxref, tag"
-     "           WHERE tagxref.rid=:rid AND tagxref.tagtype=2"
-     "             AND tag.tagid=tagxref.tagid AND tagxref.srcid=0"
-     "             AND tag.tagname GLOB 'sym-*'"
-     "           ORDER BY 1))"
-     "    == (SELECT group_concat(x) FROM ("
-     "          SELECT tag.tagid AS x FROM tagxref, tag"
-     "           WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2"
-     "             AND tag.tagid=tagxref.tagid AND tagxref.srcid=0"
-     "             AND tag.tagname GLOB 'sym-*'"
-     "           ORDER BY 1))"
-  );
 
   /* This query returns a single row if check-in :rid is the first
   ** check-in of a new branch.  In other words, it returns a row if
   ** check-in :rid has the 'newbranch' tag.
   */
@@ -145,26 +122,21 @@
         cnt++;
       }
       db_reset(&isBr);
     }
     db_reset(&q1);
-    if( cnt==0 ){
-      db_bind_int(&q2, ":rid", rid);
-      if( db_step(&q2)==SQLITE_ROW ){
-        cnt++;
-      }
-      db_reset(&q2);
+    if( cnt==0 && !is_a_leaf(rid) ){
+      cnt++;
     }
     if( cnt==0 ){
       db_bind_int(&ins, ":rid", rid);
       db_step(&ins);
       db_reset(&ins);
     }
   }
   db_finalize(&ins);
   db_finalize(&isBr);
-  db_finalize(&q2);
   db_finalize(&q1);
   bag_clear(&pending);
   bag_clear(&seen);
   if( closeMode==1 ){
     db_multi_exec(