You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2021/01/27 01:07:56 UTC

[asterixdb] 10/11: [NO ISSUE][DOC] Document multi-part dataverse name in SQL++ EBNF

This is an automated email from the ASF dual-hosted git repository.

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git

commit ef1479adcdb0d5fda10b42d54af0b0c06f008506
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Tue Jan 26 12:33:54 2021 -0800

    [NO ISSUE][DOC] Document multi-part dataverse name in SQL++ EBNF
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    - Add multi-part dataverse name to SQL++ EBNF documentation
    - Add other missing elements to documentation
    
    Change-Id: Iff45873ead4a94db655f32e9c9d8e0128ce03a73
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/9743
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
 asterixdb/asterix-doc/src/main/grammar/sqlpp.ebnf  | 59 ++++++++++------------
 .../asterix-doc/src/main/markdown/sqlpp/0_toc.md   |  2 +-
 .../asterix-doc/src/main/markdown/sqlpp/2_expr.md  | 53 ++++++++++---------
 .../asterix-doc/src/main/markdown/sqlpp/3_query.md |  4 +-
 .../src/main/markdown/sqlpp/7_ddl_dml.md           | 54 ++++++++++++--------
 .../src/main/markdown/sqlpp/appendix_1_keywords.md | 34 +++++++------
 6 files changed, 111 insertions(+), 95 deletions(-)

diff --git a/asterixdb/asterix-doc/src/main/grammar/sqlpp.ebnf b/asterixdb/asterix-doc/src/main/grammar/sqlpp.ebnf
index d338068..aae81ec 100644
--- a/asterixdb/asterix-doc/src/main/grammar/sqlpp.ebnf
+++ b/asterixdb/asterix-doc/src/main/grammar/sqlpp.ebnf
@@ -32,7 +32,7 @@ Subquery ::= ("(" Selection ")")
 
 FunctionCall ::= OrdinaryFunctionCall | AggregateFunctionCall | WindowFunctionCall
 
-OrdinaryFunctionCall ::= Identifier "(" Expr ("," Expr)* ")"
+OrdinaryFunctionCall ::= (DataverseName ".")? Identifier "(" Expr ("," Expr)* ")"
 
 AggregateFunctionCall ::= Identifier "(" ("DISTINCT")? Expr ")" ("FILTER" "(" "WHERE" Expr ")")?
 
@@ -44,13 +44,13 @@ SearchedCaseExpr ::= "CASE" ("WHEN" Expr "THEN" Expr)+ ("ELSE" Expr)? "END"
 
 Constructor ::= ObjectConstructor | ArrayConstructor | MultisetConstructor
 
-ObjectConstructor ::= "{" ( Expr ( ":" Expr )?( ","Expr ( ":" Expr )? )* )? "}"
+ObjectConstructor ::= "{" ( Expr ( ":" Expr )? ( "," Expr ( ":" Expr )? )* )? "}"
 
 ArrayConstructor ::= "[" Expr ("," Expr)* "]"
 
 MultisetConstructor ::= "{{" Expr ("," Expr)* "}}"
 
-Query ::= (Expr | Selection) ";"
+Query ::= (Expr | Selection)
 
 Selection ::= WithClause? QueryBlock UnionOption* OrderByClause? ( LimitClause | OffsetClause )?
 
@@ -79,15 +79,12 @@ WhereClause ::= "WHERE" Expr
 
 GroupByClause ::= "GROUP BY" GroupingElement ("," GroupingElement)* GroupAsClause?
 
-GroupingElement ::=  GroupByExprPair
-              | ( "(" GroupByExprPair ( "," GroupByExprPair )* ")")
+GroupingElement ::= OrdinaryGroupingSet
               | ( "GROUPING" "SETS" "(" GroupingElement ("," GroupingElement)* ")" )
               | ( ( "ROLLUP" | "CUBE" ) "(" OrdinaryGroupingSet ( "," OrdinaryGroupingSet )* ")" )
               | ( "(" ")" )
 
-OrdinaryGroupingSet ::= GroupByExprPair | ( "(" GroupByExprPair ( "," GroupByExprPair )* ")")
-
-GroupByExprPair ::= Expr ("AS"? Variable)?
+OrdinaryGroupingSet ::= NamedExpr | ( "(" NamedExpr ( "," NamedExpr )* ")")
 
 GroupAsClause ::= "GROUP AS" Variable
 
