]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The COMPLETION virtual table now looks at the names of databases, tables,
authordrh <drh@noemail.net>
Tue, 11 Jul 2017 01:38:45 +0000 (01:38 +0000)
committerdrh <drh@noemail.net>
Tue, 11 Jul 2017 01:38:45 +0000 (01:38 +0000)
and columns in addition to SQL keywords.

FossilOrigin-Name: 1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef

ext/misc/completion.c
manifest
manifest.uuid

index f4cd1b91b7f5353a5f598bf2717779eb362028eb..ae11ef4220498348f7da3b434795ec095a6d36f6 100644 (file)
@@ -54,7 +54,7 @@ struct completion_cursor {
 
 /* Values for ePhase:
 */
-#define COMPLETION_FIRST_PHASE   0
+#define COMPLETION_FIRST_PHASE   1
 #define COMPLETION_KEYWORDS      1
 #define COMPLETION_PRAGMAS       2
 #define COMPLETION_FUNCTIONS     3
@@ -63,8 +63,9 @@ struct completion_cursor {
 #define COMPLETION_TRIGGERS      6
 #define COMPLETION_DATABASES     7
 #define COMPLETION_TABLES        8
-#define COMPLETION_MODULES       9
-#define COMPLETION_LAST_PHASE    10
+#define COMPLETION_COLUMNS       9
+#define COMPLETION_MODULES       10
+#define COMPLETION_EOF           11
 
 /*
 ** The completionConnect() method is invoked to create a new
@@ -138,6 +139,7 @@ static void completionCursorReset(completion_cursor *pCur){
   sqlite3_free(pCur->zPrefix);   pCur->zPrefix = 0;  pCur->nPrefix = 0;
   sqlite3_free(pCur->zLine);     pCur->zLine = 0;    pCur->nLine = 0;
   sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
+  pCur->j = 0;
 }
 
 /*
@@ -178,28 +180,103 @@ static const char *completionKwrds[] = {
 */
 static int completionNext(sqlite3_vtab_cursor *cur){
   completion_cursor *pCur = (completion_cursor*)cur;
+  int eNextPhase = 0;/* Next phase to try if current phase reaches end */
+  int iCol = -1;     /* If >=0 then step pCur->pStmt and use the i-th column */
   pCur->iRowid++;
-  if( pCur->ePhase==COMPLETION_FIRST_PHASE ){
-    pCur->ePhase = COMPLETION_KEYWORDS;
-    pCur->j = -1;
-  }
-  if( pCur->ePhase==COMPLETION_KEYWORDS ){
-    while(1){
-      const char *z;
-      pCur->j++;
-      if( pCur->j >=  sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){
-        pCur->ePhase = COMPLETION_LAST_PHASE;
+  while( pCur->ePhase!=COMPLETION_EOF ){
+    switch( pCur->ePhase ){
+      case COMPLETION_KEYWORDS: {
+        if( pCur->j >=  sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){
+          pCur->zCurrentRow = 0;
+          pCur->ePhase = COMPLETION_DATABASES;
+        }else{
+          pCur->zCurrentRow = completionKwrds[pCur->j++];
+        }
+        iCol = -1;
+        break;
+      }
+      case COMPLETION_DATABASES: {
+        if( pCur->pStmt==0 ){
+          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
+                             &pCur->pStmt, 0);
+        }
+        iCol = 1;
+        eNextPhase = COMPLETION_TABLES;
+        break;
+      }
+      case COMPLETION_TABLES: {
+        if( pCur->pStmt==0 ){
+          sqlite3_stmt *pS2;
+          char *zSql = 0;
+          const char *zSep = "";
+          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
+          while( sqlite3_step(pS2)==SQLITE_ROW ){
+            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+            zSql = sqlite3_mprintf(
+               "%z%s"
+               "SELECT name FROM \"%w\".sqlite_master"
+               " WHERE type='table'",
+               zSql, zSep, zDb
+            );
+            if( zSql==0 ) return SQLITE_NOMEM;
+            zSep = " UNION ";
+          }
+          sqlite3_finalize(pS2);
+          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
+          sqlite3_free(zSql);
+        }
+        iCol = 0;
+        eNextPhase = COMPLETION_COLUMNS;
         break;
       }
-      z = completionKwrds[pCur->j];
-      if( pCur->nPrefix==0 
-       || sqlite3_strnicmp(pCur->zPrefix, z, pCur->nPrefix)==0
-      ){
-        pCur->zCurrentRow = z;
+      case COMPLETION_COLUMNS: {
+        if( pCur->pStmt==0 ){
+          sqlite3_stmt *pS2;
+          char *zSql = 0;
+          const char *zSep = "";
+          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
+          while( sqlite3_step(pS2)==SQLITE_ROW ){
+            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+            zSql = sqlite3_mprintf(
+               "%z%s"
+               "SELECT pti.name FROM \"%w\".sqlite_master AS sm"
+                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
+               " WHERE sm.type='table'",
+               zSql, zSep, zDb, zDb
+            );
+            if( zSql==0 ) return SQLITE_NOMEM;
+            zSep = " UNION ";
+          }
+          sqlite3_finalize(pS2);
+          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
+          sqlite3_free(zSql);
+        }
+        iCol = 0;
+        eNextPhase = COMPLETION_EOF;
         break;
       }
     }
+    if( iCol<0 ){
+      /* This case is when the phase presets zCurrentRow */
+      if( pCur->zCurrentRow==0 ) continue;
+    }else{
+      if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
+        /* Extract the next row of content */
+        pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
+      }else{
+        /* When all rows are finished, advance to the next phase */
+        sqlite3_finalize(pCur->pStmt);
+        pCur->pStmt = 0;
+        pCur->ePhase = eNextPhase;
+        continue;
+      }
+    }
+    if( pCur->nPrefix==0 ) break;
+    if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){
+      break;
+    }
   }
+
   return SQLITE_OK;
 }
 
@@ -246,7 +323,7 @@ static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
 */
 static int completionEof(sqlite3_vtab_cursor *cur){
   completion_cursor *pCur = (completion_cursor*)cur;
-  return pCur->ePhase >= COMPLETION_LAST_PHASE;
+  return pCur->ePhase >= COMPLETION_EOF;
 }
 
 /*
index 1325b5b8ae6695890a30174891397736cd37d593..2900651ce016d9e6f6c9e0bf5979fda02537b171 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Incomplete\simplementation\sof\sthe\sCOMPLETION\stable-valued\sfunction.\s\sSo\sfar\sit\nonly\sworks\sfor\sSQL\skeywords.
-D 2017-07-11T00:09:44.330
+C The\sCOMPLETION\svirtual\stable\snow\slooks\sat\sthe\snames\sof\sdatabases,\stables,\nand\scolumns\sin\saddition\sto\sSQL\skeywords.
+D 2017-07-11T01:38:45.049
 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba
@@ -256,7 +256,7 @@ F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5df
 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d
 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
-F ext/misc/completion.c 1b58092f73e9c6025d055b5e01f22273f378de2bf3a1db0d6b5dfe79dddce5f7
+F ext/misc/completion.c 813c7faecc8fe3dd5c5503b87d4bb44ed6b841ff3398d19fbccec251da0af25f
 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2
 F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e
@@ -1629,7 +1629,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P bd8a1fb9b33418717c786a7275f636cd4d5facd66de9a416f948b61c6490c743
-R c31437c94c579e099f5c663f8abfebe7
+P caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09
+R 1115796824efacad1a0f50faf8b6a73d
 U drh
-Z 2bab86907269899ac4b24013169de866
+Z e368c5a978df04c5e378d21fe41e060f
index ec03a9d9636f8cac6861fd48d6089729f70d2e56..d37dfde6102dbda4fb1fe7d66e8f78fb86a33c14 100644 (file)
@@ -1 +1 @@
-caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09
\ No newline at end of file
+1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef
\ No newline at end of file