From: drh Date: Tue, 11 Jul 2017 01:38:45 +0000 (+0000) Subject: The COMPLETION virtual table now looks at the names of databases, tables, X-Git-Tag: version-3.20.0~82 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dc4dde6bd9ee6409ce5987e38f0e3d667f906679;p=thirdparty%2Fsqlite.git The COMPLETION virtual table now looks at the names of databases, tables, and columns in addition to SQL keywords. FossilOrigin-Name: 1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef --- diff --git a/ext/misc/completion.c b/ext/misc/completion.c index f4cd1b91b7..ae11ef4220 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -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; } /* diff --git a/manifest b/manifest index 1325b5b8ae..2900651ce0 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index ec03a9d963..d37dfde610 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09 \ No newline at end of file +1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef \ No newline at end of file