protected override void VisitInnerJoin(InnerJoin item)
 {
     if (_DetectingMetadataQuery)
     {
         item.RightHand.Source.Accept(this);
     }
 }
示例#2
0
        public Join <TDto> InnerJoin(string tableName, string tableAlias = null, string dbSchema = "dbo")
        {
            var innerJoin = new InnerJoin <TDto>(_spry, this, new SprySelectTable <TDto>(_spry, tableName, tableAlias, dbSchema));

            _joins.Add(innerJoin);
            return(innerJoin);
        }
示例#3
0
        static void Main(string[] args)
        {
            var freesql = new FreeSql.FreeSqlBuilder()
                          .UseConnectionString(FreeSql.DataType.PostgreSQL, "")
                          .Build();

            TableInfomationInitor.Initialize(freesql, typeof(Test), typeof(DomainFlags));
            OrmNavigate <Test> .Join <Test2>(item => item.DomainFlags, item => item.Id);

            var sql    = new JoinTemplate <Test>(freesql);
            var result = sql.ToList(item => new
            {
                item.Id,
                item.DomainFlags,
                DomainName = RightJoin <DomainFlags> .MapFrom(item => item.Name)
            });

            sql = new JoinTemplate <Test>(freesql);
            var result1 = sql.ToList(item => new
            {
                item.Id,
                item.DomainFlags,
                DomainName = InnerJoin <DomainFlags> .MapFrom(item => item.Name)
            });

            Console.ReadKey();
        }
