Пример #1
0
        private void VisitCorrelationStatement(CorrelationStatement statement, string functionName)
        {
            SelectStatement statement1 = (SelectStatement)statement.First;
            SelectStatement statement2 = (SelectStatement)statement.Second;

            if (((statement1.From.Count != 1) && (!(statement1.From[0].Source is Name))) ||
                ((statement2.From.Count != 1) && (!(statement2.From[0].Source is Name))))
            {
                throw new NotImplementedException();
            }
            else if ((statement1.Output.Count != statement2.Output.Count) && (statement1.Output.Count == 0))
            {
                throw new NotImplementedException();
            }

            string table1 = ((Name)(statement1.From[0].Source)).LastPart;
            string table2 = ((Name)(statement2.From[0].Source)).LastPart;

            ExpressionToken        whereExpression = null;
            List <ExpressionToken> expressions1    = new List <ExpressionToken>();
            List <ExpressionToken> expressions2    = new List <ExpressionToken>();

            for (int i = 0; i < statement1.Output.Count; i++)
            {
                if ((!(statement1.Output[i] is Name)) && (!(statement2.Output[i] is Name)))
                {
                    throw new NotImplementedException();
                }
                expressions1.Add(Sql.Name(table1, ((Name)(statement1.Output[i])).LastPart));
                expressions2.Add(Sql.Name(table2, ((Name)(statement2.Output[i])).LastPart));
                if (whereExpression == null)
                {
                    whereExpression = expressions1[i].IsEqual(expressions2[i]);
                }
                else
                {
                    whereExpression = whereExpression.And(expressions1[i].IsEqual(expressions2[i]));
                }
            }
            if (statement2.Where != null)
            {
                whereExpression = whereExpression.And(AddPrefixToExpressionToken(((ExpressionToken)statement2.Where), table2));
            }

            ExpressionToken tempExpression = Sql.Function(functionName, Sql.Select.From(table2).Where(whereExpression));

            if (statement1.Where != null)
            {
                tempExpression = tempExpression.And(AddPrefixToExpressionToken(((ExpressionToken)statement1.Where), table1));
            }

            SelectStatement correlationStatement =
                Sql.Select.Output(expressions1).From(table1)
                .Where(tempExpression);

            VisitStatement(correlationStatement);
        }
Пример #2
0
        protected void VisitWhenNotMatchedBySourceToken(MergeStatement statement
                                                        , string targetAlias
                                                        , string targetTable
                                                        , string targetColumnOn
                                                        , string sourceAlias
                                                        , string sourceTable
                                                        , string sourceColumnOn
                                                        , bool isTop
                                                        )
        {
            ExpressionToken tempExpression = new ExpressionToken();

            if (statement.WhenNotMatchedBySource.Count != 0)
            {
                foreach (WhenMatchedToken item in statement.WhenNotMatchedBySource)
                {
                    tempExpression = Sql.Name(targetAlias, targetColumnOn)
                                     .NotIn(Sql.Select.Output(sourceColumnOn).From(sourceTable));

                    if (item.AndCondition != null)
                    {
                        if (item.AndCondition is BinaryToken)
                        {
                            ((BinaryToken)item.AndCondition).First = Sql.Name(targetAlias, ((Name)((BinaryToken)item.AndCondition).First).LastPart);
                        }
                        else if (item.AndCondition is UnaryToken)
                        {
                            ((UnaryToken)item.AndCondition).Token = Sql.Name(targetAlias, ((Name)((UnaryToken)item.AndCondition).Token).LastPart);
                        }
                        tempExpression = tempExpression.And((ExpressionToken)item.AndCondition);
                    }

                    if (isTop)
                    {
                        tempExpression = tempExpression.And(Sql.Name(targetAlias, targetColumnOn)
                                                            .In(Sql.Select.Output(sourceColumnOn).From(TopAlias)));
                    }

                    DeleteStatement whenNotMatchedBySourceDelete =
                        Sql.Delete.From(Sql.NameAs(targetTable, targetAlias))
                        .Where(tempExpression);

                    VisitStatement(whenNotMatchedBySourceDelete);
                    State.WriteStatementTerminator();
                }
            }
        }
