Jelajahi Sumber

HADOOP-2502 Insert/Select timestamp, Timestamp data type in HQL

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/trunk@609730 13f79535-47bb-0310-9956-ffa450edef68
Michael Stack 17 tahun lalu
induk
melakukan
c17b3467f0

+ 2 - 0
src/contrib/hbase/CHANGES.txt

@@ -154,6 +154,8 @@ Trunk (unreleased changes)
    HADOOP-2471 Add reading/writing MapFile to PerformanceEvaluation suite
    HADOOP-2522 Separate MapFile benchmark from PerformanceEvaluation
                (Tom White via Stack)
+   HADOOP-2502 Insert/Select timestamp, Timestamp data type in HQL
+               (Edward Yoon via Stack)
                
 
 

+ 0 - 6
src/contrib/hbase/build.xml

@@ -69,17 +69,11 @@
   <property name="hbaseshell.src.dir" 
        value="${src.dir}/org/apache/hadoop/hbase/shell" /> 
      <mkdir dir="${hbaseshell.src.dir}/generated" />
-     <mkdir dir="${hbaseshell.src.dir}/algebra/generated"/>
      <javacc
        target="${hbaseshell.src.dir}/HBaseShell.jj"
        outputdirectory="${hbaseshell.src.dir}/generated"
        javacchome="${javacc.home}"
      />
-     <javacc
-       target="${hbaseshell.src.dir}/algebra/ExpressionParser.jj"
-       outputdirectory="${hbaseshell.src.dir}/algebra/generated"
-       javacchome="${javacc.home}"
-     />
   </target>
 
   <target name="compile" depends="init,javacc">

+ 2 - 2
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/CreateCommand.java