示例#4
0
        public async Task <(Actor, string, Cast, string)[]> GetTuple()
        {
            string aliasactor = "actor";
            string aliascast  = "cast";

            try
            {
                var query = await _dao.NewQueryBuilder()
                            .Select()
                            .AllFields <Actor>(aliasactor).Comma()
                            .Field <Actor>(aliasactor, a => a.ActorName, "ACTORNAME_2").Comma()
                            .AllFields <Cast>(aliascast).Comma()
                            .Field <Cast>(aliascast, c => c.Role, "ACTORROLE_2")
                            .From()
                            .Tables
                            (
                    FlatTable <Actor> .WithAlias(aliasactor),
                    InnerJoin <Cast> .WithAlias(aliascast),
                    (a, c) => a.Id == c.ActorId
                            )
                            .OrderBy <Actor>(aliasactor, a => a.Id)
                            .GetItemsArrayAsync <(Actor Actor, string Actorname, Cast Cast, string Role)>()
                            .ConfigureAwait(false);

                return(query);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            return(null);
        }
示例#5
0
        public InnerJoinIterator(Iterator iterator, InnerJoin innerJoin)
        {
            this._iterator  = iterator;
            this._innerJoin = innerJoin;

            //TODO get RowCount from database.
        }
示例#6
0
 protected override void SetupJoinConditions()
 {
     //InnerJoin
     //    .Left("Id")
     //    .Right("Id");
     InnerJoin
     .Left("Vigencia")
     .Right("Year");
 }
示例#7
0
        public void Visit(InnerJoin node)
        {
            var tr1 = node.LeftTableRef;
            var tr2 = node.RightTableRef;
            var on  = node.OnCond;

            VisitChild(1, _verdictColumn, _verdictGroupFunc, tr1, tr2);
            VisitChild(2, _verdictColumn && IsVerdictPassthroughWhere(on), false, on);
        }
        public void When_building_nested_Then_builds_properly()
        {
            var join = new OuterJoin(new TableClause("Lol l"), new TableClause("Wat w"), "l.WatID = w.ID");

            var innerJoin = new InnerJoin(join, new TableClause("Derp d"), "l.DerpID = d.ID");

            innerJoin.ToSql().Should().BeEquivalentToIgnoringNewLines(@"Lol l
    OUTER JOIN Wat w ON l.WatID = w.ID
    INNER JOIN Derp d ON l.DerpID = d.ID");
        }
示例#9
0
        /// <summary>
        /// Generates the text for an InnerJoin builder.
        /// </summary>
        /// <param name="item">The InnerJoin builder to generate the text for.</param>
        protected internal override void VisitInnerJoin(InnerJoin item)
        {
            StringBuilder joinBuilder = new StringBuilder();

            if (options.VerboseInnerJoin)
            {
                joinBuilder.Append("INNER ");
            }
            joinBuilder.Append("JOIN");
            visitFilteredJoin(item, joinBuilder.ToString());
        }
        public void When_building_nested_Then_builds_properly()
        {
            var join = new OuterJoin(new TableClause("Lol l"), new TableClause("Wat w"), "l.WatID = w.ID");

            var innerJoin = new InnerJoin(join, new TableClause("Derp d"), "l.DerpID = d.ID");

            Assert.That(
                innerJoin.ToSql(),
                SqlCompareConstraint.EqualTo(@"Lol l
    OUTER JOIN Wat w ON l.WatID = w.ID
    INNER JOIN Derp d ON l.DerpID = d.ID"));
        }
示例#11
0
 public MathStroke()
 {
     m_width             = default(T).Set(0.5);
     m_width_abs         = default(T).Set(0.5);
     m_width_eps         = default(T).Set(0.5).Divide(default(T).Set(1024.0));
     m_width_sign        = 1;
     m_miter_limit       = default(T).Set(4.0);
     m_inner_miter_limit = default(T).Set(1.01);
     m_approx_scale      = default(T).Set(1.0);
     LineCap             = LineCap.Butt;
     LineJoin            = LineJoin.MiterJoin;
     InnerJoin           = InnerJoin.InnerMiter;
 }
示例#12
0
 public StrokeMath()
 {
     m_width = 0.5;
     m_width_abs = 0.5;
     m_width_eps = 0.5 / 1024.0;
     m_width_sign = 1;
     m_miter_limit = 4.0;
     m_inner_miter_limit = 1.01;
     m_approx_scale = 1.0;
     m_line_cap = LineCap.Butt;
     m_line_join = LineJoin.Miter;
     m_inner_join = InnerJoin.Miter;
 }
示例#13
0
 public StrokeMath()
 {
     _width             = 0.5;
     _width_abs         = 0.5;
     _width_eps         = 0.5 / 1024.0;
     _width_sign        = 1;
     _miter_limit       = 4.0;
     _inner_miter_limit = 1.01;
     _approx_scale      = 1.0;
     _line_cap          = LineCap.Butt;
     _line_join         = LineJoin.Miter;
     _inner_join        = InnerJoin.Miter;
 }
示例#14
0
        private void runJoin(JoinSetting setting)
        {
            List <Row> left  = helper.DataTable2List(dictDataTable[setting.LeftDTName]);
            List <Row> right = helper.DataTable2List(dictDataTable[setting.RightDTName]);

            List <JoinCondition> joinConditions = new List <JoinCondition>();

            foreach (string[] item in setting.JoinConditions)
            {
                joinConditions.Add(new JoinCondition(item[0], item[1]));
            }

            List <Mapping> mappings = new List <Mapping>();

            foreach (string[] item in setting.Mappings)
            {
                mappings.Add(new Mapping(item[0], item[1], item[2], item[3]));
            }

            BaseJoin join;

            switch (setting.Type)
            {
            case "leftjoin":
                join = new LeftJoin();
                break;

            case "innerjoin":
                join = new InnerJoin();
                break;

            default:
                throw new NotImplementedException();
            }

            join.Left(new GenericEnumerableOperation(left))
            .Right(new GenericEnumerableOperation(right));

            join.JoinCondition(joinConditions);
            join.Mapping(mappings);

            join.PrepareForExecution(new SingleThreadedPipelineExecuter());
            IEnumerable <Row> result = join.Execute(null);
            List <Row>        items  = new List <Row>(result);

            DataTable dtResult = helper.List2DataTable(items);

            dictDataTable.Add(setting.OutputName, dtResult);
        }
示例#15
0
        /// <summary>
        /// Adds an inner join to the query.
        /// </summary>
        /// <param name="alias">The alias.</param>
        /// <param name="onCriteria">The ON criteria.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">
        /// alias is null
        /// or
        /// alias.table is null
        /// </exception>
        public SqlQuery InnerJoin(IAlias alias, ICriteria onCriteria)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }

            if (string.IsNullOrEmpty(alias.Table))
            {
                throw new ArgumentNullException("alias.table");
            }

            var join = new InnerJoin(alias.Table, alias.Name, onCriteria);

            Join(join);

            if (alias is IHaveJoins haveJoins)
            {
                AliasWithJoins[alias.Name] = haveJoins;
            }

            return(this);
        }
示例#16
0
        internal static bool TryParseSources(ScriptParser Parser, out SourceDefinition Source)
        {
            if (!TryParseSource(Parser, out Source))
            {
                return(false);
            }

            while (true)
            {
                string s = Parser.PeekNextToken().ToUpper();

                switch (s)
                {
                case ",":
                    Parser.NextToken();
                    if (!TryParseSource(Parser, out SourceDefinition Source2))
                    {
                        return(false);
                    }

                    Source = new CrossJoin(Source, Source2, Source.Start, Parser.Position - Source.Start, Parser.Expression);
                    break;

                case "INNER":
                case "JOIN":
                    Parser.NextToken();

                    if (s == "INNER")
                    {
                        if (Parser.NextToken().ToUpper() != "JOIN")
                        {
                            return(false);
                        }
                    }

                    if (!TryParseSource(Parser, out Source2))
                    {
                        return(false);
                    }

                    ScriptNode Conditions = ParseJoinConditions(Parser);
                    Source = new InnerJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression);
                    break;

                case "LEFT":
                    Parser.NextToken();

                    switch (Parser.NextToken().ToUpper())
                    {
                    case "JOIN":
                        break;

                    case "OUTER":
                        if (Parser.NextToken().ToUpper() != "JOIN")
                        {
                            return(false);
                        }
                        break;

                    default:
                        return(false);
                    }

                    if (!TryParseSource(Parser, out Source2))
                    {
                        return(false);
                    }

                    Conditions = ParseJoinConditions(Parser);
                    Source     = new LeftOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression);
                    break;

                case "RIGHT":
                    Parser.NextToken();

                    switch (Parser.NextToken().ToUpper())
                    {
                    case "JOIN":
                        break;

                    case "OUTER":
                        if (Parser.NextToken().ToUpper() != "JOIN")
                        {
                            return(false);
                        }
                        break;

                    default:
                        return(false);
                    }

                    if (!TryParseSource(Parser, out Source2))
                    {
                        return(false);
                    }

                    Conditions = ParseJoinConditions(Parser);
                    Source     = new RightOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression);
                    break;

                case "FULL":
                    Parser.NextToken();

                    switch (Parser.NextToken().ToUpper())
                    {
                    case "JOIN":
                        break;

                    case "OUTER":
                        if (Parser.NextToken().ToUpper() != "JOIN")
                        {
                            return(false);
                        }
                        break;

                    default:
                        return(false);
                    }

                    if (!TryParseSource(Parser, out Source2))
                    {
                        return(false);
                    }

                    Conditions = ParseJoinConditions(Parser);
                    Source     = new FullOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression);
                    break;

                case "OUTER":
                    Parser.NextToken();

                    if (Parser.NextToken().ToUpper() != "JOIN")
                    {
                        return(false);
                    }

                    if (!TryParseSource(Parser, out Source2))
                    {
                        return(false);
                    }

                    Conditions = ParseJoinConditions(Parser);
                    Source     = new FullOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression);
                    break;

                default:
                    return(true);
                }
            }
        }
