/ Check-in [63efd50a]
Login

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

Overview
Comment:Minor optimizations in the pragma module. (CVS 2029)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 63efd50a1608eb4ccac44a233c0f77c3956f9fa0
User & Date: drh 2004-10-25 20:33:44
Context
2004-10-26
00:08
Fix a bug in the ".databases" command of the command-line shell. Ticket #973 (CVS 2030) check-in: 507d8e6f user: drh tags: trunk
2004-10-25
20:33
Minor optimizations in the pragma module. (CVS 2029) check-in: 63efd50a user: drh tags: trunk
2004-10-23
05:10
Tighter encoding of the keyword hash table in the tokenizer. (CVS 2028) check-in: 7b9886f8 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to mkopcodeh.awk.

     1      1   #!/usr/bin/awk -f
            2  +#
            3  +# Generate the file opcodes.h.
     2      4   #
     3      5   # This AWK script scans a concatenation of the parse.h output file from the
     4      6   # parser and the vdbe.c source file in order to generate the opcodes numbers
     5      7   # for all opcodes.  
     6      8   #
     7      9   # The lines of the vdbe.c that we are interested in are of the form:
     8     10   #
     9     11   #       case OP_aaaa:      /* same as TK_bbbbb */
    10     12   #
    11     13   # The TK_ comment is optional.  If it is present, then the value assigned to
    12     14   # the OP_ is the same as the TK_ value.  If missing, the OP_ value is assigned
    13     15   # a small integer that is different from every other OP_ value.
           16  +#
           17  +# We go to the trouble of making some OP_ value the same as TK_ values
           18  +# as an optimization.  During parsing, things like expression operators
           19  +# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth.  Later
           20  +# during code generation, we need to generate corresponding opcodes like
           21  +# OP_Add and OP_Divide.  By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
           22  +# code to translation from one to the other is avoided.  This makes the
           23  +# code generator run (infinitesimally) faster and more importantly it makes
           24  +# the total library smaller.
    14     25   #
    15     26   
    16     27   # Remember the TK_ values from the parse.h file
    17     28   /^#define TK_/ {
    18     29     tk[$2] = $3
    19     30   }
    20     31   

Changes to src/pragma.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the PRAGMA command.
    13     13   **
    14         -** $Id: pragma.c,v 1.71 2004/10/22 20:29:22 drh Exp $
           14  +** $Id: pragma.c,v 1.72 2004/10/25 20:33:44 drh Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include <ctype.h>
    18     18   
    19     19   #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
    20     20   # include "pager.h"
    21     21   # include "btree.h"
    22     22   #endif
    23     23   
    24         -/*
    25         -** Interpret the given string as a boolean value.
    26         -*/
    27         -static int getBoolean(const u8 *z){
    28         -  static const u8 *azTrue[] = { "yes", "on", "true" };
    29         -  int i;
    30         -  if( z[0]==0 ) return 0;
    31         -  if( sqlite3IsNumber(z, 0, SQLITE_UTF8) ){
    32         -    return atoi(z);
    33         -  }
    34         -  for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){
    35         -    if( sqlite3StrICmp(z,azTrue[i])==0 ) return 1;
    36         -  }
    37         -  return 0;
    38         -}
    39         -
    40     24   /*
    41     25   ** Interpret the given string as a safety level.  Return 0 for OFF,
    42     26   ** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
    43     27   ** unrecognized string argument.
    44     28   **
    45     29   ** Note that the values returned are one less that the values that
    46     30   ** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
    47     31   ** to support legacy SQL code.  The safety level used to be boolean
    48     32   ** and older scripts may have used numbers 0 for OFF and 1 for ON.
    49     33   */
    50         -static int getSafetyLevel(u8 *z){
    51         -  static const struct {
    52         -    const u8 *zWord;
    53         -    int val;
    54         -  } aKey[] = {
    55         -    { "no",    0 },
    56         -    { "off",   0 },
    57         -    { "false", 0 },
    58         -    { "yes",   1 },
    59         -    { "on",    1 },
    60         -    { "true",  1 },
    61         -    { "full",  2 },
    62         -  };
    63         -  int i;
    64         -  if( z[0]==0 ) return 1;
    65         -  if( sqlite3IsNumber(z, 0, SQLITE_UTF8) ){
           34  +static int getSafetyLevel(const u8 *z){
           35  +                             /* 123456789 123456789 */
           36  +  static const char zText[] = "onoffalseyestruefull";
           37  +  static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
           38  +  static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
           39  +  static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
           40  +  int i, n;
           41  +  if( isdigit(*z) ){
    66     42       return atoi(z);
    67     43     }
    68         -  for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
    69         -    if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
           44  +  n = strlen(z);
           45  +  for(i=0; i<sizeof(iLength); i++){
           46  +    if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
           47  +      return iValue[i];
           48  +    }
    70     49     }
    71     50     return 1;
    72     51   }
           52  +
           53  +/*
           54  +** Interpret the given string as a boolean value.
           55  +*/
           56  +static int getBoolean(const u8 *z){
           57  +  return getSafetyLevel(z)&1;
           58  +}
    73     59   
    74     60   /*
    75     61   ** Interpret the given string as a temp db location. Return 1 for file
    76     62   ** backed temporary databases, 2 for the Red-Black tree in memory database
    77     63   ** and 0 to use the compile-time default.
    78     64   */
    79     65   static int getTempStore(const char *z){
................................................................................
   126    112   
   127    113   /*
   128    114   ** Check to see if zRight and zLeft refer to a pragma that queries
   129    115   ** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
   130    116   ** Also, implement the pragma.
   131    117   */
   132    118   static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
   133         -  static const struct {
          119  +  static const struct sPragmaType {
   134    120       const char *zName;  /* Name of the pragma */
   135    121       int mask;           /* Mask for the db->flags value */
   136    122     } aPragma[] = {
   137    123       { "vdbe_trace",               SQLITE_VdbeTrace     },
   138    124       { "sql_trace",                SQLITE_SqlTrace      },
   139    125       { "vdbe_listing",             SQLITE_VdbeListing   },
   140    126       { "full_column_names",        SQLITE_FullColNames  },
................................................................................
   141    127       { "short_column_names",       SQLITE_ShortColNames },
   142    128       { "count_changes",            SQLITE_CountRows     },
   143    129       { "empty_result_callbacks",   SQLITE_NullCallback  },
   144    130   /* The following is VERY experimental */
   145    131       { "writable_schema",          SQLITE_WriteSchema   },
   146    132     };
   147    133     int i;
   148         -  for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
   149         -    if( sqlite3StrICmp(zLeft, aPragma[i].zName)==0 ){
          134  +  const struct sPragmaType *p;
          135  +  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
          136  +    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
   150    137         sqlite3 *db = pParse->db;
   151    138         Vdbe *v;
   152    139         if( zRight==0 ){
   153    140           v = sqlite3GetVdbe(pParse);
   154    141           if( v ){
   155         -          returnSingleInt(pParse,
   156         -               aPragma[i].zName, (db->flags&aPragma[i].mask)!=0);
          142  +          returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
   157    143           }
   158    144         }else if( getBoolean(zRight) ){
   159         -        db->flags |= aPragma[i].mask;
          145  +        db->flags |= p->mask;
   160    146         }else{
   161         -        db->flags &= ~aPragma[i].mask;
          147  +        db->flags &= ~p->mask;
   162    148         }
   163    149         return 1;
   164    150       }
   165    151     }
   166    152     return 0;
   167    153   }
   168    154