Пример #3
0
        protected void VisitWhenNotMatchedThenInsertToken(MergeStatement statement
                                                          , IList <string> tempUpdateAliases
                                                          , string targetAlias
                                                          , string targetColumnOn
                                                          , string targetTable
                                                          , string sourceAlias
                                                          , string sourceTable
                                                          , string sourceColumnOn)
        {
            ExpressionToken tempExpression = new ExpressionToken();

            if (statement.WhenNotMatched.Count != 0)
            {
                int counter = 0;

                foreach (WhenMatchedToken item in statement.WhenNotMatched)
                {
                    IList <CTEDefinition> tmpSourceList = new List <CTEDefinition>();

                    tempExpression = Sql.Name(sourceAlias, sourceColumnOn)
                                     .NotIn(Sql.Select.Output(targetColumnOn).From(targetTable));

                    if (item.AndCondition != null)
                    {
                        if (item.AndCondition is BinaryToken)
                        {
                            ((BinaryToken)item.AndCondition).First = Sql.Name(sourceAlias, ((Name)((BinaryToken)item.AndCondition).First).LastPart);
                        }
                        else if (item.AndCondition is UnaryToken)
                        {
                            ((UnaryToken)item.AndCondition).Token = Sql.Name(sourceAlias, ((Name)((UnaryToken)item.AndCondition).Token).LastPart);
                        }
                        tempExpression = tempExpression.And((ExpressionToken)item.AndCondition);
                    }

                    CTEDefinition source = Sql.With(sourceAlias).As(
                        Sql.Select.From(Sql.NameAs(sourceTable, sourceAlias)).Where(tempExpression));
                    tmpSourceList.Add(source);


                    InsertStatement insertStatement = Sql.Insert.Into(targetTable);

                    if ((((WhenNotMatchedTokenThenInsertToken)item).Values.Count == 0) ||
                        (((WhenNotMatchedTokenThenInsertToken)item).Columns.Count == 0) ||
                        (((WhenNotMatchedTokenThenInsertToken)item).Columns.Count != ((WhenNotMatchedTokenThenInsertToken)item).Values.Count))
                    {
                        insertStatement.Columns.Add(targetColumnOn);
                        insertStatement.From(Sql.Select.From(sourceAlias).Output(sourceColumnOn));
                    }
                    else
                    {
                        foreach (Name columnName in ((WhenNotMatchedTokenThenInsertToken)item).Columns)
                        {
                            insertStatement.Columns.Add(Sql.Name(columnName.LastPart));
                        }
                        SelectStatement fromSelect = Sql.Select.From(sourceAlias);
                        foreach (Token outputColumn in ((WhenNotMatchedTokenThenInsertToken)item).Values)
                        {
                            fromSelect.Output.Add(Sql.Name(((Name)outputColumn).LastPart));
                        }
                        insertStatement.From(fromSelect);
                    }

                    VisitCommonTableExpressions(tmpSourceList);
                    VisitStatement(insertStatement);

                    State.WriteStatementTerminator();

                    InsertStatement whenNotMatchedInsert =
                        Sql.Insert.Into(Sql.Name(targetTable))
                        .From(Sql.Select.From(Sql.Name(sourceAlias))
                              .Where(tempExpression));

                    counter++;
                }
            }
        }
