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);
        }
Esempio n. 2
0
        public void TestParseLines()
        {
            string file_string = @"zzz!10,NAV15BEO0Zll
before zzz!11,87NSZSSP4Jll
zzz!12,MZOTXUFT9Tll after
zzz!13,6DFOKC74ZGll
zzz!14,3KZ94GFGLZll
zzz!15,VQTMAXWCDKll";

            string[] expected =
            {
                "10,NAV15BEO0Z",
                "11,87NSZSSP4J",
                "12,MZOTXUFT9T",
                "13,6DFOKC74ZG",
                "14,3KZ94GFGLZ",
                "15,VQTMAXWCDK"
            };

            string           query  = "LOAD DATA LOCAL INFILE 'myfile.txt' INTO TABLE imptest FIELDS TERMINATED BY ',' LINES STARTING BY 'zzz!' TERMINATED BY 'll'";
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens(query);
            LoadDataParser   parser = new LoadDataParser(tokens);

            Assert.AreEqual("zzz!", parser.lines_starting_by);
            Assert.AreEqual("ll", parser.lines_terminated_by);

            string[] actual = ClientSession.ParseLines(file_string, parser);
            foreach (var a in actual)
            {
                Console.WriteLine(a);
            }
            Assert.IsTrue(actual.SequenceEqual(expected));
        }
        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 SelectClause_Comments()
        {
            using (StringReader reader = new StringReader(
                       @"select top 1
					oh.TaxAmt / oh.SubTotal /* tax percent */
				from
					Sales.SalesOrderHeader oh;"                    ))
                using (ITSQLTokenizer tokenizer = new TSQLTokenizer(reader))
                {
                    Assert.IsTrue(tokenizer.MoveNext());

                    TSQLSelectClause select = new TSQLSelectClauseParser().Parse(tokenizer);
                    Assert.AreEqual(11, select.Tokens.Count);
                    Assert.AreEqual(TSQLKeywords.FROM, tokenizer.Current.AsKeyword.Keyword);

                    Assert.AreEqual(1, select.Columns.Count);
                    Assert.IsNull(select.Columns[0].ColumnAlias);
                    Assert.AreEqual(TSQLExpressionType.Operator, select.Columns[0].Expression.Type);

                    TSQLOperatorExpression operatorExpression = select.Columns[0].Expression.AsOperator;
                    Assert.AreEqual("/", operatorExpression.Operator.Text);
                    Assert.AreEqual(TSQLExpressionType.Column, operatorExpression.LeftSide.Type);

                    TSQLColumnExpression leftSide = operatorExpression.LeftSide.AsColumn;
                    Assert.AreEqual("oh", leftSide.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("TaxAmt", leftSide.Column.Name);
                    Assert.AreEqual(TSQLExpressionType.Column, operatorExpression.RightSide.Type);

                    TSQLColumnExpression rightSide = operatorExpression.RightSide.AsColumn;
                    Assert.AreEqual("oh", rightSide.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("SubTotal", rightSide.Column.Name);
                    Assert.AreEqual(" tax percent ", select.Columns.Last().Tokens.Last().AsMultilineComment.Comment);
                }
        }
Esempio n. 5
0
        public TSQLIntoClause Parse(TSQLTokenizer tokenizer)
        {
            TSQLIntoClause into = new TSQLIntoClause();

            if (
                tokenizer.Current == null ||
                tokenizer.Current.Type != TSQLTokenType.Keyword ||
                tokenizer.Current.AsKeyword.Keyword != TSQLKeywords.INTO)
            {
                throw new ApplicationException("INTO expected.");
            }

            into.Tokens.Add(tokenizer.Current);

            while (
                tokenizer.Read() &&
                (
                    tokenizer.Current.Type == TSQLTokenType.Identifier ||
                    (
                        tokenizer.Current.Type == TSQLTokenType.Character &&
                        tokenizer.Current.AsCharacter.Character == TSQLCharacters.Period
                    ) ||
                    tokenizer.Current.Type == TSQLTokenType.Whitespace ||
                    tokenizer.Current.Type == TSQLTokenType.SingleLineComment ||
                    tokenizer.Current.Type == TSQLTokenType.MultilineComment
                ))
            {
                into.Tokens.Add(tokenizer.Current);
            }

            return(into);
        }
Esempio n. 6
0
        public void ShouldResolveRecursiveCaseStatement()
        {
            //Arrange
            string rawTsql = " CASE                                                    " +
                             "   WHEN someValue > anotherValue THEN                    " +
                             "      CASE                                               " +
                             "         WHEN NullIf(val_01,0) IS NULL THEN NULL         " +
                             "         WHEN NullIf(val_02,0) IS NULL THEN Null         " +
                             "         WHEN(100 / val_02 * val_01) <= 100 THEN 'Green' " +
                             "         WHEN 100 + 25 <= 125 THEN 'Yellow'" +
                             "         ELSE 'Red'                                      " +
                             "      END                                                " +
                             "   ELSE                                                  " +
                             "      CASE                                               " +
                             "         WHEN NULLIF(val_03, 0) IS NULL THEN NULL        " +
                             "         WHEN NullIf(val_02,0) IS NULL THEN NULL         " +
                             "         WHEN(100 / val_02 * val_03) <= 100 THEN 'Green' " +
                             "         WHEN(100 / val_02 * val_03) <= 125 THEN 'Yellow'" +
                             "         ELSE 'Red'                                      " +
                             "      END                                                " +
                             " END";

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

            //Act
            Expression expression = resolver.Resolve(tokens, ref fileIndex, context);

            //Assert
            Assert.Equal(tokens.Length, fileIndex);
        }
        public TSQLIntoClause Parse(TSQLTokenizer tokenizer)
        {
            TSQLIntoClause into = new TSQLIntoClause();

            if (
                tokenizer.Current == null ||
                tokenizer.Current.Type != TSQLTokenType.Keyword ||
                tokenizer.Current.AsKeyword.Keyword != TSQLKeywords.INTO)
            {
                throw new ApplicationException("INTO expected.");
            }

            into.Tokens.Add(tokenizer.Current);

            while (
                tokenizer.Read() &&
                (
                    tokenizer.Current.Type == TSQLTokenType.Identifier ||
                    (
                        tokenizer.Current.Type == TSQLTokenType.Character &&
                        tokenizer.Current.AsCharacter.Character == TSQLCharacters.Period
                    ) ||
                    tokenizer.Current.Type == TSQLTokenType.Whitespace ||
                    tokenizer.Current.Type == TSQLTokenType.SingleLineComment ||
                    tokenizer.Current.Type == TSQLTokenType.MultilineComment
                ))
            {
                into.Tokens.Add(tokenizer.Current);
            }

            return into;
        }
        public void SelectClause_UnaryOperator()
        {
            using (StringReader reader = new StringReader(
                       @"SELECT
					+1;"                    ))
                using (ITSQLTokenizer tokenizer = new TSQLTokenizer(reader))
                {
                    Assert.IsTrue(tokenizer.MoveNext());

                    TSQLSelectClause select = new TSQLSelectClauseParser().Parse(tokenizer);
                    Assert.AreEqual(3, select.Tokens.Count);
                    Assert.IsTrue(tokenizer.Current.IsCharacter(TSQLCharacters.Semicolon));

                    Assert.AreEqual(1, select.Columns.Count);

                    TSQLSelectColumn column = select.Columns[0];

                    Assert.IsNull(column.ColumnAlias);
                    Assert.AreEqual(TSQLExpressionType.Operator, column.Expression.Type);

                    TSQLOperatorExpression tsqlOperator = column.Expression.AsOperator;

                    Assert.AreEqual("+", tsqlOperator.Operator.Text);
                    Assert.IsNull(tsqlOperator.LeftSide);

                    Assert.AreEqual(TSQLExpressionType.Constant, tsqlOperator.RightSide.Type);
                    Assert.AreEqual(1, tsqlOperator.RightSide.AsConstant.Literal.AsNumericLiteral.Value);
                }
        }
        public void SelectClause_VariableAssignment()
        {
            using (StringReader reader = new StringReader(
                       @"SELECT @id = p.ProductID
				FROM Production.Product p
				WHERE
					p.[Name] = 'Blade';"                    ))
                using (ITSQLTokenizer tokenizer = new TSQLTokenizer(reader))
                {
                    Assert.IsTrue(tokenizer.MoveNext());

                    TSQLSelectClause select = new TSQLSelectClauseParser().Parse(tokenizer);
                    Assert.AreEqual(6, select.Tokens.Count);
                    Assert.AreEqual(TSQLKeywords.FROM, tokenizer.Current.AsKeyword.Keyword);

                    Assert.AreEqual(1, select.Columns.Count);

                    TSQLSelectColumn column = select.Columns[0];

                    Assert.IsNull(column.ColumnAlias);
                    Assert.AreEqual(TSQLExpressionType.VariableAssignment, column.Expression.Type);

                    TSQLVariableAssignmentExpression assignmentExpression = column.Expression.AsVariableAssignment;
                    Assert.AreEqual("=", assignmentExpression.Operator.Text);

                    Assert.AreEqual("@id", assignmentExpression.Variable.Text);

                    TSQLColumnExpression columnExpression = assignmentExpression.ValueExpression.AsColumn;
                    Assert.AreEqual("p", columnExpression.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("ProductID", columnExpression.Column.Name);
                }
        }
        public void SelectClause_FullyQualifiedFunction()
        {
            using (StringReader reader = new StringReader(
                       @"SELECT
					p.ProductID, 
					p.[Name],
					Test.dbo.Multiply(p.SafetyStockLevel, p.StandardCost) AS RestockCost
				FROM
					Production.Product p
				ORDER BY
					p.[Name];"                    ))
                using (ITSQLTokenizer tokenizer = new TSQLTokenizer(reader))
                {
                    Assert.IsTrue(tokenizer.MoveNext());

                    TSQLSelectClause select = new TSQLSelectClauseParser().Parse(tokenizer);
                    Assert.AreEqual(25, select.Tokens.Count);
                    Assert.AreEqual(TSQLKeywords.FROM, tokenizer.Current.AsKeyword.Keyword);

                    Assert.AreEqual(3, select.Columns.Count);

                    TSQLSelectColumn column = select.Columns[0];

                    Assert.IsNull(column.ColumnAlias);
                    Assert.AreEqual(TSQLExpressionType.Column, column.Expression.Type);
                    Assert.AreEqual("p", column.Expression.AsColumn.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("ProductID", column.Expression.AsColumn.Column.Name);

                    column = select.Columns[1];

                    Assert.IsNull(column.ColumnAlias);
                    Assert.AreEqual(TSQLExpressionType.Column, column.Expression.Type);
                    Assert.AreEqual("p", column.Expression.AsColumn.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("Name", column.Expression.AsColumn.Column.Name);

                    column = select.Columns[2];

                    Assert.AreEqual("RestockCost", column.ColumnAlias.Name);
                    Assert.AreEqual(TSQLExpressionType.Function, column.Expression.Type);

                    TSQLFunctionExpression functionExpression = column.Expression.AsFunction;

                    Assert.AreEqual("Multiply", functionExpression.Function.Name);
                    Assert.AreEqual(3, functionExpression.QualifiedPath.Count);
                    Assert.AreEqual("Test", functionExpression.QualifiedPath[0].AsIdentifier.Name);
                    Assert.AreEqual(".", functionExpression.QualifiedPath[1].AsCharacter.Text);
                    Assert.AreEqual("dbo", functionExpression.QualifiedPath[2].AsIdentifier.Name);

                    TSQLColumnExpression argumentExpression = functionExpression.Arguments[0].AsColumn;
                    Assert.AreEqual("p", argumentExpression.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("SafetyStockLevel", argumentExpression.Column.Name);

                    argumentExpression = functionExpression.Arguments[1].AsColumn;
                    Assert.AreEqual("p", argumentExpression.TableReference.Single().AsIdentifier.Name);
                    Assert.AreEqual("StandardCost", argumentExpression.Column.Name);
                }
        }
        public TSQLStatement Parse(TSQLTokenizer tokenizer)
        {
            TSQLWithStatement with = new TSQLWithStatementParser().Parse(tokenizer);

            TSQLStatement statement = new TSQLStatementParserFactory().Create(tokenizer.Current).Parse(tokenizer);

            statement.Tokens.InsertRange(0, with.Tokens);

            return statement;
        }
        public TSQLStatement Parse(TSQLTokenizer tokenizer)
        {
            TSQLWithStatement with = new TSQLWithStatementParser().Parse(tokenizer);

            TSQLStatement statement = new TSQLStatementParserFactory().Create(tokenizer.Current).Parse(tokenizer);

            statement.Tokens.InsertRange(0, with.Tokens);

            return(statement);
        }
Esempio n. 13
0
        public static FindCreateStatementResult FindCreate(string body)
        {
            var tokenizer = new TSQLTokenizer(body);

            tokenizer.MoveNext();

            while (tokenizer.Current != null && tokenizer.Current.AsKeyword?.Keyword != TSQLKeywords.CREATE)
            {
                tokenizer.MoveNext();
            }

            if (tokenizer.Current == null)
            {
                // Oops, we reached the end of the file and did not find the CREATE!
                return(null);
            }

            var createToken = tokenizer.Current.AsKeyword;

            tokenizer.MoveNext();

            var typeKeyword = tokenizer.Current.AsKeyword;

            tokenizer.MoveNext();

            // the object owner is optional
            var token0 = tokenizer.Current;

            tokenizer.MoveNext();
            var token1 = tokenizer.Current;

            tokenizer.MoveNext();
            var token2 = tokenizer.Current;

            tokenizer.MoveNext();

            TSQLIdentifier entityNameToken;

            if (token1.AsCharacter?.Text == ".")
            {
                entityNameToken = token2.AsIdentifier;
            }
            else
            {
                entityNameToken = token0.AsIdentifier;
            }

            return(new FindCreateStatementResult
            {
                CreateBeginPosition = createToken.BeginPosition,
                TypeEndPosition = typeKeyword.EndPosition,
                NameEndPosition = entityNameToken.EndPosition
            });
        }
 public void SelectClause_StopAtFrom()
 {
     using (StringReader reader = new StringReader(@"select a from b;"))
         using (IEnumerator <TSQLToken> tokenizer = new TSQLTokenizer(reader))
         {
             Assert.IsTrue(tokenizer.MoveNext());
             TSQLSelectClause select = new TSQLSelectClauseParser().Parse(tokenizer);
             Assert.AreEqual(2, select.Tokens.Count);
             Assert.AreEqual(TSQLKeywords.FROM, tokenizer.Current.AsKeyword.Keyword);
         }
 }
Esempio n. 15
0
 public void Parse_uspSearchCandidateResumes_NoWhitespace()
 {
     using (StringReader reader = new StringReader(Resources.AdventureWorks2014_dbo_uspSearchCandidateResumes))
         using (TSQLTokenizer lexer = new TSQLTokenizer(reader))
         {
             TokenComparisons.CompareStreamStartToList(
                 GetuspSearchCandidateResumesTokens()
                 .Where(t => !(t is TSQLWhitespace)).ToList(),
                 lexer);
         }
 }
Esempio n. 16
0
        public void Parse_GO()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("GO");

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLKeyword(0, "GO")
            },
                tokens);
        }
Esempio n. 17
0
        public void KeywordToken_SimpleKeywordLowercase()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("go ", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLKeyword(0, "go"),
                new TSQLWhitespace(2, " ")
            },
                tokens);
        }
Esempio n. 18
0
        public void MoneyLiteral_ForeignNegative()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("£-.1 ", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLMoneyLiteral(0, "£-.1"),
                new TSQLWhitespace(4, " ")
            },
                tokens);
        }
Esempio n. 19
0
        public void StringLiteralToken_DoubleQuote()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("\"name\" ", useQuotedIdentifiers: false, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLStringLiteral(0, "\"name\""),
                new TSQLWhitespace(6, " ")
            },
                tokens);
        }
Esempio n. 20
0
        public void Operator_NotEqualExclamation()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("!= ", useQuotedIdentifiers: false, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLOperator(0, "!="),
                new TSQLWhitespace(2, " ")
            },
                tokens);
        }
Esempio n. 21
0
        public void IdentifierToken_EscapedBracketedIdentifier2()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("[a]]a] ", useQuotedIdentifiers: false, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLIdentifier(0, "[a]]a]"),
                new TSQLWhitespace(6, " ")
            },
                tokens);
        }
Esempio n. 22
0
        public void IncompleteToken_Comment()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("/* something", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLIncompleteCommentToken(0, "/* something")
            },
                tokens);
            Assert.IsFalse(tokens[0].IsComplete);
        }
