Add DDL support for optionally associating meta record with dataset record.

-Fixed the TestExecutor.runScriptAndCompareWithResult() to compare fields
 after "Time"-prefixed fields.

Change-Id: I613316985dbd7f553d946f95c5b1a1df56914902
Reviewed-on: https://asterix-gerrit.ics.uci.edu/666
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Yingyi Bu <buyingyi@gmail.com>
diff --git a/asterix-lang-aql/src/main/javacc/AQL.html b/asterix-lang-aql/src/main/javacc/AQL.html
index b50d554..3da5e77 100644
--- a/asterix-lang-aql/src/main/javacc/AQL.html
+++ b/asterix-lang-aql/src/main/javacc/AQL.html
@@ -342,7 +342,7 @@
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod21">DatasetSpecification</A></TD>
 <TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "external" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod18">Identifier</A> &lt;RIGHTPAREN&gt; <A HREF="#prod28">IfNotExists</A> "using" <A HREF="#prod31">AdapterName</A> <A HREF="#prod32">Configuration</A> ( "on" <A HREF="#prod18">Identifier</A> )? ( "hints" <A HREF="#prod33">Properties</A> )? ( "using" "compaction" "policy" <A HREF="#prod34">CompactionPolicy</A> ( <A HREF="#prod32">Configuration</A> )? )? | ( "internal" | "temporary" )? &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod18">Identifier</A> &lt;RIGHTPAREN&gt; <A HREF="#prod28">IfNotExists</A> <A HREF="#prod35">PrimaryKey</A> ( "autogenerated" )? ( "on" <A HREF="#prod18">Identifier</A> )? ( "hints" <A HREF="#prod33">Properties</A> )? ( "using" "compaction" "policy" <A HREF="#prod34">CompactionPolicy</A> ( <A HREF="#prod32">Configuration</A> )? )? ( "with filter on" <A HREF="#prod36">NestedField</A> )? )</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( "external" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; <A HREF="#prod28">IfNotExists</A> "using" <A HREF="#prod31">AdapterName</A> <A HREF="#prod32">Configuration</A> ( "on" <A HREF="#prod18">Identifier</A> )? ( "hints" <A HREF="#prod33">Properties</A> )? ( "using" "compaction" "policy" <A HREF="#prod34">CompactionPolicy</A> ( <A HREF="#prod32">Configuration</A> )? )? | ( "internal" | "temporary" )? &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> ( &lt;COMMA&gt; <A HREF="#prod27">TypeName</A> )? &lt;RIGHTPAREN&gt; <A HREF="#prod28">IfNotExists</A> <A HREF="#prod35">PrimaryKey</A> ( "autogenerated" )? ( "on" <A HREF="#prod18">Identifier</A> )? ( "hints" <A HREF="#prod33">Properties</A> )? ( "using" "compaction" "policy" <A HREF="#prod34">CompactionPolicy</A> ( <A HREF="#prod32">Configuration</A> )? )? ( "with filter on" <A HREF="#prod36">NestedField</A> )? )</TD>
 </TR>
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod16">RefreshExternalDatasetStatement</A></TD>
@@ -437,7 +437,7 @@
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod10">InsertStatement</A></TD>
 <TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"insert" "into" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> <A HREF="#prod15">Query</A></TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( "insert" | "upsert" ) "into" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> <A HREF="#prod15">Query</A></TD>
 </TR>
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod11">DeleteStatement</A></TD>
@@ -562,7 +562,7 @@
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod36">NestedField</A></TD>
 <TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )*</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( "@" )? <A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )*</TD>
 </TR>
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod40">StringLiteral</A></TD>
diff --git a/asterix-lang-aql/src/main/javacc/AQL.jj b/asterix-lang-aql/src/main/javacc/AQL.jj
index 93e3f68..ea95871 100644
--- a/asterix-lang-aql/src/main/javacc/AQL.jj
+++ b/asterix-lang-aql/src/main/javacc/AQL.jj
@@ -416,6 +416,7 @@
   String compactionPolicy = null;
   boolean temp = false;
   List<String> filterField = null;
+  Pair<Identifier,Identifier> metaTypeComponents = new Pair<Identifier, Identifier>(null, null);
 }
 {
   (
@@ -434,6 +435,8 @@
                                    nameComponents.second,
                                    typeComponents.first,
                                    typeComponents.second,
+                                   metaTypeComponents.first,
+                                   metaTypeComponents.second,
                                    nodeGroupName != null? new Identifier(nodeGroupName): null,
                                    compactionPolicy,
                                    compactionPolicyProperties,
@@ -446,9 +449,20 @@
     | ("internal" | "temporary" {
             temp = token.image.toLowerCase().equals("temporary");
         }
-      )? 
+      )?
     <DATASET> nameComponents = QualifiedName()
     <LEFTPAREN> typeComponents = TypeName() <RIGHTPAREN>
+    (
+        { String name; }
+        <WITH>
+        name = Identifier()
+        {
+            if(!name.equals("meta")){
+                throw new ParseException("We can only support one additional associated field called \"meta\".");
+            }
+        }
+        <LEFTPAREN> metaTypeComponents = TypeName() <RIGHTPAREN>
+    )?
     ifNotExists = IfNotExists()
     primaryKeyFields = PrimaryKey()
     ("autogenerated" { autogenerated = true; } )?
@@ -465,6 +479,8 @@
                                    nameComponents.second,
                                    typeComponents.first,
                                    typeComponents.second,
+                                   metaTypeComponents.first,
+                                   metaTypeComponents.second,
                                    nodeGroupName != null ? new Identifier(nodeGroupName) : null,
                                    compactionPolicy,
                                    compactionPolicyProperties,
@@ -1386,7 +1402,23 @@
 {
   lit = Identifier()
   {
-    exprList.add(lit);
+    boolean meetParens = false;
+  }
+  (
+    <LEFTPAREN><RIGHTPAREN>
+    {
+        if(lit.equals("meta")){
+            exprList.add(lit+"()");
+        }else{
+            throw new ParseException("The string before () has to be \"meta\".");
+        }
+        meetParens = true;
+    }
+  )?
+  {
+    if(!meetParens){
+        exprList.add(lit);
+    }
   }
   (<DOT>
     lit = Identifier()