示例#17
0
		public void inner_join(InnerJoin ij)
		{
			base.GetGenerator().inner_join(ij);
		}
示例#18
0
        /// <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);
                }
                }
            }
        }
示例#19
0
        private void JoinClause()
        {
            // Large set of defaults for joins.
            // This is where we start to think about moving some
            // parsing into the individual elements, esp. since
            // the responsibility for executing the query is
            // delegated to the executive.
            do
            {
                Join j = null;
                Join.OrientationType orientation = Join.OrientationType.Left;

                if (tokenizer.Token == "LEFT")
                {
                    orientation = Join.OrientationType.Left;
                    tokenizer.Match("LEFT");
                }

                if (tokenizer.Token == "RIGHT")
                {
                    orientation = Join.OrientationType.Right;
                    tokenizer.Match("RIGHT");
                }

                if (tokenizer.Token == "JOIN")
                {
                    tokenizer.Match("JOIN");
                    j = new InnerJoin();
                }

                if (tokenizer.Token == "INNER")
                {
                    tokenizer.Match("INNER");
                    tokenizer.Match("JOIN");
                    j = new InnerJoin();
                }

                if (tokenizer.Token == "OUTER")
                {
                    tokenizer.Match("OUTER");
                    tokenizer.Match("JOIN");
                    j = new OuterJoin();
                }

                j.Orientation = orientation;
                j.TableName = tokenizer.Token;
                tokenizer.GetToken();

                tokenizer.Match("ON");
                j.LeftField = tokenizer.Token;
                tokenizer.GetToken();
                tokenizer.Match("=");
                j.RightField = tokenizer.Token;
                tokenizer.GetToken();
                ((SelectQuery)this.Query).Joins.Add(j);
            } while (tokenizer.Token == "JOIN" ||
                    tokenizer.Token == "LEFT" ||
                    tokenizer.Token == "RIGHT" ||
                    tokenizer.Token == "INNER" ||
                    tokenizer.Token == "OUTER");
        }
