UnQL

Check-in [a8abdbeadb]
Login

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

Overview
Comment:Add parsing of "in" and "WITHIN" operators. Missing implementions.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a8abdbeadb52a66a67c8f4f2d4e68f48935e2151
User & Date: drh 2011-07-16 12:22:11
Context
2011-07-16
12:26
Add support for the [] operator on objects. Using the [] operator with an array or string does not work yet. check-in: e049952168 user: dan tags: trunk
12:22
Add parsing of "in" and "WITHIN" operators. Missing implementions. check-in: a8abdbeadb user: drh tags: trunk
06:53
Add support for SELECT queries with no FROM clause (i.e. "SELECT <expr>;"). check-in: 61dc9bee92 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/parse.y.

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
288
289
290
291
292
293
294

295
296
297
298
299
300
301
%right QM.
%left OR.
%left AND.
%left BITOR.
%left BITXOR.
%left BITAND.
%left LIKEOP NE EQEQ EQ3 NE3.
%left IN GT LE LT GE.
%left LSHIFT RSHIFT URSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%right BITNOT BANG.
%left COLLATE.

%include {
................................................................................
expr(A) ::= expr(X) BITAND(OP) expr(Y).          {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) BITXOR(OP) expr(Y).          {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) BITOR(OP) expr(Y).           {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) LSHIFT|RSHIFT|URSHIFT(OP) expr(Y).
                                                 {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).      {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).  {A = biExpr(p,X,@OP,Y);}

expr(A) ::= expr(X) LIKEOP(OP) expr(Y).          {A = biExpr(p,X,@OP,Y);}
expr(A) ::= BANG(OP) expr(X).                    {A = biExpr(p,X,@OP,0);}
expr(A) ::= BITNOT(OP) expr(X).                  {A = biExpr(p,X,@OP,0);}
expr(A) ::= MINUS(OP) expr(X). [BITNOT]          {A = biExpr(p,X,@OP,0);}
expr(A) ::= PLUS(OP) expr(X). [BITNOT]           {A = biExpr(p,X,@OP,0);}
expr(A) ::= LP select(X) RP.                     {A = subqExpr(p,X);}
expr(A) ::= LP expr(X) RP.                       {A = X;}







|







 







>







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
%right QM.
%left OR.
%left AND.
%left BITOR.
%left BITXOR.
%left BITAND.
%left LIKEOP NE EQEQ EQ3 NE3.
%left WITHIN IN GT LE LT GE.
%left LSHIFT RSHIFT URSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%right BITNOT BANG.
%left COLLATE.

%include {
................................................................................
expr(A) ::= expr(X) BITAND(OP) expr(Y).          {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) BITXOR(OP) expr(Y).          {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) BITOR(OP) expr(Y).           {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) LSHIFT|RSHIFT|URSHIFT(OP) expr(Y).
                                                 {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).      {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).  {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) IN|WITHIN(OP) expr(Y).       {A = biExpr(p,X,@OP,Y);}
expr(A) ::= expr(X) LIKEOP(OP) expr(Y).          {A = biExpr(p,X,@OP,Y);}
expr(A) ::= BANG(OP) expr(X).                    {A = biExpr(p,X,@OP,0);}
expr(A) ::= BITNOT(OP) expr(X).                  {A = biExpr(p,X,@OP,0);}
expr(A) ::= MINUS(OP) expr(X). [BITNOT]          {A = biExpr(p,X,@OP,0);}
expr(A) ::= PLUS(OP) expr(X). [BITNOT]           {A = biExpr(p,X,@OP,0);}
expr(A) ::= LP select(X) RP.                     {A = subqExpr(p,X);}
expr(A) ::= LP expr(X) RP.                       {A = X;}

Changes to src/tokenize.c.

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107

108
109
110

111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

/**********************************************************************
** The following code is automatically generated
** by ../tool/mkkeywordhash.c
*/
/* Hash score: 51 */
static int keywordCode(const char *z, int n){
  /* zText[] encodes 278 bytes of keywords in 198 bytes */
  /*   BEGINTORDEROLLBACKELSELECTGROUPDATEACHAVINGLOBYALLIKEXISTS         */
  /*   ASCENDINGCOLLATEXCEPTCOLLECTIONULLIMITCREATEDELETEDESCENDING       */
  /*   DROPRAGMAFLATTENOTIFROMUNIONVALUEWHEREinullCOMMITINSERT            */
  /*   INTERSECTOFFSETfalsetrue                                           */
  static const char zText[197] = {
    'B','E','G','I','N','T','O','R','D','E','R','O','L','L','B','A','C','K',
    'E','L','S','E','L','E','C','T','G','R','O','U','P','D','A','T','E','A',
    'C','H','A','V','I','N','G','L','O','B','Y','A','L','L','I','K','E','X',

    'I','S','T','S','A','S','C','E','N','D','I','N','G','C','O','L','L','A',
    'T','E','X','C','E','P','T','C','O','L','L','E','C','T','I','O','N','U',
    'L','L','I','M','I','T','C','R','E','A','T','E','D','E','L','E','T','E',
    'D','E','S','C','E','N','D','I','N','G','D','R','O','P','R','A','G','M',
    'A','F','L','A','T','T','E','N','O','T','I','F','R','O','M','U','N','I',
    'O','N','V','A','L','U','E','W','H','E','R','E','i','n','u','l','l','C',
    'O','M','M','I','T','I','N','S','E','R','T','I','N','T','E','R','S','E',
    'C','T','O','F','F','S','E','T','f','a','l','s','e','t','r','u','e',

  };
  static const unsigned char aHash[80] = {
       0,  12,  36,  13,  29,   0,  37,   1,  39,   7,   0,  46,  21,

       8,  20,   0,   0,   4,  45,  10,  33,  31,  40,   0,   0,   0,
       0,  34,   0,   0,   0,  16,   0,   0,   0,  44,   0,   0,   6,
       0,   0,   0,   0,  35,   0,   0,   0,   0,   0,   0,   0,   0,
      19,  24,  43,  32,   9,  23,   0,   0,  28,   2,  17,  27,   0,
      42,   0,   0,   0,  30,   0,   0,  22,  25,   0,   0,  38,  26,

      41,   5,
  };
  static const unsigned char aNext[46] = {
       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,   0,  18,   0,   0,   0,   0,
       3,   0,   0,   0,   0,   0,   0,  14,   0,   0,   0,   0,   0,
       0,  11,   0,   0,   0,   0,  15,
  };
  static const unsigned char aLen[46] = {
       5,   4,   5,   8,   4,   6,   5,   6,   4,   6,   4,   2,   3,
       4,   6,   2,   3,   9,   7,   6,  10,   4,   5,   6,   6,   4,
      10,   2,   4,   6,   7,   3,   2,   4,   5,   5,   5,   2,   4,
       6,   6,   9,   6,   3,   5,   4,
  };
  static const unsigned short int aOffset[46] = {
       0,   3,   6,  10,  18,  20,  26,  29,  34,  37,  42,  45,  47,
      49,  52,  58,  58,  58,  67,  73,  79,  88,  91,  96, 102, 108,
     108, 115, 118, 121, 127, 133, 136, 137, 141, 146, 151, 156, 157,
     161, 167, 173, 182, 185, 188, 193,
  };
  static const unsigned char aCode[46] = {
    TK_BEGIN,      TK_INTO,       TK_ORDER,      TK_ROLLBACK,   TK_ELSE,       
    TK_SELECT,     TK_GROUP,      TK_UPDATE,     TK_FLATTENOP,  TK_HAVING,     
    TK_LIKEOP,     TK_BY,         TK_ALL,        TK_LIKEOP,     TK_EXISTS,     
    TK_AS,         TK_ASCENDING,  TK_ASCENDING,  TK_COLLATE,    TK_EXCEPT,     
    TK_COLLECTION, TK_NULL,       TK_LIMIT,      TK_CREATE,     TK_DELETE,     
    TK_DESCENDING, TK_DESCENDING, TK_IN,         TK_DROP,       TK_PRAGMA,     
    TK_FLATTENOP,  TK_NOT,        TK_IF,         TK_FROM,       TK_UNION,      
    TK_VALUE,      TK_WHERE,      TK_IN,         TK_NULL,       TK_COMMIT,     
    TK_INSERT,     TK_INTERSECT,  TK_OFFSET,     TK_SET,        TK_FALSE,      
    TK_TRUE,       
  };
  int h, i;
  if( n<2 ) return TK_ID;
  h = (z[0]*4 ^ z[n-1]*3 ^ n) % 80;
  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
    if( aLen[i]==n && memcmp(&zText[aOffset[i]],z,n)==0 ){







|
|
|
|

|


|
>
|
|
|
|
|
|
<
|
>


<
>
|
<
|
|
|
>
|



|
|
|


|
|
|
|



|
|
|




|
|
|
|
|
|
|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110

111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

/**********************************************************************
** The following code is automatically generated
** by ../tool/mkkeywordhash.c
*/
/* Hash score: 51 */
static int keywordCode(const char *z, int n){
  /* zText[] encodes 282 bytes of keywords in 202 bytes */
  /*   BEGINTORDEROLLBACKELSELECTGROUPDATEACHAVINGLOBYWITHINSERTALL       */
  /*   IKEXISTSASCENDINGCOLLATEXCEPTCOLLECTIONULLIMITCREATEDELETE         */
  /*   DESCENDINGDROPRAGMAFLATTENOTIFROMUNIONVALUEWHEREinullCOMMIT        */
  /*   INTERSECTOFFSETfalsetrue                                           */
  static const char zText[201] = {
    'B','E','G','I','N','T','O','R','D','E','R','O','L','L','B','A','C','K',
    'E','L','S','E','L','E','C','T','G','R','O','U','P','D','A','T','E','A',
    'C','H','A','V','I','N','G','L','O','B','Y','W','I','T','H','I','N','S',
    'E','R','T','A','L','L','I','K','E','X','I','S','T','S','A','S','C','E',
    'N','D','I','N','G','C','O','L','L','A','T','E','X','C','E','P','T','C',
    'O','L','L','E','C','T','I','O','N','U','L','L','I','M','I','T','C','R',
    'E','A','T','E','D','E','L','E','T','E','D','E','S','C','E','N','D','I',
    'N','G','D','R','O','P','R','A','G','M','A','F','L','A','T','T','E','N',
    'O','T','I','F','R','O','M','U','N','I','O','N','V','A','L','U','E','W',
    'H','E','R','E','i','n','u','l','l','C','O','M','M','I','T','I','N','T',

    'E','R','S','E','C','T','O','F','F','S','E','T','f','a','l','s','e','t',
    'r','u','e',
  };
  static const unsigned char aHash[80] = {

       0,  12,  37,  15,  30,   0,  38,   1,  40,   7,   0,  46,  23,
       8,  22,   0,   0,   4,  45,  10,  34,  32,  41,   0,   0,   0,

       0,  35,   0,   0,   0,  18,  13,   0,   0,  44,   0,   0,   6,
       0,   0,   0,   0,  36,   0,   0,   0,   0,   0,   0,   0,   0,
      21,  26,  43,  33,   9,  25,   0,   0,   0,   2,  19,  29,   0,
      42,   0,   0,   0,  31,   0,   0,  24,  27,   0,   0,  39,  28,
      14,   5,
  };
  static const unsigned char aNext[46] = {
       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      11,   0,   0,   0,   0,   0,   0,   0,   0,   0,  20,   0,   0,
       0,   0,   3,   0,   0,   0,   0,   0,  16,   0,   0,   0,   0,
       0,   0,   0,   0,   0,   0,  17,
  };
  static const unsigned char aLen[46] = {
       5,   4,   5,   8,   4,   6,   5,   6,   4,   6,   4,   2,   6,
       6,   3,   4,   6,   2,   3,   9,   7,   6,  10,   4,   5,   6,
       6,   4,  10,   4,   6,   7,   3,   2,   4,   5,   5,   5,   2,
       4,   6,   9,   6,   3,   5,   4,
  };
  static const unsigned short int aOffset[46] = {
       0,   3,   6,  10,  18,  20,  26,  29,  34,  37,  42,  45,  47,
      51,  57,  59,  62,  68,  68,  68,  77,  83,  89,  98, 101, 106,
     112, 118, 118, 128, 131, 137, 143, 146, 147, 151, 156, 161, 166,
     167, 171, 177, 186, 189, 192, 197,
  };
  static const unsigned char aCode[46] = {
    TK_BEGIN,      TK_INTO,       TK_ORDER,      TK_ROLLBACK,   TK_ELSE,       
    TK_SELECT,     TK_GROUP,      TK_UPDATE,     TK_FLATTENOP,  TK_HAVING,     
    TK_LIKEOP,     TK_BY,         TK_WITHIN,     TK_INSERT,     TK_ALL,        
    TK_LIKEOP,     TK_EXISTS,     TK_AS,         TK_ASCENDING,  TK_ASCENDING,  
    TK_COLLATE,    TK_EXCEPT,     TK_COLLECTION, TK_NULL,       TK_LIMIT,      
    TK_CREATE,     TK_DELETE,     TK_DESCENDING, TK_DESCENDING, TK_DROP,       
    TK_PRAGMA,     TK_FLATTENOP,  TK_NOT,        TK_IF,         TK_FROM,       
    TK_UNION,      TK_VALUE,      TK_WHERE,      TK_IN,         TK_NULL,       
    TK_COMMIT,     TK_INTERSECT,  TK_OFFSET,     TK_SET,        TK_FALSE,      
    TK_TRUE,       
  };
  int h, i;
  if( n<2 ) return TK_ID;
  h = (z[0]*4 ^ z[n-1]*3 ^ n) % 80;
  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
    if( aLen[i]==n && memcmp(&zText[aOffset[i]],z,n)==0 ){

Changes to tool/mkkeywordhash.c.

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
..
99
100
101
102
103
104
105

106
107
108
109
110
111
112
  { "GLOB",         "TK_LIKEOP",     },
  { "GROUP",        "TK_GROUP",      },
  { "HAVING",       "TK_HAVING",     },
  { "IF",           "TK_IF",         },
  { "INSERT",       "TK_INSERT",     },
  { "INTERSECT",    "TK_INTERSECT",  },
  { "in",           "TK_IN",         },
  { "IN",           "TK_IN",         },
  { "INTO",         "TK_INTO",       },
  { "LIKE",         "TK_LIKEOP",     },
  { "LIMIT",        "TK_LIMIT",      },
  { "NOT",          "TK_NOT",        },
  { "NULL",         "TK_NULL",       },
  { "null",         "TK_NULL",       },
  { "OFFSET",       "TK_OFFSET",     },
................................................................................
  { "SELECT",       "TK_SELECT",     },
  { "SET",          "TK_SET",        },
  { "true",         "TK_TRUE",       },
  { "UNION",        "TK_UNION",      },
  { "UPDATE",       "TK_UPDATE",     },
  { "VALUE",        "TK_VALUE",      },
  { "WHERE",        "TK_WHERE",      },

};

/* Number of keywords */
static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0]));

/*
** Comparision function for two Keyword records







<







 







>







81
82
83
84
85
86
87

88
89
90
91
92
93
94
..
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  { "GLOB",         "TK_LIKEOP",     },
  { "GROUP",        "TK_GROUP",      },
  { "HAVING",       "TK_HAVING",     },
  { "IF",           "TK_IF",         },
  { "INSERT",       "TK_INSERT",     },
  { "INTERSECT",    "TK_INTERSECT",  },
  { "in",           "TK_IN",         },

  { "INTO",         "TK_INTO",       },
  { "LIKE",         "TK_LIKEOP",     },
  { "LIMIT",        "TK_LIMIT",      },
  { "NOT",          "TK_NOT",        },
  { "NULL",         "TK_NULL",       },
  { "null",         "TK_NULL",       },
  { "OFFSET",       "TK_OFFSET",     },
................................................................................
  { "SELECT",       "TK_SELECT",     },
  { "SET",          "TK_SET",        },
  { "true",         "TK_TRUE",       },
  { "UNION",        "TK_UNION",      },
  { "UPDATE",       "TK_UPDATE",     },
  { "VALUE",        "TK_VALUE",      },
  { "WHERE",        "TK_WHERE",      },
  { "WITHIN",       "TK_WITHIN",     },
};

/* Number of keywords */
static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0]));

/*
** Comparision function for two Keyword records