Пример #4
0
        protected void VisitWhenMatchedDeleteToken(MergeStatement statement
                                                   , string targetAlias
                                                   , string targetTable
                                                   , string targetColumnOn
                                                   , string sourceAlias
                                                   , string sourceTable
                                                   , string sourceColumnOn
                                                   , bool isTop)
        {
            ExpressionToken tempExpression = new ExpressionToken();

            if (statement.WhenMatched != null)
            {
                foreach (WhenMatchedToken item in statement.WhenMatched)
                {
                    bool            isTargetCondition = true;
                    SelectStatement sourceSelect      = Sql.Select.Output(sourceColumnOn).From(sourceTable);

                    if (item.AndCondition != null)
                    {
                        if ((item.AndCondition is BinaryToken) &&
                            (
                                (((Name)((BinaryToken)item.AndCondition).First).FirstPart == sourceAlias) ||
                                ((Name)((BinaryToken)item.AndCondition).First).FirstPart == sourceTable)
                            )
                        {
                            ((BinaryToken)item.AndCondition).First = Sql.Name(sourceTable, ((Name)((BinaryToken)item.AndCondition).First).LastPart);
                            sourceSelect.Where((BinaryToken)item.AndCondition);
                            isTargetCondition = false;
                        }

                        else if ((item.AndCondition is UnaryToken) &&
                                 (
                                     (((Name)((UnaryToken)item.AndCondition).Token).FirstPart == sourceAlias) ||
                                     (((Name)((UnaryToken)item.AndCondition).Token).FirstPart == sourceTable)
                                 )
                                 )
                        {
                            ((UnaryToken)item.AndCondition).Token = Sql.Name(sourceTable, ((Name)((UnaryToken)item.AndCondition).Token).LastPart);
                            sourceSelect.Where((UnaryToken)item.AndCondition);
                            isTargetCondition = false;
                        }
                    }
                    tempExpression = Sql.Name(targetAlias, targetColumnOn)
                                     .In(sourceSelect);

                    if ((item.AndCondition != null) && isTargetCondition)
                    {
                        if (item.AndCondition is BinaryToken)
                        {
                            ((BinaryToken)item.AndCondition).First = Sql.Name(targetAlias, ((Name)((BinaryToken)item.AndCondition).First).LastPart);
                        }
                        else if (item.AndCondition is UnaryToken)
                        {
                            ((UnaryToken)item.AndCondition).Token = Sql.Name(targetAlias, ((Name)((UnaryToken)item.AndCondition).Token).LastPart);
                        }
                        tempExpression = tempExpression.And((ExpressionToken)item.AndCondition);
                    }

                    if (isTop)
                    {
                        tempExpression = tempExpression.And(Sql.Name(targetAlias, targetColumnOn)
                                                            .In(Sql.Select.Output(sourceColumnOn).From(TopAlias)));
                    }

                    if ((item is WhenMatchedTokenThenDeleteToken))
                    {
                        DeleteStatement deleteStatement = Sql.Delete.From(Sql.NameAs(targetTable, targetAlias))
                                                          .Where(tempExpression);
                        VisitStatement(deleteStatement);
                        State.WriteStatementTerminator();
                    }
                }
            }
        }
