KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > smallsql > database > SQLParser


1 /* =============================================================
2  * SmallSQL : a free Java DBMS library for the Java(tm) platform
3  * =============================================================
4  *
5  * (C) Copyright 2004-2006, by Volker Berlin.
6  *
7  * Project Info: http://www.smallsql.de/
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ---------------
28  * SQLParser.java
29  * ---------------
30  * Author: Volker Berlin
31  *
32  */

33 package smallsql.database;
34
35 import java.util.List JavaDoc;
36 import java.sql.*;
37
38
39 public class SQLParser {
40
41     SSConnection con;
42     private char[] sql;
43     private List JavaDoc tokens;
44     private int tokenIdx;
45
46     Command parse(SSConnection con, String JavaDoc sql) throws SQLException{
47         this.con = con;
48         Command cmd = parse( sql.toCharArray() );
49         SQLToken token = nextToken();
50         if(token != null){
51                 throw createSyntaxError( token, "Additional token after end of SQL statement");
52         }
53         return cmd;
54     }
55     
56     
57     final private Command parse(char[] sql) throws SQLException{
58         this.sql = sql;
59         this.tokens = SQLTokenizer.parseSQL( sql );
60         tokenIdx = 0;
61
62         SQLToken token = nextToken(COMMANDS);
63         switch (token.value){
64             case SQLTokenizer.SELECT:
65                     return select();
66             case SQLTokenizer.DELETE:
67                     return delete();
68             case SQLTokenizer.INSERT:
69                     return insert();
70             case SQLTokenizer.UPDATE:
71                     return update();
72             case SQLTokenizer.CREATE:
73                     return create();
74             case SQLTokenizer.DROP:
75                     return drop();
76             case SQLTokenizer.ALTER:
77                     return alter();
78             case SQLTokenizer.SET:
79                     return set();
80             case SQLTokenizer.USE:
81                     token = nextToken(MISSING_EXPRESSION);
82                     String JavaDoc name = token.getName( sql );
83                     checkValidIdentifer( name, token );
84                     CommandSet set = new CommandSet( con.log, SQLTokenizer.USE);
85                     set.name = name;
86                     return set;
87             case SQLTokenizer.EXECUTE:
88                     return execute();
89             case SQLTokenizer.TRUNCATE:
90                     return truncate();
91             default:
92                     throw new Error JavaDoc();
93         }
94     }
95     
96     
97     Expression parseExpression(String JavaDoc expr) throws SQLException{
98         this.sql = expr.toCharArray();
99         this.tokens = SQLTokenizer.parseSQL( sql );
100         tokenIdx = 0;
101         return expression( null, 0);
102     }
103
104     private StringBuffer JavaDoc getSyntaxError( SQLToken token ){
105         StringBuffer JavaDoc msg = new StringBuffer JavaDoc(256);
106         if(token != null){
107             msg.append( "Syntax error at offset ").append( token.offset )
108                .append( " on '" ).append( sql, token.offset, token.length ).append("'. ");
109         }else{
110             msg.append( "Syntax error, unexpected end of SQL string. ");
111         }
112         return msg;
113     }
114
115     private SQLException createSyntaxError(SQLToken token, int[] validValues){
116         StringBuffer JavaDoc msg = getSyntaxError( token );
117
118         msg.append( "Requied keywords are: " );
119         for(int i=0; i<validValues.length; i++){
120             String JavaDoc name = SQLTokenizer.getKeyWord(validValues[i]);
121             if(name == null) name = String.valueOf( (char)validValues[i] );
122             msg.append( name );
123             if (i < validValues.length - 2)
124                 msg.append( ", ");
125             else
126             if ( i == validValues.length - 2 )
127                 msg.append( " or ");
128         }
129
130         return createSyntaxError( msg, token );
131     }
132
133     private SQLException createSyntaxError( StringBuffer JavaDoc msg, SQLToken token){
134         int offset = (token != null) ? token.offset : sql.length;
135         int begin = Math.max( 0, offset-40);
136         int end = Math.min( offset+20, sql.length );
137         String JavaDoc lineSeparator = System.getProperty( "line.separator" );
138         msg.append( lineSeparator );
139         msg.append( sql, begin, end-begin);
140         msg.append( lineSeparator );
141         for(; begin<offset; begin++) msg.append(' ');
142         msg.append('^');
143         return Utils.createSQLException( msg.toString()/* , offset*/ );
144     }
145
146     private SQLException createSyntaxError(SQLToken token, String JavaDoc errorMsg){
147         StringBuffer JavaDoc msg = getSyntaxError( token ).append(errorMsg);
148         return createSyntaxError( msg, token );
149     }
150     
151
152     private void checkValidIdentifer(String JavaDoc name, SQLToken token) throws SQLException{
153         if(token.value == SQLTokenizer.ASTERISK) return;
154         if(token.value != SQLTokenizer.VALUE &&
155            token.value != SQLTokenizer.IDENTIFER &&
156            token.value < 200){
157             throw createSyntaxError( token, "Identifer expected.");
158         }
159         if(name.length() == 0)
160             throw createSyntaxError( token, "Empty Identifer.");
161         if(name.charAt(0) < '@')
162             throw createSyntaxError( token, "Wrong Identifer '" + name + "'.");
163     }
164     
165     
166     final private boolean isKeyword(SQLToken token){
167         if(token == null) return false;
168         switch(token.value){
169             case SQLTokenizer.SELECT:
170             case SQLTokenizer.INSERT:
171             case SQLTokenizer.UPDATE:
172             case SQLTokenizer.UNION:
173             case SQLTokenizer.FROM:
174             case SQLTokenizer.WHERE:
175             case SQLTokenizer.GROUP:
176             case SQLTokenizer.HAVING:
177             case SQLTokenizer.ORDER:
178             case SQLTokenizer.COMMA:
179             case SQLTokenizer.SET:
180                 return true;
181         }
182         return false;
183     }
184     
185     /**
186      * Return the last token that the method nextToken has return
187      */

188     private SQLToken lastToken(){
189         if(tokenIdx > tokens.size()){
190             return null;
191         }
192         return (SQLToken)tokens.get( tokenIdx-1 );
193     }
194     private void previousToken(){
195         tokenIdx--;
196     }
197
198     private SQLToken nextToken(){
199         if(tokenIdx >= tokens.size()){
200             tokenIdx++; // erhöht werden, damit previousToken() funktioniert
201
return null;
202         }
203         return (SQLToken)tokens.get( tokenIdx++ );
204     }
205
206     private SQLToken nextToken( int[] validValues) throws SQLException{
207         SQLToken token = nextToken();
208         if(token == null) throw createSyntaxError( token, validValues);
209         if(validValues == MISSING_EXPRESSION) return token; // eine Expression kann in jedem Token enthalten sein
210
if(validValues == MISSING_IDENTIFER){
211             // folgende Token sind keine gültigen Identifer
212
switch(token.value){
213                 case SQLTokenizer.PARENTHESIS_L:
214                 case SQLTokenizer.PARENTHESIS_R:
215                 case SQLTokenizer.COMMA:
216                     throw createSyntaxError( token, validValues);
217             }
218             return token;
219         }
220         for(int i=validValues.length-1; i>=0; i--){
221             if(token.value == validValues[i]) return token;
222         }
223         throw createSyntaxError( token, validValues);
224     }
225     
226
227     /**
228      * A single SELECT of a UNION or only a simple single SELECT.
229      * @return
230      * @throws SQLException
231      */

232     private CommandSelect singleSelect() throws SQLException{
233         CommandSelect selCmd = new CommandSelect(con.log);
234         SQLToken token;
235         // scan for prefixe like DISTINCT, ALL and the TOP clause; sample: SELECT TOP 15 ...
236
Switch: while(true){
237             token = nextToken(MISSING_EXPRESSION);
238             switch(token.value){
239                 case SQLTokenizer.TOP:
240                     token = nextToken(MISSING_EXPRESSION);
241                     try{
242                         int maxRows = Integer.parseInt(token.getName(sql));
243                         selCmd.setMaxRows(maxRows);
244                     }catch(Exception JavaDoc e){
245                         throw createSyntaxError(token, e.getMessage());
246                     }
247                     break;
248                 case SQLTokenizer.ALL:
249                     selCmd.setDistinct(false);
250                     break;
251                 case SQLTokenizer.DISTINCT:
252                     selCmd.setDistinct(true);
253                     break;
254                 default:
255                     previousToken();
256                     break Switch;
257             }
258         }
259
260         while(true){
261             Expression column = expression(selCmd, 0);
262             selCmd.addColumnExpression( column );
263
264             token = nextToken();
265             if(token == null) return selCmd; // SELECT ohne FROM
266

267             boolean as = false;
268             if(token.value == SQLTokenizer.AS){
269                 token = nextToken(MISSING_EXPRESSION);
270                 as = true;
271             }
272
273             if(as || (!isKeyword(token))){
274                 String JavaDoc alias = token.getName( sql );
275                 checkValidIdentifer( alias, token);
276                 column.setAlias( alias );
277                 token = nextToken();
278                 if(token == null) return selCmd; // SELECT ohne FROM
279
}
280
281             switch(token.value){
282                 case SQLTokenizer.COMMA:
283                         if(column == null) throw createSyntaxError( token, MISSING_EXPRESSION );
284                         column = null;
285                         break;
286                 case SQLTokenizer.FROM:
287                         if(column == null) throw createSyntaxError( token, MISSING_EXPRESSION );
288                         column = null;
289                         from(selCmd);
290                         return selCmd;
291
292                 default:
293                         if(!isKeyword(token))
294                             throw createSyntaxError( token, new int[]{SQLTokenizer.COMMA, SQLTokenizer.FROM} );
295                         previousToken();
296                         return selCmd;
297             }
298         }
299     }
300     
301     
302     final private CommandSelect select() throws SQLException{
303         CommandSelect selCmd = singleSelect();
304         SQLToken token = nextToken();
305                 
306         UnionAll union = null;
307     
308         while(token != null && token.value == SQLTokenizer.UNION){
309             if(union == null){
310                 union = new UnionAll();
311                 union.addDataSource(new ViewResult( con, selCmd ));
312                 selCmd = new CommandSelect(con.log);
313                 selCmd.setSource( union );
314                 DataSources from = new DataSources();
315                 from.add(union);
316                 selCmd.setFrom( from );
317                 selCmd.addColumnExpression( new ExpressionName("*") );
318             }
319             nextToken(MISSING_ALL);
320             nextToken(MISSING_SELECT);
321             union.addDataSource( new ViewResult( con, singleSelect() ) );
322             token = nextToken();
323         }
324         if(token != null && token.value == SQLTokenizer.ORDER){
325             order( selCmd );
326         }else{
327             previousToken();
328         }
329         return selCmd;
330     }
331
332
333     private Command delete() throws SQLException{
334         CommandDelete cmd = new CommandDelete(con.log);
335         nextToken(MISSING_FROM);
336         from(cmd);
337         SQLToken token = nextToken();
338         if(token != null){
339             if(token.value != SQLTokenizer.WHERE)
340                 throw this.createSyntaxError(token, MISSING_WHERE);
341             where(cmd);
342         }
343         return cmd;
344     }
345
346
347     private Command truncate() throws SQLException{
348         CommandDelete cmd = new CommandDelete(con.log);
349         nextToken(MISSING_TABLE);
350         from(cmd);
351         return cmd;
352     }
353
354
355     private Command insert() throws SQLException{
356         SQLToken token = nextToken( MISSING_INTO );
357         token = nextToken( MISSING_IDENTIFER );
358         CommandInsert cmd = new CommandInsert( con.log, token.getName(sql) );
359
360         int parthesisCount = 0;
361
362         token = nextToken(MISSING_PARENTHESIS_VALUES_SELECT);
363         if(token.value == SQLTokenizer.PARENTHESIS_L){
364             token = nextToken(MISSING_EXPRESSION);
365             if(token.value == SQLTokenizer.SELECT){
366                 parthesisCount++;
367                 cmd.noColumns = true;
368             }else{
369                 previousToken();
370                 Expressions list = expressionParenthesisList(cmd);
371                 for(int i=0; i<list.size(); i++){
372                     cmd.addColumnExpression( list.get( i ) );
373                 }
374                 token = nextToken(MISSING_PARENTHESIS_VALUES_SELECT);
375             }
376         }else cmd.noColumns = true;
377         
378 Switch: while(true)
379         switch(token.value){
380             case SQLTokenizer.VALUES:{
381                 token = nextToken(MISSING_PARENTHESIS_L);
382                 cmd.addValues( expressionParenthesisList(cmd) );
383                 return cmd;
384             }
385             case SQLTokenizer.SELECT:
386                 cmd.addValues( select() );
387                 while(parthesisCount-- > 0){
388                     nextToken(MISSING_PARENTHESIS_R);
389                 }
390                 return cmd;
391             case SQLTokenizer.PARENTHESIS_L:
392                 token = nextToken(MISSING_PARENTHESIS_VALUES_SELECT);
393                 parthesisCount++;
394                 continue Switch;
395             default:
396                 throw new Error JavaDoc();
397         }
398     }
399
400
401     private Command update() throws SQLException{
402         CommandUpdate cmd = new CommandUpdate(con.log);
403         // read table name
404
DataSources tables = new DataSources();
405         cmd.setFrom( tables );
406         cmd.setSource( rowSource( cmd, tables, 0 ) );
407         
408         SQLToken token = nextToken(MISSING_SET);
409         while(true){
410             token = nextToken();
411             Expression dest = expressionSingle( cmd, token);
412             if(dest.getType() != Expression.NAME) throw createSyntaxError( token, MISSING_IDENTIFER );
413             nextToken(MISSING_EQUALS);
414             Expression src = expression(cmd, 0);
415             cmd.addSetting( dest, src);
416             token = nextToken();
417             if(token == null) break;
418             switch(token.value){
419                 case SQLTokenizer.WHERE:
420                     where(cmd);
421                     return cmd;
422                 case SQLTokenizer.COMMA:
423                     continue;
424                 default: throw createSyntaxError( token, MISSING_WHERE_COMMA );
425             }
426         }
427         return cmd;
428     }
429
430
431     private Command create() throws SQLException{
432         SQLToken token = nextToken();
433         if(token == null) throw createSyntaxError( token, COMMANDS_CREATE );
434         switch(token.value){
435             case SQLTokenizer.DATABASE:
436                 return createDatabase();
437             case SQLTokenizer.TABLE:
438                 return createTable();
439             case SQLTokenizer.VIEW:
440                 return createView();
441             case SQLTokenizer.INDEX:
442                 return createIndex();
443             case SQLTokenizer.PROCEDURE:
444                 return createProcedure();
445             default:
446                 throw createSyntaxError( token, COMMANDS_CREATE );
447         }
448     }
449     
450
451     private CommandCreateDatabase createDatabase() throws SQLException{
452         SQLToken token = nextToken();
453         if(token == null) throw createSyntaxError( token, MISSING_EXPRESSION );
454         return new CommandCreateDatabase( con.log, token.getName(sql));
455     }
456     
457
458     private CommandCreateTable createTable() throws SQLException{
459         SQLToken token = nextToken( MISSING_IDENTIFER ); // table name
460
String JavaDoc tableName = token.getName(sql);
461         CommandCreateTable cmdCreate = new CommandCreateTable( con.log, tableName);
462         token = nextToken( MISSING_PARENTHESIS_L );
463
464         nextCol:
465         while(true){
466             token = nextToken( MISSING_EXPRESSION );
467             
468             String JavaDoc constraintName;
469             if(token.value == SQLTokenizer.CONSTRAINT){
470                 // reading a CONSTRAINT with name
471
token = nextToken( MISSING_IDENTIFER );
472                 constraintName = token.getName(sql);
473                 checkValidIdentifer( constraintName, token );
474                 
475                 token = nextToken( MISSING_KEYTYPE );
476             }else{
477                 constraintName = null;
478             }
479             switch(token.value){
480                 case SQLTokenizer.PRIMARY:
481                 case SQLTokenizer.UNIQUE:
482                 case SQLTokenizer.FOREIGN:
483                     IndexDescription index = index(cmdCreate, token.value, tableName, constraintName, null);
484                     if(token.value == SQLTokenizer.FOREIGN){
485                         nextToken( MISSING_REFERENCES );
486                         token = nextToken( MISSING_IDENTIFER );
487                         String JavaDoc pk = token.getName(sql);
488                         Expressions expressions = new Expressions();
489                         Strings columns = new Strings();
490                         expressionDefList( cmdCreate, expressions, columns );
491                         IndexDescription pkIndex = new IndexDescription( null, pk, SQLTokenizer.UNIQUE, expressions, columns);
492                         ForeignKey foreignKey = new ForeignKey(pk, pkIndex, tableName, index);
493                         cmdCreate.addForeingnKey(foreignKey);
494                     }else{
495                         cmdCreate.addIndex( index );
496                     }
497     
498                     token = nextToken( MISSING_COMMA_PARENTHESIS );
499                     switch(token.value){
500                         case SQLTokenizer.PARENTHESIS_R:
501                             return cmdCreate;
502                         case SQLTokenizer.COMMA:
503                             continue nextCol;
504                     }
505             }
506             // the token is a column name
507
String JavaDoc colName = token.getName( sql );
508             
509             Column col = datatype(false);
510             col.setName( colName );
511
512             token = nextToken(MISSING_OPTIONS_DATATYPE);
513             boolean nullableWasSet = false;
514             boolean defaultWasSet = col.isAutoIncrement(); // with data type COUNTER already this value is set
515
while(true){
516                 switch(token.value){
517                     case SQLTokenizer.PARENTHESIS_R:
518                         cmdCreate.addColumn( col );
519                         return cmdCreate;
520                     case SQLTokenizer.COMMA:
521                         cmdCreate.addColumn( col );
522                         continue nextCol;
523                     case SQLTokenizer.DEFAULT:
524                         if(defaultWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS );
525                         int offset = token.offset + token.length;
526                         token = nextToken();
527                         if(token != null) offset = token.offset;
528                         previousToken();
529                         Expression expr = expression(cmdCreate, 0);
530                         SQLToken last = lastToken();
531                         int length = last.offset + last.length - offset;
532                         String JavaDoc def = new String JavaDoc( sql, offset, length );
533                         col.setDefaultValue( expr, def );
534                         defaultWasSet = true;
535                         break;
536                     case SQLTokenizer.IDENTITY:
537                         if(defaultWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS );
538                         col.setAutoIncrement(true);
539                         defaultWasSet = true;
540                         break;
541                     case SQLTokenizer.NULL:
542                         if(nullableWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS );
543                         //col.setNullable(true); ist bereits default
544
nullableWasSet = true;
545                         break;
546                     case SQLTokenizer.NOT:
547                         if(nullableWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS );
548                         token = nextToken( MISSING_NULL );
549                         col.setNullable(false);
550                         nullableWasSet = true;
551                         break;
552                     case SQLTokenizer.PARENTHESIS_L:
553                         throw createSyntaxError(token, MISSING_COMMA_PARENTHESIS);
554                     case SQLTokenizer.PRIMARY:
555                     case SQLTokenizer.UNIQUE:
556                         IndexDescription index = index(cmdCreate, token.value, tableName, null, colName);
557                         cmdCreate.addIndex( index );
558                         break;
559                     default:
560                         throw new Error JavaDoc();
561                 }
562                 token = nextToken( MISSING_OPTIONS_DATATYPE );
563             }
564         }
565     }
566     
567     /**
568      * Parse construct like:<br>
569      * <li>PRIMARY KEY (col1)
570      * <li>UNIQUE (col1, col2)
571      * <li>FOREIGN KEY REFERENCES ref_table(col1)
572      * @param cmd
573      * @param constraintType one of SQLTokenizer.PRIMARY, SQLTokenizer.UNIQUE or SQLTokenizer.FOREIGN.
574      * @param if it a constrain of the current column else null
575      * @return a new IndexDescription
576      */

577     private IndexDescription index(Command cmd, int constraintType, String JavaDoc tableName, String JavaDoc contrainName, String JavaDoc columnName) throws SQLException{
578         if(constraintType != SQLTokenizer.UNIQUE) nextToken( MISSING_KEY );
579         SQLToken token = nextToken( MISSING_EXPRESSION );
580         switch(token.value){
581             case SQLTokenizer.CLUSTERED:
582             case SQLTokenizer.NONCLUSTERED:
583                 // skipping, this tokens form MS SQL Server are ignored
584
token = nextToken( MISSING_EXPRESSION );
585                 break;
586         }
587         Strings columns = new Strings();
588         Expressions expressions = new Expressions();
589         if(columnName != null){
590             //Constraint for a single column together with the column defination
591
columns.add(columnName);
592             expressions.add(new ExpressionName(columnName));
593             previousToken();
594         }else{
595             //Constraint as addition definition
596
previousToken();
597             expressionDefList( cmd, expressions, columns );
598         }
599         return new IndexDescription( contrainName, tableName, constraintType, expressions, columns);
600     }
601
602
603     /**
604      * Read a DataTpe description. This is used for CREATE TABLE and CONVERT function.
605      * @param isEscape true then the datatypes start with SQL_
606      */

607     private Column datatype(boolean isEscape) throws SQLException{
608         SQLToken token;
609         int dataType;
610         if(isEscape){
611             token = nextToken( MISSING_SQL_DATATYPE );
612             switch(token.value){
613                 case SQLTokenizer.SQL_BIGINT: dataType = SQLTokenizer.BIGINT; break;
614                 case SQLTokenizer.SQL_BINARY: dataType = SQLTokenizer.BINARY; break;
615                 case SQLTokenizer.SQL_BIT: dataType = SQLTokenizer.BIT; break;
616                 case SQLTokenizer.SQL_CHAR: dataType = SQLTokenizer.CHAR; break;
617                 case SQLTokenizer.SQL_DATE: dataType = SQLTokenizer.DATE; break;
618                 case SQLTokenizer.SQL_DECIMAL: dataType = SQLTokenizer.DECIMAL; break;
619                 case SQLTokenizer.SQL_DOUBLE: dataType = SQLTokenizer.DOUBLE; break;
620                 case SQLTokenizer.SQL_FLOAT: dataType = SQLTokenizer.FLOAT; break;
621                 case SQLTokenizer.SQL_INTEGER: dataType = SQLTokenizer.INT; break;
622                 case SQLTokenizer.SQL_LONGVARBINARY: dataType = SQLTokenizer.LONGVARBINARY;break;
623                 case SQLTokenizer.SQL_LONGVARCHAR: dataType = SQLTokenizer.LONGVARCHAR;break;
624                 case SQLTokenizer.SQL_REAL: dataType = SQLTokenizer.REAL; break;
625                 case SQLTokenizer.SQL_SMALLINT: dataType = SQLTokenizer.SMALLINT; break;
626                 case SQLTokenizer.SQL_TIME: dataType = SQLTokenizer.TIME; break;
627                 case SQLTokenizer.SQL_TIMESTAMP: dataType = SQLTokenizer.TIMESTAMP; break;
628                 case SQLTokenizer.SQL_TINYINT: dataType = SQLTokenizer.TINYINT; break;
629                 case SQLTokenizer.SQL_VARBINARY: dataType = SQLTokenizer.VARBINARY; break;
630                 case SQLTokenizer.SQL_VARCHAR: dataType = SQLTokenizer.VARCHAR; break;
631                 default: throw new Error JavaDoc();
632             }
633         }else{
634             token = nextToken( MISSING_DATATYPE );
635             dataType = token.value;
636         }
637         Column col = new Column();
638
639         // zweiteiliger Datentyp
640
if(dataType == SQLTokenizer.LONG){
641             token = nextToken();
642             if(token != null && token.value == SQLTokenizer.RAW){
643                 dataType = SQLTokenizer.LONGVARBINARY;
644             }else{
645                 dataType = SQLTokenizer.LONGVARCHAR;
646                 previousToken();
647             }
648         }
649
650         token = nextToken( MISSING_OPTIONS_DATATYPE );
651         switch(dataType){
652             case SQLTokenizer.RAW:
653                 dataType = SQLTokenizer.VARBINARY;
654                 // no break;
655
case SQLTokenizer.CHAR:
656             case SQLTokenizer.VARCHAR:
657             case SQLTokenizer.NCHAR:
658             case SQLTokenizer.NVARCHAR:
659             case SQLTokenizer.BINARY:
660             case SQLTokenizer.VARBINARY:
661             {
662                 // maximale Spaltengröße ermitteln
663
int displaySize;
664                 if(token.value != SQLTokenizer.PARENTHESIS_L){
665                     displaySize = 30;
666                 }else{
667                     token = nextToken( MISSING_EXPRESSION );
668                     try{
669                         displaySize = Integer.parseInt(token.getName(sql) );
670                     }catch(Exception JavaDoc e){
671                         throw createSyntaxError(token, MISSING_NUMBERVALUE );
672                     }
673                     nextToken( MISSING_PARENTHESIS_R );
674                     token = nextToken(MISSING_OPTIONS_DATATYPE);
675                 }
676                 col.setPrecision( displaySize );
677                 break;
678             }
679             case SQLTokenizer.SYSNAME:
680                 col.setPrecision(255);
681                 dataType = SQLTokenizer.VARCHAR;
682                 break;
683             case SQLTokenizer.COUNTER:
684                 col.setAutoIncrement(true);
685                 dataType = SQLTokenizer.INT;
686                 break;
687             case SQLTokenizer.NUMERIC:
688             case SQLTokenizer.DECIMAL:
689                 if(token.value == SQLTokenizer.PARENTHESIS_L){
690                     // read the precision of the data type
691
token = nextToken( MISSING_EXPRESSION );
692                     int value;
693                     try{
694                         value = Integer.parseInt(token.getName(sql) );
695                     }catch(Exception JavaDoc e){
696                         throw createSyntaxError(token, MISSING_NUMBERVALUE );
697                     }
698                     col.setPrecision(value);
699                     token = nextToken( MISSING_COMMA_PARENTHESIS );
700                     if(token.value == SQLTokenizer.COMMA){
701                         // read the scale of the data type
702
token = nextToken( MISSING_EXPRESSION );
703                         try{
704                             value = Integer.parseInt(token.getName(sql) );
705                         }catch(Exception JavaDoc e){
706                             throw createSyntaxError(token, MISSING_NUMBERVALUE );
707                         }
708                         col.setScale(value);
709                         nextToken( MISSING_PARENTHESIS_R );
710                     }
711                     token = nextToken(MISSING_OPTIONS_DATATYPE);
712                 }else{
713                     col.setPrecision(18); //default Precision for decimal and numeric
714
}
715                 break;
716         }
717         col.setDataType( dataType );
718         this.previousToken();
719         return col;
720     }
721     
722     private CommandCreateView createView() throws SQLException{
723         SQLToken token = nextToken(MISSING_IDENTIFER );
724         String JavaDoc viewName = token.getName(sql);
725         checkValidIdentifer( viewName, token );
726
727         nextToken(MISSING_AS);
728         token = nextToken(MISSING_SELECT);
729         CommandCreateView cmd = new CommandCreateView( con.log, viewName );
730         
731         cmd.sql = new String JavaDoc(sql, token.offset, sql.length-token.offset );
732         select(); //Parse to check for valid
733
return cmd;
734     }
735
736
737     private CommandCreateDatabase createIndex() throws SQLException{
738         //TODO Create Index
739
throw Utils.createSQLException("UnsupportedOperation Create Index");
740     }
741
742     private CommandCreateDatabase createProcedure() throws SQLException{
743         //TODO Create Procedure
744
throw Utils.createSQLException("UnsupportedOperation Create Procedure");
745     }
746
747     private Command drop() throws SQLException{
748         SQLToken tokenType = nextToken(COMMANDS_CREATE);
749         
750         SQLToken token = nextToken( MISSING_EXPRESSION );
751         String JavaDoc catalog = null;
752         String JavaDoc name = token.getName( sql );
753         checkValidIdentifer( name, token );
754         token = nextToken();
755         //check if the object name include a database name
756
if(token != null && token.value == SQLTokenizer.POINT){
757             token = nextToken(MISSING_EXPRESSION);
758             catalog = name;
759             name = token.getName( sql );
760             checkValidIdentifer( name, token );
761             token = nextToken();
762         }
763         previousToken();
764
765         switch(tokenType.value){
766             case SQLTokenizer.DATABASE:
767             case SQLTokenizer.TABLE:
768             case SQLTokenizer.VIEW:
769             case SQLTokenizer.INDEX:
770             case SQLTokenizer.PROCEDURE:
771                 return new CommandDrop( con.log, catalog, name, tokenType.value);
772             default:
773                 throw createSyntaxError( tokenType, COMMANDS_CREATE );
774         }
775     }
776
777
778     private Command alter() throws SQLException{
779         //TODO implement ALTER
780
throw Utils.createSQLException("UnsupportedOperation Alter");
781     }
782     
783
784     private CommandSet set() throws SQLException{
785         SQLToken token = nextToken( COMMANDS_SET );
786         switch(token.value){
787             case SQLTokenizer.TRANSACTION:
788                 return setTransaction();
789             default:
790                 throw new Error JavaDoc();
791         }
792     }
793
794     private CommandSet setTransaction() throws SQLException{
795         SQLToken token = nextToken( MISSING_ISOLATION );
796         token = nextToken( MISSING_LEVEL );
797         token = nextToken( COMMANDS_TRANS_LEVEL );
798         CommandSet cmd = new CommandSet( con.log, SQLTokenizer.LEVEL );
799         switch(token.value){
800             case SQLTokenizer.READ:
801                 token = nextToken( MISSING_COMM_UNCOMM );
802                 switch(token.value){
803                     case SQLTokenizer.COMMITTED:
804                         cmd.isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
805                         break;
806                     case SQLTokenizer.UNCOMMITTED:
807                         cmd.isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
808                         break;
809                     default:
810                         throw new Error JavaDoc();
811                 }
812                 return cmd;
813             case SQLTokenizer.REPEATABLE:
814                 token = nextToken( MISSING_READ );
815                 cmd.isolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
816                 return cmd;
817             case SQLTokenizer.SERIALIZABLE:
818                 cmd.isolationLevel = Connection.TRANSACTION_SERIALIZABLE;
819                 return cmd;
820             default:
821                 throw new Error JavaDoc();
822         }
823
824
825     }
826
827     private Command execute() throws SQLException{
828         //TODO Execute
829
throw Utils.createSQLException("UnsupportedOperation Execute");
830     }
831
832     /**
833      * Read a Expression list in parenthesis like of VALUES() or functions.
834      * The left parenthesis is already consumed.
835      *
836      * @param cmd is needed to add parameters "?" with addParameter()
837      * @see #expressionDefList
838      */

839     private Expressions expressionParenthesisList(Command cmd) throws SQLException{
840         Expressions list = new Expressions();
841         {
842             SQLToken token = nextToken();
843             if(token != null && token.value == SQLTokenizer.PARENTHESIS_R){
844                 // empty list like functions without params
845
return list;
846             }
847             previousToken();
848         }
849         while(true){
850             list.add( expression(cmd, 0) );
851             SQLToken token = nextToken(MISSING_COMMA_PARENTHESIS);
852             switch(token.value){
853                 case SQLTokenizer.PARENTHESIS_R:
854                     return list;
855                 case SQLTokenizer.COMMA:
856                     continue;
857                 default:
858                     throw new Error JavaDoc();
859             }
860         }
861     }
862
863     
864     /**
865      * Read a list of expressions. The list is limit from specific SQL keywords like SELECT, GROUP BY, ORDER BY
866      */

867     private Expressions expressionTokenList(Command cmd, int listType) throws SQLException{
868         Expressions list = new Expressions();
869         while(true){
870             Expression expr = expression(cmd, 0);
871             list.add( expr );
872             SQLToken token = nextToken();
873             
874             if(listType == SQLTokenizer.ORDER && token != null){
875                 switch(token.value){
876                     case SQLTokenizer.DESC:
877                         expr.setAlias(SQLTokenizer.DESC_STR);
878                         //kein break;
879
case SQLTokenizer.ASC:
880                         token = nextToken();
881                 }
882             }
883             
884             if(token == null) {
885                 previousToken();
886                 return list;
887             }
888
889             switch(token.value){
890                 case SQLTokenizer.COMMA:
891                     continue;
892                 default:
893                     if(isKeyword(token) ){
894                         previousToken();
895                         return list;
896                     }
897                     throw createSyntaxError( token, MISSING_TOKEN_LIST);
898             }
899         }
900     }
901     
902     
903     private void expressionDefList(Command cmd, Expressions expressions, Strings columns) throws SQLException{
904         SQLToken token = nextToken();
905         if(token.value != SQLTokenizer.PARENTHESIS_L) throw createSyntaxError(token, MISSING_PARENTHESIS_L );
906         Loop:
907         while(true){
908             int offset = token.offset + token.length;
909             token = nextToken();
910             if(token != null) offset = token.offset;
911             previousToken();
912             
913             expressions.add( expression(cmd, 0) );
914             SQLToken last = lastToken();
915             int length = last.offset + last.length - offset;
916             columns.add( new String JavaDoc( sql, offset, length ) );
917
918             token = nextToken(MISSING_COMMA_PARENTHESIS);
919             switch(token.value){
920                 case SQLTokenizer.PARENTHESIS_R:
921                     break Loop;
922                 case SQLTokenizer.COMMA:
923                     continue;
924                 default:
925                     throw new Error JavaDoc();
926             }
927         }
928     }
929     
930
931     /**
932      * Read a complex expression that can be build from multiple atomic expressions.
933      * @param cmd is needed to add parameters "?" with addParameter()
934      * @param previousOperationLevel the level of the left operation.
935      */

936     private Expression expression(Command cmd, int previousOperationLevel) throws SQLException{
937         SQLToken token = nextToken();
938         if(token == null) return null;
939         Expression leftExpr;
940         switch(token.value){
941             case SQLTokenizer.NOT:
942                 leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NOT / 10), ExpressionArithmetic.NOT);
943                 break;
944             case SQLTokenizer.MINUS:
945                 leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NEGATIVE / 10), ExpressionArithmetic.NEGATIVE);
946                 break;
947             case SQLTokenizer.TILDE:
948                 leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.BIT_NOT / 10), ExpressionArithmetic.BIT_NOT);
949                 break;
950             case SQLTokenizer.PARENTHESIS_L:
951                 leftExpr = expression( cmd, 0);
952                 token = nextToken(MISSING_PARENTHESIS_R);
953                 break;
954             default:
955                 leftExpr = expressionSingle( cmd, token);
956         }
957         boolean isNot = false;
958         while((token = nextToken()) != null){
959             Expression rightExpr;
960             int operation = ExpressionArithmetic.getOperationFromToken(token.value);
961             int level = operation / 10;
962             if(previousOperationLevel >= level){
963                 previousToken();
964                 return leftExpr;
965             }
966             switch(token.value){
967                 case SQLTokenizer.PLUS:
968                 case SQLTokenizer.MINUS:
969                 case SQLTokenizer.ASTERISK:
970                 case SQLTokenizer.SLACH:
971                 case SQLTokenizer.PERCENT:
972                 case SQLTokenizer.EQUALS:
973                 case SQLTokenizer.LESSER:
974                 case SQLTokenizer.LESSER_EQU:
975                 case SQLTokenizer.GREATER:
976                 case SQLTokenizer.GREATER_EQU:
977                 case SQLTokenizer.UNEQUALS:
978                 case SQLTokenizer.LIKE:
979                 case SQLTokenizer.OR:
980                 case SQLTokenizer.AND:
981                 case SQLTokenizer.BIT_AND:
982                 case SQLTokenizer.BIT_OR:
983                 case SQLTokenizer.BIT_XOR:
984                     rightExpr = expression( cmd, level );
985                     leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, operation );
986                     break;
987                 case SQLTokenizer.BETWEEN:
988                     rightExpr = expression( cmd, ExpressionArithmetic.AND );
989                     nextToken( MISSING_AND );
990                     Expression rightExpr2 = expression( cmd, level );
991                     leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, rightExpr2, operation );
992                     break;
993                 case SQLTokenizer.IN:
994                     nextToken(MISSING_PARENTHESIS_L);
995                     token = nextToken(MISSING_EXPRESSION);
996                     if(token.value == SQLTokenizer.SELECT){
997                         CommandSelect cmdSel = select();
998                         leftExpr = new ExpressionInSelect( con, leftExpr, cmdSel, operation );
999                         nextToken(MISSING_PARENTHESIS_R);
1000                    }else{
1001                        previousToken();
1002                        Expressions list = expressionParenthesisList( cmd );
1003                        leftExpr = new ExpressionArithmetic( leftExpr, list, operation );
1004                    }
1005                    break;
1006                case SQLTokenizer.IS:
1007                    token = nextToken(MISSING_NOT_NULL);
1008                    if(token.value == SQLTokenizer.NOT){
1009                        nextToken(MISSING_NULL);
1010                        operation++;
1011                    }
1012                    leftExpr = new ExpressionArithmetic( leftExpr, operation );
1013                    break;
1014                case SQLTokenizer.NOT:
1015                    token = nextToken(MISSING_BETWEEN_IN);
1016                    previousToken();
1017                    isNot = true;
1018                    continue;
1019                default:
1020                        previousToken();
1021                        return leftExpr;
1022            }
1023            if(isNot){
1024                isNot = false;
1025                leftExpr = new ExpressionArithmetic( leftExpr, ExpressionArithmetic.NOT);
1026            }
1027        }
1028        previousToken();
1029        return leftExpr;
1030    }
1031
1032    /**
1033     * parst einen einzelne Expression, wie 12, 'qwert', 0x3F oder column name
1034     *
1035     * @param cmd is needed to add parameters "?" with addParameter()
1036     */

