/ Check-in [d8254047]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Get sqlite3_expert building on Windows.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | schemalint
Files: files | file ages | folders
SHA3-256: d8254047b30f7c1be486bf39d4420678604573b951b5cc83c19ebf74aba0864c
User & Date: drh 2017-05-03 12:50:46
Context
2017-05-03
13:05
Fix a harmless compiler warning on Windows. check-in: 593e5dd0 user: drh tags: schemalint
12:50
Get sqlite3_expert building on Windows. check-in: d8254047 user: drh tags: schemalint
12:15
In sqlite3expert.c, do not copy the schema for virtual tables. Updates to makefiles to make building easier. check-in: da15752d user: drh tags: schemalint
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.msc.

  1395   1395     $(TOP)\ext\fts3\fts3_test.c \
  1396   1396     $(TOP)\ext\rbu\test_rbu.c \
  1397   1397     $(TOP)\ext\session\test_session.c
  1398   1398   
  1399   1399   # Statically linked extensions.
  1400   1400   #
  1401   1401   TESTEXT = \
         1402  +  $(TOP)\ext\expert\sqlite3expert.c \
         1403  +  $(TOP)\ext\expert\test_expert.c \
  1402   1404     $(TOP)\ext\misc\amatch.c \
  1403   1405     $(TOP)\ext\misc\carray.c \
  1404   1406     $(TOP)\ext\misc\closure.c \
  1405   1407     $(TOP)\ext\misc\csv.c \
  1406   1408     $(TOP)\ext\misc\eval.c \
  1407   1409     $(TOP)\ext\misc\fileio.c \
  1408   1410     $(TOP)\ext\misc\fuzzer.c \