@@ -142,7 +139,9 @@ SingleStmnt ::= UseStmnt
                |UpsertStmnt
                |DeleteStmnt
 
-UseStmnt ::= "USE" Identifier
+UseStmnt ::= "USE" DataverseName
+
+SetStmnt ::= "SET" Identifier StringLiteral
 
 CreateStmnt ::= CreateDataverse
               | CreateType
@@ -151,11 +150,13 @@ CreateStmnt ::= CreateDataverse
               | CreateSynonym
               | CreateFunction
 
-QualifiedName ::= Identifier ("." Identifier)?
+DataverseName ::= Identifier ("." Identifier)*
 
-DoubleQualifiedName ::= Identifier "." Identifier ("." Identifier)?
+QualifiedName ::= (DataverseName ".")? Identifier
 
-CreateDataverse ::= "CREATE" "DATAVERSE" Identifier ("IF" "NOT" "EXISTS")?
+DoubleQualifiedName ::= (DataverseName ".")? Identifier "." Identifier
+
+CreateDataverse ::= "CREATE" "DATAVERSE" DataverseName ("IF" "NOT" "EXISTS")?
 
 CreateType ::= "CREATE" "TYPE" QualifiedName ("IF" "NOT" "EXISTS")? "AS" ObjectTypeDef
 
@@ -189,13 +190,14 @@ CreateExternalDataset ::= "EXTERNAL" "DATASET" QualifiedName DatasetTypeDef
                             ( "HINTS" Properties )?
                             ( "WITH" ObjectConstructor )?
 
-DatasetTypeDef ::= DatasetReferenceTypeDef | DatasetObjectTypeDef
+DatasetTypeDef ::= ( "(" TypeReference ")" )
+                | ( "(" DatasetFieldDef ("," DatasetFieldDef )* ")" ( ("CLOSED" | "OPEN") "TYPE" )? )
 
-DatasetReferenceTypeDef ::= "(" TypeReference ")"
+DatasetFieldDef ::= Identifier TypeReference ("NOT" "UNKNOWN")?
 
-DatasetObjectTypeDef ::= "(" DatasetObjectField ("," DatasetObjectField )* ")" ( ("CLOSED" | "OPEN") "TYPE" )?
+PrimaryKey ::= "PRIMARY" "KEY" NestedField ( "," NestedField )* ("AUTOGENERATED")?
 
-DatasetObjectField ::= Identifier TypeReference ("NOT" "UNKNOWN")?
+NestedField ::= Identifier ( "." Identifier )*
 
 AdapterName ::= Identifier
 
@@ -205,36 +207,33 @@ KeyValuePair ::= "(" StringLiteral "=" StringLiteral ")"
 
 Properties ::= ( "(" Identifier "=" ( StringLiteral | IntegerLiteral ) ( "," Identifier "=" ( StringLiteral | IntegerLiteral ) )* ")" )?
 
-PrimaryKey ::= "PRIMARY" "KEY" NestedField ( "," NestedField )* ("AUTOGENERATED")?
-
-NestedField ::= Identifier ( "." Identifier )*
-
 CreateIndex ::= CreateSecondaryIndex | CreatePrimaryKeyIndex
 
-CreateSecondaryIndex ::= "CREATE" ("INDEX" Identifier ("IF" "NOT" "EXISTS")? "ON" QualifiedName
-                       "(" ( IndexField ) ( "," IndexField )* ")" ("TYPE" IndexType)? ("ENFORCED")?)
+CreateSecondaryIndex ::= "CREATE" "INDEX" Identifier ("IF" "NOT" "EXISTS")? "ON" QualifiedName
+                       "(" IndexField ( "," IndexField )* ")" ("TYPE" IndexType)? ("ENFORCED")?
 
-CreatePrimaryKeyIndex ::=  "CREATE" "PRIMARY" "INDEX" Identifier? ("IF" "NOT" "EXISTS")? "ON" QualifiedName ("TYPE" "BTREE")?
+CreatePrimaryKeyIndex ::= "CREATE" "PRIMARY" "INDEX" Identifier? ("IF" "NOT" "EXISTS")? "ON" QualifiedName ("TYPE" "BTREE")?
 
-IndexField ::= NestedField (":" TypeReference)?
+IndexField ::= NestedField ( ":" TypeReference "?"? )?
 
 IndexType ::= "BTREE"
              |"RTREE"
              |"KEYWORD"