1037    private Expression expressionSingle(Command cmd, SQLToken token) throws SQLException{
1038        boolean isMinus = false;
1039        if(token != null){
1040            switch(token.value){
1041                case SQLTokenizer.NULL:
1042                        return new ExpressionValue( null, SQLTokenizer.NULL );
1043                case SQLTokenizer.STRING:
1044                        return new ExpressionValue( token.getName(null), SQLTokenizer.VARCHAR );
1045                case SQLTokenizer.IDENTIFER:
1046                        {
1047                        String JavaDoc name = token.getName(null);
1048                        checkValidIdentifer( name, token );
1049                        ExpressionName expr = new ExpressionName( name );
1050                        SQLToken token2 = nextToken();
1051                        if(token2 != null && token2.value == SQLTokenizer.POINT){
1052                            token = nextToken(MISSING_EXPRESSION);
1053                            expr.setNameAfterTableAlias( token.getName( sql ) );
1054                        }else{
1055                            previousToken();
1056                        }
1057                        return expr;
1058                        }
1059                case SQLTokenizer.TRUE:
1060                        return new ExpressionValue( Boolean.TRUE, SQLTokenizer.BOOLEAN );
1061                case SQLTokenizer.FALSE:
1062                        return new ExpressionValue( Boolean.FALSE, SQLTokenizer.BOOLEAN );
1063                case SQLTokenizer.ESCAPE_L:{
1064                        token = nextToken(COMMANDS_ESCAPE);
1065                        SQLToken para = nextToken(MISSING_EXPRESSION);
1066                        Expression expr;
1067                        switch(token.value){
1068                            case SQLTokenizer.D: // date escape sequence
1069
expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.DATE), SQLTokenizer.DATE );
1070                                break;
1071                            case SQLTokenizer.T: // time escape sequnce
1072
expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIME), SQLTokenizer.TIME );
1073                                break;
1074                            case SQLTokenizer.TS: // timestamp escape sequence
1075
expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIMESTAMP), SQLTokenizer.TIMESTAMP );
1076                                break;
1077                            case SQLTokenizer.FN: // function escape sequence
1078
nextToken(MISSING_PARENTHESIS_L);
1079                                expr = function(cmd, para, true);
1080                                break;
1081                            case SQLTokenizer.CALL: // call escape sequence
1082
throw new java.lang.UnsupportedOperationException JavaDoc("call escape sequence");
1083                            default: throw new Error JavaDoc();
1084                        }
1085                        token = nextToken( ESCAPE_MISSING_CLOSE );
1086                        return expr;
1087                }
1088                case SQLTokenizer.QUESTION:
1089                        ExpressionValue param = new ExpressionValue();
1090                        cmd.addParameter( param );
1091                        return param;
1092                case SQLTokenizer.CASE:
1093                        return caseExpr(cmd);
1094                case SQLTokenizer.MINUS:
1095                case SQLTokenizer.PLUS:
1096                        // Vorzeichenerkennung
1097
do{
1098                            if(token.value == SQLTokenizer.MINUS)
1099                                    isMinus = !isMinus;
1100                            token = nextToken();
1101                            if(token == null) throw createSyntaxError( token, MISSING_EXPRESSION );
1102                        }while(token.value == SQLTokenizer.MINUS || token.value == SQLTokenizer.PLUS);
1103                        // kein Break
1104
default:
1105                        SQLToken token2 = nextToken();
1106                        if(token2 != null && token2.value == SQLTokenizer.PARENTHESIS_L){
1107                            if(isMinus)
1108                                return new ExpressionArithmetic( function( cmd, token, false ), ExpressionArithmetic.NEGATIVE );
1109                            return function( cmd, token, false );
1110                        }else{
1111                            // Konstanter Ausdruck oder Identifer
1112
char chr1 = sql[ token.offset ];
1113                            if(chr1 == '$'){
1114                                previousToken();
1115                                String JavaDoc tok = new String JavaDoc(sql, token.offset+1, token.length-1);
1116                                if(isMinus) tok = "-" + tok;
1117                                return new ExpressionValue( new Money(Double.parseDouble(tok)), SQLTokenizer.MONEY );
1118                            }
1119                            String JavaDoc tok = new String JavaDoc(sql, token.offset, token.length);
1120                            if((chr1 >= '0' && '9' >= chr1) || chr1 == '.'){
1121                                previousToken();
1122                                //erstes Zeichen ein digit
1123
if(token.length>1 && (sql[ token.offset +1 ] | 0x20) == 'x'){
1124                                    // binär Daten als Hex
1125
if(isMinus) throw createSyntaxError( token, "Invalid operator binary for data type varbinary.");
1126                                    return new ExpressionValue( Utils.hex2bytes( sql, token.offset+2, token.length-2), SQLTokenizer.BINARY );
1127                                }
1128                                if(isMinus) tok = "-" + tok;
1129                                if(Utils.indexOf( '.', sql, token.offset, token.length ) >= 0 ||
1130                                   Utils.indexOf( 'e', sql, token.offset, token.length ) >= 0){
1131                                    return new ExpressionValue( new Double JavaDoc(tok), SQLTokenizer.DOUBLE );
1132                                }else{
1133                                    try{
1134                                        return new ExpressionValue( new Integer JavaDoc(tok), SQLTokenizer.INT );
1135                                    }catch(NumberFormatException JavaDoc e){
1136                                        return new ExpressionValue( new Long JavaDoc(tok), SQLTokenizer.BIGINT );
1137                                    }
1138                                }
1139                            }else{
1140                                // Bezeichner
1141
checkValidIdentifer( tok, token );
1142                                ExpressionName expr = new ExpressionName(tok);
1143                                if(token2 != null && token2.value == SQLTokenizer.POINT){
1144                                    token = nextToken(MISSING_EXPRESSION);
1145                                    expr.setNameAfterTableAlias( token.getName( sql ) );
1146                                }else{
1147                                    previousToken();
1148                                }
1149                                if(isMinus)
1150                                    return new ExpressionArithmetic( expr, ExpressionArithmetic.NEGATIVE );
1151                                return expr;
1152                            }
1153                        }
1154            }
1155        }
1156        return null;
1157    }
1158    
1159    
1160    ExpressionFunctionCase caseExpr(final Command cmd) throws SQLException{
1161        ExpressionFunctionCase expr = new ExpressionFunctionCase();
1162        SQLToken token = nextToken(MISSING_EXPRESSION);
1163        
1164        Expression input = null;
1165        if(token.value != SQLTokenizer.WHEN){
1166            // simple CASE Syntax
1167
previousToken();
1168            input = expression(cmd, 0);
1169            token = nextToken(MISSING_WHEN_ELSE_END);
1170        }
1171            
1172        while(true){
1173            switch(token.value){
1174                case SQLTokenizer.WHEN:
1175                    Expression condition = expression(cmd, 0);
1176                    if(input != null){
1177                        // simple CASE Syntax
1178
condition = new ExpressionArithmetic( input, condition, ExpressionArithmetic.EQUALS);
1179                    }
1180                    nextToken(MISSING_THEN);
1181                    Expression result = expression(cmd, 0);
1182                    expr.addCase(condition, result);
1183                    break;
1184                case SQLTokenizer.ELSE:
1185                    expr.setElseResult(expression(cmd, 0));
1186                    break;
1187                case SQLTokenizer.END:
1188                    expr.setEnd();
1189                    return expr;
1190                default:
1191                    throw new Error JavaDoc();
1192            }
1193            token = nextToken(MISSING_WHEN_ELSE_END);
1194        }
1195    }
1196    
1197
1198    /**
1199     * Parse any functions. The left parenthesis is already consumed from token list.
1200     * @param token the SQLToken of the function
1201     * @param isEscape If the function is a FN ESCAPE sequence
1202     */

