SQLite

Check-in [2aef41815a]
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
Timelines: family | ancestors | descendants | both | checkindex
Files: files | file ages | folders
SHA3-256: 2aef41815a9f1786ebdf09d8f6cfa59a8e7d733253eafeae24fa6e2a093bb1d8
User & Date: dan 2017-10-31 12:01:01.861
Context
2017-10-31
15:49
Add build infrastructure for the sqlite3_checker command-line utility. (check-in: 429e3c3c85 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: 2aef41815a user: dan tags: checkindex)
2017-10-30
19:38
Add support for indexes on expressions to incremental_index_check. (check-in: 8c1c701fdb user: dan tags: checkindex)
Changes
Unified Diff Show Whitespace Changes Patch
Changes to ext/repair/checkindex.c.
269
270
271
272
273
274
275










276
277
278
279
280
281
282




283
284
285









286
287
288
289
290
291
292
    int i;
    for(i=0; i<pIdx->nCol; i++){
      sqlite3_free(pIdx->aCol[i].zExpr);
    }
    sqlite3_free(pIdx);
  }
}











#define CIDX_PARSE_EOF   0
#define CIDX_PARSE_COMMA 1      /*  "," */
#define CIDX_PARSE_OPEN  2      /*  "(" */
#define CIDX_PARSE_CLOSE 3      /*  ")" */

static int cidxFindNext(const char *zIn, const char **pzOut){




  const char *z = zIn;

  while( 1 ){









    *pzOut = z;
    switch( *z ){
      case '\0':
        return CIDX_PARSE_EOF;
      case '(':
        return CIDX_PARSE_OPEN;
      case ')':







>
>
>
>
>
>
>
>
>
>






|
>
>
>
>



>
>
>
>
>
>
>
>
>







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    int i;
    for(i=0; i<pIdx->nCol; i++){
      sqlite3_free(pIdx->aCol[i].zExpr);
    }
    sqlite3_free(pIdx);
  }
}

static int cidx_isspace(char c){
  return c==' ' || c=='\t' || c=='\r' || c=='\n';
}

static int cidx_isident(char c){
  return c<0 
    || (c>='0' && c<='9') || (c>='a' && c<='z') 
    || (c>='A' && c<='Z') || c=='_';
}

#define CIDX_PARSE_EOF   0
#define CIDX_PARSE_COMMA 1      /*  "," */
#define CIDX_PARSE_OPEN  2      /*  "(" */
#define CIDX_PARSE_CLOSE 3      /*  ")" */

static int cidxFindNext(
  const char *zIn, 
  const char **pzOut,
  int *pbDoNotTrim                /* OUT: True if prev is -- comment */
){
  const char *z = zIn;

  while( 1 ){
    if( z[0]=='-' && z[1]=='-' ){
      z += 2;
      while( z[0]!='\n' ){
        if( z[0]=='\0' ) return CIDX_PARSE_EOF;
        z++;
      }
      while( cidx_isspace(*z) ) z++;
      *pbDoNotTrim = 1;
    }else{
    *pzOut = z;
    switch( *z ){
      case '\0':
        return CIDX_PARSE_EOF;
      case '(':
        return CIDX_PARSE_OPEN;
      case ')':
308
309
310
311
312
313
314











315
316
317



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
        }
        break;
      }

      case '[':
        while( *z++!=']' );
        break;












      default:
        z++;



    }
  }

  assert( 0 );
  return -1;
}

static int cidx_isspace(char c){
  return c==' ' || c=='\t' || c=='\r' || c=='\n';
}

static int cidx_isident(char c){
  return c<0 
    || (c>='0' && c<='9') || (c>='a' && c<='z') 
    || (c>='A' && c<='Z') || c=='_';
}

