Example #1
0
        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);
        }
Example #2
0
 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"));
        }
Example #4
0
        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);
        }