1203    private Expression function( Command cmd, SQLToken token, boolean isEscape ) throws SQLException{
1204        Expression expr;
1205        switch(token.value){
1206            case SQLTokenizer.CONVERT:{
1207                Column col;
1208                Expression style = null;
1209                if(isEscape){
1210                    expr = expression( cmd, 0);
1211                    nextToken(MISSING_COMMA);
1212                    col = datatype(isEscape);
1213                }else{
1214                    col = datatype(isEscape);
1215                    nextToken(MISSING_COMMA);
1216                    expr = expression( cmd, 0);
1217                    token = nextToken(MISSING_COMMA_PARENTHESIS);
1218                    if(token.value == SQLTokenizer.COMMA){
1219                        style = expression( cmd, 0);
1220                    }else
1221                        previousToken();
1222                }
1223                nextToken(MISSING_PARENTHESIS_R);
1224                return new ExpressionFunctionConvert( col, expr, style );
1225            }
1226            case SQLTokenizer.CAST:
1227                expr = expression( cmd, 0);
1228                nextToken(MISSING_AS);
1229                Column col = datatype(false);
1230                nextToken(MISSING_PARENTHESIS_R);
1231                return new ExpressionFunctionConvert( col, expr, null );
1232            case SQLTokenizer.TIMESTAMPDIFF:
1233                token = nextToken(MISSING_INTERVALS);
1234                nextToken(MISSING_COMMA);
1235                expr = expression( cmd, 0);
1236                nextToken(MISSING_COMMA);
1237                expr = new ExpressionFunctionTimestampDiff( token.value, expr, expression( cmd, 0));
1238                nextToken(MISSING_PARENTHESIS_R);
1239                return expr;
1240            case SQLTokenizer.TIMESTAMPADD:
1241                token = nextToken(MISSING_INTERVALS);
1242                nextToken(MISSING_COMMA);
1243                expr = expression( cmd, 0);
1244                nextToken(MISSING_COMMA);
1245                expr = new ExpressionFunctionTimestampAdd( token.value, expr, expression( cmd, 0));
1246                nextToken(MISSING_PARENTHESIS_R);
1247                return expr;
1248        }
1249        Expressions paramList = expressionParenthesisList(cmd);
1250        int paramCount = paramList.size();
1251        Expression[] params = paramList.toArray();
1252        boolean invalidParamCount;
1253        switch(token.value){
1254        // numeric functions:
1255
case SQLTokenizer.ABS:
1256                invalidParamCount = (paramCount != 1);
1257                expr = new ExpressionFunctionAbs();
1258                break;
1259            case SQLTokenizer.ACOS:
1260                invalidParamCount = (paramCount != 1);
1261                expr = new ExpressionFunctionACos();
1262                break;
1263            case SQLTokenizer.ASIN:
1264                invalidParamCount = (paramCount != 1);
1265                expr = new ExpressionFunctionASin();
1266                break;
1267            case SQLTokenizer.ATAN:
1268                invalidParamCount = (paramCount != 1);
1269                expr = new ExpressionFunctionATan();
1270                break;
1271            case SQLTokenizer.ATAN2:
1272                invalidParamCount = (paramCount != 2);
1273                expr = new ExpressionFunctionATan2();
1274                break;
1275            case SQLTokenizer.CEILING:
1276                invalidParamCount = (paramCount != 1);
1277                expr = new ExpressionFunctionCeiling();
1278                break;
1279            case SQLTokenizer.COS:
1280                invalidParamCount = (paramCount != 1);
1281                expr = new ExpressionFunctionCos();
1282                break;
1283            case SQLTokenizer.COT:
1284                invalidParamCount = (paramCount != 1);
1285                expr = new ExpressionFunctionCot();
1286                break;
1287            case SQLTokenizer.DEGREES:
1288                invalidParamCount = (paramCount != 1);
1289                expr = new ExpressionFunctionDegrees();
1290                break;
1291            case SQLTokenizer.EXP:
1292                invalidParamCount = (paramCount != 1);
1293                expr = new ExpressionFunctionExp();
1294                break;
1295            case SQLTokenizer.FLOOR:
1296                invalidParamCount = (paramCount != 1);
1297                expr = new ExpressionFunctionFloor();
1298                break;
1299            case SQLTokenizer.LOG:
1300                invalidParamCount = (paramCount != 1);
1301                expr = new ExpressionFunctionLog();
1302                break;
1303            case SQLTokenizer.LOG10:
1304                invalidParamCount = (paramCount != 1);
1305                expr = new ExpressionFunctionLog10();
1306                break;
1307            case SQLTokenizer.MOD:
1308                invalidParamCount = (paramCount != 2);
1309                expr = new ExpressionFunctionMod();
1310                break;
1311            case SQLTokenizer.PI:
1312                invalidParamCount = (paramCount != 0);
1313                expr = new ExpressionFunctionPI();
1314                break;
1315            case SQLTokenizer.POWER:
1316                invalidParamCount = (paramCount != 2);
1317                expr = new ExpressionFunctionPower();
1318                break;
1319            case SQLTokenizer.RADIANS:
1320                invalidParamCount = (paramCount != 1);
1321                expr = new ExpressionFunctionRadians();
1322                break;
1323            case SQLTokenizer.RAND:
1324                invalidParamCount = (paramCount != 0) && (paramCount != 1);
1325                expr = new ExpressionFunctionRand();
1326                break;
1327            case SQLTokenizer.ROUND:
1328                invalidParamCount = (paramCount != 2);
1329                expr = new ExpressionFunctionRound();
1330                break;
1331            case SQLTokenizer.SIN:
1332                invalidParamCount = (paramCount != 1);
1333                expr = new ExpressionFunctionSin();
1334                break;
1335            case SQLTokenizer.SIGN:
1336                invalidParamCount = (paramCount != 1);
1337                expr = new ExpressionFunctionSign();
1338                break;
1339            case SQLTokenizer.SQRT:
1340                invalidParamCount = (paramCount != 1);
1341                expr = new ExpressionFunctionSqrt();
1342                break;
1343            case SQLTokenizer.TAN:
1344                invalidParamCount = (paramCount != 1);
1345                expr = new ExpressionFunctionTan();
1346                break;
1347            case SQLTokenizer.TRUNCATE:
1348                invalidParamCount = (paramCount != 2);
1349                expr = new ExpressionFunctionTruncate();
1350                break;
1351         
1352        // string functions:
1353
case SQLTokenizer.ASCII:
1354                invalidParamCount = (paramCount != 1);
1355                expr = new ExpressionFunctionAscii();
1356                break;
1357            case SQLTokenizer.CHAR:
1358                invalidParamCount = (paramCount != 1);
1359                expr = new ExpressionFunctionChar();
1360                break;
1361            case SQLTokenizer.CONCAT:
1362                if(paramCount != 2){
1363                    invalidParamCount = true;
1364                    expr = null;//only for compiler
1365
break;
1366                }
1367                invalidParamCount = false;
1368                expr = new ExpressionArithmetic( params[0], params[1], ExpressionArithmetic.ADD);
1369                break;
1370            case SQLTokenizer.DIFFERENCE:
1371                invalidParamCount = (paramCount != 2);
1372                expr = new ExpressionFunctionDifference();
1373                break;
1374            case SQLTokenizer.INSERT:
1375                invalidParamCount = (paramCount != 4);
1376                expr = new ExpressionFunctionInsert();
1377                break;
1378            case SQLTokenizer.LCASE:
1379                invalidParamCount = (paramCount != 1);
1380                expr = new ExpressionFunctionLCase();
1381                break;
1382            case SQLTokenizer.LEFT:
1383                invalidParamCount = (paramCount != 2);
1384                expr = new ExpressionFunctionLeft();
1385                break;
1386            case SQLTokenizer.LENGTH:
1387                invalidParamCount = (paramCount != 1);
1388                expr = new ExpressionFunctionLength();
1389                break;
1390            case SQLTokenizer.LOCATE:
1391                invalidParamCount = (paramCount != 2) && (paramCount != 3);
1392                expr = new ExpressionFunctionLocate();
1393                break;
1394            case SQLTokenizer.LTRIM:
1395                invalidParamCount = (paramCount != 1);
1396                expr = new ExpressionFunctionLTrim();
1397                break;
1398            case SQLTokenizer.REPEAT:
1399                invalidParamCount = (paramCount != 2);
1400                expr = new ExpressionFunctionRepeat();
1401                break;
1402            case SQLTokenizer.REPLACE:
1403                invalidParamCount = (paramCount != 3);
1404                expr = new ExpressionFunctionReplace();
1405                break;
1406            case SQLTokenizer.RIGHT:
1407                invalidParamCount = (paramCount != 2);
1408                expr = new ExpressionFunctionRight();
1409                break;
1410            case SQLTokenizer.RTRIM:
1411                invalidParamCount = (paramCount != 1);
1412                expr = new ExpressionFunctionRTrim();
1413                break;
1414            case SQLTokenizer.SPACE:
1415                invalidParamCount = (paramCount != 1);
1416                expr = new ExpressionFunctionSpace();
1417                break;
1418            case SQLTokenizer.SOUNDEX:
1419                invalidParamCount = (paramCount != 1);
1420                expr = new ExpressionFunctionSoundex();
1421                break;
1422            case SQLTokenizer.SUBSTRING:
1423                invalidParamCount = (paramCount != 3);
1424                expr = new ExpressionFunctionSubstring();
1425                break;
1426            case SQLTokenizer.UCASE:
1427                invalidParamCount = (paramCount != 1);
1428                expr = new ExpressionFunctionUCase();
1429                break;
1430                
1431        // date time functions
1432
case SQLTokenizer.CURDATE:
1433                invalidParamCount = (paramCount != 0);
1434                expr = new ExpressionValue( new DateTime(DateTime.now(), SQLTokenizer.DATE), SQLTokenizer.DATE);
1435                break;
1436            case SQLTokenizer.CURTIME:
1437                invalidParamCount = (paramCount != 0);
1438                expr = new ExpressionValue( new DateTime(DateTime.now(), SQLTokenizer.TIME), SQLTokenizer.TIME);
1439                break;
1440            case SQLTokenizer.DAYOFMONTH:
1441                invalidParamCount = (paramCount != 1);
1442                expr = new ExpressionFunctionDayOfMonth();
1443                break;
1444            case SQLTokenizer.DAYOFWEEK:
1445                invalidParamCount = (paramCount != 1);
1446                expr = new ExpressionFunctionDayOfWeek();
1447                break;
1448            case SQLTokenizer.DAYOFYEAR:
1449                invalidParamCount = (paramCount != 1);
1450                expr = new ExpressionFunctionDayOfYear();
1451                break;
1452            case SQLTokenizer.HOUR:
1453                invalidParamCount = (paramCount != 1);
1454                expr = new ExpressionFunctionHour();
1455                break;
1456            case SQLTokenizer.MINUTE:
1457                invalidParamCount = (paramCount != 1);
1458                expr = new ExpressionFunctionMinute();
1459                break;
1460            case SQLTokenizer.MONTH:
1461                invalidParamCount = (paramCount != 1);
1462                expr = new ExpressionFunctionMonth();
1463                break;
1464            case SQLTokenizer.NOW:
1465                invalidParamCount = (paramCount != 0);
1466                expr = new ExpressionValue( new DateTime(DateTime.now(), SQLTokenizer.TIMESTAMP), SQLTokenizer.TIMESTAMP);
1467                break;
1468                
1469        // system functions:
1470
case SQLTokenizer.IIF:
1471                invalidParamCount = (paramCount != 3);
1472                expr = new ExpressionFunctionIIF();
1473                break;
1474            case SQLTokenizer.SWITCH:
1475                invalidParamCount = (paramCount % 2 != 0);
1476                ExpressionFunctionCase exprCase = new ExpressionFunctionCase();
1477                for(int i=0; i < paramCount-1; i +=2)
1478                    exprCase.addCase(params[i], params[i+1] );
1479                exprCase.setEnd();
1480                expr = exprCase;
1481                break;
1482            case SQLTokenizer.IFNULL:
1483                switch(paramCount){
1484                    case 1:
1485                        return new ExpressionArithmetic( params[0], ExpressionArithmetic.ISNULL );
1486                    case 2:
1487                        invalidParamCount = false;
1488                        expr = new ExpressionFunctionIIF();
1489                        Expression[] newParams = new Expression[3];
1490                        newParams[0] = new ExpressionArithmetic( params[0], ExpressionArithmetic.ISNULL );
1491                        newParams[1] = params[1];
1492                        newParams[2] = params[0];
1493                        params = newParams;
1494                        paramCount = 3;
1495                        break;
1496                    default:
1497                        invalidParamCount = true;
1498                        expr = null; // only for Compiler
1499
}
1500                break;
1501                    
1502        // now come the aggregate functions
1503
case SQLTokenizer.COUNT:
1504                    invalidParamCount = (paramCount != 1);
1505                    if(params[0].getType() == Expression.NAME){
1506                        //detect special case COUNT(*)
1507
ExpressionName param = (ExpressionName)params[0];
1508                        if("*".equals(param.getName()) && param.getTableAlias() == null){
1509                            params[0] = new ExpressionValue();
1510                        }
1511                    }
1512                    expr = new ExpressionName( Expression.COUNT );
1513                    break;
1514            case SQLTokenizer.SUM:
1515                    invalidParamCount = (paramCount != 1);
1516                    expr = new ExpressionName( Expression.SUM );
1517                    break;
1518            case SQLTokenizer.MAX:
1519                    invalidParamCount = (paramCount != 1);
1520                    expr = new ExpressionName( Expression.MAX );
1521                    break;
1522            case SQLTokenizer.MIN:
1523                    invalidParamCount = (paramCount != 1);
1524                    expr = new ExpressionName( Expression.MIN );
1525                    break;
1526            case SQLTokenizer.FIRST:
1527                    invalidParamCount = (paramCount != 1);
1528                    expr = new ExpressionName( Expression.FIRST );
1529                    break;
1530            case SQLTokenizer.LAST:
1531                    invalidParamCount = (paramCount != 1);
1532                    expr = new ExpressionName( Expression.LAST );
1533                    break;
1534            case SQLTokenizer.AVG:
1535                    if(paramCount != 1){
1536                        invalidParamCount = true;
1537                        expr = null;//Only for the compiler
1538
break;
1539                    }
1540                    expr = new ExpressionName( Expression.SUM );
1541                    expr.setParams( params );
1542                    Expression expr2 = new ExpressionName( Expression.COUNT );
1543                    expr2.setParams( params );
1544                    expr = new ExpressionArithmetic( expr, expr2, ExpressionArithmetic.DIV );
1545                    return expr;
1546            default: throw createSyntaxError(token, "Unknown function.");
1547        }
1548        if(invalidParamCount) throw createSyntaxError( token, "Invalid parameter count." );
1549        expr.setParams( params );
1550        return expr;
1551    }
1552
1553    /**
1554     * read a table or view name in a FROM clause. If the keyword AS exists then read it also the alias
1555     */