static int cidxParseSQL(CidxCursor *pCsr, CidxIndex *pIdx, const char *zSql){
  const char *z = zSql;
  const char *z1;
  int e;
  int rc = SQLITE_OK;
  int nParen = 1;

  CidxColumn *pCol = pIdx->aCol;

  e = cidxFindNext(z, &z);
  if( e!=CIDX_PARSE_OPEN ) goto parse_error;
  z1 = z+1;
  z++;
  while( nParen>0 ){
    e = cidxFindNext(z, &z);
    if( e==CIDX_PARSE_EOF ) goto parse_error;
    if( (e==CIDX_PARSE_COMMA || e==CIDX_PARSE_CLOSE) && nParen==1 ){
      const char *z2 = z;
      if( pCol->zExpr ) goto parse_error;


      while( cidx_isspace(z[-1]) ) z--;
      if( 0==sqlite3_strnicmp(&z[-3], "asc", 3) && 0==cidx_isident(z[-4]) ){
        z -= 3;
        while( cidx_isspace(z[-1]) ) z--;
      }else
      if( 0==sqlite3_strnicmp(&z[-4], "desc", 4) && 0==cidx_isident(z[-5]) ){
        z -= 4;
        while( cidx_isspace(z[-1]) ) z--;
      }


      while( cidx_isspace(z1[0]) ) z1++;
      pCol->zExpr = cidxMprintf(&rc, "%.*s", z-z1, z1);
      pCol++;
      z = z1 = z2+1;
    }
    if( e==CIDX_PARSE_OPEN ) nParen++;
    if( e==CIDX_PARSE_CLOSE ) nParen--;
    z++;







>
>
>
>
>
>
>
>
>
>
>



>
>
>







<
<
<
<
<
<
<
<
<
<






>


|




|





>

|



|



>
|
|







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361










362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
        }
        break;
      }

      case '[':
        while( *z++!=']' );
        break;
  
        case '/':
          if( z[1]=='*' ){
            z += 2;
            while( z[0]!='*' || z[1]!='/' ){
              if( z[1]=='\0' ) return CIDX_PARSE_EOF;
              z++;
            }
            z += 2;
            break;
          }

      default:
        z++;
          break;
      }
      *pbDoNotTrim = 0;
    }
  }

  assert( 0 );
  return -1;
}











static int cidxParseSQL(CidxCursor *pCsr, CidxIndex *pIdx, const char *zSql){
  const char *z = zSql;
  const char *z1;
  int e;
  int rc = SQLITE_OK;
  int nParen = 1;
  int bDoNotTrim = 0;
  CidxColumn *pCol = pIdx->aCol;

  e = cidxFindNext(z, &z, &bDoNotTrim);
  if( e!=CIDX_PARSE_OPEN ) goto parse_error;
  z1 = z+1;
  z++;
  while( nParen>0 ){
    e = cidxFindNext(z, &z, &bDoNotTrim);
    if( e==CIDX_PARSE_EOF ) goto parse_error;
    if( (e==CIDX_PARSE_COMMA || e==CIDX_PARSE_CLOSE) && nParen==1 ){
      const char *z2 = z;
      if( pCol->zExpr ) goto parse_error;

      if( bDoNotTrim==0 ){
      while( cidx_isspace(z[-1]) ) z--;
        if( !sqlite3_strnicmp(&z[-3], "asc", 3) && 0==cidx_isident(z[-4]) ){
        z -= 3;
        while( cidx_isspace(z[-1]) ) z--;
      }else
          if( !sqlite3_strnicmp(&z[-4], "desc", 4) && 0==cidx_isident(z[-5]) ){
        z -= 4;
        while( cidx_isspace(z[-1]) ) z--;
      }
        while( cidx_isspace(z1[0]) ) z1++;
      }

      pCol->zExpr = cidxMprintf(&rc, "%.*s", z-z1, z1);
      pCol++;
      z = z1 = z2+1;
    }
    if( e==CIDX_PARSE_OPEN ) nParen++;
    if( e==CIDX_PARSE_CLOSE ) nParen--;
    z++;
Changes to test/checkindex.test.
314
315
316
317
318
319
320



























321
322
323
  {row missing} {'{"w":4, "z":4}',4} 
  {row data mismatch} {'{"x":1, "y":1}',1} 
  {} {'{"x":2, "y":2}',2} 
  {} {'{"x":3, "y":3}',3} 
  {} {'{"x":5, "y":5}',5}
}





























finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  {row missing} {'{"w":4, "z":4}',4} 
  {row data mismatch} {'{"x":1, "y":1}',1} 
  {} {'{"x":2, "y":2}',2} 
  {} {'{"x":3, "y":3}',3} 
  {} {'{"x":5, "y":5}',5}
}

#-------------------------------------------------------------------------
#
do_execsql_test 6.0 {
  CREATE TABLE t6(x INTEGER PRIMARY KEY, y, z);
  CREATE INDEX t6x1 ON t6(y, /* one,two,three */ z);
  CREATE INDEX t6x2 ON t6(z, -- hello,world,
  y);

  CREATE INDEX t6x3 ON t6(z -- hello,world
  , y);

  INSERT INTO t6 VALUES(1, 2, 3);
  INSERT INTO t6 VALUES(4, 5, 6);
}

do_index_check_test 6.1 t6x1 {
  {} 2,3,1 
  {} 5,6,4
}
do_index_check_test 6.2 t6x2 {
  {} 3,2,1 
  {} 6,5,4
}
do_index_check_test 6.2 t6x3 {
  {} 3,2,1 
  {} 6,5,4
}

finish_test