internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(sref.SharedExpression)) { return(sref); } return(new SqlSharedExpressionRef((SqlSharedExpression)this.Visit(sref.SharedExpression))); }
internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { if (!this.isDebugMode) { throw Error.InvalidFormatNode("SharedRef"); } sb.Append("SHAREDREF("); this.Visit(sref.SharedExpression.Expression); sb.Append(")"); return sref; }
internal virtual SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { return sref; }
internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { if (this.ingoreExternalRefs && !this.nodeMap.ContainsKey(sref.SharedExpression)) { return sref; } return new SqlSharedExpressionRef((SqlSharedExpression)this.Visit(sref.SharedExpression)); }
private SqlNode VisitGroupBy(Expression sequence, LambdaExpression keyLambda, LambdaExpression elemLambda, LambdaExpression resultSelector) { // Convert seq.Group(elem, key) into // // SELECT s.key, MULTISET(select s2.elem from seq AS s2 where s.key == s2.key) // FROM seq AS s // // where key and elem can be either simple scalars or object constructions // SqlSelect seq = this.VisitSequence(sequence); seq = this.LockSelect(seq); SqlAlias seqAlias = new SqlAlias(seq); SqlAliasRef seqAliasRef = new SqlAliasRef(seqAlias); // evaluate the key expression relative to original sequence this.map[keyLambda.Parameters[0]] = seqAliasRef; SqlExpression keyExpr = this.VisitExpression(keyLambda.Body); // make a duplicate of the original sequence to use as a foundation of our group multiset SqlDuplicator sd = new SqlDuplicator(); SqlSelect selDup = (SqlSelect)sd.Duplicate(seq); // rebind key in relative to the duplicate sequence SqlAlias selDupAlias = new SqlAlias(selDup); SqlAliasRef selDupRef = new SqlAliasRef(selDupAlias); this.map[keyLambda.Parameters[0]] = selDupRef; SqlExpression keyDup = this.VisitExpression(keyLambda.Body); SqlExpression elemExpr = null; SqlExpression elemOnGroupSource = null; if (elemLambda != null) { // evaluate element expression relative to the duplicate sequence this.map[elemLambda.Parameters[0]] = selDupRef; elemExpr = this.VisitExpression(elemLambda.Body); // evaluate element expression relative to original sequence this.map[elemLambda.Parameters[0]] = seqAliasRef; elemOnGroupSource = this.VisitExpression(elemLambda.Body); } else { // no elem expression supplied, so just use an alias ref to the duplicate sequence. // this will resolve to whatever was being produced by the sequence elemExpr = selDupRef; elemOnGroupSource = seqAliasRef; } // Make a sub expression out of the key. This will allow a single definition of the // expression to be shared at multiple points in the tree (via SqlSharedExpressionRef's) SqlSharedExpression keySubExpr = new SqlSharedExpression(keyExpr); keyExpr = new SqlSharedExpressionRef(keySubExpr); // construct the select clause that picks out the elements (this may be redundant...) SqlSelect selElem = new SqlSelect(elemExpr, selDupAlias, this.dominatingExpression); selElem.Where = sql.Binary(SqlNodeType.EQ2V, keyExpr, keyDup); // Finally, make the MULTISET node. this will be used as part of the final select SqlSubSelect ss = sql.SubSelect(SqlNodeType.Multiset, selElem); // add a layer to the original sequence before applying the actual group-by clause SqlSelect gsel = new SqlSelect(new SqlSharedExpressionRef(keySubExpr), seqAlias, this.dominatingExpression); gsel.GroupBy.Add(keySubExpr); SqlAlias gselAlias = new SqlAlias(gsel); SqlSelect result = null; if (resultSelector != null) { // Create final select to include construction of group multiset // select new Grouping { Key = key, Group = Multiset(select elem from seq where match) } from ... Type elementType = typeof(IGrouping<,>).MakeGenericType(keyExpr.ClrType, elemExpr.ClrType); SqlExpression keyGroup = new SqlGrouping(elementType, this.typeProvider.From(elementType), keyExpr, ss, this.dominatingExpression); SqlSelect keyGroupSel = new SqlSelect(keyGroup, gselAlias, this.dominatingExpression); SqlAlias kgAlias = new SqlAlias(keyGroupSel); SqlAliasRef kgAliasRef = new SqlAliasRef(kgAlias); this.map[resultSelector.Parameters[0]] = sql.Member(kgAliasRef, elementType.GetProperty("Key")); this.map[resultSelector.Parameters[1]] = kgAliasRef; // remember the select that has the actual group (for optimizing aggregates later) this.gmap[kgAliasRef] = new GroupInfo { SelectWithGroup = gsel, ElementOnGroupSource = elemOnGroupSource }; SqlExpression resultExpr = this.VisitExpression(resultSelector.Body); result = new SqlSelect(resultExpr, kgAlias, this.dominatingExpression); // remember the select that has the actual group (for optimizing aggregates later) this.gmap[resultExpr] = new GroupInfo { SelectWithGroup = gsel, ElementOnGroupSource = elemOnGroupSource }; } else { // Create final select to include construction of group multiset // select new Grouping { Key = key, Group = Multiset(select elem from seq where match) } from ... Type elementType = typeof(IGrouping<,>).MakeGenericType(keyExpr.ClrType, elemExpr.ClrType); SqlExpression resultExpr = new SqlGrouping(elementType, this.typeProvider.From(elementType), keyExpr, ss, this.dominatingExpression); result = new SqlSelect(resultExpr, gselAlias, this.dominatingExpression); // remember the select that has the actual group (for optimizing aggregates later) this.gmap[resultExpr] = new GroupInfo { SelectWithGroup = gsel, ElementOnGroupSource = elemOnGroupSource }; } return result; }
internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { // always make a copy return (SqlExpression) SqlDuplicator.Copy(sref.SharedExpression.Expression); }
internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { return this.VisitExpression(sref.SharedExpression.Expression); }
internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { throw Error.UnexpectedSharedExpressionReference(); }
internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) { return(this.VisitExpression(sref.SharedExpression.Expression)); }