sqllogictest
Check-in [4e38bbb44f]
Not logged in

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

Overview
Comment:Add the "onlyif" condition prefix. Implement hash checking of skipped by labeled queries in verify mode.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:4e38bbb44fee7f16c4e42a5467d03c055cda5ebf
User & Date: drh 2008-12-06 02:02:31
Context
2008-12-06
02:37
Update the about.wiki page to talk about the new skipif and onlyif modifiers and how to use them to work around database incompatibilities. check-in: 816758c2ee user: drh tags: trunk
02:02
Add the "onlyif" condition prefix. Implement hash checking of skipped by labeled queries in verify mode. check-in: 4e38bbb44f user: drh tags: trunk
2008-12-05
23:09
Initial set of test files with "random" selects. slt_bad_*.proto produced different results on the engines, or didn't run at all. slt_good_*.proto produced exactly the same results with both SQLite and MSSQL, with mostly the same results on MySQL. Will be updating these to skip more tests MySQL has problems with. check-in: 2663d48f3c user: shaneh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/sqllogictest.c.

29
30
31
32
33
34
35

36
37
38
39
40
41
42
...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
...
445
446
447
448
449
450
451
452




453
454
455
456
457
458
459
460
461

462
463

464
465


466
467
468
469
470

471































472
473
474
475
476
477
478
...
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522

#include "sqllogictest.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef WIN32
#include <unistd.h>

#endif
#include <string.h>

#include "slt_sqlite.c"
#include "slt_odbc3.c"

#define DEFAULT_HASH_THRESHOLD 8
................................................................................
  int nErr = 0;                        /* Number of errors */
  int nCmd = 0;                        /* Number of SQL statements processed */
  int nSkipped = 0;                    /* Number of SQL statements skipped */
  int nResult;                         /* Number of query results */
  char **azResult;                     /* Query result vector */
  Script sScript;                      /* Script parsing status */
  FILE *in;                            /* For reading script */
  int hashThreshold = DEFAULT_HASH_THRESHOLD;  /* Hash result if this long or longer */
  int bHt = 0;                         /* Non-zero if a hash threshold option was */
                                       /* given on the command line. */

  /* Add calls to the registration procedures for new database engine
  ** interfaces here
  */
  registerSqlite();
#ifndef OMIT_ODBC
  registerODBC3();