Esempio n. 23
0
        public void IdentifierToken_QuotedUnicodeIdentifier()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("N\"name\" ", useQuotedIdentifiers: true, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLIdentifier(0, "N\"name\""),
                new TSQLWhitespace(7, " ")
            },
                tokens);
        }
Esempio n. 24
0
        public void IncompleteToken_StringLiteral()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("'", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLIncompleteStringToken(0, "'")
            },
                tokens);
            Assert.IsFalse(tokens[0].IsComplete);
        }
Esempio n. 25
0
        public void IncompleteToken_Identifier()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("[dbo", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLIncompleteIdentifierToken(0, "[dbo")
            },
                tokens);
            Assert.IsFalse(tokens[0].IsComplete);
        }
Esempio n. 26
0
        public void BinaryToken_SimpleBinaryLiteral()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("0x69048AEFDD010E ", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLBinaryLiteral(0, "0x69048AEFDD010E"),
                new TSQLWhitespace(16, " ")
            },
                tokens);
        }
Esempio n. 27
0
        public void BinaryToken_BinaryLiteralEndWithLetter()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("0x69048AEFDD010EJ", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLBinaryLiteral(0, "0x69048AEFDD010E"),
                new TSQLIdentifier(16, "J")
            },
                tokens);
        }
Esempio n. 28
0
        public void StringLiteralToken_SingleQuoteUnicode()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("N'name' ", useQuotedIdentifiers: false, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLStringLiteral(0, "N'name'"),
                new TSQLWhitespace(7, " ")
            },
                tokens);
        }
