SQLite

Check-in [272dc74fd0]
Login

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

Overview
Comment:Get rid of the hash table used to track IN operators in the sqlite3_normalized_sql() implementation. Use simple integer variables instead.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 272dc74fd0304d6a28aaa8798d13e2f950c1a24d92d17519e3c32aef86714586
User & Date: drh 2018-12-05 23:56:02.639
Context
2018-12-06
01:08
Fix a missing mutex in the sqlite3_normalized_sql() interface when it is called on a prepared statement that did not previously have a computed normalization of the input SQL. (check-in: 1a1a59c6c5 user: drh tags: trunk)
00:05
Merge ALTER TABLE and sqlite3_normalized_sql() fixes from trunk. (check-in: acf10b3f8d user: drh tags: begin-concurrent)
2018-12-05
23:56
Get rid of the hash table used to track IN operators in the sqlite3_normalized_sql() implementation. Use simple integer variables instead. (check-in: 272dc74fd0 user: drh tags: trunk)
23:45
The sqlite3_normalized_sql() interface should not be transforming quoted identifier names into wildcards. Fix this, and at the same time simplify the code substantially. (check-in: e8540377ec user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/prepare.c.
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
  int nZ;                /* Size of the output string in bytes */
  int i;                 /* Next character to read from zSql[] */
  int j;                 /* Next character to fill in on z[] */
  int tokenType = 0;     /* Type of the next token */
  int prevTokenType = 0; /* Type of the previous token, except spaces */
  int n;                 /* Size of the next token */
  int nParen = 0;        /* Nesting level of parenthesis */
  Hash inHash;           /* Table of parenthesis levels to output index. */


  db = sqlite3VdbeDb(pVdbe);
  assert( db!=0 );
  if( zSql==0 ) return 0;
  nZ = estimateNormalizedSize(zSql, nSql);
  z = sqlite3DbMallocRawNN(db, nZ);
  if( z==0 ) goto normalizeError;
  sqlite3HashInit(&inHash);
  for(i=j=0; i<nSql && zSql[i]; i+=n){
    int flags = 0;
    if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
    n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
    switch( tokenType ){
      case TK_SPACE: {
        break;







|
>







<







789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

805
806
807
808
809
810
811
  int nZ;                /* Size of the output string in bytes */
  int i;                 /* Next character to read from zSql[] */
  int j;                 /* Next character to fill in on z[] */
  int tokenType = 0;     /* Type of the next token */
  int prevTokenType = 0; /* Type of the previous token, except spaces */
  int n;                 /* Size of the next token */
  int nParen = 0;        /* Nesting level of parenthesis */
  int iStartIN = 0;      /* Start of RHS of IN operator in z[] */
  int nParenAtIN = 0;    /* Value of nParent at start of RHS of IN operator */

  db = sqlite3VdbeDb(pVdbe);
  assert( db!=0 );
  if( zSql==0 ) return 0;
  nZ = estimateNormalizedSize(zSql, nSql);
  z = sqlite3DbMallocRawNN(db, nZ);
  if( z==0 ) goto normalizeError;

  for(i=j=0; i<nSql && zSql[i]; i+=n){
    int flags = 0;
    if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
    n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
    switch( tokenType ){
      case TK_SPACE: {
        break;
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
        break;
      }
      case TK_LP:
      case TK_RP: {
        if( tokenType==TK_LP ){
          nParen++;
          if( prevTokenType==TK_IN ){

            assert( nParen<nSql );
            sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
          }
        }else{
          int jj;
          assert( nParen<nSql );
          jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
          if( jj>0 ){
            sqlite3HashInsert(&inHash, zSql+nParen, 0);
            assert( jj+6<nZ );
            memcpy(z+jj+1, "?,?,?", 5);
            j = jj+6;
            assert( nZ-1-j>=0 );
            assert( nZ-1-j<nZ );
            memset(z+j, 0, nZ-1-j);

          }
          nParen--;
        }
        assert( nParen>=0 );
        /* Fall through */
      }
      case TK_MINUS:







>
|
<


<
|
<
<
<
|
|
|



>







822
823
824
825
826
827
828
829
830

831
832

833



834
835
836
837
838
839
840
841
842
843
844
845
846
847
        break;
      }
      case TK_LP:
      case TK_RP: {
        if( tokenType==TK_LP ){
          nParen++;
          if( prevTokenType==TK_IN ){
            iStartIN = j;
            nParenAtIN = nParen;

          }
        }else{

          if( iStartIN>0 && nParen==nParenAtIN ){



            assert( iStartIN+6<nZ );
            memcpy(z+iStartIN+1, "?,?,?", 5);
            j = iStartIN+6;
            assert( nZ-1-j>=0 );
            assert( nZ-1-j<nZ );
            memset(z+j, 0, nZ-1-j);
            iStartIN = 0;
          }
          nParen--;
        }
        assert( nParen>=0 );
        /* Fall through */
      }
      case TK_MINUS:
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
          }
        }
        if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
          z[j++] = ' ';
        }
        if( tokenType==TK_ID ){
          int i2 = i, n2 = n;
          if( nParen>0 ){
            assert( nParen<nSql );
            sqlite3HashInsert(&inHash, zSql+nParen, 0);
          }
          if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
        }
        copyNormalizedToken(zSql, i, n, flags, z, &j);
        break;
      }
    }
  }
  assert( j<nZ && "one" );
  while( j>0 && z[j-1]==' ' ){ j--; }
  if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
  z[j] = 0;
  assert( j<nZ && "two" );
  sqlite3HashClear(&inHash);
  return z;

normalizeError:
  sqlite3DbFree(db, z);
  sqlite3HashClear(&inHash);
  return 0;
}
#endif /* SQLITE_ENABLE_NORMALIZE */

/*
** Rerun the compilation of a statement after a schema change.
**







|
<
<
<












<




<







879
880
881
882
883
884
885
886



887
888
889
890
891
892
893
894
895
896
897
898

899
900
901
902

903
904
905
906
907
908
909
          }
        }
        if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
          z[j++] = ' ';
        }
        if( tokenType==TK_ID ){
          int i2 = i, n2 = n;
          if( nParen==nParenAtIN ) iStartIN = 0;



          if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
        }
        copyNormalizedToken(zSql, i, n, flags, z, &j);
        break;
      }
    }
  }
  assert( j<nZ && "one" );
  while( j>0 && z[j-1]==' ' ){ j--; }
  if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
  z[j] = 0;
  assert( j<nZ && "two" );

  return z;

normalizeError:
  sqlite3DbFree(db, z);

  return 0;
}
#endif /* SQLITE_ENABLE_NORMALIZE */

/*
** Rerun the compilation of a statement after a schema change.
**