................................................................................
    int bSkip = 0; /* True if we should skip the current record. */

    /* Tokenizer the first line of the record.  This also records the
    ** line number of the first record in sScript.startLine */
    tokenizeLine(&sScript);

    bSkip = 0;
    while( strcmp(sScript.azToken[0],"skipif")==0 ){




      /* This allows skipping a statement or query record for a 
      ** particular database engine.  In this way, SQL features
      ** implmented by a majority of the engines can be tested 
      ** without causing spurious errors for engines that don't
      ** support it.
      **
      ** Once this record is encountered, an the current selected
      ** db interface matches the db engine specified in the record,
      ** the we skip this rest of this record.

      */
      if( stricmp(sScript.azToken[1], zDbEngine)==0 ){

        bSkip = -1;
        break;


      }
      nextLine(&sScript);
      tokenizeLine(&sScript);
    }
    if( bSkip ) {

      nSkipped++;































      continue;
    }

    /* Figure out the record type and do appropriate processing */
    if( strcmp(sScript.azToken[0],"statement")==0 ){
      int k = 0;

................................................................................
        fprintf(stderr, "%s:%d: statement error\n",
                zScriptFile, sScript.startLine);
        nErr++;
      }
    }else if( strcmp(sScript.azToken[0],"query")==0 ){
      int k = 0;
      int c;
      char zHash[100];

      /* Verify that the type string consists of one or more characters
      ** from the set "TIR". */
      for(k=0; (c = sScript.azToken[1][k])!=0; k++){
        if( c!='T' && c!='I' && c!='R' ){
          fprintf(stderr, "%s:%d: unknown type character '%c' in type string\n",
                  zScriptFile, sScript.startLine, c);







>







 







|
|
|







 







|
>
>
>
>
|
<
|
|
|



|
>

|
>
|
<
>
>





>

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







 







<







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
...
446
447
448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
...
547
548
549
550
551
552
553

554
555
556
557
558
559
560

#include "sqllogictest.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef WIN32
#include <unistd.h>
#define stricmp strcasecmp
#endif
#include <string.h>

#include "slt_sqlite.c"
#include "slt_odbc3.c"

#define DEFAULT_HASH_THRESHOLD 8
................................................................................
  int nErr = 0;                        /* Number of errors */
  int nCmd = 0;                        /* Number of SQL statements processed */
  int nSkipped = 0;                    /* Number of SQL statements skipped */
  int nResult;                         /* Number of query results */
  char **azResult;                     /* Query result vector */
  Script sScript;                      /* Script parsing status */
  FILE *in;                            /* For reading script */
  char zHash[100];                     /* Storage space for hash results */
  int hashThreshold = DEFAULT_HASH_THRESHOLD;  /* Threshold for hashing res */
  int bHt = 0;                         /* True if -ht command-line option */

  /* Add calls to the registration procedures for new database engine
  ** interfaces here
  */
  registerSqlite();
#ifndef OMIT_ODBC
  registerODBC3();
................................................................................
    int bSkip = 0; /* True if we should skip the current record. */

    /* Tokenizer the first line of the record.  This also records the
    ** line number of the first record in sScript.startLine */
    tokenizeLine(&sScript);

    bSkip = 0;
    while( strcmp(sScript.azToken[0],"skipif")==0 
        || strcmp(sScript.azToken[0],"onlyif")==0
    ){
      int bMatch;
      /* The "skipif" and "onlyif" modifiers allow skipping or using
      ** statement or query record for a particular database engine.

      ** In this way, SQL features implmented by a majority of the
      ** engines can be tested without causing spurious errors for
      ** engines that don't support it.
      **
      ** Once this record is encountered, an the current selected
      ** db interface matches the db engine specified in the record,
      ** the we skip this rest of this record for "skipif" or for
      ** "onlyif" we skip the record if the record does not match.
      */
      bMatch = stricmp(sScript.azToken[1], zDbEngine)==0;
      if( sScript.azToken[0][0]=='s' ){
        if( bMatch ) bSkip = -1;

      }else{
        if( !bMatch ) bSkip = -1;
      }
      nextLine(&sScript);
      tokenizeLine(&sScript);
    }
    if( bSkip ) {
      int n;
      nSkipped++;
      if( !verifyMode ) continue;
      if( strcmp(sScript.azToken[0],"query")!=0 ) continue;
      if( sScript.azToken[3][0]==0 ) continue;

      /* We are skipping this record.  But we observe that it is a query
      ** with a named hash value and we are in verify mode.  Even though 
      ** we are going to skip the SQL evaluation, we might as well check
      ** the hash of the result.
      */
      while( !nextIsBlank(&sScript) && nextLine(&sScript)
             && strcmp(sScript.zLine,"----")!=0 ){
        /* Skip over the SQL text */
      }
      if( strcmp(sScript.zLine, "----")==0 ) nextLine(&sScript);
      if( sScript.zLine[0]==0 ) continue;
      n = sscanf(sScript.zLine, "%*d values hashing to %32s", zHash);
      if( n!=1 ){
        md5_add(sScript.zLine);
        md5_add("\n");
        while( !nextIsBlank(&sScript) && nextLine(&sScript) ){
          md5_add(sScript.zLine);
          md5_add("\n");
        }
        strcpy(zHash, md5_finish());
      }
      if( checkValue(sScript.azToken[3], zHash) ){
        fprintf(stderr, "%s:%d: labeled result [%s] does not agree with "
                        "previous values\n", zScriptFile, 
                        sScript.startLine, sScript.azToken[3]);
        nErr++;
      }
      continue;
    }

    /* Figure out the record type and do appropriate processing */
    if( strcmp(sScript.azToken[0],"statement")==0 ){
      int k = 0;

................................................................................
        fprintf(stderr, "%s:%d: statement error\n",
                zScriptFile, sScript.startLine);
        nErr++;
      }
    }else if( strcmp(sScript.azToken[0],"query")==0 ){
      int k = 0;
      int c;


      /* Verify that the type string consists of one or more characters
      ** from the set "TIR". */
      for(k=0; (c = sScript.azToken[1][k])!=0; k++){
        if( c!='T' && c!='I' && c!='R' ){
          fprintf(stderr, "%s:%d: unknown type character '%c' in type string\n",
                  zScriptFile, sScript.startLine, c);