Esempio n. 29
0
        public void CharacterToken_Period()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens(". ", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLCharacter(0, "."),
                new TSQLWhitespace(1, " ")
            },
                tokens);
        }
Esempio n. 30
0
        public void IdentifierToken_SimpleIdentifier()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("a ", useQuotedIdentifiers: false, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLIdentifier(0, "a"),
                new TSQLWhitespace(1, " ")
            },
                tokens);
        }
Esempio n. 31
0
        public void Operator_LessThan()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("< ", useQuotedIdentifiers: false, includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLOperator(0, "<"),
                new TSQLWhitespace(1, " ")
            },
                tokens);
        }
Esempio n. 32
0
        public void BinaryToken_EmptyBinaryLiteralCaseInsensitive()
        {
            List <TSQLToken> tokens = TSQLTokenizer.ParseTokens("0X ", includeWhitespace: true);

            TokenComparisons.CompareTokenLists(
                new List <TSQLToken>()
            {
                new TSQLBinaryLiteral(0, "0X"),
                new TSQLWhitespace(2, " ")
            },
                tokens);
        }
        public TSQLUnknownStatement Parse(TSQLTokenizer tokenizer)
        {
            TSQLUnknownStatement statement = new TSQLUnknownStatement();

            while (
                tokenizer.Read() &&
                !(
                    tokenizer.Current is TSQLCharacter &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.Semicolon
                ))
            {
                statement.Tokens.Add(tokenizer.Current);
            }

            if (
                tokenizer.Current != null &&
                tokenizer.Current is TSQLCharacter &&
                tokenizer.Current.AsCharacter.Character == TSQLCharacters.Semicolon)
            {
                statement.Tokens.Add(tokenizer.Current);
            }

            return statement;
        }
        public TSQLSelectClause Parse(TSQLTokenizer tokenizer)
        {
            TSQLSelectClause select = new TSQLSelectClause();

            if (
                tokenizer.Current == null ||
                tokenizer.Current.Type != TSQLTokenType.Keyword ||
                tokenizer.Current.AsKeyword.Keyword != TSQLKeywords.SELECT)
            {
                throw new ApplicationException("SELECT expected.");
            }

            select.Tokens.Add(tokenizer.Current);

            // can contain ALL, DISTINCT, TOP, PERCENT, WITH TIES, AS

            // ends with FROM, semicolon, or keyword other than those listed above, when used outside of parens

            // recursively walk down and back up parens

            int nestedLevel = 0;

            while (
                tokenizer.Read() &&
                !(
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.Semicolon
                ) &&
                !(
                    nestedLevel == 0 &&
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses
                ) &&
                (
                    nestedLevel > 0 ||
                    tokenizer.Current.Type != TSQLTokenType.Keyword ||
                    (
                        tokenizer.Current.Type == TSQLTokenType.Keyword &&
                        tokenizer.Current.AsKeyword.Keyword.In
                        (
                            TSQLKeywords.ALL,
                            TSQLKeywords.AS,
                            TSQLKeywords.DISTINCT,
                            TSQLKeywords.PERCENT,
                            TSQLKeywords.TOP,
                            TSQLKeywords.WITH,
                            TSQLKeywords.NULL,
                            TSQLKeywords.CASE,
                            TSQLKeywords.WHEN,
                            TSQLKeywords.THEN,
                            TSQLKeywords.ELSE,
                            TSQLKeywords.AND,
                            TSQLKeywords.OR,
                            TSQLKeywords.BETWEEN,
                            TSQLKeywords.EXISTS,
                            TSQLKeywords.END,
                            TSQLKeywords.IN,
                            TSQLKeywords.IS,
                            TSQLKeywords.NOT,
                            TSQLKeywords.OVER,
                            TSQLKeywords.IDENTITY,
                            TSQLKeywords.LIKE
                        )
                    )
                ))
            {
                select.Tokens.Add(tokenizer.Current);

                if (tokenizer.Current.Type == TSQLTokenType.Character)
                {
                    TSQLCharacters character = tokenizer.Current.AsCharacter.Character;

                    if (character == TSQLCharacters.OpenParentheses)
                    {
                        // should we recurse for correlated subqueries?
                        nestedLevel++;

                        if (tokenizer.Read())
                        {
                            if (
                                tokenizer.Current.Type == TSQLTokenType.Keyword &&
                                tokenizer.Current.AsKeyword.Keyword == TSQLKeywords.SELECT)
                            {
                                TSQLSelectStatement selectStatement = new TSQLSelectStatementParser().Parse(tokenizer);

                                select.Tokens.AddRange(selectStatement.Tokens);

                                if (
                                    tokenizer.Current != null &&
                                    tokenizer.Current.Type == TSQLTokenType.Character &&
                                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses)
                                {
                                    nestedLevel--;
                                    select.Tokens.Add(tokenizer.Current);
                                }
                            }
                            else
                            {
                                select.Tokens.Add(tokenizer.Current);
                            }
                        }
                    }
                    else if (character == TSQLCharacters.CloseParentheses)
                    {
                        nestedLevel--;
                    }
                }
            }

            return select;
        }
        public TSQLFromClause Parse(TSQLTokenizer tokenizer)
        {
            TSQLFromClause from = new TSQLFromClause();

            if (
                tokenizer.Current == null ||
                tokenizer.Current.Type != TSQLTokenType.Keyword ||
                tokenizer.Current.AsKeyword.Keyword != TSQLKeywords.FROM)
            {
                throw new ApplicationException("FROM expected.");
            }

            from.Tokens.Add(tokenizer.Current);

            // derived tables
            // TVF
            int nestedLevel = 0;

            while (
                tokenizer.Read() &&
                !(
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.Semicolon
                ) &&
                !(
                    nestedLevel == 0 &&
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses
                ) &&
                (
                    nestedLevel > 0 ||
                    tokenizer.Current.Type != TSQLTokenType.Keyword ||
                    (
                        tokenizer.Current.Type == TSQLTokenType.Keyword &&
                        tokenizer.Current.AsKeyword.Keyword.In
                        (
                            TSQLKeywords.JOIN,
                            TSQLKeywords.ON,
                            TSQLKeywords.INNER,
                            TSQLKeywords.LEFT,
                            TSQLKeywords.RIGHT,
                            TSQLKeywords.OUTER,
                            TSQLKeywords.CROSS,
                            TSQLKeywords.FULL,
                            TSQLKeywords.AS,
                            TSQLKeywords.PIVOT,
                            TSQLKeywords.UNPIVOT,
                            TSQLKeywords.WITH,
                            TSQLKeywords.MERGE,
                            TSQLKeywords.TABLESAMPLE,
                            TSQLKeywords.FOR,
                            TSQLKeywords.FROM, // FOR SYSTEM_TIME FROM
                            TSQLKeywords.BETWEEN,
                            TSQLKeywords.AND,
                            TSQLKeywords.IN,
                            TSQLKeywords.REPEATABLE,
                            TSQLKeywords.ALL
                        )
                    )
                ))
            {
                from.Tokens.Add(tokenizer.Current);

                if (tokenizer.Current.Type == TSQLTokenType.Character)
                {
                    TSQLCharacters character = tokenizer.Current.AsCharacter.Character;

                    if (character == TSQLCharacters.OpenParentheses)
                    {
                        // should we recurse for derived tables?
                        nestedLevel++;

                        if (tokenizer.Read())
                        {
                            if (
                                tokenizer.Current.Type == TSQLTokenType.Keyword &&
                                tokenizer.Current.AsKeyword.Keyword == TSQLKeywords.SELECT)
                            {
                                TSQLSelectStatement selectStatement = new TSQLSelectStatementParser().Parse(tokenizer);

                                from.Tokens.AddRange(selectStatement.Tokens);

                                if (
                                    tokenizer.Current != null &&
                                    tokenizer.Current.Type == TSQLTokenType.Character &&
                                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses)
                                {
                                    nestedLevel--;
                                    from.Tokens.Add(tokenizer.Current);
                                }
                            }
                            else
                            {
                                from.Tokens.Add(tokenizer.Current);
                            }
                        }
                    }
                    else if (character == TSQLCharacters.CloseParentheses)
                    {
                        nestedLevel--;
                    }
                }
            }

            return from;
        }
        public TSQLSelectStatement Parse(TSQLTokenizer tokenizer)
        {
            TSQLSelectStatement select = new TSQLSelectStatement();

            // should whitespace be excluded from statement parsing logic?

            // should I differentiate keywords that start commands?

            // correlated subqueries
            // scalar function calls

            // SELECT clause

            TSQLSelectClause selectClause = new TSQLSelectClauseParser().Parse(tokenizer);

            select.Select = selectClause;

            select.Tokens.AddRange(selectClause.Tokens);

            if (tokenizer.Current.IsKeyword(TSQLKeywords.INTO))
            {
                TSQLIntoClause intoClause = new TSQLIntoClauseParser().Parse(tokenizer);

                select.Into = intoClause;

                select.Tokens.AddRange(intoClause.Tokens);
            }

            if (tokenizer.Current.IsKeyword(TSQLKeywords.FROM))
            {
                TSQLFromClause fromClause = new TSQLFromClauseParser().Parse(tokenizer);

                select.From = fromClause;

                select.Tokens.AddRange(fromClause.Tokens);
            }

            if (tokenizer.Current.IsKeyword(TSQLKeywords.WHERE))
            {
                TSQLWhereClause whereClause = new TSQLWhereClauseParser().Parse(tokenizer);

                select.Where = whereClause;

                select.Tokens.AddRange(whereClause.Tokens);
            }

            if (tokenizer.Current.IsKeyword(TSQLKeywords.GROUP))
            {
                TSQLGroupByClause groupByClause = new TSQLGroupByClauseParser().Parse(tokenizer);

                select.GroupBy = groupByClause;

                select.Tokens.AddRange(groupByClause.Tokens);
            }

            if (tokenizer.Current.IsKeyword(TSQLKeywords.HAVING))
            {
                TSQLHavingClause havingClause = new TSQLHavingClauseParser().Parse(tokenizer);

                select.Having = havingClause;

                select.Tokens.AddRange(havingClause.Tokens);
            }

            if (tokenizer.Current.IsKeyword(TSQLKeywords.ORDER))
            {
                TSQLOrderByClause orderByClause = new TSQLOrderByClauseParser().Parse(tokenizer);

                select.OrderBy = orderByClause;

                select.Tokens.AddRange(orderByClause.Tokens);
            }

            if (tokenizer.Current.IsCharacter(TSQLCharacters.Semicolon))
            {
                select.Tokens.Add(tokenizer.Current);
            }

            return select;
        }
 TSQLStatement ITSQLStatementParser.Parse(TSQLTokenizer tokenizer)
 {
     return Parse(tokenizer);
 }
 TSQLMergeStatement Parse(TSQLTokenizer tokenizer)
 {
     throw new NotImplementedException();
 }
        public TSQLHavingClause Parse(TSQLTokenizer tokenizer)
        {
            TSQLHavingClause having = new TSQLHavingClause();

            if (
                tokenizer.Current == null ||
                tokenizer.Current.Type != TSQLTokenType.Keyword ||
                tokenizer.Current.AsKeyword.Keyword != TSQLKeywords.HAVING)
            {
                throw new ApplicationException("HAVING expected.");
            }

            having.Tokens.Add(tokenizer.Current);

            // subqueries
            int nestedLevel = 0;

            while (
                tokenizer.Read() &&
                !(
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.Semicolon
                ) &&
                !(
                    nestedLevel == 0 &&
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses
                ) &&
                (
                    nestedLevel > 0 ||
                    tokenizer.Current.Type != TSQLTokenType.Keyword ||
                    (
                        tokenizer.Current.Type == TSQLTokenType.Keyword &&
                        tokenizer.Current.AsKeyword.Keyword.In
                        (
                            TSQLKeywords.NULL,
                            TSQLKeywords.CASE,
                            TSQLKeywords.WHEN,
                            TSQLKeywords.THEN,
                            TSQLKeywords.ELSE,
                            TSQLKeywords.AND,
                            TSQLKeywords.OR,
                            TSQLKeywords.BETWEEN,
                            TSQLKeywords.EXISTS,
                            TSQLKeywords.END,
                            TSQLKeywords.IN,
                            TSQLKeywords.IS,
                            TSQLKeywords.NOT,
                            TSQLKeywords.LIKE
                        )
                    )
                ))
            {
                having.Tokens.Add(tokenizer.Current);

                if (tokenizer.Current.Type == TSQLTokenType.Character)
                {
                    TSQLCharacters character = tokenizer.Current.AsCharacter.Character;

                    if (character == TSQLCharacters.OpenParentheses)
                    {
                        // should we recurse for subqueries?
                        nestedLevel++;

                        if (tokenizer.Read())
                        {
                            if (
                                tokenizer.Current.Type == TSQLTokenType.Keyword &&
                                tokenizer.Current.AsKeyword.Keyword == TSQLKeywords.SELECT)
                            {
                                TSQLSelectStatement selectStatement = new TSQLSelectStatementParser().Parse(tokenizer);

                                having.Tokens.AddRange(selectStatement.Tokens);

                                if (
                                    tokenizer.Current != null &&
                                    tokenizer.Current.Type == TSQLTokenType.Character &&
                                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses)
                                {
                                    nestedLevel--;
                                    having.Tokens.Add(tokenizer.Current);
                                }
                            }
                            else
                            {
                                having.Tokens.Add(tokenizer.Current);
                            }
                        }
                    }
                    else if (character == TSQLCharacters.CloseParentheses)
                    {
                        nestedLevel--;
                    }
                }
            }

            return having;
        }
 TSQLClause ITSQLClauseParser.Parse(TSQLTokenizer tokenizer)
 {
     return Parse(tokenizer);
 }
 public TSQLDeleteStatement Parse(TSQLTokenizer tokenizer)
 {
     throw new NotImplementedException();
 }
        public TSQLOrderByClause Parse(TSQLTokenizer tokenizer)
        {
            TSQLOrderByClause orderBy = new TSQLOrderByClause();

            TSQLKeyword keyword = tokenizer.Current.AsKeyword;

            if (keyword == null ||
                keyword.Keyword != TSQLKeywords.ORDER)
            {
                throw new ApplicationException("ORDER expected.");
            }

            orderBy.Tokens.Add(keyword);

            // subqueries
            int nestedLevel = 0;

            while (
                tokenizer.Read() &&
                !(
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.Semicolon
                ) &&
                !(
                    nestedLevel == 0 &&
                    tokenizer.Current.Type == TSQLTokenType.Character &&
                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses
                ) &&
                (
                    nestedLevel > 0 ||
                    tokenizer.Current.Type != TSQLTokenType.Keyword ||
                    (
                        tokenizer.Current.Type == TSQLTokenType.Keyword &&
                        tokenizer.Current.AsKeyword.Keyword.In
                        (
                            TSQLKeywords.BY,
                            TSQLKeywords.NULL,
                            TSQLKeywords.CASE,
                            TSQLKeywords.WHEN,
                            TSQLKeywords.THEN,
                            TSQLKeywords.ELSE,
                            TSQLKeywords.AND,
                            TSQLKeywords.OR,
                            TSQLKeywords.BETWEEN,
                            TSQLKeywords.EXISTS,
                            TSQLKeywords.END,
                            TSQLKeywords.IN,
                            TSQLKeywords.IS,
                            TSQLKeywords.NOT,
                            TSQLKeywords.OVER,
                            TSQLKeywords.LIKE,
                            TSQLKeywords.ASC,
                            TSQLKeywords.DESC,
                            TSQLKeywords.FETCH,
                            TSQLKeywords.COLLATE
                        )
                    )
                ))
            {
                orderBy.Tokens.Add(tokenizer.Current);

                if (tokenizer.Current.Type == TSQLTokenType.Character)
                {
                    TSQLCharacters character = tokenizer.Current.AsCharacter.Character;

                    if (character == TSQLCharacters.OpenParentheses)
                    {
                        // should we recurse for subqueries?
                        nestedLevel++;

                        if (tokenizer.Read())
                        {
                            if (
                                tokenizer.Current.Type == TSQLTokenType.Keyword &&
                                tokenizer.Current.AsKeyword.Keyword == TSQLKeywords.SELECT)
                            {
                                TSQLSelectStatement selectStatement = new TSQLSelectStatementParser().Parse(tokenizer);

                                orderBy.Tokens.AddRange(selectStatement.Tokens);

                                if (
                                    tokenizer.Current != null &&
                                    tokenizer.Current.Type == TSQLTokenType.Character &&
                                    tokenizer.Current.AsCharacter.Character == TSQLCharacters.CloseParentheses)
                                {
                                    nestedLevel--;
                                    orderBy.Tokens.Add(tokenizer.Current);
                                }
                            }
                            else
                            {
                                orderBy.Tokens.Add(tokenizer.Current);
                            }
                        }
                    }
                    else if (character == TSQLCharacters.CloseParentheses)
                    {
                        nestedLevel--;
                    }
                }
            }

            return orderBy;
        }