1556    private RowSource tableSource( Command cmd, DataSources tables) throws SQLException{
1557        SQLToken token = nextToken(MISSING_EXPRESSION);
1558        switch(token.value){
1559            case SQLTokenizer.PARENTHESIS_L: // (
1560
return rowSource( cmd, tables, SQLTokenizer.PARENTHESIS_R );
1561            case SQLTokenizer.ESCAPE_L: // {
1562
token = nextToken(MISSING_OJ);
1563                    return rowSource( cmd, tables, SQLTokenizer.ESCAPE_R );
1564            case SQLTokenizer.SELECT:
1565                    // inner select
1566
ViewResult viewResult = new ViewResult( con, select() );
1567                    tables.add(viewResult);
1568                    return viewResult;
1569        }
1570        String JavaDoc catalog = null;
1571        String JavaDoc name = token.getName( sql );
1572        checkValidIdentifer( name, token );
1573        token = nextToken();
1574        //check if the table name include a database name
1575
if(token != null && token.value == SQLTokenizer.POINT){
1576            token = nextToken(MISSING_EXPRESSION);
1577            catalog = name;
1578            name = token.getName( sql );
1579            checkValidIdentifer( name, token );
1580            token = nextToken();
1581        }
1582        //TableResult table = new TableResult();
1583
//table.setName( catalog, name );
1584
TableView tableView = Database.getTableView( con, catalog, name);
1585        TableViewResult table = TableViewResult.createResult(tableView);
1586        tables.add( table );
1587
1588        if(token != null && token.value == SQLTokenizer.AS){
1589            // skip AS keyword, if exists
1590
token = nextToken(MISSING_EXPRESSION);
1591            table.setAlias( token.getName( sql ) );
1592        }else{
1593            previousToken();
1594        }
1595        return table;
1596    }
1597
1598    /**
1599     * read a join in a from clause.
1600     */

