Fossil SCM

Update the mechanism for reporting SQL that does not use indices. The warnings can be suppressed by comments in the SQL text.

drh 2010-03-31 15:27 UTC trunk
Commit 9f1d490dd6e692dc5392b452038080d728d742aa
+2 -2
--- src/branch.c
+++ src/branch.c
@@ -246,11 +246,11 @@
246246
247247
db_prepare(&q,
248248
"SELECT DISTINCT value FROM tagxref"
249249
" WHERE tagid=%d AND value NOT NULL"
250250
" AND rid IN leaves"
251
- " ORDER BY value",
251
+ " ORDER BY value /*sort*/",
252252
TAG_BRANCH
253253
);
254254
cnt = 0;
255255
while( db_step(&q)==SQLITE_ROW ){
256256
const char *zBr = db_column_text(&q, 0);
@@ -275,11 +275,11 @@
275275
" WHERE tagid=%d AND value NOT NULL"
276276
" EXCEPT "
277277
"SELECT value FROM tagxref"
278278
" WHERE tagid=%d AND value NOT NULL"
279279
" AND rid IN leaves"
280
- " ORDER BY value",
280
+ " ORDER BY value /*sort*/",
281281
TAG_BRANCH, TAG_BRANCH
282282
);
283283
while( db_step(&q)==SQLITE_ROW ){
284284
const char *zBr = db_column_text(&q, 0);
285285
if( cnt==0 ){
286286
--- src/branch.c
+++ src/branch.c
@@ -246,11 +246,11 @@
246
247 db_prepare(&q,
248 "SELECT DISTINCT value FROM tagxref"
249 " WHERE tagid=%d AND value NOT NULL"
250 " AND rid IN leaves"
251 " ORDER BY value",
252 TAG_BRANCH
253 );
254 cnt = 0;
255 while( db_step(&q)==SQLITE_ROW ){
256 const char *zBr = db_column_text(&q, 0);
@@ -275,11 +275,11 @@
275 " WHERE tagid=%d AND value NOT NULL"
276 " EXCEPT "
277 "SELECT value FROM tagxref"
278 " WHERE tagid=%d AND value NOT NULL"
279 " AND rid IN leaves"
280 " ORDER BY value",
281 TAG_BRANCH, TAG_BRANCH
282 );
283 while( db_step(&q)==SQLITE_ROW ){
284 const char *zBr = db_column_text(&q, 0);
285 if( cnt==0 ){
286
--- src/branch.c
+++ src/branch.c
@@ -246,11 +246,11 @@
246
247 db_prepare(&q,
248 "SELECT DISTINCT value FROM tagxref"
249 " WHERE tagid=%d AND value NOT NULL"
250 " AND rid IN leaves"
251 " ORDER BY value /*sort*/",
252 TAG_BRANCH
253 );
254 cnt = 0;
255 while( db_step(&q)==SQLITE_ROW ){
256 const char *zBr = db_column_text(&q, 0);
@@ -275,11 +275,11 @@
275 " WHERE tagid=%d AND value NOT NULL"
276 " EXCEPT "
277 "SELECT value FROM tagxref"
278 " WHERE tagid=%d AND value NOT NULL"
279 " AND rid IN leaves"
280 " ORDER BY value /*sort*/",
281 TAG_BRANCH, TAG_BRANCH
282 );
283 while( db_step(&q)==SQLITE_ROW ){
284 const char *zBr = db_column_text(&q, 0);
285 if( cnt==0 ){
286
+3 -3
--- src/browse.c
+++ src/browse.c
@@ -217,15 +217,15 @@
217217
}
218218
219219
/* Generate a multi-column table listing the contents of zD[]
220220
** directory.
221221
*/
222
- mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles");
223
- cnt = db_int(0, "SELECT count(*) FROM localfiles");
222
+ mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
223
+ cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
224224
nCol = 4;
225225
nRow = (cnt+nCol-1)/nCol;
226
- db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x");
226
+ db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
227227
@ <table border="0" width="100%%"><tr><td valign="top" width="25%%">
228228
i = 0;
229229
while( db_step(&q)==SQLITE_ROW ){
230230
const char *zFN;
231231
if( i==nRow ){
232232
--- src/browse.c
+++ src/browse.c
@@ -217,15 +217,15 @@
217 }
218
219 /* Generate a multi-column table listing the contents of zD[]
220 ** directory.
221 */
222 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles");
223 cnt = db_int(0, "SELECT count(*) FROM localfiles");
224 nCol = 4;
225 nRow = (cnt+nCol-1)/nCol;
226 db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x");
227 @ <table border="0" width="100%%"><tr><td valign="top" width="25%%">
228 i = 0;
229 while( db_step(&q)==SQLITE_ROW ){
230 const char *zFN;
231 if( i==nRow ){
232
--- src/browse.c
+++ src/browse.c
@@ -217,15 +217,15 @@
217 }
218
219 /* Generate a multi-column table listing the contents of zD[]
220 ** directory.
221 */
222 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
223 cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
224 nCol = 4;
225 nRow = (cnt+nCol-1)/nCol;
226 db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
227 @ <table border="0" width="100%%"><tr><td valign="top" width="25%%">
228 i = 0;
229 while( db_step(&q)==SQLITE_ROW ){
230 const char *zFN;
231 if( i==nRow ){
232
+11 -11
--- src/db.c
+++ src/db.c
@@ -278,38 +278,38 @@
278278
}
279279
280280
/*
281281
** Print warnings if a query is inefficient.
282282
*/
283
-static void db_stats(Stmt *pStmt){
283
+static void db_stats(sqlite3_stmt *pStmt){
284284
#ifdef FOSSIL_DEBUG
285285
int c1, c2;
286
- c1 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
287
- c2 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_SORT, 1);
288
- /* printf("**** steps=%d & sorts=%d in [%s]\n", c1, c2,
289
- sqlite3_sql(pStmt->pStmt)); */
290
- if( c1>5 ){
291
- fossil_warning("%d scan steps in [%s]", c1, sqlite3_sql(pStmt->pStmt));
292
- }else if( c2 ){
293
- fossil_warning("sort w/o index in [%s]", sqlite3_sql(pStmt->pStmt));
286
+ const char *zSql = sqlite3_sql(pStmt);
287
+ if( zSql==0 ) return;
288
+ c1 = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
289
+ c2 = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_SORT, 1);
290
+ if( c1>5 && strstr(zSql,"/*scan*/")==0 ){
291
+ fossil_warning("%d scan steps in [%s]", c1, zSql);
292
+ }else if( c2 && strstr(zSql,"/*sort*/")==0 && strstr(zSql,"/*scan*/")==0 ){
293
+ fossil_warning("sort w/o index in [%s]", zSql);
294294
}
295295
#endif
296296
}
297297
298298
/*
299299
** Reset or finalize a statement.
300300
*/
301301
int db_reset(Stmt *pStmt){
302302
int rc;
303
- db_stats(pStmt);
303
+ db_stats(pStmt->pStmt);
304304
rc = sqlite3_reset(pStmt->pStmt);
305305
db_check_result(rc);
306306
return rc;
307307
}
308308
int db_finalize(Stmt *pStmt){
309309
int rc;
310
- db_stats(pStmt);
310
+ db_stats(pStmt->pStmt);
311311
blob_reset(&pStmt->sql);
312312
rc = sqlite3_finalize(pStmt->pStmt);
313313
db_check_result(rc);
314314
pStmt->pStmt = 0;
315315
if( pStmt->pNext ){
316316
--- src/db.c
+++ src/db.c
@@ -278,38 +278,38 @@
278 }
279
280 /*
281 ** Print warnings if a query is inefficient.
282 */
283 static void db_stats(Stmt *pStmt){
284 #ifdef FOSSIL_DEBUG
285 int c1, c2;
286 c1 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
287 c2 = sqlite3_stmt_status(pStmt->pStmt, SQLITE_STMTSTATUS_SORT, 1);
288 /* printf("**** steps=%d & sorts=%d in [%s]\n", c1, c2,
289 sqlite3_sql(pStmt->pStmt)); */
290 if( c1>5 ){
291 fossil_warning("%d scan steps in [%s]", c1, sqlite3_sql(pStmt->pStmt));
292 }else if( c2 ){
293 fossil_warning("sort w/o index in [%s]", sqlite3_sql(pStmt->pStmt));
294 }
295 #endif
296 }
297
298 /*
299 ** Reset or finalize a statement.
300 */
301 int db_reset(Stmt *pStmt){
302 int rc;
303 db_stats(pStmt);
304 rc = sqlite3_reset(pStmt->pStmt);
305 db_check_result(rc);
306 return rc;
307 }
308 int db_finalize(Stmt *pStmt){
309 int rc;
310 db_stats(pStmt);
311 blob_reset(&pStmt->sql);
312 rc = sqlite3_finalize(pStmt->pStmt);
313 db_check_result(rc);
314 pStmt->pStmt = 0;
315 if( pStmt->pNext ){
316
--- src/db.c
+++ src/db.c
@@ -278,38 +278,38 @@
278 }
279
280 /*
281 ** Print warnings if a query is inefficient.
282 */
283 static void db_stats(sqlite3_stmt *pStmt){
284 #ifdef FOSSIL_DEBUG
285 int c1, c2;
286 const char *zSql = sqlite3_sql(pStmt);
287 if( zSql==0 ) return;
288 c1 = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
289 c2 = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_SORT, 1);
290 if( c1>5 && strstr(zSql,"/*scan*/")==0 ){
291 fossil_warning("%d scan steps in [%s]", c1, zSql);
292 }else if( c2 && strstr(zSql,"/*sort*/")==0 && strstr(zSql,"/*scan*/")==0 ){
293 fossil_warning("sort w/o index in [%s]", zSql);
294 }
295 #endif
296 }
297
298 /*
299 ** Reset or finalize a statement.
300 */
301 int db_reset(Stmt *pStmt){
302 int rc;
303 db_stats(pStmt->pStmt);
304 rc = sqlite3_reset(pStmt->pStmt);
305 db_check_result(rc);
306 return rc;
307 }
308 int db_finalize(Stmt *pStmt){
309 int rc;
310 db_stats(pStmt->pStmt);
311 blob_reset(&pStmt->sql);
312 rc = sqlite3_finalize(pStmt->pStmt);
313 db_check_result(rc);
314 pStmt->pStmt = 0;
315 if( pStmt->pNext ){
316
+5 -5
--- src/timeline.c
+++ src/timeline.c
@@ -256,11 +256,11 @@
256256
const char *zBr;
257257
int gidx;
258258
static Stmt qparent;
259259
static Stmt qbranch;
260260
db_static_prepare(&qparent,
261
- "SELECT pid FROM plink WHERE cid=:rid ORDER BY isprim DESC"
261
+ "SELECT pid FROM plink WHERE cid=:rid ORDER BY isprim DESC /*sort*/"
262262
);
263263
db_static_prepare(&qbranch,
264264
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
265265
TAG_BRANCH
266266
);
@@ -876,11 +876,11 @@
876876
blob_appendf(&sql, " ORDER BY event.mtime DESC");
877877
}
878878
blob_appendf(&sql, " LIMIT %d", nEntry);
879879
db_multi_exec("%s", blob_str(&sql));
880880
881
- n = db_int(0, "SELECT count(*) FROM timeline");
881
+ n = db_int(0, "SELECT count(*) FROM timeline /*scan*/");
882882
if( n<nEntry && zAfter ){
883883
cgi_redirect(url_render(&url, "a", 0, "b", 0));
884884
}
885885
if( zAfter==0 && zBefore==0 && zCirca==0 ){
886886
blob_appendf(&desc, "%d most recent %ss", n, zEType);
@@ -905,16 +905,16 @@
905905
if( zSearch ){
906906
blob_appendf(&desc, " matching \"%h\"", zSearch);
907907
}
908908
if( g.okHistory ){
909909
if( zAfter || n==nEntry ){
910
- zDate = db_text(0, "SELECT min(timestamp) FROM timeline");
910
+ zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
911911
timeline_submenu(&url, "Older", "b", zDate, "a");
912912
free(zDate);
913913
}
914914
if( zBefore || (zAfter && n==nEntry) ){
915
- zDate = db_text(0, "SELECT max(timestamp) FROM timeline");
915
+ zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
916916
timeline_submenu(&url, "Newer", "a", zDate, "b");
917917
free(zDate);
918918
}else if( tagid==0 ){
919919
if( zType[0]!='a' ){
920920
timeline_submenu(&url, "All Types", "y", "all", 0);
@@ -936,11 +936,11 @@
936936
timeline_submenu(&url, "200 Events", "n", "200", 0);
937937
}
938938
}
939939
}
940940
blob_zero(&sql);
941
- db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC");
941
+ db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC /*scan*/");
942942
@ <h2>%b(&desc)</h2>
943943
blob_reset(&desc);
944944
www_print_timeline(&q, tmFlags, 0);
945945
db_finalize(&q);
946946
style_footer();
947947
--- src/timeline.c
+++ src/timeline.c
@@ -256,11 +256,11 @@
256 const char *zBr;
257 int gidx;
258 static Stmt qparent;
259 static Stmt qbranch;
260 db_static_prepare(&qparent,
261 "SELECT pid FROM plink WHERE cid=:rid ORDER BY isprim DESC"
262 );
263 db_static_prepare(&qbranch,
264 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
265 TAG_BRANCH
266 );
@@ -876,11 +876,11 @@
876 blob_appendf(&sql, " ORDER BY event.mtime DESC");
877 }
878 blob_appendf(&sql, " LIMIT %d", nEntry);
879 db_multi_exec("%s", blob_str(&sql));
880
881 n = db_int(0, "SELECT count(*) FROM timeline");
882 if( n<nEntry && zAfter ){
883 cgi_redirect(url_render(&url, "a", 0, "b", 0));
884 }
885 if( zAfter==0 && zBefore==0 && zCirca==0 ){
886 blob_appendf(&desc, "%d most recent %ss", n, zEType);
@@ -905,16 +905,16 @@
905 if( zSearch ){
906 blob_appendf(&desc, " matching \"%h\"", zSearch);
907 }
908 if( g.okHistory ){
909 if( zAfter || n==nEntry ){
910 zDate = db_text(0, "SELECT min(timestamp) FROM timeline");
911 timeline_submenu(&url, "Older", "b", zDate, "a");
912 free(zDate);
913 }
914 if( zBefore || (zAfter && n==nEntry) ){
915 zDate = db_text(0, "SELECT max(timestamp) FROM timeline");
916 timeline_submenu(&url, "Newer", "a", zDate, "b");
917 free(zDate);
918 }else if( tagid==0 ){
919 if( zType[0]!='a' ){
920 timeline_submenu(&url, "All Types", "y", "all", 0);
@@ -936,11 +936,11 @@
936 timeline_submenu(&url, "200 Events", "n", "200", 0);
937 }
938 }
939 }
940 blob_zero(&sql);
941 db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC");
942 @ <h2>%b(&desc)</h2>
943 blob_reset(&desc);
944 www_print_timeline(&q, tmFlags, 0);
945 db_finalize(&q);
946 style_footer();
947
--- src/timeline.c
+++ src/timeline.c
@@ -256,11 +256,11 @@
256 const char *zBr;
257 int gidx;
258 static Stmt qparent;
259 static Stmt qbranch;
260 db_static_prepare(&qparent,
261 "SELECT pid FROM plink WHERE cid=:rid ORDER BY isprim DESC /*sort*/"
262 );
263 db_static_prepare(&qbranch,
264 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
265 TAG_BRANCH
266 );
@@ -876,11 +876,11 @@
876 blob_appendf(&sql, " ORDER BY event.mtime DESC");
877 }
878 blob_appendf(&sql, " LIMIT %d", nEntry);
879 db_multi_exec("%s", blob_str(&sql));
880
881 n = db_int(0, "SELECT count(*) FROM timeline /*scan*/");
882 if( n<nEntry && zAfter ){
883 cgi_redirect(url_render(&url, "a", 0, "b", 0));
884 }
885 if( zAfter==0 && zBefore==0 && zCirca==0 ){
886 blob_appendf(&desc, "%d most recent %ss", n, zEType);
@@ -905,16 +905,16 @@
905 if( zSearch ){
906 blob_appendf(&desc, " matching \"%h\"", zSearch);
907 }
908 if( g.okHistory ){
909 if( zAfter || n==nEntry ){
910 zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
911 timeline_submenu(&url, "Older", "b", zDate, "a");
912 free(zDate);
913 }
914 if( zBefore || (zAfter && n==nEntry) ){
915 zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
916 timeline_submenu(&url, "Newer", "a", zDate, "b");
917 free(zDate);
918 }else if( tagid==0 ){
919 if( zType[0]!='a' ){
920 timeline_submenu(&url, "All Types", "y", "all", 0);
@@ -936,11 +936,11 @@
936 timeline_submenu(&url, "200 Events", "n", "200", 0);
937 }
938 }
939 }
940 blob_zero(&sql);
941 db_prepare(&q, "SELECT * FROM timeline ORDER BY timestamp DESC /*scan*/");
942 @ <h2>%b(&desc)</h2>
943 blob_reset(&desc);
944 www_print_timeline(&q, tmFlags, 0);
945 db_finalize(&q);
946 style_footer();
947
+4 -3
--- src/wiki.c
+++ src/wiki.c
@@ -672,11 +672,11 @@
672672
db_prepare(&q,
673673
"SELECT"
674674
" substr(tagname, 6),"
675675
" (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC)"
676676
" FROM tag WHERE tagname GLOB 'wiki-*'"
677
- " ORDER BY lower(tagname)"
677
+ " ORDER BY lower(tagname) /*sort*/"
678678
);
679679
while( db_step(&q)==SQLITE_ROW ){
680680
const char *zName = db_column_text(&q, 0);
681681
int size = db_column_int(&q, 1);
682682
if( size>0 ){
@@ -703,11 +703,12 @@
703703
if( !g.okRdWiki ){ login_needed(); return; }
704704
zTitle = PD("title","*");
705705
style_header("Wiki Pages Found");
706706
@ <ul>
707707
db_prepare(&q,
708
- "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%' ORDER BY lower(tagname)" ,
708
+ "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
709
+ " ORDER BY lower(tagname) /*sort*/" ,
709710
zTitle);
710711
while( db_step(&q)==SQLITE_ROW ){
711712
const char *zName = db_column_text(&q, 0);
712713
@ <li><a href="%s(g.zBaseURL)/wiki?name=%T(zName)">%h(zName)</a></li>
713714
}
@@ -1027,11 +1028,11 @@
10271028
}else
10281029
if( strncmp(g.argv[2],"list",n)==0 ){
10291030
Stmt q;
10301031
db_prepare(&q,
10311032
"SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1032
- " ORDER BY lower(tagname)"
1033
+ " ORDER BY lower(tagname) /*sort*/"
10331034
);
10341035
while( db_step(&q)==SQLITE_ROW ){
10351036
const char *zName = db_column_text(&q, 0);
10361037
printf( "%s\n",zName);
10371038
}
10381039
--- src/wiki.c
+++ src/wiki.c
@@ -672,11 +672,11 @@
672 db_prepare(&q,
673 "SELECT"
674 " substr(tagname, 6),"
675 " (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC)"
676 " FROM tag WHERE tagname GLOB 'wiki-*'"
677 " ORDER BY lower(tagname)"
678 );
679 while( db_step(&q)==SQLITE_ROW ){
680 const char *zName = db_column_text(&q, 0);
681 int size = db_column_int(&q, 1);
682 if( size>0 ){
@@ -703,11 +703,12 @@
703 if( !g.okRdWiki ){ login_needed(); return; }
704 zTitle = PD("title","*");
705 style_header("Wiki Pages Found");
706 @ <ul>
707 db_prepare(&q,
708 "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%' ORDER BY lower(tagname)" ,
 
709 zTitle);
710 while( db_step(&q)==SQLITE_ROW ){
711 const char *zName = db_column_text(&q, 0);
712 @ <li><a href="%s(g.zBaseURL)/wiki?name=%T(zName)">%h(zName)</a></li>
713 }
@@ -1027,11 +1028,11 @@
1027 }else
1028 if( strncmp(g.argv[2],"list",n)==0 ){
1029 Stmt q;
1030 db_prepare(&q,
1031 "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1032 " ORDER BY lower(tagname)"
1033 );
1034 while( db_step(&q)==SQLITE_ROW ){
1035 const char *zName = db_column_text(&q, 0);
1036 printf( "%s\n",zName);
1037 }
1038
--- src/wiki.c
+++ src/wiki.c
@@ -672,11 +672,11 @@
672 db_prepare(&q,
673 "SELECT"
674 " substr(tagname, 6),"
675 " (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC)"
676 " FROM tag WHERE tagname GLOB 'wiki-*'"
677 " ORDER BY lower(tagname) /*sort*/"
678 );
679 while( db_step(&q)==SQLITE_ROW ){
680 const char *zName = db_column_text(&q, 0);
681 int size = db_column_int(&q, 1);
682 if( size>0 ){
@@ -703,11 +703,12 @@
703 if( !g.okRdWiki ){ login_needed(); return; }
704 zTitle = PD("title","*");
705 style_header("Wiki Pages Found");
706 @ <ul>
707 db_prepare(&q,
708 "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
709 " ORDER BY lower(tagname) /*sort*/" ,
710 zTitle);
711 while( db_step(&q)==SQLITE_ROW ){
712 const char *zName = db_column_text(&q, 0);
713 @ <li><a href="%s(g.zBaseURL)/wiki?name=%T(zName)">%h(zName)</a></li>
714 }
@@ -1027,11 +1028,11 @@
1028 }else
1029 if( strncmp(g.argv[2],"list",n)==0 ){
1030 Stmt q;
1031 db_prepare(&q,
1032 "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1033 " ORDER BY lower(tagname) /*sort*/"
1034 );
1035 while( db_step(&q)==SQLITE_ROW ){
1036 const char *zName = db_column_text(&q, 0);
1037 printf( "%s\n",zName);
1038 }
1039

Keyboard Shortcuts

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