Пример #5
0
        protected void VisitWhenMatchedUpdateToken(MergeStatement statement
                                                   , IList <string> tempUpdateAliases
                                                   , string targetAlias
                                                   , string targetTable
                                                   , string targetColumnOn
                                                   , string sourceAlias
                                                   , string sourceTable
                                                   , string sourceColumnOn
                                                   , bool isTop)
        {
            int             counter        = 0;
            ExpressionToken tempExpression = new ExpressionToken();

            if (statement.WhenMatched != null)
            {
                foreach (WhenMatchedToken item in statement.WhenMatched)
                {
                    if (!(item is WhenMatchedTokenThenDeleteToken))
                    {
                        IList <CTEDefinition> updatedList = new List <CTEDefinition>();
                        string tempAlias = "tmp_" + counter;

                        tempExpression = (IsEqualsToken)(statement.On);

                        if (((WhenMatchedTokenThenUpdateSetToken)item).Set.Count != 0)
                        {
                            foreach (BinaryEqualToken setItem in ((WhenMatchedTokenThenUpdateSetToken)item).Set)
                            {
                                if (setItem.First is Name)
                                {
                                    setItem.First = Sql.Name(((Name)setItem.First).LastPart);
                                }

                                if (setItem.Second is Name)
                                {
                                    setItem.Second = Sql.Name(sourceAlias, ((Name)setItem.Second).LastPart);
                                }
                            }
                        }

                        if (item.AndCondition != null)
                        {
                            if (item.AndCondition is BinaryToken)
                            {
                                ((BinaryToken)item.AndCondition).First = Sql.Name(targetAlias, ((Name)((BinaryToken)item.AndCondition).First).LastPart);
                            }
                            else if (item.AndCondition is UnaryToken)
                            {
                                ((UnaryToken)item.AndCondition).Token = Sql.Name(targetAlias, ((Name)((UnaryToken)item.AndCondition).Token).LastPart);
                            }
                            tempExpression = tempExpression.And((ExpressionToken)item.AndCondition);
                        }

                        if (isTop)
                        {
                            tempExpression = tempExpression.And(Sql.Name(targetAlias, targetColumnOn)
                                                                .In(Sql.Select.Output(sourceColumnOn).From(TopAlias)));
                        }

                        CreateTableStatement createTempTable =
                            Sql.CreateTemporaryTable(tempAlias)
                            .As(Sql.With("updated").As(
                                    Sql.Update(Sql.NameAs(targetTable, targetAlias))
                                    .Set(((WhenMatchedTokenThenUpdateSetToken)item).Set)
                                    .From(Sql.NameAs(sourceTable, sourceAlias))
                                    .Where(tempExpression)
                                    .Output(Sql.Name(targetAlias, targetColumnOn)))
                                .Select().From("updated").Output(targetColumnOn));

                        VisitStatement(createTempTable);
                        State.WriteStatementTerminator();

                        tempUpdateAliases.Add(tempAlias);

                        counter++;
                        State.WriteStatementTerminator();
                    }
                }
            }
        }