1601    private Join join(Command cmd, DataSources tables, RowSource left, int type) throws SQLException{
1602        RowSource right = rowSource(cmd, tables, 0);
1603        SQLToken token = nextToken();
1604
1605        while(true){
1606            if(token == null) throw createSyntaxError(null, "Invalid Join Syntax");
1607
1608            switch(token.value){
1609                case SQLTokenizer.ON:
1610                    if(type == Join.RIGHT_JOIN)
1611                        return new Join( Join.LEFT_JOIN, right, left, expression( cmd, 0 ) );
1612                    return new Join( type, left, right, expression( cmd, 0 ) );
1613                default:
1614                    if(!right.hasAlias()){
1615                        right.setAlias( token.getName( sql ) );
1616                        token = nextToken();
1617                        continue;
1618                    }
1619                    throw createSyntaxError( token, new int[]{SQLTokenizer.ON} );
1620            }
1621        }
1622    }
1623
1624    /**
1625     * returns a row source. A row source is a Table, Join, View or a row function.
1626     *
1627     */

1628    private RowSource rowSource(Command cmd, DataSources tables, int parenthesis) throws SQLException{
1629        RowSource fromSource = null;
1630        fromSource = tableSource(cmd, tables);
1631
1632        while(true){
1633            SQLToken token = nextToken();
1634            if(token == null) return fromSource;
1635            switch(token.value){
1636                case SQLTokenizer.ON:
1637                    previousToken();
1638                    return fromSource;
1639                case SQLTokenizer.CROSS:
1640                    nextToken(MISSING_JOIN);
1641                    // kein break
1642
case SQLTokenizer.COMMA:
1643                    fromSource = new Join( Join.CROSS_JOIN, fromSource, tableSource(cmd, tables), null);
1644                    break;
1645                case SQLTokenizer.INNER:
1646                    nextToken(MISSING_JOIN);
1647                    fromSource = join( cmd, tables, fromSource, Join.INNER_JOIN );
1648                    break;
1649                case SQLTokenizer.LEFT:
1650                    token = nextToken(MISSING_OUTER_JOIN);
1651                    if(token.value == SQLTokenizer.OUTER)
1652                        token = nextToken(MISSING_JOIN);
1653                    fromSource = join( cmd, tables, fromSource, Join.LEFT_JOIN );
1654                    break;
1655                case SQLTokenizer.RIGHT:
1656                    token = nextToken(MISSING_OUTER_JOIN);
1657                    if(token.value == SQLTokenizer.OUTER)
1658                        token = nextToken(MISSING_JOIN);
1659                    fromSource = join( cmd, tables, fromSource, Join.RIGHT_JOIN );
1660                    break;
1661                case SQLTokenizer.FULL:
1662                    token = nextToken(MISSING_OUTER_JOIN);
1663                    if(token.value == SQLTokenizer.OUTER)
1664                        token = nextToken(MISSING_JOIN);
1665                    fromSource = join( cmd, tables, fromSource, Join.FULL_JOIN );
1666                    break;
1667                case SQLTokenizer.PARENTHESIS_R:
1668                case SQLTokenizer.ESCAPE_R:
1669                    if(parenthesis == token.value) return fromSource;
1670                    if(parenthesis == 0){
1671                        previousToken();
1672                        return fromSource;
1673                    }
1674                    throw createSyntaxError( token, "Unexpexted closing parethesis in from clause." );
1675                default:
1676                    if(isKeyword(token)){
1677                        previousToken();
1678                        return fromSource;
1679                    }
1680                    if(!fromSource.hasAlias()){
1681                        fromSource.setAlias( token.getName( sql ) );
1682                        break;
1683                    }
1684                    throw createSyntaxError( token, new int[]{SQLTokenizer.COMMA, SQLTokenizer.GROUP, SQLTokenizer.ORDER, SQLTokenizer.HAVING} );
1685            }
1686        }
1687    }
1688
1689    private void from(CommandSelect cmd) throws SQLException{
1690        DataSources tables = new DataSources();
1691        cmd.setFrom(tables);
1692        cmd.setSource( rowSource( cmd, tables, 0 ) );
1693
1694        SQLToken token;
1695        while(null != (token = nextToken())){
1696            switch(token.value){
1697                case SQLTokenizer.WHERE:
1698                    where( cmd );
1699                    break;
1700                case SQLTokenizer.GROUP:
1701                    group( cmd );
1702                    break;
1703                case SQLTokenizer.HAVING:
1704                    having( cmd );
1705                    break;
1706                default:
1707                    previousToken();
1708                    return;
1709            }
1710        }
1711    }
1712
1713    private void order(CommandSelect cmd) throws SQLException{
1714        nextToken(MISSING_BY);
1715        cmd.setOrder( expressionTokenList(cmd, SQLTokenizer.ORDER) );
1716    }
1717
1718    private void group(CommandSelect cmd) throws SQLException{
1719        nextToken(MISSING_BY);
1720        cmd.setGroup( expressionTokenList(cmd, SQLTokenizer.GROUP) );
1721    }
1722
1723    private void where(CommandSelect cmd) throws SQLException{
1724        cmd.setWhere( expression(cmd, 0) );
1725    }
1726
1727    private void having(CommandSelect cmd) throws SQLException{
1728        cmd.setHaving( expression(cmd, 0) );
1729    }
1730
1731
1732    private static final int[] COMMANDS = {SQLTokenizer.SELECT, SQLTokenizer.DELETE, SQLTokenizer.INSERT, SQLTokenizer.UPDATE, SQLTokenizer.CREATE, SQLTokenizer.DROP, SQLTokenizer.ALTER, SQLTokenizer.SET, SQLTokenizer.USE, SQLTokenizer.EXECUTE, SQLTokenizer.TRUNCATE};
1733    private static final int[] COMMANDS_ESCAPE = {SQLTokenizer.D, SQLTokenizer.T, SQLTokenizer.TS, SQLTokenizer.FN, SQLTokenizer.CALL};
1734    private static final int[] COMMANDS_CREATE = {SQLTokenizer.DATABASE, SQLTokenizer.TABLE, SQLTokenizer.VIEW, SQLTokenizer.INDEX, SQLTokenizer.PROCEDURE};
1735    private static final int[] COMMANDS_SET = {SQLTokenizer.TRANSACTION};
1736    private static final int[] MISSING_TABLE = {SQLTokenizer.TABLE};
1737    private static final int[] ESCAPE_MISSING_CLOSE = {SQLTokenizer.ESCAPE_R};
1738    private static final int[] MISSING_EXPRESSION = {SQLTokenizer.VALUE};
1739    private static final int[] MISSING_IDENTIFER = {SQLTokenizer.IDENTIFER};
1740    private static final int[] MISSING_BY = {SQLTokenizer.BY};
1741    private static final int[] MISSING_PARENTHESIS_L = {SQLTokenizer.PARENTHESIS_L};
1742    private static final int[] MISSING_PARENTHESIS_R = {SQLTokenizer.PARENTHESIS_R};
1743    private static final int[] MISSING_DATATYPE = {SQLTokenizer.BIT, SQLTokenizer.BOOLEAN, SQLTokenizer.BINARY, SQLTokenizer.VARBINARY, SQLTokenizer.RAW, SQLTokenizer.LONGVARBINARY, SQLTokenizer.BLOB, SQLTokenizer.TINYINT, SQLTokenizer.SMALLINT, SQLTokenizer.INT, SQLTokenizer.COUNTER, SQLTokenizer. BIGINT, SQLTokenizer.SMALLMONEY, SQLTokenizer.MONEY, SQLTokenizer.DECIMAL, SQLTokenizer.NUMERIC, SQLTokenizer.REAL, SQLTokenizer.FLOAT, SQLTokenizer.DOUBLE, SQLTokenizer.DATE, SQLTokenizer.TIME, SQLTokenizer.TIMESTAMP, SQLTokenizer.SMALLDATETIME, SQLTokenizer.CHAR, SQLTokenizer.NCHAR, SQLTokenizer.VARCHAR, SQLTokenizer.NVARCHAR, SQLTokenizer.LONG, SQLTokenizer.LONGNVARCHAR, SQLTokenizer.LONGVARCHAR, SQLTokenizer.CLOB, SQLTokenizer.NCLOB, SQLTokenizer.UNIQUEIDENTIFIER, SQLTokenizer.JAVA_OBJECT, SQLTokenizer.SYSNAME};
1744    private static final int[] MISSING_SQL_DATATYPE = { SQLTokenizer.SQL_BIGINT , SQLTokenizer.SQL_BINARY , SQLTokenizer.SQL_BIT , SQLTokenizer.SQL_CHAR , SQLTokenizer.SQL_DATE , SQLTokenizer.SQL_DECIMAL , SQLTokenizer.SQL_DOUBLE , SQLTokenizer.SQL_FLOAT , SQLTokenizer.SQL_INTEGER , SQLTokenizer.SQL_LONGVARBINARY , SQLTokenizer.SQL_LONGVARCHAR , SQLTokenizer.SQL_REAL , SQLTokenizer.SQL_SMALLINT , SQLTokenizer.SQL_TIME , SQLTokenizer.SQL_TIMESTAMP , SQLTokenizer.SQL_TINYINT , SQLTokenizer.SQL_VARBINARY , SQLTokenizer.SQL_VARCHAR };
1745    private static final int[] MISSING_INTO = {SQLTokenizer.INTO};
1746    private static final int[] MISSING_BETWEEN_IN = {SQLTokenizer.BETWEEN, SQLTokenizer.IN};
1747    private static final int[] MISSING_NOT_NULL = {SQLTokenizer.NOT, SQLTokenizer.NULL};
1748    private static final int[] MISSING_NULL = {SQLTokenizer.NULL};
1749    private static final int[] MISSING_COMMA = {SQLTokenizer.COMMA};
1750    private static final int[] MISSING_COMMA_PARENTHESIS = {SQLTokenizer.COMMA, SQLTokenizer.PARENTHESIS_R};
1751    private static final int[] MISSING_PARENTHESIS_VALUES_SELECT = {SQLTokenizer.PARENTHESIS_L, SQLTokenizer.VALUES, SQLTokenizer.SELECT};
1752    private static final int[] MISSING_TOKEN_LIST = {SQLTokenizer.COMMA, SQLTokenizer.FROM, SQLTokenizer.GROUP, SQLTokenizer.HAVING, SQLTokenizer.ORDER};
1753    private static final int[] MISSING_FROM = {SQLTokenizer.FROM};
1754    private static final int[] MISSING_SET = {SQLTokenizer.SET};
1755    private static final int[] MISSING_EQUALS = {SQLTokenizer.EQUALS};
1756    private static final int[] MISSING_WHERE = {SQLTokenizer.WHERE};
1757    private static final int[] MISSING_WHERE_COMMA = {SQLTokenizer.WHERE, SQLTokenizer.COMMA};
1758    private static final int[] MISSING_ISOLATION = {SQLTokenizer.ISOLATION};
1759    private static final int[] MISSING_LEVEL = {SQLTokenizer.LEVEL};
1760    private static final int[] COMMANDS_TRANS_LEVEL = {SQLTokenizer.READ, SQLTokenizer.REPEATABLE, SQLTokenizer.SERIALIZABLE};
1761    private static final int[] MISSING_READ = {SQLTokenizer.READ};
1762    private static final int[] MISSING_COMM_UNCOMM = {SQLTokenizer.COMMITTED, SQLTokenizer.UNCOMMITTED};
1763    private static final int[] MISSING_OPTIONS_DATATYPE = { SQLTokenizer.DEFAULT, SQLTokenizer.IDENTITY, SQLTokenizer.NOT, SQLTokenizer.NULL, SQLTokenizer.PRIMARY, SQLTokenizer.UNIQUE, SQLTokenizer.COMMA, SQLTokenizer.PARENTHESIS_R, SQLTokenizer.PARENTHESIS_L};
1764    private static final int[] MISSING_NUMBERVALUE = {SQLTokenizer.NUMBERVALUE};
1765    private static final int[] MISSING_AND = {SQLTokenizer.AND};
1766    private static final int[] MISSING_JOIN = {SQLTokenizer.JOIN};
1767    private static final int[] MISSING_OUTER_JOIN = {SQLTokenizer.OUTER, SQLTokenizer.JOIN};
1768    private static final int[] MISSING_OJ = {SQLTokenizer.OJ};
1769    private static final int[] MISSING_KEYTYPE = {SQLTokenizer.PRIMARY, SQLTokenizer.UNIQUE, SQLTokenizer.FOREIGN};
1770    private static final int[] MISSING_KEY = {SQLTokenizer.KEY};
1771    private static final int[] MISSING_REFERENCES = {SQLTokenizer.REFERENCES};
1772    private static final int[] MISSING_AS = {SQLTokenizer.AS};
1773    private static final int[] MISSING_SELECT = {SQLTokenizer.SELECT};
1774    private static final int[] MISSING_INTERVALS = {SQLTokenizer.SQL_TSI_FRAC_SECOND, SQLTokenizer.SQL_TSI_SECOND, SQLTokenizer.SQL_TSI_MINUTE, SQLTokenizer.SQL_TSI_HOUR, SQLTokenizer.SQL_TSI_DAY, SQLTokenizer.SQL_TSI_WEEK, SQLTokenizer.SQL_TSI_MONTH, SQLTokenizer.SQL_TSI_QUARTER, SQLTokenizer.SQL_TSI_YEAR, SQLTokenizer.MILLISECOND, SQLTokenizer.SECOND, SQLTokenizer.MINUTE, SQLTokenizer.HOUR, SQLTokenizer.DAY, SQLTokenizer.WEEK, SQLTokenizer.MONTH, SQLTokenizer.QUARTER, SQLTokenizer.YEAR, SQLTokenizer.D};
1775    private static final int[] MISSING_ALL = {SQLTokenizer.ALL};
1776    private static final int[] MISSING_THEN = {SQLTokenizer.THEN};
1777    private static final int[] MISSING_WHEN_ELSE_END = {SQLTokenizer.WHEN, SQLTokenizer.ELSE, SQLTokenizer.END};
1778    
1779    
1780}
Popular Tags