+             |"FULLTEXT"
              |"NGRAM" "(" IntegerLiteral ")"
 
 CreateSynonym ::= "CREATE" "SYNONYM" QualifiedName "FOR" QualifiedName ("IF" "NOT" "EXISTS")?
 
-FunctionDeclaration ::= "DECLARE" "FUNCTION" Identifier "(" ( (Variable ("," Variable)*) | "..." )? ")" "{" Expr "}"
+FunctionDeclaration ::= "DECLARE" "FUNCTION" Identifier "(" ( (Identifier ("," Identifier)*) | "..." )? ")" "{" Expr "}"
 
 CreateFunction ::= "CREATE" ("OR" "REPLACE")? "FUNCTION" QualifiedName ("IF" "NOT" "EXISTS")? "(" FunctionParameters? ")"
                   ( ("{" Expr "}") | ExternalFunctionDef )
 
-FunctionParameters ::=  ( Variable ((":")? TypeExpr)? ("," Variable ((":")? TypeExpr)? )* ) | "..."
+FunctionParameters ::=  ( Identifier ((":")? TypeExpr)? ("," Identifier ((":")? TypeExpr)? )* ) | "..."
 
 ExternalFunctionDef ::= ("RETURNS" TypeExpr)? "AS" StringLiteral ("," StringLiteral )* "AT" QualifiedName ("WITH" ObjectConstructor)?
 