Пример #6
0
        private void VisitCorrelationStatement(CorrelationStatement statement, string functionName)
        {
            SelectStatement statement1 = (SelectStatement)statement.First;
            SelectStatement statement2 = (SelectStatement)statement.Second;

            if (((statement1.From.Count != 1) && (!(statement1.From[0].Source is Name))) ||
                ((statement2.From.Count != 1) && (!(statement2.From[0].Source is Name))))
            {
                throw new NotImplementedException();
            }
            else if ((statement1.Output.Count != statement2.Output.Count) && (statement1.Output.Count == 0))
            {
                throw new NotImplementedException();
            }

            string table1          = ((Name)(statement1.From[0].Source)).LastPart;
            string table2          = ((Name)(statement2.From[0].Source)).LastPart;
            var    table1Name      = ((Name)(statement1.From[0].Source));
            var    table2Name      = ((Name)(statement2.From[0].Source));
            var    statement1Alias = statement1.Alias;

            //here we have 2 possible cases
            //case 1) table1Name equals table2Name
            // In this case "EXIST" statement will not work properly.To fix that,  first statement, including it's own "WHERE" expression
            //should be placed inside subquery with alias
            //case 2) table1Name not equal table2Name
            // in this case it is not nessesary to use subquery for first statement. Just place  WHERE clause to EXIST part
            var isSameTableMode = string.Equals($"{table1Name.FirstPart}.{table1Name.LastPart}"
                                                , $"{table2Name.FirstPart}.{table2Name.LastPart}"
                                                , StringComparison.OrdinalIgnoreCase);

            ExpressionToken        whereExpression = null;
            List <ExpressionToken> expressions1    = new List <ExpressionToken>();
            List <ExpressionToken> expressions2    = new List <ExpressionToken>();

            for (int i = 0; i < statement1.Output.Count; i++)
            {
                if ((!(statement1.Output[i] is Name)) && (!(statement2.Output[i] is Name)))
                {
                    throw new NotImplementedException();
                }

                Name name1 = null;

                if (isSameTableMode)
                {
                    // use alias of first statements since we will use subquery for it
                    name1 = Sql.Name(statement1Alias, ((Name)(statement1.Output[i])).Alias).As(((Name)(statement1.Output[i])).Alias);
                }
                else
                {
                    //use table name or alias directly
                    if (!string.IsNullOrWhiteSpace(table1Name.Alias))
                    {
                        name1 = Sql.Name(table1Name.Alias, ((Name)(statement1.Output[i])).LastPart).As(((Name)(statement1.Output[i])).Alias);
                    }
                    else
                    {
                        name1 = Sql.Name(table1Name.FirstPart, table1Name.LastPart, ((Name)(statement1.Output[i])).LastPart).As(((Name)(statement1.Output[i])).Alias);
                    }
                }

                expressions1.Add(name1);

                if (!string.IsNullOrWhiteSpace(table2Name.Alias))
                {
                    expressions2.Add(Sql.Name(table2Name.Alias, ((Name)(statement2.Output[i])).LastPart).As(((Name)(statement2.Output[i])).Alias));
                }
                else
                {
                    expressions2.Add(Sql.Name(table2Name.FirstPart, table2Name.LastPart, ((Name)(statement2.Output[i])).LastPart).As(((Name)(statement2.Output[i])).Alias));
                }

                if (whereExpression == null)
                {
                    whereExpression = expressions1[i].IsEqual(expressions2[i]);
                }
                else
                {
                    whereExpression = whereExpression.And(expressions1[i].IsEqual(expressions2[i]));
                }
            }

            if (statement2.Where != null)
            {
                whereExpression = whereExpression.And(AddPrefixToExpressionToken(((ExpressionToken)statement2.Where), table2Name.LastPart));
            }

            ExpressionToken tempExpression = Sql.Function(functionName, Sql.Select.From(table2Name).Where(whereExpression));

            if (statement1.Where != null && !isSameTableMode)
            {
                tempExpression = tempExpression.And(AddPrefixToExpressionToken(((ExpressionToken)statement1.Where), table1Name.LastPart));
            }

            SelectStatement correlationStatement = null;

            correlationStatement = isSameTableMode
                ? Sql.Select.Output(expressions1) //case 1
                                   .From(statement1)
                                   .Where(tempExpression)
                : Sql.Select.Output(expressions1) //case 2
                                   .From(table1Name)
                                   .Where(tempExpression);


            VisitStatement(correlationStatement);
        }
Пример #7
0
        protected void VisitWhenMatchedUpdateToken(MergeStatement statement
                                                   , IList <string> tempUpdateAliases
                                                   , string targetAlias
                                                   , string targetTable
                                                   , string targetColumnOn
                                                   , string sourceAlias
                                                   , string sourceTable
                                                   , string sourceColumnOn
                                                   , bool isTop)
        {
            var counter = 0;

            if (statement.WhenMatched != null)
            {
                foreach (var item in statement.WhenMatched)
                {
                    if (!(item is WhenMatchedTokenThenDeleteToken))
                    {
                        var tempTableSelectStatement = Sql.Select.Output(Sql.Name(targetAlias, targetColumnOn))
                                                       .From(targetTable, targetAlias)
                                                       .InnerJoin(Sql.Name(sourceTable).As(sourceAlias), Sql.Name(targetAlias, targetColumnOn).IsEqual(Sql.Name(sourceAlias, sourceColumnOn)));


                        var tempAlias = "tmp_" + counter;

                        ExpressionToken tempExpression = (IsEqualsToken)(statement.On);

                        if (item.AndCondition != null)
                        {
                            tempExpression = tempExpression.And(AddPrefixToExpressionToken((ExpressionToken)item.AndCondition, targetAlias));
                        }

                        if (isTop)
                        {
                            tempExpression = tempExpression.And(Sql.Name(targetAlias, targetColumnOn)
                                                                .In(Sql.Select.Output(sourceColumnOn).From(TopAlias)));
                        }
                        tempTableSelectStatement = tempTableSelectStatement.Where(tempExpression);

                        var createTempTable =
                            Sql.CreateTemporaryTable(tempAlias)
                            .As(tempTableSelectStatement);

                        VisitStatement(createTempTable);
                        State.WriteStatementTerminator();

                        tempUpdateAliases.Add(tempAlias);

                        if (((WhenMatchedTokenThenUpdateSetToken)item).Set.Count != 0)
                        {
                            foreach (var setItem in ((WhenMatchedTokenThenUpdateSetToken)item).Set)
                            {
                                if (setItem.First is Name)
                                {
                                    setItem.First = Sql.Name(targetAlias, ((Name)setItem.First).LastPart);
                                }

                                if (setItem.Second is Name)
                                {
                                    setItem.Second = Sql.Name(sourceAlias, ((Name)setItem.Second).LastPart);
                                }
                            }
                        }

                        var updateTable =
                            Sql.Update(Sql.NameAs(targetTable, targetAlias))
                            .Set(((WhenMatchedTokenThenUpdateSetToken)item).Set)
                            .From(Sql.NameAs(sourceTable, sourceAlias))
                            .Where(tempExpression);

                        counter++;
                        VisitStatement(updateTable);
                        State.WriteStatementTerminator();
                    }
                }
            }
        }
