public override SqlFragment Visit(DbNewInstanceExpression expression) { Debug.Assert(expression.ResultType.EdmType is CollectionType); SelectStatement s = new SelectStatement(); ColumnFragment c = new ColumnFragment(null, null); if (expression.Arguments.Count != 0) c.Literal = (LiteralFragment)expression.Arguments[0].Accept(this); else c.Literal = new LiteralFragment("NULL"); c.ColumnAlias = "X"; s.Columns.Add(c); return s; }
private SelectStatement VisitInputExpressionEnsureSelect(DbExpression e, string name, TypeUsage type) { InputFragment fragment = VisitInputExpression(e, name, type); if (fragment is SelectStatement) return (fragment as SelectStatement); SelectStatement s = new SelectStatement(); // if the fragment is a union then it needs to be wrapped if (fragment is UnionFragment) (fragment as UnionFragment).Wrap(scope); s.From = fragment; return s; }
private InputFragment WrapJoinInputIfNecessary(InputFragment fragment, bool isRightPart) { if (fragment is SelectStatement || fragment is UnionFragment) { fragment.Wrap(scope); fragment.Scoped = true; } else if (fragment is JoinFragment && isRightPart) { SelectStatement select = new SelectStatement(); select.From = fragment; select.Name = fragment.Name; select.Wrap(scope); return select; } return fragment; }
public SelectStatement WrapIfNotCompatible(SelectStatement select, DbExpressionKind expressionKind) { if (select.IsCompatible(expressionKind)) return select; SelectStatement newSelect = new SelectStatement(); select.Wrap(scope); newSelect.From = select; return newSelect; }
public void Visit(SelectStatement f) { }
/// <summary> /// If input sqlFragment is a group by structure, is flattened to remove some nested correlation queries. /// </summary> /// <param name="input"></param> /// <returns></returns> private SqlFragment TryFlatteningGroupBy(SqlFragment input) { SelectStatement select = null; SelectStatement tmpFrag = null, tmpFrag2 = null, tmpFrag3 = null; InputFragment table = null; string objName = null, colName = null, queryName = null; // First part assert is a kind-of structure we are looking for tmpFrag = input as SelectStatement; if (tmpFrag == null) goto NoChanges; tmpFrag = ( tmpFrag ).From as SelectStatement; if (tmpFrag == null) goto NoChanges; queryName = tmpFrag.Name; if (tmpFrag.Columns.Count < 2) goto NoChanges; if (!(tmpFrag.Columns[0] is ColumnFragment)) goto NoChanges; colName = objName = (tmpFrag.Columns[0] as ColumnFragment).ActualColumnName; tmpFrag2 = tmpFrag.From as SelectStatement; if (tmpFrag2 == null) goto NoChanges; if (tmpFrag2.Columns.Count < 1 || !(tmpFrag2.Columns[0] is ColumnFragment)) goto NoChanges; if (string.CompareOrdinal(objName, tmpFrag2.Columns[0].ActualColumnName) != 0) goto NoChanges; if (tmpFrag.Columns[1].Literal == null ) goto NoChanges; tmpFrag2 = tmpFrag.Columns[1].Literal as SelectStatement; if (tmpFrag2 == null) goto NoChanges; if ((tmpFrag2.Columns.Count != 1) || !(tmpFrag2.Columns[0].Literal != null)) goto NoChanges; tmpFrag3 = tmpFrag2.From as SelectStatement; if (tmpFrag3 == null) goto NoChanges; table = tmpFrag3.From as InputFragment; if (table == null) goto NoChanges; FunctionFragment func = tmpFrag2.Columns[0].Literal as FunctionFragment; if( tmpFrag3.Columns.Count != 1 || !( tmpFrag3.Columns[ 0 ] is ColumnFragment )) goto NoChanges; if (func == null) goto NoChanges; // Yes it is the kind-of type we like, then optimize it select = new SelectStatement(this); table.Name = null; string tableName = null; TableFragment t = tmpFrag3.From as TableFragment; if (t == null) tableName = tmpFrag3.Columns[0].TableName; else tableName = t.Table; select.From = table; select.Columns.Add(new ColumnFragment(tableName, colName)); select.Columns.Add(new ColumnFragment(tableName, "C0") { ColumnAlias = "C1", Literal = new FunctionFragment() { Argument = new ColumnFragment(tableName, tmpFrag3.Columns[0].ActualColumnName), Distinct = tmpFrag3.IsDistinct, Name = func.Name } }); select.Wrap(null); select.Name = queryName; select.AddGroupBy(select.Columns[0]); (input as SelectStatement).From = select; NoChanges: return input; }
public override SqlFragment Visit(DbApplyExpression expression) { DbExpressionBinding inputBinding = expression.Input; InputFragment input = VisitInputExpression(inputBinding.Expression, inputBinding.VariableName, inputBinding.VariableType); DbExpressionBinding applyBinding = expression.Apply; InputFragment apply = VisitInputExpression(applyBinding.Expression, applyBinding.VariableName, applyBinding.VariableType); SelectStatement select = new SelectStatement(this); bool isInputSelect = false; if (!(input is TableFragment)) { input.Wrap(scope); isInputSelect = true; } apply.Wrap(scope); select.From = input; select.Wrap(scope); if (apply is SelectStatement) { SelectStatement applySel = apply as SelectStatement; foreach (ColumnFragment f in applySel.Columns) { SelectStatement newColSelect = new SelectStatement(this); newColSelect.From = applySel.From; newColSelect.Where = applySel.Where; if (isInputSelect) { VisitAndReplaceTableName(newColSelect.Where, (input as SelectStatement).From.Name, input.Name); } newColSelect.Limit = applySel.Limit; newColSelect.Columns.Add( f ); newColSelect.Wrap(scope); scope.Add(applySel.From.Name, applySel.From); ColumnFragment newCol = new ColumnFragment(apply.Name, f.ColumnName); newCol.Literal = newColSelect; newCol.PushInput(newCol.ColumnName); newCol.PushInput(apply.Name); select.AddColumn( newCol, scope); if (string.IsNullOrEmpty(newCol.ColumnAlias)) { newColSelect.Name = newCol.ColumnName; newCol.ColumnAlias = newCol.ColumnName; } scope.Remove(newColSelect); } scope.Remove(applySel.From); scope.Remove(apply); } return select; }
public override SqlFragment Visit(DbApplyExpression expression) { DbExpressionBinding inputBinding = expression.Input; InputFragment input = VisitInputExpression(inputBinding.Expression, inputBinding.VariableName, inputBinding.VariableType); DbExpressionBinding applyBinding = expression.Apply; InputFragment apply = VisitInputExpression(applyBinding.Expression, applyBinding.VariableName, applyBinding.VariableType); SelectStatement select = new SelectStatement(this); bool isInputSelect = false; if (!(input is TableFragment)) { input.Wrap(scope); isInputSelect = true; } apply.Wrap(scope); select.From = input; select.Wrap(scope); if (apply is SelectStatement) { SelectStatement applySel = apply as SelectStatement; foreach (ColumnFragment f in applySel.Columns) { SelectStatement newColSelect = new SelectStatement(this); newColSelect.From = applySel.From; newColSelect.Where = applySel.Where; if (isInputSelect) { VisitAndReplaceTableName(newColSelect.Where, (input as SelectStatement).From.Name, input.Name, null); } newColSelect.Limit = applySel.Limit; newColSelect.OrderBy = applySel.OrderBy; newColSelect.Skip = applySel.Skip; newColSelect.GroupBy = applySel.GroupBy; newColSelect.IsDistinct = applySel.IsDistinct; newColSelect.Columns.Add(f); newColSelect.Wrap(scope); scope.Add(applySel.From.Name, applySel.From); ColumnFragment newCol = new ColumnFragment(apply.Name, f.ColumnName); newCol.Literal = newColSelect; newCol.PushInput(newCol.ColumnName); newCol.PushInput(apply.Name); select.AddColumn(newCol, scope); if (string.IsNullOrEmpty(newCol.ColumnAlias)) { newColSelect.Name = newCol.ColumnName; newCol.ColumnAlias = newCol.ColumnName; } scope.Remove(newColSelect); } scope.Remove(applySel.From); scope.Remove(apply); } else if (apply is UnionFragment) { UnionFragment uf = apply as UnionFragment; if (uf.Left == null || uf.Right == null) throw new Exception("Union fragment is not properly formed."); var left = uf.Left as SelectStatement; var right = uf.Right as SelectStatement; if (left == null || right == null) throw new NotImplementedException(); var whereleft = left.Where as BinaryFragment; var whereright = right.Where as BinaryFragment; if (whereleft == null || whereright == null) throw new NotImplementedException(); LiteralFragment literalFragmentWhere = null; //checking where left if (whereleft.Left is ColumnFragment && whereleft.Right is ColumnFragment) { // we replace the where part for a dummy one if (whereright.Left is ColumnFragment && whereright.Right is ColumnFragment) { literalFragmentWhere = new LiteralFragment("1 = 1"); } } if (literalFragmentWhere == null) throw new NotImplementedException(); var leftouterjoin = new JoinFragment(); leftouterjoin.JoinType = Metadata.GetOperator(DbExpressionKind.LeftOuterJoin); leftouterjoin.Name = apply.Name; // validating that column fragment on the left matches the name // for the input fragment var leftColumnFragment = whereleft.Left as ColumnFragment; if (leftColumnFragment == null) throw new NotImplementedException(); if (!leftColumnFragment.TableName.Equals(input.Name)) new NotImplementedException(); var conditionJoin = new BinaryFragment(); conditionJoin.Left = whereleft.Left; //update to the new reference var newColumnFragment = whereright.Right as ColumnFragment; if (newColumnFragment != null) { newColumnFragment.TableName = uf.Name; } conditionJoin.Right = newColumnFragment; conditionJoin.Operator = whereleft.Operator; leftouterjoin.Condition = conditionJoin; (uf.Left as SelectStatement).Where = literalFragmentWhere; (uf.Right as SelectStatement).Where = literalFragmentWhere; leftouterjoin.Left = input; leftouterjoin.Right = uf; return leftouterjoin; } return select; }
List <ColumnFragment> GetDefaultColumnsForFragment(InputFragment input) { List <ColumnFragment> columns = new List <ColumnFragment>(); if (input is TableFragment) { return(GetDefaultColumnsForTable(input as TableFragment)); } else if (input is JoinFragment || input is UnionFragment) { Debug.Assert(input.Left != null); if (input is UnionFragment) { generator.Ops.Push(OpType.Union); } columns = GetDefaultColumnsForFragment(input.Left); if (input is JoinFragment && input.Right != null) { List <ColumnFragment> right = GetDefaultColumnsForFragment(input.Right); columns.AddRange(right); } if (input is UnionFragment) { generator.Ops.Pop(); } } else if (input is SelectStatement) { SelectStatement select = input as SelectStatement; foreach (ColumnFragment cf in select.Columns) { ColumnFragment newColumn = new ColumnFragment(cf.TableName, string.IsNullOrEmpty(cf.ColumnAlias) ? cf.ActualColumnName : cf.ColumnAlias ); if (generator.GetTopOp() == OpType.Join) { newColumn.ColumnAlias = cf.ColumnAlias; newColumn.PushInput(cf.ColumnName); if (cf.TableName != null) { newColumn.PushInput(cf.TableName); } } else { newColumn.PushInput(cf.ActualColumnName); if (cf.TableName != null && cf.ColumnAlias == null) { newColumn.PushInput(cf.TableName); } } if (select.Name != null) { newColumn.PushInput(select.Name); // add the scope } columns.Add(newColumn); } return(columns); } else { throw new NotImplementedException(); } if (!String.IsNullOrEmpty(input.Name) && input.Name != From.Name) { foreach (ColumnFragment c in columns) { c.PushInput(input.Name); } } return(columns); }