public void ShouldResolveUpdateStatementWithAliasTarget()
        {
            //Arrange
            string rawTsql = "update GL " +
                             "set somevalue = nil.col_01, someOtherValue = gl.col_02 " +
                             "from [SOME_table] nil " +
                             "inner join [dbo].[TABLE_02] GL";

            IDataManipulationResolver resolver = new UpdateStatementResolver();
            int                      fileIndex = 0;
            CompilerContext          context   = new CompilerContext("xUnit", "stdserver", "stdDatabase", true);
            ReadOnlySpan <TSQLToken> tokens    = TSQLTokenizer.ParseTokens(rawTsql).ToArray();

            //Act
            DataManipulation statement = resolver.Resolve(tokens, ref fileIndex, context);

            //Assert
            Assert.Equal(tokens.Length, fileIndex);
            Assert.Equal(ExpressionType.COLUMN, statement.Expressions[0].Type);
            Assert.Equal("stdDatabase.dbo.TABLE_02.somevalue", statement.Expressions[0].Name);
            Assert.Equal("stdDatabase.unrelated.SOME_table.col_01", statement.Expressions[0].ChildExpressions[0].Name);
            Assert.Equal(ExpressionType.COLUMN, statement.Expressions[1].Type);
            Assert.Equal("stdDatabase.dbo.TABLE_02.someOtherValue", statement.Expressions[1].Name);
            Assert.Equal("stdDatabase.dbo.TABLE_02.col_02", statement.Expressions[1].ChildExpressions[0].Name);
        }
        public void ShouldResolveUpdateStatement()
        {
            //Arrange
            string rawTsql = "update someFactTable " +
                             "set somecolumn = nil.col_01, someOtherColumn = [dbo].gl.col_02 " +
                             "from DWH_DB.[dbo].[someFactTable]";

            IDataManipulationResolver resolver = new UpdateStatementResolver();
            int                      fileIndex = 0;
            CompilerContext          context   = new CompilerContext("xUnit", "stdserver", "stdDatabase", true);
            ReadOnlySpan <TSQLToken> tokens    = TSQLTokenizer.ParseTokens(rawTsql).ToArray();

            //Act
            DataManipulation statement = resolver.Resolve(tokens, ref fileIndex, context);

            //Assert
            Assert.Equal(tokens.Length, fileIndex);
            Assert.Equal(2, statement.Expressions.Count);
            Assert.Equal(ExpressionType.COLUMN, statement.Expressions[0].Type);
            Assert.Equal("DWH_DB.dbo.someFactTable.somecolumn", statement.Expressions[0].Name);
            Assert.Equal("stdDatabase.unrelated.nil.col_01", statement.Expressions[0].ChildExpressions[0].Name);
            Assert.Equal(ExpressionType.COLUMN, statement.Expressions[1].Type);
            Assert.Equal("DWH_DB.dbo.someFactTable.someOtherColumn", statement.Expressions[1].Name);
            Assert.Equal("stdDatabase.dbo.gl.col_02", statement.Expressions[1].ChildExpressions[0].Name);
        }
        public void ShouldResolveUpdateStatementWithRecursiveExpressions()
        {
            //Arrange
            string rawTsql = "update alias1 " +
                             "set alias1.tIsLastRecord = case when alias2.tValidUntil is Null THEN 0 ELSE alias2.tValidUntil END " +
                             "from Stage_DB.dbo.someTable as alias1 " +
                             "join (SELECT * from someOtherTable) alias2 on alias1.col13 = alias2.col37";

            IDataManipulationResolver resolver = new UpdateStatementResolver();
            int                      fileIndex = 0;
            CompilerContext          context   = new CompilerContext("xUnit", "stdserver", "stdDatabase", true);
            ReadOnlySpan <TSQLToken> tokens    = TSQLTokenizer.ParseTokens(rawTsql).ToArray();

            //Act
            DataManipulation statement = resolver.Resolve(tokens, ref fileIndex, context);

            //Assert
            Assert.Equal(tokens.Length, fileIndex);
            Assert.Equal(ExpressionType.COLUMN, statement.Expressions[0].Type);
            Assert.Equal("Stage_DB.dbo.someTable.tIsLastRecord", statement.Expressions[0].Name);
            Assert.Single(statement.Expressions[0].ChildExpressions);
            Assert.Equal("stdDatabase.unrelated.someOtherTable.tValidUntil", statement.Expressions[0].ChildExpressions[0].Name);
        }
Exemple #4
0
        internal void AnalyzeTSQLContentString(string tsqlContent, CompilerContext context)
        {
            List <TSQLToken>         tokensWithComments = TSQLTokenizer.ParseTokens(tsqlContent);
            ReadOnlySpan <TSQLToken> tokens             = FormatTokenList(tokensWithComments);

            int fileIndex = 0;

            while (fileIndex < tokens.Length)
            {
                IDataManipulationResolver manipulationResolver;
                DataManipulation          manipulation;

                switch (tokens[fileIndex].Text.ToLower())
                {
                case "use":
                    new UseStatementResolver().ResolveUseStatement(tokens, ref fileIndex, context);
                    break;

                //case "declare":
                //    new VariableDeclarationResolver().Resolve(tokens, ref fileIndex, context);
                //    break;
                //case "set":
                //    gic.AssignVariableValue(tokens, ref fileIndex);
                //    break;
                case "with":
                    var withResolver = new WithStatementResolver();
                    withResolver.Resolve(tokens, ref fileIndex, context);
                    break;

                case "merge":
                    manipulationResolver = new MergeStatementResolver();
                    manipulation         = manipulationResolver.Resolve(tokens, ref fileIndex, context);
                    context.DataManipulations.Add(manipulation);
                    context.DropCommonTableExpressions();
                    break;

                case "bulk":
                    var bulkStatementResolver = new BulkInsertStatementResolver();
                    bulkStatementResolver.Resolve(tokens, ref fileIndex, context);
                    break;

                case "insert":
                    manipulationResolver = new InsertStatementResolver();
                    manipulation         = manipulationResolver.Resolve(tokens, ref fileIndex, context);
                    context.DataManipulations.Add(manipulation);
                    context.DropCommonTableExpressions();
                    break;

                case "update":
                    manipulationResolver = new UpdateStatementResolver();
                    manipulation         = manipulationResolver.Resolve(tokens, ref fileIndex, context);
                    context.DataManipulations.Add(manipulation);
                    context.DropCommonTableExpressions();
                    break;

                case "select":
                    SelectStatementResolver selectResolver = new SelectStatementResolver();
                    SelectStatement         statement      = selectResolver.ResolveTopLevel(tokens, ref fileIndex, context);
                    if (statement.TargetObject == null)
                    {
                        if (context.ConsiderQueries)
                        {
                            context.DataQueries.Add(statement.Expression);
                        }
                    }
                    else
                    {
                        context.AddSelectWithIntoClause(statement);
                    }

                    context.DropCommonTableExpressions();
                    break;

                //case "drop":
                //    gic.ResolveDropStatement(tokens, ref fileIndex, causer);
                //    break;
                case "create":
                    new CreateStatementResolver().Resolve(tokens, ref fileIndex, context);
                    break;

                //case "exec":*
                //case "execute": throw new NotImplementedException("Execute statements are no supported yet");
                default:
                    fileIndex++;
                    break;
                }
            }

            result.DataQueries       = context.DataQueries;
            result.DataManipulations = context.DataManipulations;
        }