private static Pair <ExprNode, ExprTableAccessNode> HandleTableSubchain( IList <ExprNode> tableKeys, IList <Chainable> chain, TableMetaData table, Func <IList <Chainable>, ExprDotNodeImpl> dotNodeFunction) { if (chain.IsEmpty()) { var nodeX = new ExprTableAccessNodeTopLevel(table.TableName); nodeX.AddChildNodes(tableKeys); return(new Pair <ExprNode, ExprTableAccessNode>(nodeX, nodeX)); } // We make an exception when the table is keyed and the column is found and there are no table keys provided. // This accommodates the case "select MyTable.a from MyTable". var columnOrOtherName = chain[0].GetRootNameOrEmptyString(); var tableColumn = table.Columns.Get(columnOrOtherName); if (tableColumn != null && table.IsKeyed && tableKeys.IsEmpty()) { return(null); // let this be resolved as an identifier } if (chain.Count == 1) { if (chain[0] is ChainableName) { var nodeX = new ExprTableAccessNodeSubprop(table.TableName, columnOrOtherName); nodeX.AddChildNodes(tableKeys); return(new Pair <ExprNode, ExprTableAccessNode>(nodeX, nodeX)); } if (columnOrOtherName.Equals("keys", StringComparison.InvariantCultureIgnoreCase)) { var nodeX = new ExprTableAccessNodeKeys(table.TableName); nodeX.AddChildNodes(tableKeys); return(new Pair <ExprNode, ExprTableAccessNode>(nodeX, nodeX)); } else { throw new ValidationException( "Invalid use of table '" + table.TableName + "', unrecognized use of function '" + columnOrOtherName + "', expected 'keys()'"); } } var node = new ExprTableAccessNodeSubprop(table.TableName, columnOrOtherName); node.AddChildNodes(tableKeys); var subchain = chain.SubList(1, chain.Count); ExprNode exprNode = dotNodeFunction.Invoke(subchain); exprNode.AddChildNode(node); return(new Pair <ExprNode, ExprTableAccessNode>(exprNode, node)); }
public static Pair <ExprTableAccessNode, IList <Chainable> > CheckTableNameGetLibFunc( TableCompileTimeResolver tableService, LazyAllocatedMap <ConfigurationCompilerPlugInAggregationMultiFunction, AggregationMultiFunctionForge> plugInAggregations, string classIdent, IList <Chainable> chain) { var index = StringValue.UnescapedIndexOfDot(classIdent); // handle special case "table.keys()" function if (index == -1) { var tableX = tableService.Resolve(classIdent); if (tableX == null) { return(null); // not a table } var funcName = chain[1].GetRootNameOrEmptyString(); if (funcName.Equals("keys", StringComparison.InvariantCultureIgnoreCase)) { var subchain = chain.SubList(2, chain.Count); var node = new ExprTableAccessNodeKeys(tableX.TableName); return(new Pair <ExprTableAccessNode, IList <Chainable> >(node, subchain)); } else { throw new ValidationException( "Invalid use of table '" + classIdent + "', unrecognized use of function '" + funcName + "', expected 'keys()'"); } } // Handle "table.property" (without the variable[...] syntax since this is ungrouped use) var tableName = StringValue.UnescapeDot(classIdent.Substring(0, index)); var table = tableService.Resolve(tableName); if (table == null) { return(null); } // this is a table access expression var sub = classIdent.Substring(index + 1, classIdent.Length); return(HandleTableAccessNode(plugInAggregations, table.TableName, sub, chain)); }
public static Pair <ExprTableAccessNode, IList <ExprChainedSpec> > CheckTableNameGetLibFunc( TableService tableService, EngineImportService engineImportService, LazyAllocatedMap <ConfigurationPlugInAggregationMultiFunction, PlugInAggregationMultiFunctionFactory> plugInAggregations, string engineURI, string classIdent, IList <ExprChainedSpec> chain) { var index = ASTUtil.UnescapedIndexOfDot(classIdent); // handle special case "table.Keys()" function if (index == -1) { if (tableService.GetTableMetadata(classIdent) == null) { return(null); // not a table } var funcName = chain[1].Name; if (funcName.ToLowerInvariant().Equals("keys")) { var subchain = chain.SubList(2, chain.Count); var node = new ExprTableAccessNodeKeys(classIdent); return(new Pair <ExprTableAccessNode, IList <ExprChainedSpec> >(node, subchain)); } else { throw ASTWalkException.From( "Invalid use of variable '" + classIdent + "', unrecognized use of function '" + funcName + "', expected 'keys()'"); } } // Handle "table.property" (without the variable[...] syntax since this is ungrouped use) var tableName = ASTUtil.UnescapeDot(classIdent.Substring(0, index)); if (tableService.GetTableMetadata(tableName) == null) { return(null); } // this is a table access expression var sub = classIdent.Substring(index + 1); return(HandleTable(engineImportService, plugInAggregations, engineURI, tableName, sub, chain)); }