示例#20
0
		public void inner_join(InnerJoin ij)
		{
			m_inner_join = ij;
		}
示例#21
0
 public void inner_join(InnerJoin ij)
 {
     m_inner_join = ij;
 }
示例#22
0
		public void inner_join(InnerJoin ij)
		{
			m_stroker.inner_join(ij);
		}
 private void AddJoin(InnerJoin item)
 {
     AddJoin(item, JoinOperator.Inner);
 }
 protected override void VisitInnerJoin(InnerJoin item)
 {
     this.AddJoin(item);
 }
示例#25
0
 public virtual void Visit(InnerJoin node)
 {
     VisitInternal(node.LeftTableRef);
     VisitInternal(node.OnCond);
     VisitInternal(node.RightTableRef);
 }
        public IEnumerable <object> ToList <TReturn>(Expression <Func <TEntity, TReturn> > expression)
        {
            var code = expression.GetHashCode();

            if (SelectHandler == null)
            {
                SelectHandler = SqlHandler.Select <TEntity>();
            }
            var type = typeof(TReturn);

            if (!JoinExpressionMapping.Contains(code))
            {
                var           nclass = NClass.DefaultDomain().Public();
                StringBuilder script = new StringBuilder();
                // 获取构造函数参数
                var arguments = ((NewExpression)expression.Body).Arguments;
                //获取匿名类成员
                var members             = ((NewExpression)expression.Body).Members;
                var joinTypeFlagMapping = new Dictionary <Type, JoinTypeFlag>();
                for (int i = 0; i < arguments.Count; i++)
                {
                    // 方法类型参数
                    if (arguments[i].NodeType == ExpressionType.Call)
                    {
                        var methodExpression    = (MethodCallExpression)arguments[i];
                        var methodDeclaringType = methodExpression.Method.DeclaringType;
                        if (methodDeclaringType.IsGenericType && methodDeclaringType.GetGenericTypeDefinition().Name.Contains("Join"))
                        {
                            var joinType = methodDeclaringType.GetGenericArguments()[0];
                            if (methodExpression.Arguments[0].NodeType == ExpressionType.Quote)
                            {
                                var quoteExpression = (UnaryExpression)methodExpression.Arguments[0];
                                if (quoteExpression.Operand.NodeType == ExpressionType.Lambda)
                                {
                                    var lambdaExpression = (LambdaExpression)quoteExpression.Operand;
                                    if (lambdaExpression.Body.NodeType == ExpressionType.MemberAccess)
                                    {
                                        var memberExpression = (MemberExpression)lambdaExpression.Body;
                                        nclass.Property(item => item
                                                        .Public()
                                                        .Type(((PropertyInfo)memberExpression.Member).PropertyType)
                                                        .Name(memberExpression.Member.Name));

                                        var definitionType = methodDeclaringType.GetGenericTypeDefinition();
                                        if (definitionType == typeof(InnerJoin <>))
                                        {
                                            joinTypeFlagMapping[joinType] = JoinTypeFlag.Inner;
                                            script.Append(InnerJoin.GetJoinScript(joinType));
                                        }
                                        else if (definitionType == typeof(LeftJoin <>))
                                        {
                                            joinTypeFlagMapping[joinType] = JoinTypeFlag.Left;
                                            script.Append(LeftJoin.GetJoinScript(joinType));
                                        }
                                        else if (definitionType == typeof(RightJoin <>))
                                        {
                                            joinTypeFlagMapping[joinType] = JoinTypeFlag.Right;
                                            script.Append(RightJoin.GetJoinScript(joinType));
                                        }
                                        script.Append($".\"{memberExpression.Member.Name}\" AS \"{members[i].Name}\",");
                                    }
                                }
                            }
                        }
                    }
                    else if (arguments[i].NodeType == ExpressionType.MemberAccess)
                    {
                        var memberExpression = (MemberExpression)arguments[i];
                        nclass.Property(item => item
                                        .Public()
                                        .Type(((PropertyInfo)memberExpression.Member).PropertyType)
                                        .Name(memberExpression.Member.Name));
                        script.Append($"a.\"{memberExpression.Member.Name}\",");
                    }
                    //JoinObjectCache<ISelect<T>, TReturn>.GetObjects = NDelegate.RandomDomain().Func<ISelect<T>, object>(builder.ToString());
                }
                if (script.Length > 1)
                {
                    script.Length -= 1;
                    var joinScript = script.ToString();
                    JoinExpressionMapping = JoinExpressionMapping.Add(code);

                    var tempClass = nclass.GetType();
                    ProxyCaller <TEntity, TReturn> .Add(code, NDelegate
                                                        .DefaultDomain(item => item.LogSyntaxError())
                                                        .Func <ISelect <TEntity>, IEnumerable <object> >($"return arg.ToList<{tempClass.GetDevelopName()}>(\"{joinScript.Replace("\"","\\\"")}\");"));

                    var builder = new StringBuilder();
                    foreach (var item in joinTypeFlagMapping)
                    {
                        var    joinFieldCache = OrmNavigate <TEntity> .JoinScriptMapping[item.Key];
                        string joinAlias      = string.Empty;
                        switch (item.Value)
                        {
                        case JoinTypeFlag.Left:
                            joinAlias = LeftJoin.GetJoinScript(item.Key);
                            builder.Append($"obj.LeftJoin(\"");
                            break;

                        case JoinTypeFlag.Inner:
                            joinAlias = InnerJoin.GetJoinScript(item.Key);
                            builder.Append($"obj.InnerJoin(\"");
                            break;

                        case JoinTypeFlag.Right:
                            joinAlias = RightJoin.GetJoinScript(item.Key);
                            builder.Append($"obj.RightJoin(\"");
                            break;

                        default:
                            break;
                        }
                        var joinFieldScript = $"\"{item.Key.Name}\" AS {joinAlias} ON a.\"{joinFieldCache.src}\" = {joinAlias}.\"{joinFieldCache.dst}\"";
                        builder.Append(joinFieldScript.Replace("\"", "\\\""));
                        builder.AppendLine("\");");
                    }

                    //$"\"{typeof(TJoinEntity).Name}\" AS {InnerJoinHelper<TJoinEntity>.JoinAliasName} ON a.\"{srcFieldName}\" = {InnerJoinHelper<TJoinEntity>.JoinAliasName}.\"{destFieldName}\"")
                    JoinFiller <TEntity, TReturn> .Add(code, NDelegate
                                                       .DefaultDomain()
                                                       .Action <ISelect <TEntity> >(builder.ToString()));
                }
            }

            JoinFiller <TEntity, TReturn> .HandlerSelect(code, SelectHandler);

            return(ProxyCaller <TEntity, TReturn> .ToList(code, SelectHandler));
        }
