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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqllogictest.c.

    29     29   
    30     30   #include "sqllogictest.h"
    31     31   #include <stdio.h>
    32     32   #include <stdlib.h>
    33     33   #include <ctype.h>
    34     34   #ifndef WIN32
    35     35   #include <unistd.h>
           36  +#define stricmp strcasecmp
    36     37   #endif
    37     38   #include <string.h>
    38     39   
    39     40   #include "slt_sqlite.c"
    40     41   #include "slt_odbc3.c"
    41     42   
    42     43   #define DEFAULT_HASH_THRESHOLD 8
................................................................................
   319    320     int nErr = 0;                        /* Number of errors */
   320    321     int nCmd = 0;                        /* Number of SQL statements processed */
   321    322     int nSkipped = 0;                    /* Number of SQL statements skipped */
   322    323     int nResult;                         /* Number of query results */
   323    324     char **azResult;                     /* Query result vector */
   324    325     Script sScript;                      /* Script parsing status */
   325    326     FILE *in;                            /* For reading script */
   326         -  int hashThreshold = DEFAULT_HASH_THRESHOLD;  /* Hash result if this long or longer */
   327         -  int bHt = 0;                         /* Non-zero if a hash threshold option was */
   328         -                                       /* given on the command line. */
          327  +  char zHash[100];                     /* Storage space for hash results */
          328  +  int hashThreshold = DEFAULT_HASH_THRESHOLD;  /* Threshold for hashing res */
          329  +  int bHt = 0;                         /* True if -ht command-line option */
   329    330   
   330    331     /* Add calls to the registration procedures for new database engine
   331    332     ** interfaces here
   332    333     */
   333    334     registerSqlite();
   334    335   #ifndef OMIT_ODBC
   335    336     registerODBC3();
................................................................................
   445    446       int bSkip = 0; /* True if we should skip the current record. */
   446    447   
   447    448       /* Tokenizer the first line of the record.  This also records the
   448    449       ** line number of the first record in sScript.startLine */
   449    450       tokenizeLine(&sScript);
   450    451   
   451    452       bSkip = 0;
   452         -    while( strcmp(sScript.azToken[0],"skipif")==0 ){
   453         -      /* This allows skipping a statement or query record for a 
   454         -      ** particular database engine.  In this way, SQL features
   455         -      ** implmented by a majority of the engines can be tested 
   456         -      ** without causing spurious errors for engines that don't
   457         -      ** support it.
          453  +    while( strcmp(sScript.azToken[0],"skipif")==0 
          454  +        || strcmp(sScript.azToken[0],"onlyif")==0
          455  +    ){
          456  +      int bMatch;
          457  +      /* The "skipif" and "onlyif" modifiers allow skipping or using
          458  +      ** statement or query record for a particular database engine.
          459  +      ** In this way, SQL features implmented by a majority of the
          460  +      ** engines can be tested without causing spurious errors for
          461  +      ** engines that don't support it.
   458    462         **
   459    463         ** Once this record is encountered, an the current selected
   460    464         ** db interface matches the db engine specified in the record,
   461         -      ** the we skip this rest of this record.
          465  +      ** the we skip this rest of this record for "skipif" or for
          466  +      ** "onlyif" we skip the record if the record does not match.
   462    467         */
   463         -      if( stricmp(sScript.azToken[1], zDbEngine)==0 ){
   464         -        bSkip = -1;
   465         -        break;
          468  +      bMatch = stricmp(sScript.azToken[1], zDbEngine)==0;
          469  +      if( sScript.azToken[0][0]=='s' ){
          470  +        if( bMatch ) bSkip = -1;
          471  +      }else{
          472  +        if( !bMatch ) bSkip = -1;
   466    473         }
   467    474         nextLine(&sScript);
   468    475         tokenizeLine(&sScript);
   469    476       }
   470    477       if( bSkip ) {
          478  +      int n;
   471    479         nSkipped++;
          480  +      if( !verifyMode ) continue;
          481  +      if( strcmp(sScript.azToken[0],"query")!=0 ) continue;
          482  +      if( sScript.azToken[3][0]==0 ) continue;
          483  +
          484  +      /* We are skipping this record.  But we observe that it is a query
          485  +      ** with a named hash value and we are in verify mode.  Even though 
          486  +      ** we are going to skip the SQL evaluation, we might as well check
          487  +      ** the hash of the result.
          488  +      */
          489  +      while( !nextIsBlank(&sScript) && nextLine(&sScript)
          490  +             && strcmp(sScript.zLine,"----")!=0 ){
          491  +        /* Skip over the SQL text */
          492  +      }
          493  +      if( strcmp(sScript.zLine, "----")==0 ) nextLine(&sScript);
          494  +      if( sScript.zLine[0]==0 ) continue;
          495  +      n = sscanf(sScript.zLine, "%*d values hashing to %32s", zHash);
          496  +      if( n!=1 ){
          497  +        md5_add(sScript.zLine);
          498  +        md5_add("\n");
          499  +        while( !nextIsBlank(&sScript) && nextLine(&sScript) ){
          500  +          md5_add(sScript.zLine);
          501  +          md5_add("\n");
          502  +        }
          503  +        strcpy(zHash, md5_finish());
          504  +      }
          505  +      if( checkValue(sScript.azToken[3], zHash) ){
          506  +        fprintf(stderr, "%s:%d: labeled result [%s] does not agree with "
          507  +                        "previous values\n", zScriptFile, 
          508  +                        sScript.startLine, sScript.azToken[3]);
          509  +        nErr++;
          510  +      }
   472    511         continue;
   473    512       }
   474    513   
   475    514       /* Figure out the record type and do appropriate processing */
   476    515       if( strcmp(sScript.azToken[0],"statement")==0 ){
   477    516         int k = 0;
   478    517   
................................................................................
   508    547           fprintf(stderr, "%s:%d: statement error\n",
   509    548                   zScriptFile, sScript.startLine);
   510    549           nErr++;
   511    550         }
   512    551       }else if( strcmp(sScript.azToken[0],"query")==0 ){
   513    552         int k = 0;
   514    553         int c;
   515         -      char zHash[100];
   516    554   
   517    555         /* Verify that the type string consists of one or more characters
   518    556         ** from the set "TIR". */
   519    557         for(k=0; (c = sScript.azToken[1][k])!=0; k++){
   520    558           if( c!='T' && c!='I' && c!='R' ){
   521    559             fprintf(stderr, "%s:%d: unknown type character '%c' in type string\n",
   522    560                     zScriptFile, sScript.startLine, c);