-DropStmnt ::= "DROP" ("DATAVERSE" Identifier
+DropStmnt ::= "DROP" ("DATAVERSE" DataverseName
                      | ("TYPE" |"DATASET" | "SYNONYM") QualifiedName
                      | "INDEX" DoubleQualifiedName
                      | "FUNCTION" FunctionSignature ) ("IF" "EXISTS")?
@@ -243,10 +242,8 @@ FunctionSignature ::= QualifiedName ( ( "(" ( FunctionParameters? | IntegerLiter
 
 LoadStmnt ::= "LOAD" "DATASET" QualifiedName "USING" AdapterName Configuration ("PRE-SORTED")?
 
-InsertStmnt ::= "INSERT" "INTO" QualifiedName Query
+InsertStmnt ::= "INSERT" "INTO" QualifiedName ("AS" Variable)? Query ("RETURNING" Expr)?
 
-UpsertStmnt ::= "UPSERT" "INTO" QualifiedName Query
+UpsertStmnt ::= "UPSERT" "INTO" QualifiedName ("AS" Variable)? Query ("RETURNING" Expr)?
 
 DeleteStmnt ::= "DELETE" "FROM" QualifiedName (("AS")? Variable)? ("WHERE" Expr)?
-
-SetStmnt ::= "SET" Identifier StringLiteral
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md
index 5d084c5..47ed4e7 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md
@@ -33,7 +33,7 @@
            * [Identifiers and Variable References](#Variable_references)
 		   * [Parameter References](#Parameter_references)
            * [Parenthesized Expressions](#Parenthesized_expressions)
-           * [Function calls](#Function_call_expressions)
+           * [Function Calls](#Function_call_expressions)
            * [Case Expressions](#Case_expressions)
            * [Constructors](#Constructors)
 * [3. Queries](#Queries)
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
index ae203bf..4453099 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
@@ -190,8 +190,8 @@ The following table demonstrates the results of `NOT` on all possible inputs.
 
 ### QuantifiedExpr
 **![](../images/diagrams/QuantifiedExpr.png)**
-##### Synonym for `SOME`: `ANY` 
- 
+##### Synonym for `SOME`: `ANY`
+
 ---
 
 Quantified expressions are used for expressing existential or universal predicates involving the elements of a collection.
@@ -207,7 +207,7 @@ Otherwise, a type error will be raised if the first expression in a quantified e
 ##### Examples
 
     EVERY x IN [ 1, 2, 3 ] SATISFIES x < 3		Returns FALSE
-    SOME x IN [ 1, 2, 3 ] SATISFIES x < 3		Returns TRUE	
+    SOME x IN [ 1, 2, 3 ] SATISFIES x < 3		Returns TRUE
 
 
 ## <a id="Path_expressions">Path Expressions</a>
@@ -242,7 +242,7 @@ and also a composition thereof.
     ({"name": "MyABCs", "array": [ "a", "b", "c"]}).array						Returns [["a", "b", "c"]]
 
     (["a", "b", "c"])[2]										Returns ["c"]
-    
+
     (["a", "b", "c"])[-1]										Returns ["c"]
 
     ({"name": "MyABCs", "array": [ "a", "b", "c"]}).array[2]					Returns ["c"]
@@ -250,7 +250,7 @@ and also a composition thereof.
     (["a", "b", "c"])[0:2]										Returns [["a", "b"]]
 
     (["a", "b", "c"])[0:]										Returns [["a", "b", "c"]]
-    
+
     (["a", "b", "c"])[-2:-1]									Returns [["b"]]
 
 
@@ -279,7 +279,7 @@ array, or multiset of data model instances).
 
 The simplest kind of expression is a literal that directly represents a value in JSON format. Here are some examples:
 
-  
+
 
 	-42
 	"Hello"
@@ -287,18 +287,18 @@ The simplest kind of expression is a literal that directly represents a value in
 	false
 	null
 
- 
+
 Numeric literals may include a sign and an optional decimal point. They may also be written in exponential notation, like this:
 
-  
+
 	5e2
 	-4.73E-2
 
-  
+
 
 String literals may be enclosed in either single quotes or double quotes. Inside a string literal, the delimiter character for that string must be "escaped" by a backward slash, as in these examples:
 
-  
+
 
 	"I read \"War and Peace\" today."
 	'I don\'t believe everything I read.'
@@ -321,7 +321,7 @@ The table below shows how to escape characters in SQL++
 
 ### <a id="Variable_references">Identifiers and Variable References</a>
 
- 
+
 Like SQL, SQL++ makes use of a language construct called an *identifier*. An identifier starts with an alphabetic character or the underscore character _ , and contains only case-sensitive alphabetic characters, numeric digits, or the special characters _ and $. It is also possible for an identifier to include other special characters, or to be the same as a reserved word, by enclosing the identifier in back-ticks (it's then called a *delimited identifier*). Identifiers are used in varia [...]
 
 	X
@@ -330,7 +330,7 @@ Like SQL, SQL++ makes use of a language construct called an *identifier*. An ide
 	`spaces in here`
 	`@&#`
 
- 
+
 A very simple kind of SQL++ expression is a variable, which is simply an identifier. As in SQL, a variable can be bound to a value, which may be an input dataset, some intermediate result during processing of a query, or the final result of a query. We'll learn more about variables when we discuss queries.
 
 Note that the SQL++ rules for delimiting strings and identifiers are different from the SQL rules. In SQL, strings are always enclosed in single quotes, and double quotes are used for delimited identifiers.
@@ -390,6 +390,9 @@ The following expression evaluates to the value 2.
 ### AggregateFunctionCall
 **![](../images/diagrams/AggregateFunctionCall.png)**
 
+### DataverseName
+**![](../images/diagrams/DataverseName.png)**
+
 ---
 
 Functions are included in SQL++, like most languages, as a way to package useful functionality or to
@@ -400,7 +403,7 @@ expression with the given parameter bindings; the parameter value bindings can t
 Note that Window functions, and aggregate functions used as window functions, have a more complex syntax.
 Window function calls are described in the section on [Window Queries](#Over_clauses).
 
-Also note that FILTER expressions can only be specified when calling [Aggregation Pseudo-Functions](#Aggregation_PseudoFunctions). 
+Also note that FILTER expressions can only be specified when calling [Aggregation Pseudo-Functions](#Aggregation_PseudoFunctions).
 
 The following example is a function call expression whose value is 8.
 
@@ -455,16 +458,16 @@ The following example illustrates the form of a case expression.
 Structured JSON values can be represented by constructors, as in these examples:
 
 	An object: { "name": "Bill", "age": 42 }
-	An array: [ 1, 2, "Hello", null ]  
-  
+	An array: [ 1, 2, "Hello", null ]
+
 In a constructed object, the names of the fields must be strings (either literal strings or computed strings), and an object may not contain any duplicate names. Of course, structured literals can be nested, as in this example:
 
-  
+
 
 	[ {"name": "Bill",
 	   "address":
 	      {"street": "25 Main St.",
-	       "city": "Cincinnati, OH"  
+	       "city": "Cincinnati, OH"
 	      }
 	  },
 	  {"name": "Mary",
@@ -475,33 +478,33 @@ In a constructed object, the names of the fields must be strings (either literal
 	   }
 	]
 
-  
+
 
 The array items in an array constructor, and the field-names and field-values in an object constructor, may be represented by expressions. For example, suppose that the variables firstname, lastname, salary, and bonus are bound to appropriate values. Then structured values might be constructed by the following expressions:
 
-  
+
 
 An object:
 
-	{ 
-	  "name": firstname || " " || lastname,  
-	  "income": salary + bonus  
+	{
+	  "name": firstname || " " || lastname,
+	  "income": salary + bonus
 	}
 
-  
+
 An array:
 
 	["1984", lastname, salary + bonus, null]
 
 
 If only one expression is specified instead of the field-name/field-value pair in an object constructor then this
-expression is supposed to provide the field value. The field name is then automatically generated based on the 
+expression is supposed to provide the field value. The field name is then automatically generated based on the
 kind of the value expression as in Q2.1:
 
   * If it is a variable reference expression then the generated field name is the name of that variable.
   * If it is a field access expression then the generated field name is the last identifier in that expression.
   * For all other cases, a compilation error will be raised.
- 
+
 
 ##### Example
 (Q2.1)
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
index 43445ed..f4bbc4d 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
@@ -662,8 +662,8 @@ Grouping is especially important when manipulating hierarchies like the ones tha
 ### OrdinaryGroupingSet
 **![](../images/diagrams/OrdinaryGroupingSet.png)**
 
-### GroupByExprPair
-**![](../images/diagrams/GroupByExprPair.png)**
+### NamedExpr
+**![](../images/diagrams/NamedExpr.png)**
 
 ---
 
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md
index 6bfac3b..222c7a4 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/7_ddl_dml.md
@@ -25,6 +25,8 @@
 ### UseStmnt
 **![](../images/diagrams/UseStmnt.png)**
 
+### DataverseName
+**![](../images/diagrams/DataverseName.png)**
 
 ---
 
@@ -36,11 +38,12 @@ As an example, the following statement sets the default dataverse to be `Commerc
 	USE Commerce;
 
 ### <a id="Sets"> Set Statement</a>
+
 The `SET` statement can be used to override certain configuration parameters. More information about `SET` can be found in [Appendix 2](#Performance_tuning).
 
 ### <a id="Functions"> Function Declaration</a>
 
-When writing a complex query, it can sometimes be helpful to define one or more auxiliary functions that each address a sub-piece of the overall query. 
+When writing a complex query, it can sometimes be helpful to define one or more auxiliary functions that each address a sub-piece of the overall query.
 
 The `DECLARE FUNCTION` statement supports the creation of such helper functions.
 In general, the function body (expression) can be any legal query expression.
@@ -52,6 +55,7 @@ The function named in the `DECLARE FUNCTION` statement is accessible only in the
 **![](../images/diagrams/FunctionDeclaration.png)**
 
 ---
+
 The following is a simple example of a temporary function definition and its use.
 
 ##### Example
@@ -76,6 +80,9 @@ For our sample data set, this returns:
 ### CreateStmnt
 **![](../images/diagrams/CreateStmnt.png)**
 
+### DataverseName
+**![](../images/diagrams/DataverseName.png)**
+
 ### QualifiedName
 **![](../images/diagrams/QualifiedName.png)**
 
@@ -94,6 +101,7 @@ It can be used to create new dataverses, datatypes, datasets, indexes, and user-
 **![](../images/diagrams/CreateDataverse.png)**
 
 ---
+
 The `CREATE DATAVERSE` statement is used to create new dataverses.
 To ease the authoring of reusable query scripts, an optional `IF NOT EXISTS` clause is included to allow
 creation to be requested either unconditionally or only if the dataverse does not already exist.
@@ -106,6 +114,7 @@ The following example creates a new dataverse named `Commerce` if one does not a
     CREATE DATAVERSE Commerce IF NOT EXISTS;
 
 #### <a id="Types"> Create Type </a>
+
 ---
 ### CreateType
 **![](../images/diagrams/CreateType.png)**
@@ -140,7 +149,7 @@ Instances of an open object type may carry additional fields, and open is the de
 
 The following example creates three new object type called `addressType` ,  `customerType` and `itemType`.
 Their fields are essentially traditional typed name/value pairs (much like SQL fields).
-Since it is defined as (defaulting to) being an open type, instances will be permitted to contain more than what is specified in the type definition. Indeed many of the customer objects contain a rating as well, however this is not necessary for the customer object to be created. As can be seen in the sample data, customers can exist without ratings or with part (or all) of the address missing. 
+Since it is defined as (defaulting to) being an open type, instances will be permitted to contain more than what is specified in the type definition. Indeed many of the customer objects contain a rating as well, however this is not necessary for the customer object to be created. As can be seen in the sample data, customers can exist without ratings or with part (or all) of the address missing.
 
 ##### Example
 
@@ -175,7 +184,7 @@ Note that the type of the `itemno` in this example is UUID. This field type can
 
 The next example creates a new object type, closed this time, called `orderType`.
 Instances of this closed type will not be permitted to have extra fields,
-although the `ship_date` field is marked as optional and may thus be `NULL` or `MISSING` in legal instances of the type. The items field is an array of instances of another object type, `itemType`. 
+although the `ship_date` field is marked as optional and may thus be `NULL` or `MISSING` in legal instances of the type. The items field is an array of instances of another object type, `itemType`.
 
 ##### Example
 
@@ -202,14 +211,8 @@ although the `ship_date` field is marked as optional and may thus be `NULL` or `
 ### DatasetTypeDef
 **![](../images/diagrams/DatasetTypeDef.png)**
 
-### DatasetReferenceTypeDef
-**![](../images/diagrams/DatasetReferenceTypeDef.png)**
-
-### DatasetObjectTypeDef
-**![](../images/diagrams/DatasetObjectTypeDef.png)**
-
-### DatasetObjectField
-**![](../images/diagrams/DatasetObjectField.png)**
+### DatasetFieldDef
+**![](../images/diagrams/DatasetFieldDef.png)**
 
 ### TypeReference
 **![](../images/diagrams/TypeReference.png)**
@@ -328,7 +331,6 @@ the URL and path needed to locate the data in HDFS and a description of the data
 ### IndexType
 **![](../images/diagrams/IndexType.png)**
 
-
 ---
 
 The `CREATE INDEX` statement creates a secondary index on one or more fields of a specified dataset.
@@ -455,7 +457,6 @@ The primary-key index can be identified by the fact that the `SearchKey` field i
 ### CreateSynonym
 **![](../images/diagrams/CreateSynonym.png)**
 
-
 ---
 
 The `CREATE SYNONYM` statement creates a synonym for a given dataset.
@@ -470,7 +471,7 @@ The target dataset does not need to exist when the synonym is created.
 
     SELECT * FROM customersSynonym;
 
-More information on how synonyms are resolved can be found in the appendix section on Variable Resolution.
+More information on how synonyms are resolved can be found in the [Appendix 3. Variable Bindings and Name Resolution](#Variable_bindings_and_name_resolution).
 
 #### <a id="Create_function">Create Function</a>
 
@@ -488,6 +489,7 @@ The body of a function can be any query expression involving the function's para
 **![](../images/diagrams/ExternalFunctionDef.png)**
 
 ---
+
 The following is an example of a `CREATE FUNCTION` statement which is similar to our earlier `DECLARE FUNCTION` example.
 
 It differs from that example in that it results in a function that is persistently registered by name in the specified dataverse (the current dataverse being used, if not otherwise specified).
@@ -525,8 +527,7 @@ would be as follows
 
 ##### Example
 
-    CREATE FUNCTION sentiment(a)
-      AS "sentiment_mod", "sent_model.sentiment" AT pylib;
+    CREATE FUNCTION sentiment(a) AS "sentiment_mod", "sent_model.sentiment" AT pylib;
 
 ### <a id="Removal">Drop Statement</a>
 
@@ -534,9 +535,21 @@ would be as follows
 ### DropStmnt
 **![](../images/diagrams/DropStmnt.png)**
 
+### DataverseName
+**![](../images/diagrams/DataverseName.png)**
+
+### QualifiedName
+**![](../images/diagrams/QualifiedName.png)**
+
+### DoubleQualifiedName
+**![](../images/diagrams/DoubleQualifiedName.png)**
+
 ### FunctionSignature
 **![](../images/diagrams/FunctionSignature.png)**
 
+### FunctionParameters
+**![](../images/diagrams/FunctionParameters.png)**
+
 ---
 
 The `DROP` statement is the inverse of the `CREATE` statement. It can be used to drop dataverses, datatypes, datasets, indexes, functions, and synonyms.
@@ -571,6 +584,9 @@ the identifying name of the function to be dropped must explicitly include that
 ### LoadStmnt
 **![](../images/diagrams/LoadStmnt.png)**
 
+### AdapterName
+**![](../images/diagrams/AdapterName.png)**
+
 ### Configuration
 **![](../images/diagrams/Configuration.png)**
 
@@ -602,7 +618,6 @@ The following example shows how to bulk load the `customers` dataset from an ext
 ### InsertStmnt
 **![](../images/diagrams/InsertStmnt.png)**
 
-
 ---
 
 The `INSERT` statement is used to insert new data into a dataset.
@@ -651,12 +666,13 @@ The following example illustrates a query-based upsert operation.
     UPSERT INTO custCopy (SELECT VALUE c FROM customers c)
 
 ### <a id="Deletes">Delete Statement</a>
+
 ---
 ### DeleteStmnt
 **![](../images/diagrams/DeleteStmnt.png)**
 
-
 ---
+
 The `DELETE` statement is used to delete data from a target dataset.
 The data to be deleted is identified by a boolean expression involving the variable bound to the target dataset in the `DELETE` statement.
 
@@ -676,5 +692,3 @@ The following examples illustrate single-object deletions.
 ##### Example
 
     DELETE FROM customers WHERE custid = "C47";
-
-
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_1_keywords.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_1_keywords.md
index d7c02d8..8da032c 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_1_keywords.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_1_keywords.md
@@ -21,22 +21,24 @@ All reserved keywords are listed in the following table:
 
 |     |     |       |    |     |    |
 | ----|-----|-------|----|-----|----|
-| AND | ANY | APPLY | AS | ASC | AT |
-| AUTOGENERATED | BETWEEN | BTREE | BY | CASE | CLOSED |
-| CREATE | COMPACTION | COMPACT | CONNECT | CORRELATE | DATASET |
-| COLLECTION | DATAVERSE | DECLARE | DEFINITION | DECLARE | DEFINITION |
-| DELETE | DESC | DISCONNECT | DISTINCT | DROP | ELEMENT |
+| ADAPTER | ALL | AND | ANY | APPLY | AS |
+| ASC | AT | AUTOGENERATED | BETWEEN | BTREE | BY |
+| CASE | CLOSED | COLLECTION | CREATE | COMPACTION | COMPACT |
+| CONNECT | CORRELATE | DATASET | DATAVERSE | DECLARE | DEFINITION |
+| DELETE | DESC | DISCONNECT | DISTINCT | DIV | DROP |
 | ELEMENT | EXPLAIN | ELSE | ENFORCED | END | EVERY |
 | EXCEPT | EXIST | EXTERNAL | FEED | FILTER | FLATTEN |
-| FOR | FROM | FULL | FUNCTION | GROUP | HAVING |
-| HINTS | IF | INTO | IN | INDEX | INGESTION |
-| INNER | INSERT | INTERNAL | INTERSECT | IS | JOIN |
-| KEYWORD | LEFT | LETTING | LET | LIKE | LIMIT |
-| LOAD | NODEGROUP | NGRAM | NOT | OFFSET | ON |
-| OPEN | OR | ORDER | OUTER | OUTPUT | OVER |
-| PATH | POLICY | PRE-SORTED | PRIMARY | RAW | REFRESH |
-| RETURN | RTREE | RUN | SATISFIES | SECONDARY | SELECT |
-| SET | SOME | TEMPORARY | THEN | TYPE | UNKNOWN |
-| UNNEST | UPDATE | USE | USING | VALUE | WHEN |
-| WHERE | WITH | WRITE |     |     |     |
+| FOR | FROM | FULL | FULLTEXT | FUNCTION | GROUP |
+| HAVING | HINTS | IF | INTO | IN | INDEX |
+| INGESTION | INNER | INSERT | INTERNAL | INTERSECT | IS |
+| JOIN | KEYWORD | LEFT | LETTING | LET | LIKE |
+| LIMIT | LOAD | MISSING | NODEGROUP | NGRAM | NOT |
+| NULL | OFFSET | ON | OPEN | OR | ORDER |
+| OUTER | OUTPUT | OVER | PATH | POLICY | PRE-SORTED |
+| PRIMARY | RAW | REFRESH | RETURN | RETURNING | RIGHT |
+| RTREE | RUN | SATISFIES | SECONDARY | SELECT | SET |
+| SOME | START | STOP | SYNONYM | TEMPORARY | THEN |
+| TO | TRUE | TYPE | UNION | UNKNOWN | UNNEST |
+| UPDATE | UPSERT | USE | USING | VALUE | VALUED |
+| WHEN | WHERE | WITH | WRITE |     |     |