1 %{
2     // to make this grammar similar to the golang N1QL grammar, we need to implement some of the convenience functions
3     // in golang that are used in the parser productions.
4     
5     function expr(type,ex) {
6	       this.type = type;
7	       this.ops = {};
8	       //console.log("Creating expression type: " + type + (ex ? (" (" + ex + ")") : ""));
9     }
10
11     expr.prototype.Alias = function() {return this.ops.name;};
12     expr.prototype.Select = function() {return this.ops.select;};
13     expr.prototype.Subquery = function() {return this.ops.subquery;};
14     expr.prototype.Keys = function() {return this.ops.keys;};
15     expr.prototype.Indexes = function() {return this.ops.indexes;};
16     
17     //
18     // return all the fields found in the parse tree. Each field will be an array of terms
19     //
20     
21     expr.prototype.getFields = function(fieldArray, aliases) {
22	       //console.log("getting fields for item type: " + this.type);
23		       
24	       if (!fieldArray) fieldArray = [];
25	       if (!aliases) aliases = {};
26	       
27	       switch (this.type) {
28	       
29	       // Subselect indicates a keyspace, and possibly an alias
30	       case "Subselect": {
31	         if (this.ops.from && this.ops.from.type == "KeyspaceTerm") {
32	           if (this.ops.from.ops.keyspace)
33	             fieldArray.push(this.ops.from.ops.keyspace);
34
35               // if we see an alias, create a new alias object to included it	           
36               if (this.ops.from.ops.as_alias) {
37                 aliases = JSON.parse(JSON.stringify(aliases));
38                 aliases[this.ops.from.ops.as_alias] = this.ops.from.ops.keyspace;
39               }
40	         }
41	       }
42	       break;
43	       
44           // if this has type "Field" or "Element", extract the path	       
45	       case "Field":
46	       case "Element": {
47             var path = [];
48             this.getFieldPath(path,fieldArray,aliases);
49             if (path.length > 0)
50                 fieldArray.push(path);
51             
52             break;
53            }
54             
55           // any ExpressionTerm or ResultTerm can have an Identifier child that indicates
56           // a field or bucket
57           case "ExpressionTerm":
58           case "ResultTerm":
59             if (this.ops.expression && this.ops.expression.type == "Identifier")
60                 fieldArray.push([this.ops.expression.ops.identifier]);
61             break;
62
63           // KeyspaceTerm gives bucket names in the from clause
64
65           case "KeyspaceTerm":
66             if (this.ops.keyspace)
67                 fieldArray.push([this.ops.keyspace]);
68             break;
69           }
70
71         // regardless, go through the "ops" object and call recursively on  our children
72         for (var name in this.ops) {
73             var child = this.ops[name];
74             if (!child)
75                 continue;
76                 
77             // if we are an array op, ignore the "mapping" and "when" fields
78             if (this.type == "Array" && (name == "mapping" || name == "when"))
79                 continue;
80                 
81             // the "satisfies" term for ANY, EVERY, etc., contains references to the bound variables,
82             // and as such we can't find any useful field information             
83             if (name == "satisfies")
84                 continue;
85                 
86             // the "FIRST" operator has an expression based on bindings, which we must ignore
87             if (this.type == "First" && (name == "expression" || name == "when"))
88                 continue;
89             
90                 
91             
92             //console.log("  got child: " + name + "(" + (child.type && child.ops) + ") = " + JSON.stringify(child));
93             
94             if (child.getFields)  {
95                 //console.log("  got child type: " + child.type);
96                 child.getFields(fieldArray,aliases);
97             }
98
99             // some children are arrays
100             else if (child.length) for (var i=0; i< child.length; i++) if (child[i] && child[i].getFields) {
101                 //console.log("  got child[" + i + "] type: " + child[i].type);
102                 child[i].getFields(fieldArray,aliases);
103             }
104         }
105     };
106     
107     //
108     // if we have a field, we can build its list of path elements
109     // Field expressions come in a variety of forms
110     //   - "Field" -> "Identifier" (first item in path), "FieldName" (next item in path) 
111     //   - "Element" -> "Field" (array expr prefix), expr (array expression)
112     // 
113     // We expect currentPath to be an array into which we put the elements in the path
114     // 
115     
116     expr.prototype.getFieldPath = function(currentPath,fieldArray,aliases) {
117	       //console.log("Getting field path for type: " + this.type);
118         // error checking: must have ops
119         if (!this.ops)
120             return;
121
122         // Field type - first might be Identifier, first element in path
123         //            - might be Element, meaning array expression
124         //  first might also be Field, needing recursive call
125         //  second is usually next item in path
126         
127         if ((this.type == "Field" || this.type == "Element") && this.ops.first) {
128             if (this.ops.first.type == "Identifier") {
129                 var id = this.ops.first.ops.identifier; // if the first element is an alias, resolve it
130                 if (aliases && aliases[id])
131                     id = aliases[id];
132                 currentPath.push(id);
133             }
134             else if (this.ops.first.type == "Field" || this.ops.first.type == "Element")
135                 this.ops.first.getFieldPath(currentPath,fieldArray,aliases);
136         }
137
138         else if (this.type == "Identifier" && this.ops.identifier) {
139             currentPath.push(this.ops.identifier);
140         }
141         
142         else if (this.type == "FieldName" && this.ops.field_name) {
143             currentPath.push(this.ops.identifier);
144         }
145
146         // if we have type "Field", the "second" field may be part of the path expression
147         
148         if (this.type == "Field" && this.ops.second && this.ops.second.type == "FieldName")
149             currentPath.push(this.ops.second.ops.field_name);
150         
151         // if we have type "Element", second is unconnected expression that should 
152         // none-the-less be scanned for other field names
153         
154         if (this.type == "Element" && this.ops.second.getFields) {
155             if (currentPath.length > 0)
156                 currentPath.push("[]"); // indicate the array reference in the path
157             this.ops.second.getFields(fieldArray);
158         }
159     };
160     
161
162     var expression = {};
163     expression.Bindings = [];
164     expression.Expressions = [];
165     expression.FALSE_EXPR = "FALSE";
166     expression.MISSING_EXPR = "MISSING";
167     expression.NULL_EXPR = "NULL";
168     expression.TRUE_EXPR = "TRUE";
169     
170     expression.NewAdd = function(first, second)                     {var e = new expr("Add"); e.ops.first = first; e.ops.second = second; return e;};
171     expression.NewAll = function(all_expr, distinct)                {var e = new expr("All"); e.ops.all_expr = all_expr; return e;};
172     expression.NewAnd = function(first, second)                     {var e = new expr("And"); e.ops.first = first; e.ops.second = second; return e;};
173     expression.NewAny = function(bindings, satisfies)               {var e = new expr("Any"); e.ops.bindings = bindings; e.ops.satisfies = satisfies; return e;};
174     expression.NewAnyEvery = function(bindings, satisfies)          {var e = new expr("AnyEvery"); e.ops.bindings = bindings; e.ops.satisfies = satisfies;return e;};
175     expression.NewArray = function(mapping, bindings, when)         {var e = new expr("Array"); e.ops.mapping = mapping; e.ops.bindings = bindings; e.ops.when = when; return e;};
176     expression.NewArrayConstruct = function(elements)               {var e = new expr("ArrayConstruct"); e.ops.elements = elements; return e;};
177     expression.NewArrayStar = function(operand)                     {var e = new expr("ArrayStar"); e.ops.operand = operand; return e;};
178     expression.NewBetween = function(item, low, high)               {var e = new expr("Between"); e.ops.item = item; e.ops.low = low; e.ops.high = high; return e;};
179     expression.NewBinding = function(name_variable, variable, binding_expr, descend)
180     {var e = new expr("Binding"); e.ops.name_variable = name_variable; e.ops.variable = variable; e.ops.binding_expr = binding_expr; e.ops.descend = descend; return e;};
181     expression.NewConcat = function(first, second)                  {var e = new expr("Concat"); e.ops.first = first; e.ops.second = second; return e;};
182     expression.NewConstant = function(value)                        {var e = new expr("Constant"); e.ops.value = value; return e;};
183     expression.NewCover = function(covered)                         {var e = new expr("Cover"); e.ops.covered = covered; return e;};
184     expression.NewDiv = function(first, second)                     {var e = new expr("Div"); e.ops.first = first; e.ops.second = second; return e;};
185     expression.NewElement = function(first, second)                 {var e = new expr("Element"); e.ops.first = first; e.ops.second = second; return e;};
186     expression.NewEq = function(first, second)                      {var e = new expr("Eq"); e.ops.first = first; e.ops.second = second; return e;};
187     expression.NewEmpty = function()                                {var e = new expr("Empty"); return e;};
188     expression.NewEvery = function(bindings, satisfies)             {var e = new expr("Every"); e.ops.bindings = bindings; e.ops.satisfies = satisfies; return e;};
189     expression.NewExists = function(operand)                        {var e = new expr("Exists"); e.ops.operand = operand; return e;};
190     expression.NewField = function(first,second)                    {var e = new expr("Field"); e.ops.first = first; e.ops.second = second; return e;};
191     expression.NewFieldName = function(field_name,case_insensitive) {var e = new expr("FieldName",field_name); e.ops.field_name = field_name; e.ops.case_insensitive = case_insensitive; return e;};
192     expression.NewFirst = function(expression,coll_bindings,when)   {var e = new expr("First"); e.ops.expression = expression; e.ops.coll_bindings = coll_bindings; e.ops.when = when; return e;};
193     expression.NewGE = function(first, second)                      {var e = new expr("GE"); e.ops.first = first; e.ops.second = second; return e;};
194     expression.NewGT = function(first, second)                      {var e = new expr("GT"); e.ops.first = first; e.ops.second = second; return e;};
195     expression.NewIdentifier = function(identifier)                 {var e = new expr("Identifier",identifier); e.ops.identifier = identifier; return e;};
196     expression.NewIn = function(first, second)                      {var e = new expr("In"); e.ops.first = first; e.ops.second = second; return e;};
197     expression.NewIsMissing = function(operand)                     {var e = new expr("IsMissing"); e.ops.operand = operand; return e;};
198     expression.NewIsNotNull = function(operand)                     {var e = new expr("IsNotNull"); e.ops.operand = operand; return e;};
199     expression.NewIsNotMissing = function(operand)                  {var e = new expr("IsNotMissing"); e.ops.operand = operand; return e;};
200     expression.NewIsNotValued = function(operand)                   {var e = new expr("IsNotValued"); e.ops.operand = operand; return e;};
201     expression.NewIsNull = function(operand)                        {var e = new expr("IsNull"); e.ops.operand = operand; return e;};
202     expression.NewIsValued = function(operand)                      {var e = new expr("IsValued"); e.ops.operand = operand; return e;};
203     expression.NewLE = function(first, second)                      {var e = new expr("LE"); e.ops.first = first; e.ops.second = second; return e;};
204     expression.NewLT = function(first, second)                      {var e = new expr("LT"); e.ops.first = first; e.ops.second = second; return e;};
205     expression.NewLike = function(first, second)                    {var e = new expr("Like"); e.ops.first = first; e.ops.second = second; return e;};
206     expression.NewMod = function(first, second)                     {var e = new expr("Mod"); e.ops.first = first; e.ops.second = second; return e;};
207     expression.NewMult = function(first, second)                    {var e = new expr("Multi"); e.ops.first = first; e.ops.second = second; return e;};
208     expression.NewNE = function(first, second)                      {var e = new expr("NE"); e.ops.first = first; e.ops.second = second; return e;};
209     expression.NewNeg = function(operand)                           {var e = new expr("Neg"); e.ops.operand = operand; return e;};
210     expression.NewNot = function(operand)                           {var e = new expr("Not"); e.ops.operand = operand; return e;};
211     expression.NewNotBetween = function(iteem, low, high)           {var e = new expr("NotBetween"); e.ops.item = item; e.ops.low = low; e.ops.high = high; return e;};
212     expression.NewNotIn = function(first, second)                   {var e = new expr("NotIn"); e.ops.first = first; e.ops.second = second; return e;};
213     expression.NewNotLike = function(first, second)                 {var e = new expr("NotLike"); e.ops.first = first; e.ops.second = second; return e;};
214     expression.NewNotWithin = function(first, second)               {var e = new expr("NotWithin"); e.ops.first = first; e.ops.second = second; return e;};
215     expression.NewObject = function(name_mapping, value_mapping, bindings, when)
216     {var e = new expr("Object"); e.ops.name_mapping = name_mapping; e.ops.value_mapping = value_mapping; e.ops.bindings = bindings; e.ops.when = when; return e;};
217     expression.NewObjectConstruct = function(mapping)               {var e = new expr("ObjectConstruct"); e.ops.mapping = mapping; return e;};
218     expression.NewOr = function(first, second)                      {var e = new expr("Or"); e.ops.first = first; e.ops.second = second; return e;};
219     expression.NewSearchedCase = function(when_terms, else_term)    {var e = new expr("SearchedCase"); e.ops.when_terms = when_terms; e.ops.else_term = else_term; return e;};
220     expression.NewSelf = function()                                 {var e = new expr("Self"); return e;};
221     expression.NewSimpleBinding = function(variable, binding_expr)  {var e = new expr("SimpleBinding"); e.ops.variable = variable; e.ops.binding_expr = binding_expr; return e;};
222     expression.NewSimpleCase = function(search_term, when_terms, else_term)
223     {var e = new expr("SimpleCase"); e.ops.search_term = search_term; e.ops.when_terms = when_terms; e.ops.else_term = else_term; return e;};
224     expression.NewSlice = function(first, second, third)            {var e = new expr("Slice"); e.ops.first = first; e.ops.second = second; e.ops.third = third; return e;};
225     expression.NewFunction = function(fname, param_expr, distinct)  {var e = new expr("Function"); e.ops.fname = fname; e.ops.param_expr = param_expr; e.ops.distinct = distinct; return e;};
226     expression.NewSub = function(first, second)                     {var e = new expr("Sub"); e.ops.first = first; e.ops.second = second; return e;};
227     expression.NewWithin = function(first, second)                  {var e = new expr("Within"); e.ops.first = first; e.ops.second = second; return e;};
228
229     //
230
231     var algebra = {};
232     algebra.EMPTY_USE = new expr("EMPTY_USE");
233     algebra.MapPairs = function(pairs)                                       {var a = new expr("Pairs"); a.ops.pairs = pairs; return a;}
234     algebra.NewAlterIndex = function(keyspace, index_name, opt_using, rename){var a = new expr("AlterIndex"); a.ops.keyspace = keyspace; a.ops.index_name = index_name; a.ops.opt_using = opt_using; a.ops.rename = rename; return a;};
235     algebra.NewAnsiJoin = function(from,join_type,join_term,for_ident)      {var a = new expr("AnsiJoin"); a.ops.from = from; a.ops.join_type = join_type; a.ops.join_term = join_term; a.ops.for_ident = for_ident; return a;};
236     algebra.NewAnsiNest = function(from,join_type,join_term,for_ident)      {var a = new expr("AnsiNest"); a.ops.from = from; a.ops.join_type = join_type; a.ops.join_term = join_term; a.ops.for_ident = for_ident; return a;};
237     algebra.NewAnsiRightJoin = function(keyspace,join_term,for_ident)       {var a = new expr("AnsiRightJoin"); a.ops.ks = keyspace; a.ops.join_term = join_term; a.ops.for_ident = for_ident; return a;};
238     algebra.NewBuildIndexes = function(keyspace,opt_index,index_names)      {var a = new expr("BuildIndexes"); a.ops.keyspace = keyspace; a.opt_index = opt_index; a.ops.index_names = index_names; return a;};
239     algebra.NewCreateIndex = function(index_name,keyspace,index_terms,index_partition,index_where,index_using,index_with) 
240       {var a = new expr("CreateIndex"); 
241       a.ops.index_name = index_name; 
242       a.ops.keyspace = keyspace; 
243       a.ops.index_terms = index_terms; 
244       a.ops.index_partition = index_partition; 
245       a.ops.index_where = index_where; 
246       a.ops.index_using = index_using; 
247       a.ops.index_where = index_where; return a;};
248     algebra.NewCreatePrimaryIndex = function(opt_name,keyspace,index_using,index_with) {var a = new expr("CreatePrimateIndex"); a.ops.opt_name = opt_name; a.ops.keyspace = keyspace; a.ops.index_using = index_using; a.ops.index_with = index_with; return a;};
249     algebra.NewDelete = function(keyspace,opt_use_keys,opt_use_indexes,opt_where,opt_limit,opt_returning) {var a = new expr("Delete"); a.ops.keyspace = keyspace; a.ops.opt_use_keys = opt_use_keys; a.ops.opt_use_indexes = opt_use_indexes; a.ops.opt_where = opt_where; a.ops.opt_limit = opt_limit; return a;};
250     algebra.NewDropIndex = function(keyspace, opt_using)                     {var a = new expr("DropIndex"); a.ops.keyspace = keyspace; a.ops.opt_using = opt_using; return a;};
251     algebra.NewExcept = function(first,except)                               {var a = new expr("Except"); a.ops.first = first; a.ops.except = except; return a;};
252     algebra.NewExceptAll = function(first,except)                            {var a = new expr("ExceptAll"); a.ops.first = first; a.ops.except = except; return a;};
253     algebra.NewExecute = function(expression)                                {var a = new expr("Execute"); a.ops.expression = expression; return a;};
254     algebra.NewExplain = function(statement)                                 {var a = new expr("Explain"); a.ops.statement = statement; return a;};
255     algebra.NewExpressionTerm = function(expression, opt_as_alias, opt_use)  {var a = new expr("ExpressionTerm"); a.ops.expression = expression; a.ops.opt_as_alias = opt_as_alias; a.ops.opt_use = opt_use; return a;};
256     algebra.NewGrantRole = function(role_list,user_list,keyspace_list)       {var a = new expr("GrantRole"); a.ops.role_list = role_list; a.ops.user_list = user_list; a.ops.keyspace_list = keyspace_list; return a;};
257     algebra.NewGroup = function(expression,opt_letting,opt_having)           {var a = new expr("Group"); a.ops.expression = expression; a.ops.opt_letting = opt_letting; a.ops.opt_having = opt_having; return a;};
258     algebra.NewIndexJoin = function(from,join_type,join_term,for_ident)      {var a = new expr("IndexJoin"); a.ops.from = from; a.ops.join_type = join_type; a.ops.join_term = join_term; a.ops.for_ident = for_ident; return a;};
259     algebra.NewIndexKeyTerm = function(index_term,opt_dir)                   {var a = new expr("IndexKeyTerm"); a.ops.index_term = index_term; a.ops.opt_dir = opt_dir; return a;};
260     algebra.NewIndexNest = function(from,join_type,join_term,for_ident)      {var a = new expr("IndexNest"); a.ops.from = from; a.ops.join_type = join_type; a.ops.join_term = join_term; a.ops.for_ident = for_ident; return a;};
261     algebra.NewIndexRef = function(index_name,opt_using)                     {var a = new expr("IndexRef"); a.ops.index_name = index_name; a.ops.opt_using = opt_using; return a;};
262     algebra.NewInferKeyspace = function(keyspace,infer_using,infer_with)     {var a = new expr("InferKeyspace"); a.ops.keyspace = keyspace; a.ops.infer_using = infer_using; a.ops.infer_with = infer_with; return a;};
263     algebra.NewInsertSelect = function(keyspace,key_expr,value_expr,fullselect,returning) {var a = new expr("InsertSelect"); a.ops.keyspace = keyspace; a.ops.key_expr = key_expr; a.ops.value_expr = value_expr; return a;};
264     algebra.NewInsertValues = function(keyspace,values_header,values_list,returning) {var a = new expr("InsertValues"); a.ops.values_header = values_header, a.ops.values_list = values_list; a.ops.returning = returning; return a;};
265     algebra.NewIntersect = function(select_terms,intersect_term)             {var a = new expr("Intersect"); a.ops.elect_terms = elect_terms; a.ops.intersect_term = intersect_term; return a;};
266     algebra.NewIntersectAll = function(select_terms,intersect_term)          {var a = new expr("IntersectAll"); a.ops.select_terms = select_terms; a.ops.intersect_term = intersect_term; return a;};
267     algebra.NewJoin = function(from,join_type,join_term)                     {var a = new expr("Join"); a.ops.from = from; a.ops.join_type = join_type; a.ops.join_term = join_term; return a;};
268     algebra.NewKeyspaceRef = function(namespace,keyspace,alias)              {var a = new expr("KeyspaceRef"); a.ops.namespace = namespace; a.ops.keyspace = keyspace; a.ops.alias = alias; return a;};
269     algebra.NewKeyspaceTerm = function(namespace,keyspace,as_alias,opt_use)  {var a = new expr("KeyspaceTerm"); a.ops.namespace = namespace; a.ops.keyspace = keyspace; a.ops.as_alias = as_alias; a.ops.opt_use = opt_use; return a;};
270     algebra.NewMerge = function(keyspace,merge_source,key,merge_actions,opt_limit,returning) {var a = new expr("Merge"); a.ops.keyspace = keyspace; a.ops.merge_source = merge_source; a.ops.key = key; a.ops.merge_actions = merge_actions; a.ops.opt_limit = opt_limit; a.ops.returning = returning; return a;};
271     algebra.NewMergeActions = function(update,del,insert)                    {var a = new expr("MergeActions"); a.ops.update = update; a.ops.del = del; a.ops.insert = insert; return a;};
272     algebra.NewMergeDelete = function(where)                                 {var a = new expr("MergeDelete"); a.ops.where = where; return a;};
273     algebra.NewMergeInsert = function(expression,where)                      {var a = new expr("MergeInsert"); a.ops.expression = expression; a.ops.where = where; return a;};
274     algebra.NewMergeSourceExpression = function(expression,alias)            {var a = new expr("MergeSourceSelect"); a.ops.expression = expression; a.ops.alias = alias; return a;};
275     algebra.NewMergeSourceFrom = function(from,alias)                        {var a = new expr("MergeSourceSelect"); a.ops.from = from; a.ops.alias = alias; return a;};
276     algebra.NewMergeSourceSelect = function(from,alias)                      {var a = new expr("MergeSourceSelect"); a.ops.from = from; a.ops.alias = alias; return a;};
277     algebra.NewMergeUpdate = function(set,unset,where)                       {var a = new expr("MergeUpdate"); a.ops.set = set; a.ops.unset = unset; a.ops.where = where; return a;};
278     algebra.NewNamedParameter = function(named_param)                        {var a = new expr("NamedParameter"); a.ops.named_param = named_param; return a;};
279     algebra.NewNest = function(from,join_type,join_term)                     {var a = new expr("Nest"); a.ops.from = from; a.ops.join_type = join_type; a.ops.join_term = join_term; return a;};
280     algebra.NewOrder = function(sort_terms)                                  {var a = new expr("Order"); a.ops.sort_terms = sort_terms; return a;};
281     algebra.NewPair = function(first,second)                                 {var a = new expr("Pair"); a.ops.first = first; a.ops.second = second; return a;};
282     algebra.NewPositionalParameter = function(positional_param)              {var a = new expr("PositionalParameter"); a.ops.positional_param = positional_param; return a;};
283     algebra.NewPrepare = function(name,statement)                            {var a = new expr("Prepare"); a.ops.name = name; a.ops.statement = statement; return a;};
284     algebra.NewProjection = function(distinct,projects)                      {var a = new expr("Projection"); a.ops.distinct = distinct; a.ops.projects = projects; return a;};
285     algebra.NewRawProjection = function(distinct,expression,as_alias)        {var a = new expr("RawProjection"); a.ops.distinct = distinct; a.ops.expression = expression; a.ops.as_alias = as_alias; return a;};
286     algebra.NewResultTerm = function(expression,star,as_alias)               {var a = new expr("ResultTerm"); a.ops.expression = expression; a.ops.star = star; a.ops.as_alias = as_alias; return a;};
287     algebra.NewRevokeRule = function(role_list,user_list,keyspace_list)      {var a = new expr("RevokeRule"); a.ops.role_list = role_list; a.ops.user_list = user_list; a.ops.keyspace_list = keyspace_list; return a;};
288     algebra.NewSelect = function(select_terms,order_by,offset,limit)         {var a = new expr("Select"); a.ops.select_terms = select_terms; a.ops.order_by = order_by; a.ops.offset = offset; a.ops.limit = limit; return a;};
289     algebra.NewSelectTerm = function(term)                                   {var a = new expr("SelectTerm"); a.ops.term = term; return a;};
290     algebra.NewSet = function(set_terms)                                     {var a = new expr("Set"); a.ops.set_terms = set_terms; return a;};
291     algebra.NewSetTerm = function(path,expression,update_for)                {var a = new expr("SetTerm"); a.ops.path = path; a.ops.expression = expression; a.ops.update_for = update_for; return a;};
292     algebra.NewSortTerm = function(expression,desc)                          {var a = new expr("SortTerm"); a.ops.expression = expression; a.ops.desc = desc; return a;};
293     algebra.NewSubquery = function(fullselect)                               {var a = new expr("Subquery"); a.ops.fullselect = fullselect; return a;};
294     algebra.NewSubqueryTerm = function(select_term,as_alias)                 {var a = new expr("SubqueryTerm"); a.ops.select_term = select_term; a.ops.as_alias = as_alias; return a;};
295     algebra.NewSubselect = function(from,let,where,group,select)             {var a = new expr("Subselect"); a.ops.from = from; a.ops.let = let; a.ops.where = where; a.ops.group = group; a.ops.select = select; return a;};
296     algebra.NewUnion = function(first,second)                                {var a = new expr("Union"); a.ops.first = first; a.ops.second = second; return a;};
297     algebra.NewUnionAll = function(first,second)                             {var a = new expr("UnionAll"); a.ops.first = first; a.ops.second = second; return a;};
298     algebra.NewUnnest = function(from,join_type,expression,as_alias)         {var a = new expr("Unnest"); a.ops.from = from; a.ops.join_type = join_type; a.ops.expression = expression; a.ops.as_alias = as_alias; return a;};
299     algebra.NewUnset = function(unset_terms)                                 {var a = new expr("Unset"); a.ops.unset_terms = unset_terms; return a;};
300     algebra.NewUnsetTerm = function(path,update_for)                         {var a = new expr("UnsetTerm"); a.ops.path = path; a.ops.update_for = update_for; return a;};
301     algebra.NewUpdate = function(keyspace,use_keys,use_indexes,set,unset,where,limit,returning) {var a = new expr("Update"); a.ops.keyspace = keyspace; a.ops.use_keys = use_keys; a.ops.use_indexes = use_indexes; a.ops.set = set; a.ops.unset = unset; a.ops.where = where; a.ops.limit = limit; a.ops.returning = returning; return a;};
302     algebra.NewUpdateFor = function(update_dimensions,when)                  {var a = new expr("UpdateFor"); a.ops.update_dimensions = update_dimensions; a.ops.when = when; return a;};
303     algebra.NewUpsertSelect = function(keyspace,key_expr,value_expr,fullselect,returning) {var a = new expr("UpsertSelect"); a.ops.keyspace = keyspace; a.ops.key_expr = key_expr; a.ops.value_expr = value_expr; a.ops.fullselect = fullselect; a.ops.returning = returning; return a;};
304     algebra.NewUpsertValues = function(keyspace,values_list,returning)       {var a = new expr("UpsertValues"); a.ops.keyspace = keyspace; a.ops.values_list = values_list; a.ops.returning = returning; return a;};
305     algebra.NewUse = function(keys,index)                                    {var a = new expr("Use"); a.ops.keys = keys; a.ops.index = index; return a;};
306
307     algebra.SubqueryTerm = "SubqueryTerm";
308     algebra.ExpressionTerm = "ExpressionTerm";
309     algebra.KeyspaceTerm = "KeyspaceTerm";
310
311     var value = {};
312     value.NewValue = function(val) {var a = new expr("Value"); a.value = val; return a;};
313
314     var datastore = {
315         INF_DEFAULT : "INF_DEFAULT",
316         DEFAULT : "DEFAULT",
317         VIEW : "VIEW",
318         GSI : "GSI",
319         FTS : "FTS"    
320     };
321     
322     var nil = null;
323
324     var statement_count = 0;
325
326     var yylex = {
327         Error: function(message) {console.log(message);}
328     };
329%}
330
331%lex
332
333qidi                        [`](([`][`])|[^`])+[`][i]
334qid                         [`](([`][`])|[^`])+[`]
335
336%options flex case-insensitive
337
338%%
339
340
341\"((\\\")|[^\"])*\" { return 'STR'; }
342
343\'(('')|[^\'])*\'   { return 'STR'; }
344
345{qidi}              { yytext = yytext.substring(1,yytext.length -2).replace("``","`"); return 'IDENT_ICASE'; }
346
347{qid}               { yytext = yytext.substring(1,yytext.length -1).replace("``","`"); return 'IDENT'; }
348                                      
349(0|[1-9][0-9]*)\.[0-9]+([eE][+\-]?[0-9]+)? { return 'NUM'; }
350
351(0|[1-9][0-9]*)[eE][+\-]?[0-9]+ { return 'NUM';  }
352
3530|[1-9][0-9]* { return 'NUM'; }
354
355(\/\*)([^\*]|(\*)+[^\/])*((\*)+\/) /* eat up block comment */ 
356
357"--"[^\n\r]*      /* eat up line comment */ 
358
359[ \t\n\r\f]+      /* eat up whitespace */ 
360
361"."               { return ("DOT"); }
362"+"               { return ("PLUS"); }
363"*"               { return ("STAR"); }
364"/"               { return ("DIV"); }
365"-"               { return ("MINUS"); }
366"%"               { return ("MOD"); }
367"=="      { return ("DEQ"); }
368"="               { return ("EQ"); }
369"!="      { return ("NE"); }
370"<>"      { return ("NE"); }
371"<"               { return ("LT"); }
372"<="      { return ("LE"); }
373">"               { return ("GT"); }
374">="      { return ("GE"); }
375"||"      { return ("CONCAT"); }
376"("               { return ("LPAREN"); }
377")"               { return ("RPAREN"); }
378"{"               { return ("LBRACE"); }
379"}"               { return ("RBRACE"); }
380","               { return ("COMMA"); }
381":"               { return ("COLON"); }
382"["               { return ("LBRACKET"); }
383"]"               { return ("RBRACKET"); }
384"]i"      { return ("RBRACKET_ICASE"); }
385";"               { return ("SEMI"); }
386"!"               { return ("NOT_A_TOKEN"); }
387
388<<EOF>>   { return 'EOF'; }
389
390 
391\$[a-zA-Z_][a-zA-Z0-9_]*   { return 'NAMED_PARAM'; }
392
393\$[1-9][0-9]*              { return 'POSITIONAL_PARAM'; }
394
395\?                         { return 'NEXT_PARAM'; }
396
397
398"all"                           { return("ALL"); }
399"alter"                         { return("ALTER"); }
400"analyze"                       { return("ANALYZE"); }
401"and"                           { return("AND"); }
402"any"                           { return("ANY"); }
403"array"                         { return("ARRAY"); }
404"as"                            { return("AS"); }
405"asc"                           { return("ASC"); }
406"begin"                         { return("BEGIN"); }
407"between"                       { return("BETWEEN"); }
408"binary"                        { return("BINARY"); }
409"boolean"                       { return("BOOLEAN"); }
410"break"                         { return("BREAK"); }
411"bucket"                        { return("BUCKET"); }
412"build"                         { return("BUILD"); }
413"by"                            { return("BY"); }
414"call"                          { return("CALL"); }
415"case"                          { return("CASE"); }
416"cast"                          { return("CAST"); }
417"cluster"                       { return("CLUSTER"); }
418"collate"                       { return("COLLATE"); }
419"collection"                    { return("COLLECTION"); }
420"commit"                        { return("COMMIT"); }
421"connect"                       { return("CONNECT"); }
422"continue"                      { return("CONTINUE"); }
423"correlated"                    { return("CORRELATED"); }
424"cover"                         { return("COVER"); }
425"create"                        { return("CREATE"); }
426"database"                      { return("DATABASE"); }
427"dataset"                       { return("DATASET"); }
428"datastore"                     { return("DATASTORE"); }
429"declare"                       { return("DECLARE"); }
430"decrement"                     { return("DECREMENT"); }
431"delete"                        { return("DELETE"); }
432"derived"                       { return("DERIVED"); }
433"desc"                          { return("DESC"); }
434"describe"                      { return("DESCRIBE"); }
435"distinct"                      { return("DISTINCT"); }
436"do"                            { return("DO"); }
437"drop"                          { return("DROP"); }
438"each"                          { return("EACH"); }
439"element"                       { return("ELEMENT"); }
440"else"                          { return("ELSE"); }
441"end"                           { return("END"); }
442"every"                         { return("EVERY"); }
443"except"                        { return("EXCEPT"); }
444"exclude"                       { return("EXCLUDE"); }
445"execute"                       { return("EXECUTE"); }
446"exists"                        { return("EXISTS"); }
447"explain"                       { return("EXPLAIN") }
448"false"                         { return("FALSE"); }
449"fetch"                         { return("FETCH"); }
450"first"                         { return("FIRST"); }
451"flatten"                       { return("FLATTEN"); }
452"for"                           { return("FOR"); }
453"force"                         { return("FORCE"); }
454"from"                          { return("FROM"); }
455"fts"                           { return("FTS"); }
456"function"                      { return("FUNCTION"); }
457"grant"                         { return("GRANT"); }
458"group"                         { return("GROUP"); }
459"gsi"                           { return("GSI"); }
460"hash"                          { return("HASH"); }
461"having"                        { return("HAVING"); }
462"if"                            { return("IF"); }
463"ignore"                        { return("IGNORE"); }
464"ilike"                         { return("ILIKE"); }
465"in"                            { return("IN"); }
466"include"                       { return("INCLUDE"); }
467"increment"                     { return("INCREMENT"); }
468"index"                         { return("INDEX"); }
469"infer"                         { return("INFER"); }
470"inline"                        { return("INLINE"); }
471"inner"                         { return("INNER"); }
472"insert"                        { return("INSERT"); }
473"intersect"                     { return("INTERSECT"); }
474"into"                          { return("INTO"); }
475"is"                            { return("IS"); }
476"join"                          { return("JOIN"); }
477"key"                           { return("KEY"); }
478"keys"                          { return("KEYS"); }
479"keyspace"                      { return("KEYSPACE"); }
480"known"                         { return("KNOWN"); }
481"last"                          { return("LAST"); }
482"left"                          { return("LEFT"); }
483"let"                           { return("LET"); }
484"letting"                       { return("LETTING"); }
485"like"                          { return("LIKE"); }
486"limit"                         { return("LIMIT"); }
487"lsm"                           { return("LSM"); }
488"map"                           { return("MAP"); }
489"mapping"                       { return("MAPPING"); }
490"matched"                       { return("MATCHED"); }
491"materialized"                  { return("MATERIALIZED"); }
492"merge"                         { return("MERGE"); }
493"minus"                         { return("MINUS"); }
494"missing"                       { return("MISSING"); }
495"namespace"                     { return("NAMESPACE"); }
496"nest"                          { return("NEST"); }
497"nl"                            { return("NL"); }
498"not"                           { return("NOT"); }
499"null"                          { return("NULL"); }
500"number"                        { return("NUMBER"); }
501"object"                        { return("OBJECT"); }
502"offset"                        { return("OFFSET"); }
503"on"                            { return("ON"); }
504"option"                        { return("OPTION"); }
505"or"                            { return("OR"); }
506"order"                         { return("ORDER"); }
507"outer"                         { return("OUTER"); }
508"over"                          { return("OVER"); }
509"parse"                         { return("PARSE"); }
510"partition"                     { return("PARTITION"); }
511"password"                      { return("PASSWORD"); }
512"path"                          { return("PATH"); }
513"pool"                          { return("POOL"); }
514"prepare"                       { return("PREPARE") }
515"primary"                       { return("PRIMARY"); }
516"private"                       { return("PRIVATE"); }
517"privilege"                     { return("PRIVILEGE"); }
518"procedure"                     { return("PROCEDURE"); }
519"probe"                         { return("PROBE"); }
520"public"                        { return("PUBLIC"); }
521"raw"                           { return("RAW"); }
522"realm"                         { return("REALM"); }
523"reduce"                        { return("REDUCE"); }
524"rename"                        { return("RENAME"); }
525"return"                        { return("RETURN"); }
526"returning"                     { return("RETURNING"); }
527"revoke"                        { return("REVOKE"); }
528"right"                         { return("RIGHT"); }
529"role"                          { return("ROLE"); }
530"rollback"                      { return("ROLLBACK"); }
531"satisfies"                     { return("SATISFIES"); }
532"schema"                        { return("SCHEMA"); }
533"select"                        { return("SELECT"); }
534"self"                          { return("SELF"); }
535"semi"                          { return("SEMI"); }
536"set"                           { return("SET"); }
537"show"                          { return("SHOW"); }
538"some"                          { return("SOME"); }
539"start"                         { return("START"); }
540"statistics"                    { return("STATISTICS"); }
541"string"                        { return("STRING"); }
542"system"                        { return("SYSTEM"); }
543"then"                          { return("THEN"); }
544"to"                            { return("TO"); }
545"transaction"                   { return("TRANSACTION"); }
546"trigger"                       { return("TRIGGER"); }
547"true"                          { return("TRUE"); }
548"truncate"                      { return("TRUNCATE"); }
549"under"                         { return("UNDER"); }
550"union"                         { return("UNION"); }
551"unique"                        { return("UNIQUE"); }
552"unknown"                       { return("UNKNOWN"); }
553"unnest"                        { return("UNNEST"); }
554"unset"                         { return("UNSET"); }
555"update"                        { return("UPDATE"); }
556"upsert"                        { return("UPSERT"); }
557"use"                           { return("USE"); }
558"user"                          { return("USER"); }
559"using"                         { return("USING"); }
560"validate"                      { return("VALIDATE"); }
561"value"                         { return("VALUE"); }
562"valued"                        { return("VALUED"); }
563"values"                        { return("VALUES"); }
564"via"                           { return("VIA"); }
565"view"                          { return("VIEW"); }
566"when"                          { return("WHEN"); }
567"where"                         { return("WHERE"); }
568"while"                         { return("WHILE"); }
569"with"                          { return("WITH"); }
570"within"                        { return("WITHIN"); }
571"work"                          { return("WORK"); }
572"xor"                           { return("XOR"); }
573
574[a-zA-Z_][a-zA-Z0-9_]*     { return 'IDENT'; }
575
576/lex
577
578/* Precedence: lowest to highest */
579%left           ORDER
580%left           UNION INTERESECT EXCEPT
581%left           JOIN NEST UNNEST FLATTEN INNER LEFT RIGHT
582%left           OR
583%left           AND
584%right          NOT
585%nonassoc       EQ DEQ NE
586%nonassoc       LT GT LE GE
587%nonassoc       LIKE
588%nonassoc       BETWEEN
589%nonassoc       IN WITHIN
590%nonassoc       EXISTS
591%nonassoc       IS                              /* IS NULL, IS MISSING, IS VALUED, IS NOT NULL, etc. */
592%left           CONCAT
593%left           PLUS MINUS
594%left           STAR DIV MOD
595
596/* Unary operators */
597%right          COVER
598%left           ALL
599%right          UMINUS
600%left           DOT LBRACKET RBRACKET
601
602/* Override precedence */
603%left           LPAREN RPAREN
604
605%start          input_list
606
607/*****************************************************************************/
608/*****************************************************************************/
609/*****************************************************************************/
610
611%%
612
613input_list:
614     inputs { /*console.log("Got input list: " + JSON.stringify($1));*/ return $1;}
615;
616
617inputs:
618input EOF
619{
620    if ($1 && $1.getFields) {
621        //console.log("Getting fields for: " + JSON.stringify($1,null,4));
622        var fields = [];
623        $1.getFields(fields);
624        $1.pathsUsed = fields;
625    }
626
627    // ignore empty expressions
628    if ($$.type == "Empty")
629      $$ = [];
630    else
631      $$ = [$1];
632}
633|
634input SEMI inputs
635{
636    if ($1 && $1.getFields) {
637        var fields = [];
638        $1.getFields(fields);
639        $1.pathsUsed = fields;
640    }
641
642    // ignore empty expressions
643    if ($$.type != "Empty")
644      $3.push($1);
645    $$ = $3;
646}
647;
648
649
650input:
651stmt 
652{
653    $$ = $1;
654    /*console.log("Got statement: " + JSON.stringify($1));*/
655}
656|
657expr_input 
658{
659    $$ = $1;
660    /*console.log("Got expression: " + JSON.stringify($1));*/
661}
662|
663/* empty is o.k. */
664{
665    $$ = expression.NewEmpty();
666}
667;
668
669/*opt_trailer:*/
670/*{*/
671  /* nothing */
672/*}*/
673/*|*/
674/*opt_trailer SEMI*/
675/*;*/
676
677stmt:
678select_stmt
679|
680dml_stmt
681|
682ddl_stmt
683|
684explain
685|
686prepare
687|
688execute
689|
690infer
691|
692role_stmt
693;
694
695explain:
696EXPLAIN stmt
697{
698    $$ = algebra.NewExplain($2)
699}
700;
701
702prepare:
703PREPARE opt_name stmt
704{
705    $$ = algebra.NewPrepare($2, $3)
706}
707;
708
709opt_name:
710/* empty */
711{
712    $$ = ""
713}
714|
715IDENT from_or_as
716{
717    $$ = $1
718}
719|
720STR from_or_as
721{
722    $$ = $1
723}
724;
725
726from_or_as:
727FROM
728|
729AS
730;
731
732execute:
733EXECUTE expr
734{
735    $$ = algebra.NewExecute($2)
736}
737;
738
739infer:
740infer_keyspace
741;
742
743infer_keyspace:
744INFER opt_keyspace keyspace_ref opt_infer_using opt_infer_with
745{
746    $$ = algebra.NewInferKeyspace($3, $4, $5)
747}
748;
749
750opt_keyspace:
751/* empty */
752{
753}
754|
755KEYSPACE
756;
757
758opt_infer_using:
759/* empty */
760{
761    $$ = datastore.INF_DEFAULT
762}
763;
764
765opt_infer_with:
766/* empty */
767{
768    $$ = nil
769}
770|
771infer_with
772;
773
774infer_with:
775WITH expr
776{
777    $$ = $2
778}
779;
780
781select_stmt:
782fullselect
783{
784    $$ = $1
785}
786;
787
788dml_stmt:
789insert
790|
791upsert
792|
793delete
794|
795update
796|
797merge
798;
799
800ddl_stmt:
801index_stmt
802;
803
804role_stmt:
805grant_role
806|
807revoke_role
808;
809
810index_stmt:
811create_index
812|
813drop_index
814|
815alter_index
816|
817build_index
818;
819
820fullselect:
821select_terms opt_order_by
822{
823    $$ = algebra.NewSelect($1, $2, nil, nil) /* OFFSET precedes LIMIT */
824}
825|
826select_terms opt_order_by limit opt_offset
827{
828    $$ = algebra.NewSelect($1, $2, $4, $3) /* OFFSET precedes LIMIT */
829}
830|
831select_terms opt_order_by offset opt_limit
832{
833    $$ = algebra.NewSelect($1, $2, $3, $4) /* OFFSET precedes LIMIT */
834}
835;
836
837select_terms:
838subselect
839{
840    $$ = $1
841}
842|
843select_terms UNION select_term
844{
845    $$ = algebra.NewUnion($1, $3)
846}
847|
848select_terms UNION ALL select_term
849{
850    $$ = algebra.NewUnionAll($1, $4)
851}
852|
853select_terms INTERSECT select_term
854{
855    $$ = algebra.NewIntersect($1, $3)
856}
857|
858select_terms INTERSECT ALL select_term
859{
860    $$ = algebra.NewIntersectAll($1, $4)
861}
862|
863select_terms EXCEPT select_term
864{
865    $$ = algebra.NewExcept($1, $3)
866}
867|
868select_terms EXCEPT ALL select_term
869{
870    $$ = algebra.NewExceptAll($1, $4)
871}
872|
873subquery_expr UNION select_term
874{
875    var left_term = algebra.NewSelectTerm($1.Select())
876    $$ = algebra.NewUnion(left_term, $3)
877}
878|
879subquery_expr UNION ALL select_term
880{
881    var left_term = algebra.NewSelectTerm($1.Select())
882    $$ = algebra.NewUnionAll(left_term, $4)
883}
884|
885subquery_expr INTERSECT select_term
886{
887    var left_term = algebra.NewSelectTerm($1.Select())
888    $$ = algebra.NewIntersect(left_term, $3)
889}
890|
891subquery_expr INTERSECT ALL select_term
892{
893    var left_term = algebra.NewSelectTerm($1.Select())
894    $$ = algebra.NewIntersectAll(left_term, $4)
895}
896|
897subquery_expr EXCEPT select_term
898{
899    var left_term = algebra.NewSelectTerm($1.Select())
900    $$ = algebra.NewExcept(left_term, $3)
901}
902|
903subquery_expr EXCEPT ALL select_term
904{
905    var left_term = algebra.NewSelectTerm($1.Select())
906    $$ = algebra.NewExceptAll(left_term, $4)
907}
908;
909
910select_term:
911subselect
912{
913    $$ = $1
914}
915|
916subquery_expr
917{
918    $$ = algebra.NewSelectTerm($1.Select())
919}
920;
921
922subselect:
923from_select
924|
925select_from
926;
927
928from_select:
929from opt_let opt_where opt_group select_clause
930{
931    $$ = algebra.NewSubselect($1, $2, $3, $4, $5)
932}
933;
934
935select_from:
936select_clause opt_from opt_let opt_where opt_group
937{
938    $$ = algebra.NewSubselect($2, $3, $4, $5, $1)
939}
940;
941
942
943/*************************************************
944 *
945 * SELECT clause
946 *
947 *************************************************/
948
949select_clause:
950SELECT
951projection
952{
953    $$ = $2
954}
955;
956
957projection:
958projects
959{
960    $$ = algebra.NewProjection(false, $1)
961}
962|
963DISTINCT projects
964{
965    $$ = algebra.NewProjection(true, $2)
966}
967|
968ALL projects
969{
970    $$ = algebra.NewProjection(false, $2)
971}
972|
973raw expr opt_as_alias
974{
975    $$ = algebra.NewRawProjection(false, $2, $3)
976}
977|
978DISTINCT raw expr opt_as_alias
979{
980    $$ = algebra.NewRawProjection(true, $3, $4)
981}
982;
983
984raw:
985RAW
986|
987ELEMENT
988|
989VALUE
990;
991
992projects:
993project
994{
995    $$ = [$1]
996}
997|
998projects COMMA project
999{
1000    $1.push($3);
1001    $$ = $1;
1002}
1003;
1004
1005project:
1006STAR
1007{
1008    $$ = algebra.NewResultTerm(expression.SELF, true, "");
1009}
1010|
1011expr DOT STAR opt_as_alias
1012{
1013    $$ = algebra.NewResultTerm($1, true, $4);
1014}
1015|
1016expr opt_as_alias
1017{
1018    $$ = algebra.NewResultTerm($1, false, $2)
1019}
1020;
1021
1022opt_as_alias:
1023/* empty */
1024{
1025    $$ = ""
1026}
1027|
1028as_alias
1029;
1030
1031as_alias:
1032alias
1033|
1034AS alias
1035{
1036    $$ = $2
1037}
1038;
1039
1040alias:
1041IDENT
1042;
1043
1044
1045/*************************************************
1046 *
1047 * FROM clause
1048 *
1049 *************************************************/
1050
1051opt_from:
1052/* empty */
1053{
1054    $$ = nil
1055}
1056|
1057from
1058;
1059
1060from:
1061FROM from_term
1062{
1063    $$ = $2
1064}
1065;
1066
1067from_term:
1068simple_from_term
1069{
1070    $$ = $1
1071}
1072|
1073from_term opt_join_type JOIN simple_from_term on_keys
1074{
1075    var ksterm = $4;
1076    ksterm.join_keys = $5;
1077    $$ = algebra.NewJoin($1, $2, ksterm)
1078}
1079|
1080from_term opt_join_type JOIN simple_from_term on_key FOR IDENT
1081{
1082    var ksterm = $4;
1083    ksterm.join_keys = $5;
1084    $$ = algebra.NewIndexJoin($1, $2, ksterm, $7)
1085}
1086|
1087from_term opt_join_type NEST simple_from_term on_keys
1088{
1089    var ksterm = $4;
1090    ksterm.join_keys = $5;
1091    $$ = algebra.NewNest($1, $2, ksterm)
1092}
1093|
1094from_term opt_join_type NEST simple_from_term on_key FOR IDENT
1095{
1096    var ksterm = $4;
1097    ksterm.join_keys = $5;
1098    $$ = algebra.NewIndexNest($1, $2, ksterm, $7)
1099}
1100|
1101from_term opt_join_type unnest expr opt_as_alias
1102{
1103    $$ = algebra.NewUnnest($1, $2, $4, $5)
1104}
1105|
1106from_term opt_join_type JOIN simple_from_term ON expr
1107{
1108    var ksterm = $4;
1109    $$ = algebra.NewAnsiJoin($1, $2, ksterm, $6)
1110}
1111|
1112from_term opt_join_type NEST simple_from_term ON expr
1113{
1114    var ksterm = $4;
1115    $$ = algebra.NewAnsiNest($1, $2, ksterm, $6)
1116}
1117|
1118simple_from_term RIGHT opt_outer JOIN simple_from_term ON expr
1119{
1120    var ksterm = $1;
1121    if (ksterm == nil) {
1122        yylex.Error("Left hand side of an ANSI RIGHT OUTER JOIN must be a keyspace.")
1123    }
1124    //ksterm.SetAnsiJoin()  
1125    $$ = algebra.NewAnsiRightJoin(ksterm, $5, $7)
1126}
1127;
1128
1129simple_from_term:
1130keyspace_term
1131{
1132    $$ = $1
1133}
1134|
1135expr opt_as_alias opt_use
1136{
1137     var other = $1;
1138     switch ($1.type) {
1139         case "Subquery":
1140              if ($2 == "") {
1141                   yylex.Error("Subquery in FROM clause must have an alias.");
1142              }
1143              if ($3 != algebra.EMPTY_USE) {
1144                   yylex.Error("FROM Subquery cannot have USE KEYS or USE INDEX.");
1145              }
1146              $$ = algebra.NewSubqueryTerm(other.Select(), $2);
1147              break;
1148         case "Identifier":
1149              var ksterm = algebra.NewKeyspaceTerm("", other.ops.identifier, $2, $3.Keys(), $3.Indexes());
1150              //$$ = algebra.NewExpressionTerm(other, $2, ksterm);
1151              $$ = ksterm;
1152              break;
1153         default:
1154              if ($3 != algebra.EMPTY_USE) {
1155                  yylex.Error("FROM Expression cannot have USE KEYS or USE INDEX.")
1156              }
1157              $$ = algebra.NewExpressionTerm(other,$2, nil);
1158     }
1159}
1160;
1161
1162unnest:
1163UNNEST
1164|
1165FLATTEN
1166;
1167
1168keyspace_term:
1169namespace_term keyspace_name opt_as_alias opt_use
1170{
1171     var ksterm = algebra.NewKeyspaceTerm($1, $2, $3, $4.Keys(), $4.Indexes())
1172     $$ = ksterm
1173}
1174;
1175
1176
1177namespace_term:
1178namespace_name
1179|
1180SYSTEM COLON
1181{
1182    $$ = "#system"
1183}
1184;
1185
1186namespace_name:
1187IDENT COLON {$$ = $1;}
1188;
1189
1190keyspace_name:
1191IDENT
1192;
1193
1194opt_use:
1195/* empty */
1196{
1197    $$ = algebra.EMPTY_USE
1198}
1199|
1200USE use_options
1201{
1202    $$ = $2
1203};
1204
1205use_options:    
1206use_keys
1207|
1208use_index
1209|
1210join_hint
1211|
1212use_index join_hint
1213{
1214    $$ = $1
1215}
1216|
1217join_hint use_index
1218{
1219    $$ = $1
1220}
1221|
1222use_keys join_hint
1223{
1224    $$ = $1
1225}
1226|
1227join_hint use_keys
1228{
1229    $$ = $1
1230}
1231;
1232
1233use_keys:
1234opt_primary KEYS expr
1235{
1236    $$ = algebra.NewUse($3, nil, algebra.JOIN_HINT_NONE)
1237}
1238;
1239
1240use_index:
1241INDEX LPAREN index_refs RPAREN
1242{
1243    $$ = algebra.NewUse(nil, $3, algebra.JOIN_HINT_NONE)
1244}
1245;
1246
1247join_hint:
1248HASH LPAREN use_hash_option RPAREN
1249{
1250    $$ = algebra.NewUse(nil, nil, $3)
1251}
1252|
1253NL
1254{
1255    $$ = algebra.NewUse(nil, nil, algebra.USE_NL)
1256}
1257;
1258
1259opt_primary:
1260/* empty */
1261{
1262}
1263|
1264PRIMARY
1265;
1266
1267index_refs:
1268index_ref
1269{
1270    $$ = [$1]
1271}
1272|
1273index_refs COMMA index_ref
1274{
1275    $1.push($3);
1276    $$ = $1;
1277}
1278;
1279
1280index_ref:
1281index_name opt_index_using
1282{
1283    $$ = algebra.NewIndexRef($1, $2);
1284}
1285;
1286
1287use_hash_option:
1288BUILD
1289{
1290    $$ = algebra.USE_HASH_BUILD
1291}
1292|
1293PROBE
1294{
1295    $$ = algebra.USE_HASH_PROBE
1296}
1297;
1298
1299opt_use_del_upd:
1300opt_use
1301{
1302 //   if $1.JoinHint() != algebra.JOIN_HINT_NONE {
1303 //       yylex.Error("Keyspace reference cannot have join hint (USE HASH or USE NL) in DELETE or UPDATE statement")
1304 //   }
1305    $$ = $1
1306}
1307;
1308
1309opt_join_type:
1310/* empty */
1311{
1312    $$ = false
1313}
1314|
1315INNER
1316{
1317    $$ = false
1318}
1319|
1320LEFT opt_outer
1321{
1322    $$ = true
1323}
1324;
1325
1326opt_outer:
1327/* empty */
1328|
1329OUTER
1330;
1331
1332on_keys:
1333ON opt_primary KEYS expr
1334{
1335    $$ = $4
1336}
1337;
1338
1339on_key:
1340ON opt_primary KEY expr
1341{
1342    $$ = $4
1343}
1344;
1345
1346
1347/*************************************************
1348 *
1349 * LET clause
1350 *
1351 *************************************************/
1352
1353opt_let:
1354/* empty */
1355{
1356    $$ = nil
1357}
1358|
1359let
1360;
1361
1362let:
1363LET bindings
1364{
1365    $$ = $2
1366}
1367;
1368
1369bindings:
1370binding
1371{
1372    $$ = [$1]
1373}
1374|
1375bindings COMMA binding
1376{
1377    $1.push($3);
1378    $$ = $1;
1379}
1380;
1381
1382binding:
1383alias EQ expr
1384{
1385    $$ = expression.NewSimpleBinding($1, $3)
1386}
1387;
1388
1389
1390/*************************************************
1391 *
1392 * WHERE clause
1393 *
1394 *************************************************/
1395
1396opt_where:
1397/* empty */
1398{
1399    $$ = nil
1400}
1401|
1402where
1403;
1404
1405where:
1406WHERE expr
1407{
1408    $$ = $2
1409}
1410;
1411
1412
1413/*************************************************
1414 *
1415 * GROUP BY clause
1416 *
1417 *************************************************/
1418
1419opt_group:
1420/* empty */
1421{
1422    $$ = nil
1423}
1424|
1425group
1426;
1427
1428group:
1429GROUP BY exprs opt_letting opt_having
1430{
1431    $$ = algebra.NewGroup($3, $4, $5)
1432}
1433|
1434letting
1435{
1436    $$ = algebra.NewGroup(nil, $1, nil)
1437}
1438;
1439
1440exprs:
1441expr
1442{
1443    $$ = [$1]
1444}
1445|
1446exprs COMMA expr
1447{
1448    $1.push($3);
1449    $$ = $1
1450}
1451;
1452
1453opt_letting:
1454/* empty */
1455{
1456    $$ = nil
1457}
1458|
1459letting
1460;
1461
1462letting:
1463LETTING bindings
1464{
1465    $$ = $2
1466}
1467;
1468
1469opt_having:
1470/* empty */
1471{
1472    $$ = nil
1473}
1474|
1475having
1476;
1477
1478having:
1479HAVING expr
1480{
1481    $$ = $2
1482}
1483;
1484
1485
1486/*************************************************
1487 *
1488 * ORDER BY clause
1489 *
1490 *************************************************/
1491
1492opt_order_by:
1493/* empty */
1494{
1495    $$ = nil
1496}
1497|
1498order_by
1499;
1500
1501order_by:
1502ORDER BY sort_terms
1503{
1504    $$ = algebra.NewOrder($3)
1505}
1506;
1507
1508sort_terms:
1509sort_term
1510{
1511    $$ = [$1]
1512}
1513|
1514sort_terms COMMA sort_term
1515{
1516    $1.push($3);
1517    $$ = $1;
1518}
1519;
1520
1521sort_term:
1522expr opt_dir
1523{
1524    $$ = algebra.NewSortTerm($1, $2)
1525}
1526;
1527
1528opt_dir:
1529/* empty */
1530{
1531    $$ = false
1532}
1533|
1534dir
1535;
1536
1537dir:
1538ASC
1539{
1540    $$ = false
1541}
1542|
1543DESC
1544{
1545    $$ = true
1546}
1547;
1548
1549
1550/*************************************************
1551 *
1552 * LIMIT clause
1553 *
1554 *************************************************/
1555
1556opt_limit:
1557/* empty */
1558{
1559    $$ = nil
1560}
1561|
1562limit
1563;
1564
1565limit:
1566LIMIT expr
1567{
1568    $$ = $2
1569}
1570;
1571
1572
1573/*************************************************
1574 *
1575 * OFFSET clause
1576 *
1577 *************************************************/
1578
1579opt_offset:
1580/* empty */
1581{
1582    $$ = nil
1583}
1584|
1585offset
1586;
1587
1588offset:
1589OFFSET expr
1590{
1591    $$ = $2
1592}
1593;
1594
1595
1596/*************************************************
1597 *
1598 * INSERT
1599 *
1600 *************************************************/
1601
1602insert:
1603INSERT INTO keyspace_ref opt_values_header values_list opt_returning
1604{
1605    $$ = algebra.NewInsertValues($3, $5, $6)
1606}
1607|
1608INSERT INTO keyspace_ref LPAREN key_expr opt_value_expr RPAREN fullselect opt_returning
1609{
1610    $$ = algebra.NewInsertSelect($3, $5, $6, $8, $9)
1611}
1612;
1613
1614keyspace_ref:
1615namespace_term keyspace_name opt_as_alias
1616{
1617    $$ = algebra.NewKeyspaceRef($1, $2, $3)
1618}
1619|
1620keyspace_name opt_as_alias
1621{
1622    $$ = algebra.NewKeyspaceRef("", $1, $2)
1623}
1624;
1625
1626opt_values_header:
1627/* empty */
1628|
1629LPAREN KEY COMMA VALUE RPAREN
1630|
1631LPAREN PRIMARY KEY COMMA VALUE RPAREN
1632;
1633
1634key:
1635KEY
1636|
1637PRIMARY KEY
1638;
1639
1640values_list:
1641values {$$=$1;}
1642|
1643values_list COMMA next_values
1644{
1645    $1.push($3);
1646    $$ = $1;
1647}
1648;
1649
1650values:
1651VALUES LPAREN expr COMMA expr RPAREN
1652{
1653    $$ = [{Key: $3, Value: $5}];
1654}
1655;
1656
1657next_values:
1658values {$$ = $1;}
1659|
1660LPAREN expr COMMA expr RPAREN
1661{
1662    $$ = [{Key: $2, Value: $4}];
1663}
1664;
1665
1666opt_returning:
1667/* empty */
1668{
1669    $$ = nil
1670}
1671|
1672returning
1673;
1674
1675returning:
1676RETURNING returns
1677{
1678    $$ = $2
1679}
1680;
1681
1682returns:
1683projects
1684{
1685    $$ = algebra.NewProjection(false, $1)
1686}
1687|
1688raw expr
1689{
1690    $$ = algebra.NewRawProjection(false, $2, "")
1691}
1692;
1693
1694key_expr:
1695key expr
1696{
1697    $$ = $2
1698}
1699;
1700
1701opt_value_expr:
1702/* empty */
1703{
1704    $$ = nil
1705}
1706|
1707COMMA VALUE expr
1708{
1709    $$ = $3
1710}
1711;
1712
1713
1714/*************************************************
1715 *
1716 * UPSERT
1717 *
1718 *************************************************/
1719
1720upsert:
1721UPSERT INTO keyspace_ref opt_values_header values_list opt_returning
1722{
1723    $$ = algebra.NewUpsertValues($3, $5, $6)
1724}
1725|
1726UPSERT INTO keyspace_ref LPAREN key_expr opt_value_expr RPAREN fullselect opt_returning
1727{
1728    $$ = algebra.NewUpsertSelect($3, $5, $6, $8, $9)
1729}
1730;
1731
1732
1733/*************************************************
1734 *
1735 * DELETE
1736 *
1737 *************************************************/
1738
1739delete:
1740DELETE FROM keyspace_ref opt_use_del_upd opt_where opt_limit opt_returning
1741{
1742    $$ = algebra.NewDelete($3, $4.Keys(), $4.Indexes(), $5, $6, $7)
1743}
1744;
1745
1746
1747/*************************************************
1748 *
1749 * UPDATE
1750 *
1751 *************************************************/
1752
1753update:
1754UPDATE keyspace_ref opt_use_del_upd set unset opt_where opt_limit opt_returning
1755{
1756    $$ = algebra.NewUpdate($2, $3.Keys(), $3.Indexes(), $4, $5, $6, $7, $8)
1757}
1758|
1759UPDATE keyspace_ref opt_use_del_upd set opt_where opt_limit opt_returning
1760{
1761    $$ = algebra.NewUpdate($2, $3.Keys(), $3.Indexes(), $4, nil, $5, $6, $7)
1762}
1763|
1764UPDATE keyspace_ref opt_use_del_upd unset opt_where opt_limit opt_returning
1765{
1766    $$ = algebra.NewUpdate($2, $3.Keys(), $3.Indexes(), nil, $4, $5, $6, $7)
1767}
1768;
1769
1770set:
1771SET set_terms
1772{
1773    $$ = algebra.NewSet($2)
1774}
1775;
1776
1777set_terms:
1778set_term
1779{
1780    $$ = [$1];
1781}
1782|
1783set_terms COMMA set_term
1784{
1785    $1.push($3);
1786    $$ = $1;
1787}
1788;
1789
1790set_term:
1791path EQ expr opt_update_for
1792{
1793    $$ = algebra.NewSetTerm($1, $3, $4)
1794}
1795;
1796
1797opt_update_for:
1798/* empty */
1799{
1800    $$ = nil
1801}
1802|
1803update_for
1804;
1805
1806update_for:
1807update_dimensions opt_when END
1808{
1809    $$ = algebra.NewUpdateFor($1, $2)
1810}
1811;
1812
1813update_dimensions:
1814FOR update_dimension
1815{
1816    $$ = [$2];
1817}
1818|
1819update_dimensions FOR update_dimension
1820{
1821    dims = [$3,$1];
1822}
1823;
1824
1825update_dimension:
1826update_binding
1827{
1828    $$ = [$1]
1829}
1830|
1831update_dimension COMMA update_binding
1832{
1833    $1.push($3);
1834    $$ = $1;
1835}
1836;
1837
1838update_binding:
1839variable IN expr
1840{
1841    $$ = expression.NewSimpleBinding($1, $3)
1842}
1843|
1844variable WITHIN expr
1845{
1846    $$ = expression.NewBinding("", $1, $3, true)
1847}
1848|
1849variable COLON variable IN expr
1850{
1851    $$ = expression.NewBinding($1, $3, $5, false)
1852}
1853|
1854variable COLON variable WITHIN expr
1855{
1856    $$ = expression.NewBinding($1, $3, $5, true)
1857}
1858;
1859
1860variable:
1861IDENT
1862;
1863
1864opt_when:
1865/* empty */
1866{
1867    $$ = nil
1868}
1869|
1870WHEN expr
1871{
1872    $$ = $2
1873}
1874;
1875
1876unset:
1877UNSET unset_terms
1878{
1879    $$ = algebra.NewUnset($2)
1880}
1881;
1882
1883unset_terms:
1884unset_term
1885{
1886    $$ = [$1]
1887}
1888|
1889unset_terms COMMA unset_term
1890{
1891    $1.push($3);
1892    $$ = $1;
1893}
1894;
1895
1896unset_term:
1897path opt_update_for
1898{
1899    $$ = algebra.NewUnsetTerm($1, $2)
1900}
1901;
1902
1903
1904/*************************************************
1905 *
1906 * MERGE
1907 *
1908 *************************************************/
1909
1910merge:
1911MERGE INTO keyspace_ref USING simple_from_term ON key_expr merge_actions opt_limit opt_returning
1912{
1913     switch ($5.type) {
1914         case algebra.SubqueryTerm:
1915              var source = algebra.NewMergeSourceSelect($5.Subquery(), $5.Alias())
1916              $$ = algebra.NewMerge($3, source, $7, $8, $9, $10)
1917         case algebra.ExpressionTerm:
1918              var source = algebra.NewMergeSourceExpression($5, "")
1919              $$ = algebra.NewMerge($3, source, $7, $8, $9, $10)
1920         case algebra.KeyspaceTerm:
1921              var source = algebra.NewMergeSourceFrom($5, "")
1922              $$ = algebra.NewMerge($3, source, $7, $8, $9, $10)
1923         default:
1924              yylex.Error("MERGE source term is UNKNOWN.")
1925     }
1926}
1927;
1928
1929merge_actions:
1930/* empty */
1931{
1932    $$ = algebra.NewMergeActions(nil, nil, nil)
1933}
1934|
1935WHEN MATCHED THEN UPDATE merge_update opt_merge_delete_insert
1936{
1937    $$ = algebra.NewMergeActions($5, $6.Delete(), $6.Insert())
1938}
1939|
1940WHEN MATCHED THEN DELETE merge_delete opt_merge_insert
1941{
1942    $$ = algebra.NewMergeActions(nil, $5, $6)
1943}
1944|
1945WHEN NOT MATCHED THEN INSERT merge_insert
1946{
1947    $$ = algebra.NewMergeActions(nil, nil, $6)
1948}
1949;
1950
1951opt_merge_delete_insert:
1952/* empty */
1953{
1954    $$ = algebra.NewMergeActions(nil, nil, nil)
1955}
1956|
1957WHEN MATCHED THEN DELETE merge_delete opt_merge_insert
1958{
1959    $$ = algebra.NewMergeActions(nil, $5, $6)
1960}
1961|
1962WHEN NOT MATCHED THEN INSERT merge_insert
1963{
1964    $$ = algebra.NewMergeActions(nil, nil, $6)
1965}
1966;
1967
1968opt_merge_insert:
1969/* empty */
1970{
1971    $$ = nil
1972}
1973|
1974WHEN NOT MATCHED THEN INSERT merge_insert
1975{
1976    $$ = $6
1977}
1978;
1979
1980merge_update:
1981set opt_where
1982{
1983    $$ = algebra.NewMergeUpdate($1, nil, $2)
1984}
1985|
1986set unset opt_where
1987{
1988    $$ = algebra.NewMergeUpdate($1, $2, $3)
1989}
1990|
1991unset opt_where
1992{
1993    $$ = algebra.NewMergeUpdate(nil, $1, $2)
1994}
1995;
1996
1997merge_delete:
1998opt_where
1999{
2000    $$ = algebra.NewMergeDelete($1)
2001}
2002;
2003
2004merge_insert:
2005expr opt_where
2006{
2007    $$ = algebra.NewMergeInsert($1, $2)
2008}
2009;
2010
2011/*************************************************
2012 *
2013 * GRANT ROLE
2014 *
2015 *************************************************/
2016
2017grant_role:
2018GRANT role_list TO user_list
2019{
2020    $$ = algebra.NewGrantRole($2, nil, $4)
2021}
2022|
2023GRANT role_list ON keyspace_list TO user_list
2024{
2025    $$ = algebra.NewGrantRole($2, $4, $6)
2026}
2027;
2028
2029role_list:
2030role_name
2031{
2032        $$ = [$1];
2033}
2034|
2035role_list COMMA role_name
2036{
2037        $1.push($3);
2038        $$ = $1;
2039}
2040;
2041
2042role_name:
2043IDENT
2044{
2045    $$ = $1
2046}
2047|
2048SELECT
2049{
2050    $$ = "select"
2051}
2052|
2053INSERT
2054{
2055    $$ = "insert"
2056}
2057|
2058UPDATE
2059{
2060    $$ = "update"
2061}
2062|
2063DELETE
2064{
2065    $$ = "delete"
2066}
2067;
2068
2069keyspace_list:
2070IDENT
2071{
2072    $$ = [$1];
2073}
2074|
2075keyspace_list COMMA IDENT
2076{
2077    $1.push($3);
2078    $$ = $1;
2079}
2080;
2081
2082user_list:
2083user
2084{
2085    $$ = [$1]
2086}
2087|
2088user_list COMMA user
2089{
2090    $1.push($3);
2091    $$ = $1;
2092}
2093;
2094
2095user:
2096IDENT
2097{
2098    $$ = $1;
2099}
2100|
2101IDENT COLON IDENT
2102{
2103    $$ = $1 + ":" + $3;
2104}
2105;
2106
2107/*************************************************
2108 *
2109 * REVOKE ROLE
2110 *
2111 *************************************************/
2112
2113revoke_role:
2114REVOKE role_list FROM user_list
2115{
2116    $$ = algebra.NewRevokeRole($2, nil, $4);
2117}
2118|
2119REVOKE role_list ON keyspace_list FROM user_list
2120{
2121    $$ = algebra.NewRevokeRole($2, $4, $6);
2122}
2123;
2124
2125/*************************************************
2126 *
2127 * CREATE INDEX
2128 *
2129 *************************************************/
2130
2131create_index:
2132CREATE PRIMARY INDEX opt_primary_name ON named_keyspace_ref index_partition opt_index_using opt_index_with
2133{
2134    $$ = algebra.NewCreatePrimaryIndex($4, $6, $7, $8, $9)
2135}
2136|
2137CREATE INDEX index_name ON named_keyspace_ref LPAREN index_terms RPAREN index_partition index_where opt_index_using opt_index_with
2138{
2139    $$ = algebra.NewCreateIndex($3, $5, $7, $9, $10, $11, $12)
2140}
2141;
2142
2143opt_primary_name:
2144/* empty */
2145{
2146    $$ = "#primary"
2147}
2148|
2149index_name
2150;
2151
2152index_name:
2153IDENT
2154;
2155
2156named_keyspace_ref:
2157keyspace_name
2158{
2159    $$ = algebra.NewKeyspaceRef("", $1, "")
2160}
2161|
2162namespace_term keyspace_name
2163{
2164    $$ = algebra.NewKeyspaceRef($1, $2, "")
2165}
2166;
2167
2168index_partition:
2169/* empty */
2170{
2171    $$ = nil
2172}
2173|
2174PARTITION BY HASH LPAREN exprs RPAREN
2175{
2176    $$ = $5
2177}
2178;
2179
2180opt_index_using:
2181/* empty */
2182{
2183    $$ = datastore.DEFAULT
2184}
2185|
2186index_using
2187;
2188
2189index_using:
2190USING VIEW
2191{
2192    $$ = datastore.VIEW
2193}
2194|
2195USING GSI
2196{
2197    $$ = datastore.GSI
2198}
2199|
2200USING FTS
2201{
2202    $$ = datastore.FTS
2203}
2204;
2205
2206opt_index_with:
2207/* empty */
2208{
2209    $$ = nil
2210}
2211|
2212index_with
2213;
2214
2215index_with:
2216WITH expr
2217{
2218    $$ = $2.Value()
2219    if ($$ == nil) {
2220        yylex.Error("WITH value must be static.")
2221    }
2222}
2223;
2224
2225index_terms:
2226index_term
2227{
2228    $$ = [$1]
2229}
2230|
2231index_terms COMMA index_term
2232{
2233    $1.push($3);
2234    $$ = $1;
2235}
2236;
2237
2238index_term:
2239index_term_expr opt_dir
2240{
2241   $$ = algebra.NewIndexKeyTerm($1, $2)
2242}
2243;
2244
2245index_term_expr:
2246index_expr
2247|
2248all index_expr
2249{
2250    $$ = expression.NewAll($2, false)
2251}
2252|
2253all DISTINCT index_expr
2254{
2255    $$ = expression.NewAll($3, true)
2256}
2257|
2258DISTINCT index_expr
2259{
2260    $$ = expression.NewAll($2, true)
2261}
2262;
2263
2264index_expr:
2265expr
2266{
2267    var exp = $1
2268    //if (exp != nil && (!exp.Indexable() || exp.Value() != nil)) {
2269    //    yylex.Error(fmt.Sprintf("Expression not indexable: %s", exp.String()))
2270    //}
2271
2272    $$ = exp
2273}
2274;
2275
2276all:
2277ALL
2278|
2279EACH
2280;
2281
2282index_where:
2283/* empty */
2284{
2285    $$ = nil
2286}
2287|
2288WHERE index_expr
2289{
2290    $$ = $2
2291}
2292;
2293
2294
2295/*************************************************
2296 *
2297 * DROP INDEX
2298 *
2299 *************************************************/
2300
2301drop_index:
2302DROP PRIMARY INDEX ON named_keyspace_ref opt_index_using
2303{
2304    $$ = algebra.NewDropIndex($5, "#primary", $6) 
2305}
2306|
2307DROP INDEX named_keyspace_ref DOT index_name opt_index_using
2308{
2309    $$ = algebra.NewDropIndex($3, $5, $6)
2310}
2311;
2312
2313/*************************************************
2314 *
2315 * ALTER INDEX
2316 *
2317 *************************************************/
2318
2319alter_index:
2320ALTER INDEX named_keyspace_ref DOT index_name opt_index_using index_with
2321{
2322    $$ = algebra.NewAlterIndex($3, $5, $6, $7)
2323}
2324;
2325
2326/*************************************************
2327 *
2328 * BUILD INDEX
2329 *
2330 *************************************************/
2331
2332build_index:
2333BUILD INDEX ON named_keyspace_ref LPAREN index_names RPAREN opt_index_using
2334{
2335    $$ = algebra.NewBuildIndexes($4, $8, $6)
2336}
2337;
2338
2339index_names:
2340index_name
2341{
2342    $$ = [];
2343}
2344|
2345index_names COMMA index_name
2346{
2347    $1.push($3);
2348    $$ = $1;
2349}
2350;
2351
2352
2353/*************************************************
2354 *
2355 * Path
2356 *
2357 *************************************************/
2358
2359path:
2360IDENT
2361{
2362    $$ = expression.NewIdentifier($1)
2363}
2364|
2365path DOT IDENT
2366{
2367    $$ = expression.NewField($1, expression.NewFieldName($3, false));
2368}
2369|
2370path DOT IDENT_ICASE
2371{
2372    var field = expression.NewField($1, expression.NewFieldName($3, true))
2373    field.SetCaseInsensitive = true;
2374    $$ = field
2375}
2376|
2377path DOT LBRACKET expr RBRACKET
2378{
2379    $$ = expression.NewField($1, $4)
2380}
2381|
2382path DOT LBRACKET expr RBRACKET_ICASE
2383{
2384    var field = expression.NewField($1, $4)
2385    field.SetCaseInsensitive = true;
2386    $$ = field
2387}
2388|
2389path LBRACKET expr RBRACKET
2390{
2391    $$ = expression.NewElement($1, $3)
2392}
2393;
2394
2395
2396/*************************************************
2397 *
2398 * Expression
2399 *
2400 *************************************************/
2401
2402expr:
2403c_expr
2404|
2405/* Nested */
2406expr DOT IDENT
2407{
2408    $$ = expression.NewField($1, expression.NewFieldName($3, false))
2409}
2410|
2411expr DOT IDENT_ICASE
2412{
2413    var field = expression.NewField($1, expression.NewFieldName($3, true))
2414    field.SetCaseInsensitive = true;
2415    $$ = field
2416}
2417|
2418expr DOT LBRACKET expr RBRACKET
2419{
2420    $$ = expression.NewField($1, $4)
2421}
2422|
2423expr DOT LBRACKET expr RBRACKET_ICASE
2424{
2425    var field = expression.NewField($1, $4)
2426    field.SetCaseInsensitive = true;
2427    $$ = field
2428}
2429|
2430expr LBRACKET expr RBRACKET
2431{
2432    $$ = expression.NewElement($1, $3)
2433}
2434|
2435expr LBRACKET expr COLON RBRACKET
2436{
2437    $$ = expression.NewSlice($1, $3)
2438}
2439|
2440expr LBRACKET expr COLON expr RBRACKET
2441{
2442    $$ = expression.NewSlice($1, $3, $5)
2443}
2444|
2445expr LBRACKET STAR RBRACKET
2446{
2447    $$ = expression.NewArrayStar($1)
2448}
2449|
2450/* Arithmetic */
2451expr PLUS expr
2452{
2453    $$ = expression.NewAdd($1, $3)
2454}
2455|
2456expr MINUS expr
2457{
2458    $$ = expression.NewSub($1, $3)
2459}
2460|
2461expr STAR expr
2462{
2463    $$ = expression.NewMult($1, $3)
2464}
2465|
2466expr DIV expr
2467{
2468    $$ = expression.NewDiv($1, $3)
2469}
2470|
2471expr MOD expr
2472{
2473    $$ = expression.NewMod($1, $3)
2474}
2475|
2476/* Concat */
2477expr CONCAT expr
2478{
2479    $$ = expression.NewConcat($1, $3)
2480}
2481|
2482/* Logical */
2483expr AND expr
2484{
2485    $$ = expression.NewAnd($1, $3)
2486}
2487|
2488expr OR expr
2489{
2490    $$ = expression.NewOr($1, $3)
2491}
2492|
2493NOT expr
2494{
2495    $$ = expression.NewNot($2)
2496}
2497|
2498/* Comparison */
2499expr EQ expr
2500{
2501    $$ = expression.NewEq($1, $3)
2502}
2503|
2504expr DEQ expr
2505{
2506    $$ = expression.NewEq($1, $3)
2507}
2508|
2509expr NE expr
2510{
2511    $$ = expression.NewNE($1, $3)
2512}
2513|
2514expr LT expr
2515{
2516    $$ = expression.NewLT($1, $3)
2517}
2518|
2519expr GT expr
2520{
2521    $$ = expression.NewGT($1, $3)
2522}
2523|
2524expr LE expr
2525{
2526    $$ = expression.NewLE($1, $3)
2527}
2528|
2529expr GE expr
2530{
2531    $$ = expression.NewGE($1, $3)
2532}
2533|
2534expr BETWEEN b_expr AND b_expr
2535{
2536    $$ = expression.NewBetween($1, $3, $5)
2537}
2538|
2539expr NOT BETWEEN b_expr AND b_expr
2540{
2541    $$ = expression.NewNotBetween($1, $4, $6)
2542}
2543|
2544expr LIKE expr
2545{
2546    $$ = expression.NewLike($1, $3)
2547}
2548|
2549expr NOT LIKE expr
2550{
2551    $$ = expression.NewNotLike($1, $4)
2552}
2553|
2554expr IN expr
2555{
2556    $$ = expression.NewIn($1, $3)
2557}
2558|
2559expr NOT IN expr
2560{
2561    $$ = expression.NewNotIn($1, $4)
2562}
2563|
2564expr WITHIN expr
2565{
2566    $$ = expression.NewWithin($1, $3)
2567}
2568|
2569expr NOT WITHIN expr
2570{
2571    $$ = expression.NewNotWithin($1, $4)
2572}
2573|
2574expr IS NULL
2575{
2576    $$ = expression.NewIsNull($1)
2577}
2578|
2579expr IS NOT NULL
2580{
2581    $$ = expression.NewIsNotNull($1)
2582}
2583|
2584expr IS MISSING
2585{
2586    $$ = expression.NewIsMissing($1)
2587}
2588|
2589expr IS NOT MISSING
2590{
2591    $$ = expression.NewIsNotMissing($1)
2592}
2593|
2594expr IS valued
2595{
2596    $$ = expression.NewIsValued($1)
2597}
2598|
2599expr IS NOT valued
2600{
2601    $$ = expression.NewIsNotValued($1)
2602}
2603|
2604EXISTS expr
2605{
2606    $$ = expression.NewExists($2)
2607}
2608;
2609
2610valued:
2611VALUED
2612|
2613KNOWN
2614;
2615
2616c_expr:
2617/* Literal */
2618literal
2619|
2620/* Construction */
2621construction_expr
2622|
2623/* Identifier */
2624IDENT
2625{
2626    $$ = expression.NewIdentifier($1)
2627}
2628|
2629/* Identifier */
2630IDENT_ICASE
2631{
2632    var ident = expression.NewIdentifier($1)
2633    ident.SetCaseInsensitive = true;
2634    $$ = ident
2635}
2636|
2637/* Self */
2638SELF
2639{
2640    $$ = expression.NewSelf()
2641}
2642|
2643/* Parameter */
2644param_expr
2645|
2646/* Function */
2647function_expr
2648|
2649/* Prefix */
2650MINUS expr %prec UMINUS
2651{
2652    $$ = expression.NewNeg($2)
2653}
2654|
2655/* Case */
2656case_expr
2657|
2658/* Collection */
2659collection_expr
2660|
2661/* Grouping and subquery */
2662paren_expr
2663|
2664/* For covering indexes */
2665COVER LPAREN expr RPAREN
2666{
2667    $$ = expression.NewCover($2)
2668}
2669;
2670
2671b_expr:
2672c_expr
2673|
2674/* Nested */
2675b_expr DOT IDENT
2676{
2677    $$ = expression.NewField($1, expression.NewFieldName($3, false));
2678}
2679|
2680b_expr DOT IDENT_ICASE
2681{
2682    var field = expression.NewField($1, expression.NewFieldName($3, true))
2683    field.SetCaseInsensitive = true;
2684    $$ = field
2685}
2686|
2687b_expr DOT LBRACKET expr RBRACKET
2688{
2689    $$ = expression.NewField($1, $4)
2690}
2691|
2692b_expr DOT LBRACKET expr RBRACKET_ICASE
2693{
2694    var field = expression.NewField($1, $4)
2695    field.SetCaseInsensitive = true;
2696    $$ = field
2697}
2698|
2699b_expr LBRACKET expr RBRACKET
2700{
2701    $$ = expression.NewElement($1, $3)
2702}
2703|
2704b_expr LBRACKET expr COLON RBRACKET
2705{
2706    $$ = expression.NewSlice($1, $3)
2707}
2708|
2709b_expr LBRACKET expr COLON expr RBRACKET
2710{
2711    $$ = expression.NewSlice($1, $3, $5)
2712}
2713|
2714b_expr LBRACKET STAR RBRACKET
2715{
2716    $$ = expression.NewArrayStar($1)
2717}
2718|
2719/* Arithmetic */
2720b_expr PLUS b_expr
2721{
2722    $$ = expression.NewAdd($1, $3)
2723}
2724|
2725b_expr MINUS b_expr
2726{
2727    $$ = expression.NewSub($1, $3)
2728}
2729|
2730b_expr STAR b_expr
2731{
2732    $$ = expression.NewMult($1, $3)
2733}
2734|
2735b_expr DIV b_expr
2736{
2737    $$ = expression.NewDiv($1, $3)
2738}
2739|
2740b_expr MOD b_expr
2741{
2742    $$ = expression.NewMod($1, $3)
2743}
2744|
2745/* Concat */
2746b_expr CONCAT b_expr
2747{
2748    $$ = expression.NewConcat($1, $3)
2749}
2750;
2751
2752
2753/*************************************************
2754 *
2755 * Literal
2756 *
2757 *************************************************/
2758
2759literal:
2760NULL
2761{
2762    $$ = expression.NULL_EXPR
2763}
2764|
2765MISSING
2766{
2767    $$ = expression.MISSING_EXPR
2768}
2769|
2770FALSE
2771{
2772    $$ = expression.FALSE_EXPR
2773}
2774|
2775TRUE
2776{
2777    $$ = expression.TRUE_EXPR
2778}
2779|
2780NUM
2781{
2782    $$ = expression.NewConstant(value.NewValue($1))
2783}
2784|
2785INT
2786{
2787    $$ = expression.NewConstant(value.NewValue($1))
2788}
2789|
2790STR
2791{
2792    $$ = expression.NewConstant(value.NewValue($1))
2793}
2794;
2795
2796
2797/*************************************************
2798 *
2799 * Construction
2800 *
2801 *************************************************/
2802
2803construction_expr:
2804object
2805|
2806array
2807;
2808
2809object:
2810LBRACE opt_members RBRACE
2811{
2812    $$ = expression.NewObjectConstruct(algebra.MapPairs($2))
2813}
2814;
2815
2816opt_members:
2817/* empty */
2818{
2819    $$ = nil
2820}
2821|
2822members
2823;
2824
2825members:
2826member
2827{
2828    $$ = [$1]
2829}
2830|
2831members COMMA member
2832{
2833    $1.push($3);
2834    $$ = $1;
2835}
2836;
2837
2838member:
2839expr COLON expr
2840{
2841    $$ = algebra.NewPair($1, $3)
2842}
2843|
2844expr
2845{
2846    var name = $1.Alias()
2847    if (name == "") {
2848        yylex.Error(fmt.Sprintf("Object member missing name or value: %s", $1.String()))
2849    }
2850
2851    $$ = algebra.NewPair(expression.NewConstant(name), $1)
2852}
2853;
2854
2855array:
2856LBRACKET opt_exprs RBRACKET
2857{
2858    $$ = expression.NewArrayConstruct($2)
2859}
2860;
2861
2862opt_exprs:
2863/* empty */
2864{
2865    $$ = nil
2866}
2867|
2868exprs
2869;
2870
2871
2872/*************************************************
2873 *
2874 * Parameter
2875 *
2876 *************************************************/
2877
2878param_expr:
2879NAMED_PARAM
2880{
2881    $$ = algebra.NewNamedParameter($1);
2882}
2883|
2884POSITIONAL_PARAM
2885{
2886    $$ = algebra.NewPositionalParameter($1);
2887}
2888|
2889NEXT_PARAM
2890{
2891    $$ = algebra.NewPositionalParameter($1);
2892}
2893;
2894
2895
2896/*************************************************
2897 *
2898 * Case
2899 *
2900 *************************************************/
2901
2902case_expr:
2903CASE simple_or_searched_case END
2904{
2905    $$ = $2
2906}
2907;
2908
2909simple_or_searched_case:
2910simple_case
2911|
2912searched_case
2913;
2914
2915simple_case:
2916expr when_thens opt_else
2917{
2918    $$ = expression.NewSimpleCase($1, $2, $3)
2919}
2920;
2921
2922when_thens:
2923WHEN expr THEN expr
2924{
2925    $$ = [{when: $2, then: $4}]
2926}
2927|
2928when_thens WHEN expr THEN expr
2929{
2930    $1.push({when: $3, then: $5});
2931    $$ = $1;
2932}
2933;
2934
2935searched_case:
2936when_thens
2937opt_else
2938{
2939    $$ = expression.NewSearchedCase($1, $2)
2940}
2941;
2942
2943opt_else:
2944/* empty */
2945{
2946    $$ = nil
2947}
2948|
2949ELSE expr
2950{
2951    $$ = $2
2952}
2953;
2954
2955
2956/*************************************************
2957 *
2958 * Function
2959 *
2960 *************************************************/
2961
2962function_expr:
2963function_name opt_exprs RPAREN
2964{
2965    $$ = expression.NewFunction($1,$2);
2966}
2967|
2968function_name DISTINCT expr RPAREN
2969{
2970    $$ = expression.NewFunction($1,$3,true);
2971}
2972|
2973function_name STAR RPAREN
2974{
2975    $$ = expression.NewFunction($1,"star");
2976}
2977;
2978
2979function_name:
2980IDENT LPAREN {$$ = $1;}
2981;
2982
2983
2984/*************************************************
2985 *
2986 * Collection
2987 *
2988 *************************************************/
2989
2990collection_expr:
2991collection_cond
2992|
2993collection_xform
2994;
2995
2996collection_cond:
2997ANY coll_bindings satisfies END
2998{
2999    $$ = expression.NewAny($2, $3)
3000}
3001|
3002SOME coll_bindings satisfies END
3003{
3004    $$ = expression.NewAny($2, $3)
3005}
3006|
3007EVERY coll_bindings satisfies END
3008{
3009    $$ = expression.NewEvery($2, $3)
3010}
3011|
3012ANY AND EVERY coll_bindings satisfies END
3013{
3014    $$ = expression.NewAnyEvery($4, $5)
3015}
3016|
3017SOME AND EVERY coll_bindings satisfies END
3018{
3019    $$ = expression.NewAnyEvery($4, $5)
3020}
3021;
3022
3023coll_bindings:
3024coll_binding
3025{
3026    $$ = [$1];
3027}
3028|
3029coll_bindings COMMA coll_binding
3030{
3031    $1.push($3);
3032    $$ = $1;
3033}
3034;
3035
3036coll_binding:
3037variable IN expr
3038{
3039    $$ = expression.NewSimpleBinding($1, $3)
3040}
3041|
3042variable WITHIN expr
3043{
3044    $$ = expression.NewBinding("", $1, $3, true)
3045}
3046|
3047variable COLON variable IN expr
3048{
3049    $$ = expression.NewBinding($1, $3, $5, false)
3050}
3051|
3052variable COLON variable WITHIN expr
3053{
3054    $$ = expression.NewBinding($1, $3, $5, true)
3055}
3056;
3057
3058satisfies:
3059SATISFIES expr
3060{
3061    $$ = $2
3062}
3063;
3064
3065collection_xform:
3066ARRAY expr FOR coll_bindings opt_when END
3067{
3068    $$ = expression.NewArray($2, $4, $5)
3069}
3070|
3071FIRST expr FOR coll_bindings opt_when END
3072{
3073    $$ = expression.NewFirst($2, $4, $5)
3074}
3075|
3076OBJECT expr COLON expr FOR coll_bindings opt_when END
3077{
3078    $$ = expression.NewObject($2, $4, $6, $7)
3079}
3080;
3081
3082
3083/*************************************************
3084 *
3085 * Parentheses and subquery
3086 *
3087 *************************************************/
3088
3089paren_expr:
3090LPAREN expr RPAREN
3091{
3092    $$ = $2
3093}
3094|
3095LPAREN all_expr RPAREN
3096{
3097    $$ = $2
3098}
3099|
3100subquery_expr
3101{
3102    $$ = $1
3103}
3104;
3105
3106subquery_expr:
3107CORRELATED LPAREN fullselect RPAREN
3108{
3109    $$ = algebra.NewSubquery($2);
3110}
3111|
3112LPAREN fullselect RPAREN
3113{
3114    $$ = algebra.NewSubquery($2);
3115}
3116;
3117
3118
3119/*************************************************
3120 *
3121 * Top-level expression input / parsing.
3122 *
3123 *************************************************/
3124
3125expr_input:
3126expr
3127|
3128all_expr
3129;
3130
3131all_expr:
3132all expr
3133{
3134    $$ = expression.NewAll($2, false)
3135}
3136|
3137all DISTINCT expr
3138{
3139    $$ = expression.NewAll($3, true)
3140}
3141|
3142DISTINCT expr
3143{
3144    $$ = expression.NewAll($2, true)
3145}
3146;
3147