public override Element VisitInnerJoinStatementExp(SqlParser.InnerJoinStatementExpContext context) { var join = new InnerJoinStatement(CreateParseInfo(context)) { Name = context.t == null ? "" : context.t.Text, Alias = context.a != null ? context.a.Text : null }; if (context.b != null) { join.Children.Add(Visit(context.b)); } if (context.j != null) { join.Children.Add(Visit(context.j)); } return(join); }
public void Visit(InnerJoinStatement statement, CommonTree tree) { Parent(tree).Children.Add(statement); SetLine(statement, tree); VisitChildren(tree); }
public void Visit(InnerJoinStatement statement) { CodeMemberMethod method = new CodeMemberMethod(); method.Name = "Join_" + Guid.NewGuid().ToString("N"); method.Attributes = MemberAttributes.Private; method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("IEnumerable", _codeStack.Peek().Scope.CodeDomReference), "outer")); GenerateCallStatement(method.Statements, statement.Line.Line); _mainType.Type.Members.Add(method); CodeTypeReference fetchAnonType; var fetchMethod = CreateFetch(statement, out fetchAnonType); method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerable", fetchAnonType), "table", new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, fetchMethod.Name)))); //create combined anon type var anon = "anon_" + Guid.NewGuid().ToString("N"); var bufferTable = new CodeTypeDeclaration(anon) { TypeAttributes = TypeAttributes.NestedPrivate }; bufferTable.BaseTypes.Add(new CodeTypeReference("IRow")); _mainType.Type.Members.Add(bufferTable); bufferTable.Members.AddRange(Scope.Current.JoinMembers.ToArray()); //Do Join var anonType = new CodeTypeReference(anon); method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IList", anonType), "join", new CodeObjectCreateExpression(new CodeTypeReference("List", anonType)))); method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", _codeStack.Peek().Scope.CodeDomReference), "o", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("outer"), "GetEnumerator"))); var outerLoop = new CodeIterationStatement(); outerLoop.InitStatement = new CodeSnippetStatement(); outerLoop.IncrementStatement = new CodeSnippetStatement(); outerLoop.TestExpression = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("o"), "MoveNext"); outerLoop.Statements.Add(new CodeVariableDeclarationStatement(_codeStack.Peek().Scope.CodeDomReference, "oc", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("o"), "Current"))); outerLoop.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", fetchAnonType), "i", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("table"), "GetEnumerator"))); var innerLoop = new CodeIterationStatement(); outerLoop.Statements.Add(innerLoop); innerLoop.InitStatement = new CodeSnippetStatement(); innerLoop.IncrementStatement = new CodeSnippetStatement(); innerLoop.TestExpression = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("i"), "MoveNext"); innerLoop.Statements.Add(new CodeVariableDeclarationStatement(fetchAnonType, "ic", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("i"), "Current"))); var booleanArgs = VisitChild(statement.Expression); string booleanString = ReplaceBooleanStatement(statement, GenerateCodeFromExpression(booleanArgs.CodeExpression)); var joinIf = new CodeConditionStatement(new CodeSnippetExpression(booleanString)); innerLoop.Statements.Add(joinIf); joinIf.TrueStatements.Add(new CodeVariableDeclarationStatement(anonType, "t", new CodeObjectCreateExpression(anonType))); for (int x = 0; x < Scope.Current.JoinMembers.Count - 1; x++) { joinIf.TrueStatements.Add(new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("t"), Scope.Current.JoinMembers[x].Name), new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("oc"), Scope.Current.JoinMembers[x].Name))); } joinIf.TrueStatements.Add(new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("t"), Scope.Current.JoinMembers[Scope.Current.JoinMembers.Count - 1].Name), new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("ic"), Scope.Current.JoinMembers[Scope.Current.JoinMembers.Count - 1].Name))); joinIf.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("join"), "Add", new CodeVariableReferenceExpression("t"))); method.Statements.Add(outerLoop); if (statement.Join != null) { var args = VisitChild(statement.Join, new CodeDomArg() { Scope = new ScopeData <Type> { Type = typeof(int), CodeDomReference = anonType } }); method.Statements.Add(new CodeMethodReturnStatement(args.CodeExpression)); method.ReturnType = args.Scope.CodeDomReference; _codeStack.Peek().Scope = args.Scope; } else { var tableType = new CodeTypeReference("CodeTable", anonType); method.ReturnType = tableType; _codeStack.Peek().Scope = new ScopeData <Type> { Type = typeof(int), CodeDomReference = tableType }; method.Statements.Add(new CodeVariableDeclarationStatement(tableType, "newTable", new CodeObjectCreateExpression(tableType))); method.Statements.Add(new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("newTable"), "SetRows", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("join"), "ToList"))); method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("newTable"))); } _codeStack.Peek().CodeExpression = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(null, method.Name), new CodeVariableReferenceExpression("join")); }
public void Visit(InnerJoinStatement statement) { string tableName = statement.Name; string tableVariable; if (statement.Alias != null) { tableVariable = statement.Alias; } else { tableVariable = statement.Name; } if (_scope.IsTableDefineSameLevel(tableName)) //table exists already { Errors.Add(new TableConflict(tableName, statement.Bounds.Start)); } if (!_scope.IsTableDefinedAnyLevel(tableName)) //we don't know this table at any level { Errors.Add(new TableNotDefined(tableName, statement.Bounds.Start)); return; } if (_scope.IsTableDefineSameLevel(tableVariable)) //if alias variable exists we have conflict { throw new InvalidOperationException(""); } var executedTables = _scope.FetchAllExecutedTablesSameLevel(); int rowCount = 0; if (executedTables.Length > 0) { rowCount = executedTables.First().Rows.Length; } var rightTableRows = new List <Row>(); if (rowCount == 0) //need to visit for semantic errors { var table = _scope.TableLookupAnyLevel(tableName); table = table.Create(); _scope.AddTable(tableVariable, table); VisitChild(statement.BooleanExpression); VisitWhereIgnoreErrors(statement.ParentQueryStatement.Where); var executeTable = table.Execute(statement.ParentQueryStatement.Limit); foreach (var e in table.Errors) { Errors.Add(e); } _scope.RemoveTable(tableVariable); } else { for (int row = 0; row < rowCount; row++) { var table = _scope.TableLookupAnyLevel(tableName); table = table.Create(); _scope.AddTable(tableVariable, table); Array.ForEach(executedTables, (x) => x.RowIndex = row); VisitChild(statement.BooleanExpression); VisitWhereIgnoreErrors(statement.ParentQueryStatement.Where); var executeTable = table.Execute(statement.ParentQueryStatement.Limit); foreach (var e in table.Errors) { Errors.Add(e); } _scope.RemoveTable(tableVariable); //remove query table _scope.AddTable(tableVariable, executeTable); // add execute table var arg = new QueryPhaseArgs(); VisitChild(statement.BooleanExpression, arg); if (arg.RowResult) //row passed join. If didn't row needs to be removed from the left joining result { Array.ForEach(executedTables, (x) => x.Rows[x.RowIndex].Expand = executeTable.Rows.Length); rightTableRows.AddRange(executeTable.Rows); } else //flag row as unmatching for all executed tables { Array.ForEach(executedTables, (x) => x.Rows[x.RowIndex].Match = false); } _scope.RemoveTable(tableVariable); } } var returnTable = _scope.TableLookupAnyLevel(tableName); var returnExecuteTable = new ExecutedTable(returnTable.Create().Descriptor) { Rows = rightTableRows.ToArray() }; _scope.AddTable(tableVariable, returnExecuteTable); executedTables = _scope.FetchAllExecutedTablesSameLevel(); Array.ForEach(executedTables, (e) => { var joinedRows = new List <Row>(); //Add matched rows Array.ForEach(e.Rows, r => { if (r.Match) { for (int x = 0; x < r.Expand; x++) { joinedRows.Add(r); } } }); e.Rows = joinedRows.ToArray(); }); VisitChild(statement.InnerJoin); }