/ Check-in [2aef4181]
Login

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

Overview
Comment:Fix a couple of issues in incremental_index_check to do with CREATE INDEX statements that contain embedded SQL comments.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | checkindex
Files: files | file ages | folders
SHA3-256: 2aef41815a9f1786ebdf09d8f6cfa59a8e7d733253eafeae24fa6e2a093bb1d8
User & Date: dan 2017-10-31 12:01:01
Context
2017-10-31
15:49
Add build infrastructure for the sqlite3_checker command-line utility. check-in: 429e3c3c user: drh tags: checkindex
12:01
Fix a couple of issues in incremental_index_check to do with CREATE INDEX statements that contain embedded SQL comments. check-in: 2aef4181 user: dan tags: checkindex
2017-10-30
19:38
Add support for indexes on expressions to incremental_index_check. check-in: 8c1c701f user: dan tags: checkindex
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/repair/checkindex.c.

   270    270       for(i=0; i<pIdx->nCol; i++){
   271    271         sqlite3_free(pIdx->aCol[i].zExpr);
   272    272       }
   273    273       sqlite3_free(pIdx);
   274    274     }
   275    275   }
   276    276   
   277         -#define CIDX_PARSE_EOF   0
   278         -#define CIDX_PARSE_COMMA 1      /*  "," */
   279         -#define CIDX_PARSE_OPEN  2      /*  "(" */
   280         -#define CIDX_PARSE_CLOSE 3      /*  ")" */
   281         -
   282         -static int cidxFindNext(const char *zIn, const char **pzOut){
   283         -  const char *z = zIn;
   284         -
   285         -  while( 1 ){
   286         -    *pzOut = z;
   287         -    switch( *z ){
   288         -      case '\0':
   289         -        return CIDX_PARSE_EOF;
   290         -      case '(':
   291         -        return CIDX_PARSE_OPEN;
   292         -      case ')':
   293         -        return CIDX_PARSE_CLOSE;
   294         -      case ',':
   295         -        return CIDX_PARSE_COMMA;
   296         -
   297         -      case '"': 
   298         -      case '\'': 
   299         -      case '`': {
   300         -        char q = *z;
   301         -        z++;
   302         -        while( *z ){
   303         -          if( *z==q ){
   304         -            z++;
   305         -            if( *z!=q ) break;
   306         -          }
   307         -          z++;
   308         -        }
   309         -        break;
   310         -      }
   311         -
   312         -      case '[':
   313         -        while( *z++!=']' );
   314         -        break;
   315         -
   316         -      default:
   317         -        z++;
   318         -    }
   319         -  }
   320         -
   321         -  assert( 0 );
   322         -  return -1;
   323         -}
   324         -
   325    277   static int cidx_isspace(char c){
   326    278     return c==' ' || c=='\t' || c=='\r' || c=='\n';
   327    279   }
   328    280   
   329    281   static int cidx_isident(char c){
   330    282     return c<0 
   331    283       || (c>='0' && c<='9') || (c>='a' && c<='z') 
   332    284       || (c>='A' && c<='Z') || c=='_';
   333    285   }
          286  +
          287  +#define CIDX_PARSE_EOF   0
          288  +#define CIDX_PARSE_COMMA 1      /*  "," */
          289  +#define CIDX_PARSE_OPEN  2      /*  "(" */
          290  +#define CIDX_PARSE_CLOSE 3      /*  ")" */
          291  +
          292  +static int cidxFindNext(
          293  +  const char *zIn, 
          294  +  const char **pzOut,
          295  +  int *pbDoNotTrim                /* OUT: True if prev is -- comment */
          296  +){
          297  +  const char *z = zIn;
          298  +
          299  +  while( 1 ){
          300  +    if( z[0]=='-' && z[1]=='-' ){
          301  +      z += 2;
          302  +      while( z[0]!='\n' ){
          303  +        if( z[0]=='\0' ) return CIDX_PARSE_EOF;
          304  +        z++;
          305  +      }
          306  +      while( cidx_isspace(*z) ) z++;
          307  +      *pbDoNotTrim = 1;
          308  +    }else{
          309  +      *pzOut = z;
          310  +      switch( *z ){
          311  +        case '\0':
          312  +          return CIDX_PARSE_EOF;
          313  +        case '(':
          314  +          return CIDX_PARSE_OPEN;
          315  +        case ')':
          316  +          return CIDX_PARSE_CLOSE;
          317  +        case ',':
          318  +          return CIDX_PARSE_COMMA;
          319  +  
          320  +        case '"': 
          321  +        case '\'': 
          322  +        case '`': {
          323  +          char q = *z;
          324  +          z++;
          325  +          while( *z ){
          326  +            if( *z==q ){
          327  +              z++;
          328  +              if( *z!=q ) break;
          329  +            }
          330  +            z++;
          331  +          }
          332  +          break;
          333  +        }
          334  +  
          335  +        case '[':
          336  +          while( *z++!=']' );
          337  +          break;
          338  +  
          339  +        case '/':
          340  +          if( z[1]=='*' ){
          341  +            z += 2;
          342  +            while( z[0]!='*' || z[1]!='/' ){
          343  +              if( z[1]=='\0' ) return CIDX_PARSE_EOF;
          344  +              z++;
          345  +            }
          346  +            z += 2;
          347  +            break;
          348  +          }
          349  +  
          350  +        default:
          351  +          z++;
          352  +          break;
          353  +      }
          354  +      *pbDoNotTrim = 0;
          355  +    }
          356  +  }
          357  +
          358  +  assert( 0 );
          359  +  return -1;
          360  +}
   334    361   
   335    362   static int cidxParseSQL(CidxCursor *pCsr, CidxIndex *pIdx, const char *zSql){
   336    363     const char *z = zSql;
   337    364     const char *z1;
   338    365     int e;
   339    366     int rc = SQLITE_OK;
   340    367     int nParen = 1;
          368  +  int bDoNotTrim = 0;
   341    369     CidxColumn *pCol = pIdx->aCol;
   342    370   
   343         -  e = cidxFindNext(z, &z);
          371  +  e = cidxFindNext(z, &z, &bDoNotTrim);
   344    372     if( e!=CIDX_PARSE_OPEN ) goto parse_error;
   345    373     z1 = z+1;
   346    374     z++;
   347    375     while( nParen>0 ){
   348         -    e = cidxFindNext(z, &z);
          376  +    e = cidxFindNext(z, &z, &bDoNotTrim);
   349    377       if( e==CIDX_PARSE_EOF ) goto parse_error;
   350    378       if( (e==CIDX_PARSE_COMMA || e==CIDX_PARSE_CLOSE) && nParen==1 ){
   351    379         const char *z2 = z;
   352    380         if( pCol->zExpr ) goto parse_error;
   353    381   
   354         -      while( cidx_isspace(z[-1]) ) z--;
   355         -      if( 0==sqlite3_strnicmp(&z[-3], "asc", 3) && 0==cidx_isident(z[-4]) ){
   356         -        z -= 3;
          382  +      if( bDoNotTrim==0 ){
   357    383           while( cidx_isspace(z[-1]) ) z--;
   358         -      }else
   359         -      if( 0==sqlite3_strnicmp(&z[-4], "desc", 4) && 0==cidx_isident(z[-5]) ){
   360         -        z -= 4;
   361         -        while( cidx_isspace(z[-1]) ) z--;
          384  +        if( !sqlite3_strnicmp(&z[-3], "asc", 3) && 0==cidx_isident(z[-4]) ){
          385  +          z -= 3;
          386  +          while( cidx_isspace(z[-1]) ) z--;
          387  +        }else
          388  +          if( !sqlite3_strnicmp(&z[-4], "desc", 4) && 0==cidx_isident(z[-5]) ){
          389  +            z -= 4;
          390  +            while( cidx_isspace(z[-1]) ) z--;
          391  +          }
          392  +        while( cidx_isspace(z1[0]) ) z1++;
   362    393         }
   363    394   
   364         -      while( cidx_isspace(z1[0]) ) z1++;
   365    395         pCol->zExpr = cidxMprintf(&rc, "%.*s", z-z1, z1);
   366    396         pCol++;
   367    397         z = z1 = z2+1;
   368    398       }
   369    399       if( e==CIDX_PARSE_OPEN ) nParen++;
   370    400       if( e==CIDX_PARSE_CLOSE ) nParen--;
   371    401       z++;

Changes to test/checkindex.test.

   314    314     {row missing} {'{"w":4, "z":4}',4} 
   315    315     {row data mismatch} {'{"x":1, "y":1}',1} 
   316    316     {} {'{"x":2, "y":2}',2} 
   317    317     {} {'{"x":3, "y":3}',3} 
   318    318     {} {'{"x":5, "y":5}',5}
   319    319   }
   320    320   
          321  +#-------------------------------------------------------------------------
          322  +#
          323  +do_execsql_test 6.0 {
          324  +  CREATE TABLE t6(x INTEGER PRIMARY KEY, y, z);
          325  +  CREATE INDEX t6x1 ON t6(y, /* one,two,three */ z);
          326  +  CREATE INDEX t6x2 ON t6(z, -- hello,world,
          327  +  y);
          328  +
          329  +  CREATE INDEX t6x3 ON t6(z -- hello,world
          330  +  , y);
          331  +
          332  +  INSERT INTO t6 VALUES(1, 2, 3);
          333  +  INSERT INTO t6 VALUES(4, 5, 6);
          334  +}
          335  +
          336  +do_index_check_test 6.1 t6x1 {
          337  +  {} 2,3,1 
          338  +  {} 5,6,4
          339  +}
          340  +do_index_check_test 6.2 t6x2 {
          341  +  {} 3,2,1 
          342  +  {} 6,5,4
          343  +}
          344  +do_index_check_test 6.2 t6x3 {
          345  +  {} 3,2,1 
          346  +  {} 6,5,4
          347  +}
   321    348   
   322    349   finish_test
   323    350