示例#27
0
 protected override void SetupJoinConditions()
 {
     InnerJoin
     .Left("Id")
     .Right("Id");
 }
示例#28
0
 public void inner_join(InnerJoin ij)
 {
     base.GetGenerator().inner_join(ij);
 }
示例#29
0
 public void inner_join(InnerJoin ij)
 {
     m_stroker.inner_join(ij);
 }
示例#30
0
        private void JoinClause()
        {
            // Large set of defaults for joins.
            // This is where we start to think about moving some
            // parsing into the individual elements, esp. since
            // the responsibility for executing the query is
            // delegated to the executive.
            do
            {
                Join j = null;
                Join.OrientationType orientation = Join.OrientationType.Left;

                if (tokenizer.Token == "LEFT")
                {
                    orientation = Join.OrientationType.Left;
                    tokenizer.Match("LEFT");
                }

                if (tokenizer.Token == "RIGHT")
                {
                    orientation = Join.OrientationType.Right;
                    tokenizer.Match("RIGHT");
                }

                if (tokenizer.Token == "JOIN")
                {
                    tokenizer.Match("JOIN");
                    j = new InnerJoin();
                }

                if (tokenizer.Token == "INNER")
                {
                    tokenizer.Match("INNER");
                    tokenizer.Match("JOIN");
                    j = new InnerJoin();
                }

                if (tokenizer.Token == "OUTER")
                {
                    tokenizer.Match("OUTER");
                    tokenizer.Match("JOIN");
                    j = new OuterJoin();
                }

                j.Orientation = orientation;
                j.TableName   = tokenizer.Token;
                tokenizer.GetToken();

                tokenizer.Match("ON");
                j.LeftField = tokenizer.Token;
                tokenizer.GetToken();
                tokenizer.Match("=");
                j.RightField = tokenizer.Token;
                tokenizer.GetToken();
                ((SelectQuery)this.Query).Joins.Add(j);
            } while (tokenizer.Token == "JOIN" ||
                     tokenizer.Token == "LEFT" ||
                     tokenizer.Token == "RIGHT" ||
                     tokenizer.Token == "INNER" ||
                     tokenizer.Token == "OUTER");
        }