left or right join
Inheritance: TableReference
 public virtual void Visit(OuterJoin node)
 {
     VisitInternal(node.LeftTableRef);
     VisitInternal(node.OnCond);
     VisitInternal(node.RightTableRef);
 }
        /// <exception cref="System.SqlSyntaxErrorException" />
        private TableReference BuildTableReference(TableReference @ref)
        {
            for (;;)
            {
                IExpression on;
                IList<string> @using;
                TableReference temp;
                var isOut = false;
                var isLeft = true;
                switch (lexer.Token())
                {
                    case MySqlToken.KwInner:
                    case MySqlToken.KwCross:
                    {
                        lexer.NextToken();
                        goto case MySqlToken.KwJoin;
                    }

                    case MySqlToken.KwJoin:
                    {
                        lexer.NextToken();
                        temp = TableFactor();
                        switch (lexer.Token())
                        {
                            case MySqlToken.KwOn:
                            {
                                lexer.NextToken();
                                on = exprParser.Expression();
                                @ref = new InnerJoin(@ref, temp, on);
                                break;
                            }

                            case MySqlToken.KwUsing:
                            {
                                lexer.NextToken();
                                Match(MySqlToken.PuncLeftParen);
                                @using = IdNameList();
                                @ref = new InnerJoin(@ref, temp, @using);
                                break;
                            }

                            default:
                            {
                                @ref = new InnerJoin(@ref, temp);
                                break;
                            }
                        }
                        break;
                    }

                    case MySqlToken.KwStraightJoin:
                    {
                        lexer.NextToken();
                        temp = TableFactor();
                        switch (lexer.Token())
                        {
                            case MySqlToken.KwOn:
                            {
                                lexer.NextToken();
                                on = exprParser.Expression();
                                @ref = new StraightJoin(@ref, temp, on);
                                break;
                            }

                            default:
                            {
                                @ref = new StraightJoin(@ref, temp);
                                break;
                            }
                        }
                        break;
                    }

                    case MySqlToken.KwRight:
                    {
                        isLeft = false;
                        goto case MySqlToken.KwLeft;
                    }

                    case MySqlToken.KwLeft:
                    {
                        lexer.NextToken();
                        if (lexer.Token() == MySqlToken.KwOuter)
                        {
                            lexer.NextToken();
                        }
                        Match(MySqlToken.KwJoin);
                        temp = TableReference();
                        switch (lexer.Token())
                        {
                            case MySqlToken.KwOn:
                            {
                                lexer.NextToken();
                                on = exprParser.Expression();
                                @ref = new OuterJoin(isLeft, @ref, temp, on);
                                break;
                            }

                            case MySqlToken.KwUsing:
                            {
                                lexer.NextToken();
                                Match(MySqlToken.PuncLeftParen);
                                @using = IdNameList();
                                @ref = new OuterJoin(isLeft, @ref, temp, @using);
                                break;
                            }

                            default:
                            {
                                var condition = temp.RemoveLastConditionElement();
                                if (condition is IExpression)
                                {
                                    @ref = new OuterJoin(isLeft, @ref, temp, (IExpression)condition);
                                }
                                else
                                {
                                    if (condition is IList)
                                    {
                                        @ref = new OuterJoin(isLeft, @ref, temp, (IList<string>)condition);
                                    }
                                    else
                                    {
                                        throw Err("conditionExpr cannot be null for outer join");
                                    }
                                }
                                break;
                            }
                        }
                        break;
                    }

                    case MySqlToken.KwNatural:
                    {
                        lexer.NextToken();
                        switch (lexer.Token())
                        {
                            case MySqlToken.KwRight:
                            {
                                isLeft = false;
                                goto case MySqlToken.KwLeft;
                            }

                            case MySqlToken.KwLeft:
                            {
                                lexer.NextToken();
                                if (lexer.Token() == MySqlToken.KwOuter)
                                {
                                    lexer.NextToken();
                                }
                                isOut = true;
                                goto case MySqlToken.KwJoin;
                            }

                            case MySqlToken.KwJoin:
                            {
                                lexer.NextToken();
                                temp = TableFactor();
                                @ref = new NaturalJoin(isOut, isLeft, @ref, temp);
                                break;
                            }

                            default:
                            {
                                throw Err("unexpected token after NATURAL for natural join:" + lexer.Token());
                            }
                        }
                        break;
                    }

                    default:
                    {
                        return @ref;
                    }
                }
            }
        }