/// <summary> /// Handle property "table" or "table[key]" where key is an integer and therefore can be a regular property /// </summary> /// <param name="propertyName">property</param> /// <param name="resolver">resolver</param> /// <returns>expression null or node</returns> public static ExprTableAccessNode MapPropertyToTableUnnested( string propertyName, TableCompileTimeResolver resolver) { // try regular property var table = resolver.Resolve(propertyName); if (table != null) { return(new ExprTableAccessNodeTopLevel(table.TableName)); } // try indexed property var pair = MapPropertyToTable(propertyName, resolver); if (pair == null) { return(null); } ExprTableAccessNode tableNode = new ExprTableAccessNodeTopLevel(pair.Second.TableName); tableNode.AddChildNode(new ExprConstantNodeImpl(pair.First.Index)); return(tableNode); }
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)); }
private static Pair <ExprNode, ExprTableAccessNode> HandleTable( IList <Chainable> chain, TableMetaData table, Func <IList <Chainable>, ExprDotNodeImpl> dotNodeFunction) { if (chain.Count == 1) { var node = new ExprTableAccessNodeTopLevel(table.TableName); return(new Pair <ExprNode, ExprTableAccessNode>(node, node)); } if (chain[1] is ChainableArray) { var tableKeys = ((ChainableArray)chain[1]).Indexes; return(HandleTableSubchain(tableKeys, chain.SubList(2, chain.Count), table, dotNodeFunction)); } else { return(HandleTableSubchain(EmptyList <ExprNode> .Instance, chain.SubList(1, chain.Count), table, dotNodeFunction)); } }