................................................................................
  2176   2178   	echo static const char *zMainloop = >> $@
  2177   2179   	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  2178   2180   	echo ; return zMainloop; } >> $@
  2179   2181   
  2180   2182   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  2181   2183   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  2182   2184   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2185  +
         2186  +sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c
         2187  +	$(LTLINK) $(NO_WARN)	$(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS)
         2188  +
         2189  +sqlite3_schemalint.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\schemalint.tcl $(SQLITE_TCL_DEP)
         2190  +	echo "#define TCLSH 2" > $@
         2191  +	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
         2192  +	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c >> $@
         2193  +	echo "static const char *tclsh_main_loop(void){" >> $@
         2194  +	echo "static const char *zMainloop = " >> $@
         2195  +	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\schemalint.tcl >> $@
         2196  +	echo "; return zMainloop; }" >> $@
         2197  +
         2198  +sqlite3_schemalint.exe: $(TESTSRC) sqlite3_schemalint.c
         2199  +	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_schemalint.c \
         2200  +		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  2183   2201   
  2184   2202   dbdump.exe:	$(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
  2185   2203   	$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
  2186   2204   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
  2187   2205   
  2188   2206   testloadext.lo:	$(TOP)\src\test_loadext.c
  2189   2207   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c

Changes to ext/expert/expert.c.

    90     90     if( p==0 ){
    91     91       fprintf(stderr, "Cannot run analysis: %s\n", zErr);
    92     92       rc = 1;
    93     93     }else{
    94     94       for(i=1; i<(argc-1); i++){
    95     95         char *zArg = argv[i];
    96     96         if( zArg[0]=='-' && zArg[1]=='-' && zArg[2]!=0 ) zArg++;
    97         -      int nArg = strlen(zArg);
           97  +      int nArg = (int)strlen(zArg);
    98     98         if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-file", nArg) ){
    99     99           if( ++i==(argc-1) ) option_requires_argument("-file");
   100    100           rc = readSqlFromFile(p, argv[i], &zErr);
   101    101         }
   102    102   
   103    103         else if( nArg>=3 && 0==sqlite3_strnicmp(zArg, "-sql", nArg) ){
   104    104           if( ++i==(argc-1) ) option_requires_argument("-sql");

Changes to ext/expert/sqlite3expert.c.

    21     21   typedef struct IdxColumn IdxColumn;
    22     22   typedef struct IdxConstraint IdxConstraint;
    23     23   typedef struct IdxScan IdxScan;
    24     24   typedef struct IdxStatement IdxStatement;
    25     25   typedef struct IdxTable IdxTable;
    26     26   typedef struct IdxWrite IdxWrite;
    27     27   
           28  +#define STRLEN  (int)strlen
           29  +
    28     30   /*
    29     31   ** A temp table name that we assume no user database will actually use.
    30     32   ** If this assumption proves incorrect triggers on the table with the
    31     33   ** conflicting name will be ignored.
    32     34   */
    33     35   #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
    34     36   
................................................................................
   208    210   */
   209    211   static int idxHashAdd(
   210    212     int *pRc, 
   211    213     IdxHash *pHash, 
   212    214     const char *zKey,
   213    215     const char *zVal
   214    216   ){
   215         -  int nKey = strlen(zKey);
          217  +  int nKey = STRLEN(zKey);
   216    218     int iHash = idxHashString(zKey, nKey);
   217         -  int nVal = (zVal ? strlen(zVal) : 0);
          219  +  int nVal = (zVal ? STRLEN(zVal) : 0);
   218    220     IdxHashEntry *pEntry;
   219    221     assert( iHash>=0 );
   220    222     for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
   221         -    if( strlen(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
          223  +    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
   222    224         return 1;
   223    225       }
   224    226     }
   225    227     pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
   226    228     if( pEntry ){
   227    229       pEntry->zKey = (char*)&pEntry[1];
   228    230       memcpy(pEntry->zKey, zKey, nKey);
................................................................................
   242    244   /*
   243    245   ** If zKey/nKey is present in the hash table, return a pointer to the 
   244    246   ** hash-entry object.
   245    247   */
   246    248   static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
   247    249     int iHash;
   248    250     IdxHashEntry *pEntry;
   249         -  if( nKey<0 ) nKey = strlen(zKey);
          251  +  if( nKey<0 ) nKey = STRLEN(zKey);
   250    252     iHash = idxHashString(zKey, nKey);
   251    253     assert( iHash>=0 );
   252    254     for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
   253         -    if( strlen(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
          255  +    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
   254    256         return pEntry;
   255    257       }
   256    258     }
   257    259     return 0;
   258    260   }
   259    261   
   260    262   /*
................................................................................
   271    273   
   272    274   /*
   273    275   ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
   274    276   ** variable to point to a copy of nul-terminated string zColl.
   275    277   */
   276    278   static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
   277    279     IdxConstraint *pNew;
   278         -  int nColl = strlen(zColl);
          280  +  int nColl = STRLEN(zColl);
   279    281   
   280    282     assert( *pRc==SQLITE_OK );
   281    283     pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
   282    284     if( pNew ){
   283    285       pNew->zColl = (char*)&pNew[1];
   284    286       memcpy(pNew->zColl, zColl, nColl+1);
   285    287     }
................................................................................
   353    355   typedef struct ExpertCsr ExpertCsr;
   354    356   struct ExpertCsr {
   355    357     sqlite3_vtab_cursor base;
   356    358     sqlite3_stmt *pData;
   357    359   };
   358    360   
   359    361   static char *expertDequote(const char *zIn){
   360         -  int n = strlen(zIn);
          362  +  int n = STRLEN(zIn);
   361    363     char *zRet = sqlite3_malloc(n);
   362    364   
   363    365     assert( zIn[0]=='\'' );
   364    366     assert( zIn[n-1]=='\'' );
   365    367   
   366    368     if( zRet ){
   367    369       int iOut = 0;
................................................................................
   662    664     sqlite3 *db,                    /* Database connection to read details from */
   663    665     const char *zTab,               /* Table name */
   664    666     IdxTable **ppOut,               /* OUT: New object (if successful) */
   665    667     char **pzErrmsg                 /* OUT: Error message (if not) */
   666    668   ){
   667    669     sqlite3_stmt *p1 = 0;
   668    670     int nCol = 0;
   669         -  int nTab = strlen(zTab);
          671  +  int nTab = STRLEN(zTab);
   670    672     int nByte = sizeof(IdxTable) + nTab + 1;
   671    673     IdxTable *pNew = 0;
   672    674     int rc, rc2;
   673    675     char *pCsr = 0;
   674    676   
   675    677     rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
   676    678     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
   677    679       const char *zCol = (const char*)sqlite3_column_text(p1, 1);
   678         -    nByte += 1 + strlen(zCol);
          680  +    nByte += 1 + STRLEN(zCol);
   679    681       rc = sqlite3_table_column_metadata(
   680    682           db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
   681    683       );
   682         -    nByte += 1 + strlen(zCol);
          684  +    nByte += 1 + STRLEN(zCol);
   683    685       nCol++;
   684    686     }
   685    687     rc2 = sqlite3_reset(p1);
   686    688     if( rc==SQLITE_OK ) rc = rc2;
   687    689   
   688    690     nByte += sizeof(IdxColumn) * nCol;
   689    691     if( rc==SQLITE_OK ){
................................................................................
   694    696       pNew->nCol = nCol;
   695    697       pCsr = (char*)&pNew->aCol[nCol];
   696    698     }
   697    699   
   698    700     nCol = 0;
   699    701     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
   700    702       const char *zCol = (const char*)sqlite3_column_text(p1, 1);
   701         -    int nCopy = strlen(zCol) + 1;
          703  +    int nCopy = STRLEN(zCol) + 1;
   702    704       pNew->aCol[nCol].zName = pCsr;
   703    705       pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
   704    706       memcpy(pCsr, zCol, nCopy);
   705    707       pCsr += nCopy;
   706    708   
   707    709       rc = sqlite3_table_column_metadata(
   708    710           db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
   709    711       );
   710    712       if( rc==SQLITE_OK ){
   711         -      nCopy = strlen(zCol) + 1;
          713  +      nCopy = STRLEN(zCol) + 1;
   712    714         pNew->aCol[nCol].zColl = pCsr;
   713    715         memcpy(pCsr, zCol, nCopy);
   714    716         pCsr += nCopy;
   715    717       }
   716    718   
   717    719       nCol++;
   718    720     }
................................................................................
   739    741   ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
   740    742   ** zIn before returning.
   741    743   */
   742    744   static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
   743    745     va_list ap;
   744    746     char *zAppend = 0;
   745    747     char *zRet = 0;
   746         -  int nIn = zIn ? strlen(zIn) : 0;
          748  +  int nIn = zIn ? STRLEN(zIn) : 0;
   747    749     int nAppend = 0;
   748    750     va_start(ap, zFmt);
   749    751     if( *pRc==SQLITE_OK ){
   750    752       zAppend = sqlite3_vmprintf(zFmt, ap);
   751    753       if( zAppend ){
   752         -      nAppend = strlen(zAppend);
          754  +      nAppend = STRLEN(zAppend);
   753    755         zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
   754    756       }
   755    757       if( zAppend && zRet ){
   756    758         memcpy(zRet, zIn, nIn);
   757    759         memcpy(&zRet[nIn], zAppend, nAppend+1);
   758    760       }else{
   759    761         sqlite3_free(zRet);
................................................................................
  1110   1112           "EXPLAIN QUERY PLAN %s", pStmt->zSql
  1111   1113       );
  1112   1114       while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
  1113   1115         int iSelectid = sqlite3_column_int(pExplain, 0);
  1114   1116         int iOrder = sqlite3_column_int(pExplain, 1);
  1115   1117         int iFrom = sqlite3_column_int(pExplain, 2);
  1116   1118         const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
  1117         -      int nDetail = strlen(zDetail);
         1119  +      int nDetail = STRLEN(zDetail);
  1118   1120         int i;
  1119   1121   
  1120   1122         for(i=0; i<nDetail; i++){
  1121   1123           const char *zIdx = 0;
  1122   1124           if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
  1123   1125             zIdx = &zDetail[i+13];
  1124   1126           }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
................................................................................
  1573   1575         sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
  1574   1576         sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
  1575   1577         sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
  1576   1578         sqlite3_step(pWriteStat);
  1577   1579         rc = sqlite3_reset(pWriteStat);
  1578   1580       }
  1579   1581   
  1580         -    pEntry = idxHashFind(&p->hIdx, zIdx, strlen(zIdx));
         1582  +    pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
  1581   1583       if( pEntry ){
  1582   1584         assert( pEntry->zVal2==0 );
  1583   1585         pEntry->zVal2 = zStat;
  1584   1586       }else{
  1585   1587         sqlite3_free(zStat);
  1586   1588       }
  1587   1589     }
................................................................................
  1812   1814     while( rc==SQLITE_OK && zStmt && zStmt[0] ){
  1813   1815       sqlite3_stmt *pStmt = 0;
  1814   1816       rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
  1815   1817       if( rc==SQLITE_OK ){
  1816   1818         if( pStmt ){
  1817   1819           IdxStatement *pNew;
  1818   1820           const char *z = sqlite3_sql(pStmt);
  1819         -        int n = strlen(z);
         1821  +        int n = STRLEN(z);
  1820   1822           pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
  1821   1823           if( rc==SQLITE_OK ){
  1822   1824             pNew->zSql = (char*)&pNew[1];
  1823   1825             memcpy(pNew->zSql, z, n+1);
  1824   1826             pNew->pNext = p->pStatement;
  1825   1827             if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
  1826   1828             p->pStatement = pNew;