Пример #8
0
        protected void VisitWhenNotMatchedThenInsertToken(MergeStatement statement
                                                          , IList <string> tempUpdateAliases
                                                          , string targetAlias
                                                          , string targetColumnOn
                                                          , string targetTable
                                                          , string sourceAlias
                                                          , string sourceTable
                                                          , string sourceColumnOn)
        {
            string          tempSourceAlias = "tmp_" + sourceAlias;
            ExpressionToken tempExpression  = new ExpressionToken();

            if (statement.WhenNotMatched.Count != 0)
            {
                int counter = 0;

                foreach (WhenMatchedToken item in statement.WhenNotMatched)
                {
                    tempExpression = Sql.Name(sourceAlias, sourceColumnOn)
                                     .NotIn(Sql.Select.Output(targetColumnOn).From(targetTable));

                    if (item.AndCondition != null)
                    {
                        tempExpression = tempExpression.And(AddPrefixToExpressionToken((ExpressionToken)item.AndCondition, sourceAlias));
                    }

                    CreateTableStatement createTempTable =
                        Sql.CreateTemporaryTable(tempSourceAlias)
                        .As(Sql.Select.From(Sql.NameAs(sourceTable, sourceAlias)).Where(tempExpression));

                    VisitStatement(createTempTable);
                    State.WriteStatementTerminator();

                    InsertStatement insertStatement = Sql.Insert.Into(targetTable);

                    if ((((WhenNotMatchedTokenThenInsertToken)item).Values.Count == 0) ||
                        (((WhenNotMatchedTokenThenInsertToken)item).Columns.Count == 0) ||
                        (((WhenNotMatchedTokenThenInsertToken)item).Columns.Count != ((WhenNotMatchedTokenThenInsertToken)item).Values.Count))
                    {
                        insertStatement.Columns.Add(targetColumnOn);
                        insertStatement.From(Sql.Select.From(tempSourceAlias).Output(sourceColumnOn));
                    }
                    else
                    {
                        foreach (Name columnName in ((WhenNotMatchedTokenThenInsertToken)item).Columns)
                        {
                            insertStatement.Columns.Add(Sql.Name(columnName.LastPart));
                        }
                        SelectStatement fromSelect = Sql.Select.From(tempSourceAlias);
                        foreach (Token outputColumn in ((WhenNotMatchedTokenThenInsertToken)item).Values)
                        {
                            fromSelect.Output.Add(Sql.Name(((Name)outputColumn).LastPart));
                        }
                        insertStatement.From(fromSelect);
                    }

                    VisitStatement(insertStatement);
                    State.WriteStatementTerminator();
                    counter++;
                    VisitStatement(Sql.DropTable(tempSourceAlias, true));
                    State.WriteStatementTerminator();
                }
            }
        }