Fossil SCM

Faster implementation of start_of_branch() using a CTE.

drh 2022-03-08 13:08 trunk merge
Commit 8736de8baad75d2630f96ef649bd3b85010eae6a89e4916f044695136aca2453
1 file changed +20 -13
+20 -13
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157157
Stmt q;
158158
int rc;
159159
int ans = rid;
160160
char *zBr = branch_of_rid(rid);
161161
db_prepare(&q,
162
- "SELECT pid, EXISTS(SELECT 1 FROM tagxref"
163
- " WHERE tagid=%d AND tagtype>0"
164
- " AND value=%Q AND rid=plink.pid)"
165
- " FROM plink"
166
- " WHERE cid=:cid AND isprim",
167
- TAG_BRANCH, zBr
162
+ "WITH RECURSIVE"
163
+ " par(pid, ex, cnt) as ("
164
+ " SELECT pid, EXISTS(SELECT 1 FROM tagxref"
165
+ " WHERE tagid=%d AND tagtype>0"
166
+ " AND value=%Q AND rid=plink.pid), 1"
167
+ " FROM plink WHERE cid=%d AND isprim"
168
+ " UNION ALL "
169
+ " SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
170
+ " WHERE tagid=%d AND tagtype>0"
171
+ " AND value=%Q AND rid=plink.pid),"
172
+ " 1+par.cnt"
173
+ " FROM plink, par"
174
+ " WHERE cid=par.pid AND isprim AND par.ex "
175
+ " LIMIT 100000 "
176
+ " )"
177
+ " SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
178
+ TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
168179
);
169180
fossil_free(zBr);
170
- do{
171
- db_reset(&q);
172
- db_bind_int(&q, ":cid", ans);
173
- rc = db_step(&q);
174
- if( rc!=SQLITE_ROW ) break;
175
- if( eType==1 && db_column_int(&q,1)==0 ) break;
181
+ rc = db_step(&q);
182
+ if( rc==SQLITE_ROW ){
176183
ans = db_column_int(&q, 0);
177
- }while( db_column_int(&q, 1)==1 && ans>0 );
184
+ }
178185
db_finalize(&q);
179186
if( eType==2 && ans>0 ){
180187
zBr = branch_of_rid(ans);
181188
ans = compute_youngest_ancestor_in_branch(rid, zBr);
182189
fossil_free(zBr);
183190
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157 Stmt q;
158 int rc;
159 int ans = rid;
160 char *zBr = branch_of_rid(rid);
161 db_prepare(&q,
162 "SELECT pid, EXISTS(SELECT 1 FROM tagxref"
163 " WHERE tagid=%d AND tagtype>0"
164 " AND value=%Q AND rid=plink.pid)"
165 " FROM plink"
166 " WHERE cid=:cid AND isprim",
167 TAG_BRANCH, zBr
 
 
 
 
 
 
 
 
 
 
 
168 );
169 fossil_free(zBr);
170 do{
171 db_reset(&q);
172 db_bind_int(&q, ":cid", ans);
173 rc = db_step(&q);
174 if( rc!=SQLITE_ROW ) break;
175 if( eType==1 && db_column_int(&q,1)==0 ) break;
176 ans = db_column_int(&q, 0);
177 }while( db_column_int(&q, 1)==1 && ans>0 );
178 db_finalize(&q);
179 if( eType==2 && ans>0 ){
180 zBr = branch_of_rid(ans);
181 ans = compute_youngest_ancestor_in_branch(rid, zBr);
182 fossil_free(zBr);
183
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157 Stmt q;
158 int rc;
159 int ans = rid;
160 char *zBr = branch_of_rid(rid);
161 db_prepare(&q,
162 "WITH RECURSIVE"
163 " par(pid, ex, cnt) as ("
164 " SELECT pid, EXISTS(SELECT 1 FROM tagxref"
165 " WHERE tagid=%d AND tagtype>0"
166 " AND value=%Q AND rid=plink.pid), 1"
167 " FROM plink WHERE cid=%d AND isprim"
168 " UNION ALL "
169 " SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
170 " WHERE tagid=%d AND tagtype>0"
171 " AND value=%Q AND rid=plink.pid),"
172 " 1+par.cnt"
173 " FROM plink, par"
174 " WHERE cid=par.pid AND isprim AND par.ex "
175 " LIMIT 100000 "
176 " )"
177 " SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
178 TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
179 );
180 fossil_free(zBr);
181 rc = db_step(&q);
182 if( rc==SQLITE_ROW ){
 
 
 
 
183 ans = db_column_int(&q, 0);
184 }
185 db_finalize(&q);
186 if( eType==2 && ans>0 ){
187 zBr = branch_of_rid(ans);
188 ans = compute_youngest_ancestor_in_branch(rid, zBr);
189 fossil_free(zBr);
190

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button