@@ -46,8 +46,8 @@ public class CreateCommand extends SchemaModificationCommand {
   public ReturnMsg execute(HBaseConfiguration conf) {
     try {
       HConnection conn = HConnectionManager.getConnection(conf);
-      if (conn.tableExists(this.tableName)) {
-        return new ReturnMsg(0, "'" + this.tableName + "' table already exist.");
+      if (conn.tableExists(tableName)) {
+        return new ReturnMsg(0, "'" + tableName + "' table already exist.");
       }
 
       HBaseAdmin admin = new HBaseAdmin(conf);

+ 5 - 5
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/DeleteCommand.java

@@ -102,17 +102,17 @@ public class DeleteCommand extends BasicCommand {
   public Text[] getColumnList(HBaseAdmin admin, HTable hTable) {
     Text[] columns = null;
     try {
-      if (this.columnList.contains("*")) {
+      if (columnList.contains("*")) {
         columns = hTable.getRow(new Text(this.rowKey)).keySet().toArray(
             new Text[] {});
       } else {
         List<Text> tmpList = new ArrayList<Text>();
-        for (int i = 0; i < this.columnList.size(); i++) {
+        for (int i = 0; i < columnList.size(); i++) {
           Text column = null;
-          if (this.columnList.get(i).contains(":"))
-            column = new Text(this.columnList.get(i));
+          if (columnList.get(i).contains(":"))
+            column = new Text(columnList.get(i));
           else
-            column = new Text(this.columnList.get(i) + ":");
+            column = new Text(columnList.get(i) + ":");
 
           tmpList.add(column);
         }

+ 3 - 3
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/DescCommand.java

@@ -49,17 +49,17 @@ public class DescCommand extends BasicCommand {
   }
 
   public ReturnMsg execute(final HBaseConfiguration conf) {
-    if (this.tableName == null)
+    if (tableName == null)
       return new ReturnMsg(0, "Syntax error : Please check 'Describe' syntax.");
     try {
       HConnection conn = HConnectionManager.getConnection(conf);
-      if (!conn.tableExists(this.tableName)) {
+      if (!conn.tableExists(tableName)) {
         return new ReturnMsg(0, "Table not found.");
       }
       HTableDescriptor[] tables = conn.listTables();
       HColumnDescriptor[] columns = null;
       for (int i = 0; i < tables.length; i++) {
-        if (tables[i].getName().equals(this.tableName)) {
+        if (tables[i].getName().equals(tableName)) {
           columns = tables[i].getFamilies().values().toArray(
               new HColumnDescriptor[] {});
           break;

+ 2 - 2
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/DisableCommand.java

@@ -43,8 +43,8 @@ public class DisableCommand extends BasicCommand {
 
     try {
       HConnection conn = HConnectionManager.getConnection(conf);
-      if (!conn.tableExists(new Text(this.tableName))) {
-        return new ReturnMsg(0, "'" + this.tableName + "'" + TABLE_NOT_FOUND);
+      if (!conn.tableExists(new Text(tableName))) {
+        return new ReturnMsg(0, "'" + tableName + "'" + TABLE_NOT_FOUND);
       }
 
       HBaseAdmin admin = new HBaseAdmin(conf);

+ 2 - 2
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/EnableCommand.java

@@ -42,8 +42,8 @@ public class EnableCommand extends BasicCommand {
     assert tableName != null;
     try {
       HConnection conn = HConnectionManager.getConnection(conf);
-      if (!conn.tableExists(new Text(this.tableName))) {
-        return new ReturnMsg(0, "'" + this.tableName + "'" + TABLE_NOT_FOUND);
+      if (!conn.tableExists(new Text(tableName))) {
+        return new ReturnMsg(0, "'" + tableName + "'" + TABLE_NOT_FOUND);
       }
 
       HBaseAdmin admin = new HBaseAdmin(conf);

+ 2 - 1
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ExitCommand.java

@@ -22,6 +22,7 @@ package org.apache.hadoop.hbase.shell;
 import java.io.Writer;
 
 import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.Shell;
 
 public class ExitCommand extends BasicCommand {
   public ExitCommand(Writer o) {
@@ -32,7 +33,7 @@ public class ExitCommand extends BasicCommand {
   HBaseConfiguration conf) {
     // TOD: Is this the best way to exit? Would be a problem if shell is run
     // inside another program -- St.Ack 09/11/2007
-    System.exit(9999);
+    System.exit(Shell.EXIT_FLAG);
     return null;
   }
 

+ 9 - 0
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/HBaseShell.jj

@@ -493,6 +493,7 @@ InsertCommand insertCommand() :
   List<String> columnfamilies = null;
   List<String> values = null;
   String table = null;
+  String timestamp = null;
   Token t = null;       
 }
 {
@@ -517,6 +518,14 @@ InsertCommand insertCommand() :
   { 
      in.setRow(t.image.substring(1, t.image.length()-1)); 
   }
+
+  [ <TIMESTAMP> 
+    timestamp = getStringLiteral()
+    {
+       in.setTimestamp(timestamp);
+    }
+  ]
+
   {
     return in;
   }

+ 3 - 2
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/HelpCommand.java

@@ -70,7 +70,7 @@ public class HelpCommand extends BasicCommand {
   private Map<? extends String, ? extends String[]> load() {
     Map<String, String[]> load = new HashMap<String, String[]>();
     load.put("SHOW", new String[] { "Show information about selected title",
-        "SHOW TABLES[or substitution variable name];" });
+        "SHOW TABLES [or substitution variable name];" });
 
     load.put("FS", new String[] {
         "Hadoop FsShell; entering a lone 'FS;' " + "will emit usage",
@@ -98,7 +98,8 @@ public class HelpCommand extends BasicCommand {
     load.put("INSERT", new String[] {
         "Insert values into table",
         "INSERT INTO table_name (column_name, ...) "
-            + "VALUES ('value', ...) WHERE row='row_key';" });
+            + "VALUES ('value', ...) WHERE row='row_key'" +
+            " [TIMESTAMP 'timestamp'];" });
 
     load.put("DELETE", new String[] {
         "Delete table data",

+ 17 - 8
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/InsertCommand.java

@@ -37,29 +37,30 @@ public class InsertCommand extends BasicCommand {
   private List<String> columnfamilies;
   private List<String> values;
   private String rowKey;
+  private String timestamp = null;
 
   public InsertCommand(Writer o) {
     super(o);
   }
 
   public ReturnMsg execute(HBaseConfiguration conf) {
-    if (this.tableName == null || this.values == null || this.rowKey == null)
+    if (tableName == null || values == null || rowKey == null)
       return new ReturnMsg(0, "Syntax error : Please check 'Insert' syntax.");
 
     HConnection conn = HConnectionManager.getConnection(conf);
-    if (!conn.tableExists(this.tableName)) {
-      return new ReturnMsg(0, "'" + this.tableName + "'" + TABLE_NOT_FOUND);
+    if (!conn.tableExists(tableName)) {
+      return new ReturnMsg(0, "'" + tableName + "'" + TABLE_NOT_FOUND);
     }
 
-    if (this.columnfamilies.size() != this.values.size())
+    if (columnfamilies.size() != values.size())
       return new ReturnMsg(0,
           "Mismatch between values list and columnfamilies list.");
 
     try {
-      HTable table = new HTable(conf, this.tableName);
+      HTable table = new HTable(conf, tableName);
       long lockId = table.startUpdate(getRow());
 
-      for (int i = 0; i < this.values.size(); i++) {
+      for (int i = 0; i < values.size(); i++) {
         Text column = null;
         if (getColumn(i).toString().contains(":"))
           column = getColumn(i);
@@ -67,7 +68,11 @@ public class InsertCommand extends BasicCommand {
           column = new Text(getColumn(i) + ":");
         table.put(lockId, column, getValue(i));
       }
-      table.commit(lockId);
+      
+      if(timestamp != null) 
+        table.commit(lockId, Long.parseLong(timestamp));
+      else
+        table.commit(lockId);
 
       return new ReturnMsg(1, "1 row inserted successfully.");
     } catch (IOException e) {
@@ -103,7 +108,11 @@ public class InsertCommand extends BasicCommand {
   public byte[] getValue(int i) {
     return this.values.get(i).getBytes();
   }
-
+  
+  public void setTimestamp(String timestamp) {
+    this.timestamp = timestamp;
+  }
+  
   @Override
   public CommandType getCommandType() {
     return CommandType.INSERT;

+ 29 - 33
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/SelectCommand.java

@@ -60,7 +60,7 @@ public class SelectCommand extends BasicCommand {
   private static final String[] HEADER_COLUMN_CELL = new String[] { "Column",
       "Cell" };
   private static final String[] HEADER = new String[] { "Row", "Column", "Cell" };
-  private static final String STAR = "*";
+  private static final String ASTERISK = "*";
 
   private final TableFormatter formatter;
 
@@ -76,20 +76,19 @@ public class SelectCommand extends BasicCommand {
   }
 
   public ReturnMsg execute(final HBaseConfiguration conf) {
-    if (this.tableName.equals("") || this.rowKey == null
-        || this.columns.size() == 0) {
+    if (tableName.equals("") || rowKey == null || columns.size() == 0) {
       return new ReturnMsg(0, "Syntax error : Please check 'Select' syntax.");
     }
     try {
       HConnection conn = HConnectionManager.getConnection(conf);
-      if (!conn.tableExists(this.tableName) && !isMetaTable()) {
-        return new ReturnMsg(0, "'" + this.tableName + "'" + TABLE_NOT_FOUND);
+      if (!conn.tableExists(tableName) && !isMetaTable()) {
+        return new ReturnMsg(0, "'" + tableName + "'" + TABLE_NOT_FOUND);
       }
 
-      HTable table = new HTable(conf, this.tableName);
+      HTable table = new HTable(conf, tableName);
       HBaseAdmin admin = new HBaseAdmin(conf);
       int count = 0;
-      if (this.whereClause) {
+      if (whereClause) {
         count = compoundWherePrint(table, admin);
       } else {
         count = scanPrint(table, admin);
@@ -102,26 +101,26 @@ public class SelectCommand extends BasicCommand {
   }
 
   private boolean isMetaTable() {
-    return (this.tableName.equals(HConstants.ROOT_TABLE_NAME)
-        || this.tableName.equals(HConstants.META_TABLE_NAME)) ? true : false;
+    return (tableName.equals(HConstants.ROOT_TABLE_NAME)
+        || tableName.equals(HConstants.META_TABLE_NAME)) ? true : false;
   }
 
   private int compoundWherePrint(HTable table, HBaseAdmin admin) {
     int count = 0;
     try {
-      if (this.version != 0) {
+      if (version != 0) {
         // A number of versions has been specified.
         byte[][] result = null;
         ParsedColumns parsedColumns = getColumns(admin, false);
-        boolean multiple = parsedColumns.isMultiple() || this.version > 1;
+        boolean multiple = parsedColumns.isMultiple() || version > 1;
         for (Text column : parsedColumns.getColumns()) {
           if(count == 0) {
             formatter.header(multiple ? HEADER_COLUMN_CELL : null);
           }
-          if (this.timestamp != 0) {
-            result = table.get(this.rowKey, column, this.timestamp, this.version);
+          if (timestamp != 0) {
+            result = table.get(rowKey, column, timestamp, version);
           } else {
-            result = table.get(this.rowKey, column, this.version);
+            result = table.get(rowKey, column, version);
           }
           for (int ii = 0; result != null && ii < result.length; ii++) {
             if (multiple) {
@@ -134,13 +133,13 @@ public class SelectCommand extends BasicCommand {
           }
         }
       } else {
-        for (Map.Entry<Text, byte[]> e : table.getRow(this.rowKey).entrySet()) {
+        for (Map.Entry<Text, byte[]> e : table.getRow(rowKey).entrySet()) {
           if(count == 0) {
             formatter.header(isMultiple() ? HEADER_COLUMN_CELL : null);
           }
           Text key = e.getKey();
           String keyStr = key.toString();
-          if (!this.columns.contains(STAR) && !this.columns.contains(keyStr)) {
+          if (!columns.contains(ASTERISK) && !columns.contains(keyStr)) {
             continue;
           }
           String cellData = toString(key, e.getValue());
@@ -210,10 +209,10 @@ public class SelectCommand extends BasicCommand {
     try {
       ParsedColumns parsedColumns = getColumns(admin, true);
       Text[] cols = parsedColumns.getColumns().toArray(new Text[] {});
-      if (this.timestamp == 0) {
-        scan = table.obtainScanner(cols, this.rowKey);
+      if (timestamp == 0) {
+        scan = table.obtainScanner(cols, rowKey);
       } else {
-        scan = table.obtainScanner(cols, this.rowKey, this.timestamp);
+        scan = table.obtainScanner(cols, rowKey, timestamp);
       }
       HStoreKey key = new HStoreKey();
       TreeMap<Text, byte[]> results = new TreeMap<Text, byte[]>();
@@ -233,7 +232,7 @@ public class SelectCommand extends BasicCommand {
             formatter.row(new String[] { r.toString(), cellData });
           }
           count++;
-          if (this.limit > 0 && count >= this.limit) {
+          if (limit > 0 && count >= limit) {
             break;
           }
         }
@@ -262,24 +261,22 @@ public class SelectCommand extends BasicCommand {
   public ParsedColumns getColumns(final HBaseAdmin admin, final boolean scanning) {
     ParsedColumns result = null;
     try {
-      if (this.columns.contains("*")) {
-        if (this.tableName.equals(HConstants.ROOT_TABLE_NAME)
-            || this.tableName.equals(HConstants.META_TABLE_NAME)) {
-          result = new ParsedColumns(Arrays
-              .asList(HConstants.COLUMN_FAMILY_ARRAY));
+      if (columns.contains(ASTERISK)) {
+        if (tableName.equals(HConstants.ROOT_TABLE_NAME)
+            || tableName.equals(HConstants.META_TABLE_NAME)) {
+          result = new ParsedColumns(Arrays.asList(HConstants.COLUMN_FAMILY_ARRAY));
         } else {
           HTableDescriptor[] tables = admin.listTables();
           for (int i = 0; i < tables.length; i++) {
-            if (tables[i].getName().equals(this.tableName)) {
-              result = new ParsedColumns(new ArrayList<Text>(tables[i].families()
-                  .keySet()));
+            if (tables[i].getName().equals(tableName)) {
+              result = new ParsedColumns(new ArrayList<Text>(tables[i].families().keySet()));
               break;
             }
           }
         }
       } else {
         List<Text> tmpList = new ArrayList<Text>();
-        for (int i = 0; i < this.columns.size(); i++) {
+        for (int i = 0; i < columns.size(); i++) {
           Text column = null;
           // Add '$' to column name if we are scanning. Scanners support
           // regex column names. Adding '$', the column becomes a
@@ -287,9 +284,8 @@ public class SelectCommand extends BasicCommand {
           // Otherwise, if the specified column is a column family, then
           // default behavior is to fetch all columns that have a matching
           // column family.
-          column = (this.columns.get(i).contains(":")) ? new Text(this.columns
-              .get(i)
-              + (scanning ? "$" : "")) : new Text(this.columns.get(i) + ":"
+          column = (columns.get(i).contains(":")) ? new Text(columns.get(i)
+              + (scanning ? "$" : "")) : new Text(columns.get(i) + ":"
               + (scanning ? "$" : ""));
           tmpList.add(column);
         }
@@ -305,7 +301,7 @@ public class SelectCommand extends BasicCommand {
    * @return True if query contains multiple columns.
    */
   private boolean isMultiple() {
-    return this.columns.size() > 1 || this.columns.contains(STAR);
+    return this.columns.size() > 1 || this.columns.contains(ASTERISK);
   }
 
   private boolean checkLimit(int count) {

+ 1 - 1
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ShowCommand.java

@@ -52,7 +52,7 @@ public class ShowCommand extends BasicCommand {
   }
 
   public ReturnMsg execute(final HBaseConfiguration conf) {
-    if (this.command == null) {
+    if (command == null) {
       return new ReturnMsg(0, "Syntax error : Please check 'Show' syntax.");
     }
     try {

+ 2 - 2
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/TruncateCommand.java

@@ -48,14 +48,14 @@ public class TruncateCommand extends BasicCommand {
       HConnection conn = HConnectionManager.getConnection(conf);
       HBaseAdmin admin = new HBaseAdmin(conf);
 
-      if (!conn.tableExists(this.tableName)) {
+      if (!conn.tableExists(tableName)) {
         return new ReturnMsg(0, "Table not found.");
       }
 
       HTableDescriptor[] tables = conn.listTables();
       HColumnDescriptor[] columns = null;
       for (int i = 0; i < tables.length; i++) {
-        if (tables[i].getName().equals(this.tableName)) {
+        if (tables[i].getName().equals(tableName)) {
           columns = tables[i].getFamilies().values().toArray(
               new HColumnDescriptor[] {});
           break;

+ 48 - 37
src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/generated/Parser.java

@@ -602,6 +602,7 @@ public class Parser implements ParserConstants {
   List<String> columnfamilies = null;
   List<String> values = null;
   String table = null;
+  String timestamp = null;
   Token t = null;
     jj_consume_token(INSERT);
     jj_consume_token(INTO);
@@ -628,6 +629,16 @@ public class Parser implements ParserConstants {
       throw new ParseException();
     }
      in.setRow(t.image.substring(1, t.image.length()-1));
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TIMESTAMP:
+      jj_consume_token(TIMESTAMP);
+      timestamp = getStringLiteral();
+       in.setTimestamp(timestamp);
+      break;
+    default:
+      jj_la1[19] = jj_gen;
+      ;
+    }
     {if (true) return in;}
     throw new Error("Missing return statement in function");
   }
@@ -656,14 +667,14 @@ public class Parser implements ParserConstants {
         t = jj_consume_token(QUOTED_IDENTIFIER);
         break;
       default:
-        jj_la1[19] = jj_gen;
+        jj_la1[20] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
      deleteCommand.setRow(t.image.substring(1, t.image.length()-1));
       break;
     default:
-      jj_la1[20] = jj_gen;
+      jj_la1[21] = jj_gen;
       ;
     }
     {if (true) return deleteCommand;}
@@ -699,7 +710,7 @@ public class Parser implements ParserConstants {
         jj_consume_token(FROM);
         break;
       default:
-        jj_la1[21] = jj_gen;
+        jj_la1[22] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -707,7 +718,7 @@ public class Parser implements ParserConstants {
        select.setRowKey(rowKey);
       break;
     default:
-      jj_la1[22] = jj_gen;
+      jj_la1[23] = jj_gen;
       ;
     }
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -717,7 +728,7 @@ public class Parser implements ParserConstants {
        select.setTimestamp(timestamp);
       break;
     default:
-      jj_la1[23] = jj_gen;
+      jj_la1[24] = jj_gen;
       ;
     }
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -728,7 +739,7 @@ public class Parser implements ParserConstants {
         select.setVersion(numVersion);
       break;
     default:
-      jj_la1[24] = jj_gen;
+      jj_la1[25] = jj_gen;
       ;
     }
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -743,7 +754,7 @@ public class Parser implements ParserConstants {
       }
       break;
     default:
-      jj_la1[25] = jj_gen;
+      jj_la1[26] = jj_gen;
       ;
     }
     {if (true) return select;}
@@ -793,7 +804,7 @@ public class Parser implements ParserConstants {
         ;
         break;
       default:
-        jj_la1[26] = jj_gen;
+        jj_la1[27] = jj_gen;
         break label_6;
       }
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -816,14 +827,14 @@ public class Parser implements ParserConstants {
           jj_consume_token(QUOTED_IDENTIFIER);
           break;
         default:
-          jj_la1[27] = jj_gen;
+          jj_la1[28] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
         }
        values.removeAll(values);
         break;
       default:
-        jj_la1[28] = jj_gen;
+        jj_la1[29] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -843,7 +854,7 @@ public class Parser implements ParserConstants {
       s = jj_consume_token(QUOTED_IDENTIFIER);
       break;
     default:
-      jj_la1[29] = jj_gen;
+      jj_la1[30] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
     }
@@ -869,7 +880,7 @@ public class Parser implements ParserConstants {
         col = jj_consume_token(ASTERISK);
         break;
       default:
-        jj_la1[30] = jj_gen;
+        jj_la1[31] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
@@ -885,14 +896,14 @@ public class Parser implements ParserConstants {
         col = jj_consume_token(STRING_LITERAL);
         break;
       default:
-        jj_la1[31] = jj_gen;
+        jj_la1[32] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
         {if (true) return col.image.substring(1,col.image.toString().length() - 1);}
       break;
     default:
-      jj_la1[32] = jj_gen;
+      jj_la1[33] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
     }
@@ -912,7 +923,7 @@ public class Parser implements ParserConstants {
         ;
         break;
       default:
-        jj_la1[33] = jj_gen;
+        jj_la1[34] = jj_gen;
         break label_7;
       }
       jj_consume_token(COMMA);
@@ -936,7 +947,7 @@ public class Parser implements ParserConstants {
         ;
         break;
       default:
-        jj_la1[34] = jj_gen;
+        jj_la1[35] = jj_gen;
         break label_8;
       }
       jj_consume_token(COMMA);
@@ -963,7 +974,7 @@ public class Parser implements ParserConstants {
         ;
         break;
       default:
-        jj_la1[35] = jj_gen;
+        jj_la1[36] = jj_gen;
         break label_9;
       }
       jj_consume_token(COMMA);
@@ -985,7 +996,7 @@ public class Parser implements ParserConstants {
       t = jj_consume_token(INTEGER_LITERAL);
       break;
     default:
-      jj_la1[36] = jj_gen;
+      jj_la1[37] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
     }
@@ -1014,14 +1025,14 @@ public class Parser implements ParserConstants {
         t = jj_consume_token(STRING_LITERAL);
         break;
       default:
-        jj_la1[37] = jj_gen;
+        jj_la1[38] = jj_gen;
         jj_consume_token(-1);
         throw new ParseException();
       }
        {if (true) return t.image.substring(1,t.image.toString().length() - 1);}
       break;
     default:
-      jj_la1[38] = jj_gen;
+      jj_la1[39] = jj_gen;
       jj_consume_token(-1);
       throw new ParseException();
     }
@@ -1042,6 +1053,12 @@ public class Parser implements ParserConstants {
     finally { jj_save(0, xla); }
   }
 
+  final private boolean jj_3_1() {
+    if (jj_scan_token(ADD)) return true;
+    if (jj_3R_10()) return true;
+    return false;
+  }
+
   final private boolean jj_3R_12() {
     Token xsp;
     xsp = jj_scanpos;
@@ -1052,12 +1069,6 @@ public class Parser implements ParserConstants {
     return false;
   }
 
-  final private boolean jj_3_1() {
-    if (jj_scan_token(ADD)) return true;
-    if (jj_3R_10()) return true;
-    return false;
-  }
-
   final private boolean jj_3R_11() {
     if (jj_scan_token(ID)) return true;
     return false;
@@ -1082,7 +1093,7 @@ public class Parser implements ParserConstants {
   public boolean lookingAhead = false;
   private boolean jj_semLA;
   private int jj_gen;
-  final private int[] jj_la1 = new int[39];
+  final private int[] jj_la1 = new int[40];
   static private int[] jj_la1_0;
   static private int[] jj_la1_1;
   static private int[] jj_la1_2;
@@ -1092,13 +1103,13 @@ public class Parser implements ParserConstants {
       jj_la1_2();
    }
    private static void jj_la1_0() {
-      jj_la1_0 = new int[] {0xf3ffe0,0xf3ffe1,0xf3ffe0,0x0,0x0,0x0,0x0,0x33dbc0,0x33dbc0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x0,0x0,0x2000000,0x3000000,0x3000000,0x40000000,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+      jj_la1_0 = new int[] {0xf3ffe0,0xf3ffe1,0xf3ffe0,0x0,0x0,0x0,0x0,0x33dbc0,0x33dbc0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x0,0x40000000,0x0,0x2000000,0x3000000,0x3000000,0x40000000,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
    }
    private static void jj_la1_1() {
-      jj_la1_1 = new int[] {0x0,0x0,0x0,0x10000000,0x70000000,0x70000000,0x10000000,0x10000000,0x10000000,0x10000000,0x0,0x398e000,0x70000,0x700000,0x398e000,0x8,0x8,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x10000008,0x10000000,0x10000008,0x0,0x30001000,0x0,0x30001000,0x8,0x8,0x8,0x30000000,0x0,0x10000000,};
+      jj_la1_1 = new int[] {0x0,0x0,0x0,0x10000000,0x70000000,0x70000000,0x10000000,0x10000000,0x10000000,0x10000000,0x0,0x398e000,0x70000,0x700000,0x398e000,0x8,0x8,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x10000008,0x10000000,0x10000008,0x0,0x30001000,0x0,0x30001000,0x8,0x8,0x8,0x30000000,0x0,0x10000000,};
    }
    private static void jj_la1_2() {
-      jj_la1_2 = new int[] {0x0,0x4,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x3,0x3,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x3,0x3,};
+      jj_la1_2 = new int[] {0x0,0x4,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x3,0x3,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x3,0x3,};
    }
   final private JJCalls[] jj_2_rtns = new JJCalls[1];
   private boolean jj_rescan = false;
@@ -1113,7 +1124,7 @@ public class Parser implements ParserConstants {
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 39; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -1126,7 +1137,7 @@ public class Parser implements ParserConstants {
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 39; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -1136,7 +1147,7 @@ public class Parser implements ParserConstants {
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 39; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -1146,7 +1157,7 @@ public class Parser implements ParserConstants {
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 39; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -1155,7 +1166,7 @@ public class Parser implements ParserConstants {
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 39; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -1164,7 +1175,7 @@ public class Parser implements ParserConstants {
     token = new Token();
     jj_ntk = -1;
     jj_gen = 0;
-    for (int i = 0; i < 39; i++) jj_la1[i] = -1;
+    for (int i = 0; i < 40; i++) jj_la1[i] = -1;
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
   }
 
@@ -1283,7 +1294,7 @@ public class Parser implements ParserConstants {
       la1tokens[jj_kind] = true;
       jj_kind = -1;
     }
-    for (int i = 0; i < 39; i++) {
+    for (int i = 0; i < 40; i++) {
       if (jj_la1[i] == jj_gen) {
         for (int j = 0; j < 32; j++) {
           if ((jj_la1_0[i] & (1<<j)) != 0) {