Skip to content

Commit

Permalink
Updated parser to handle single quoted values (#376)
Browse files Browse the repository at this point in the history
Sorry this has taken so long, @cmiles74 - been really busy both at work and at home the last months. Thanks again for your solid contributions! :)
  • Loading branch information
Christopher Miles authored and erikbra committed Jun 7, 2019
1 parent f4248c7 commit 48bc258
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
33 changes: 31 additions & 2 deletions product/roundhouse.databases.mysql/parser/Scanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,13 @@ private void ScanToken()
AnsiQuoted();
break;
} else {
goto case '`';
goto case '\'';
}

case '\'':
SingleQuoted();
break;

case '`':
Quoted();
break;
Expand Down Expand Up @@ -285,14 +289,34 @@ private void AnsiQuoted()

if (IsAtEnd()) {
// unterminated string
throw new ParserException("Unterminated quoted value on line " + line);
throw new ParserException("Unterminated double quoted value on line " + line);
}
}

Advance(); // closing quote
AddToken(Token.Type.AnsiQuote);
}

private void SingleQuoted()
{
while (!IsAtEnd() && !IsSingleQuote(Peek())) {

if (Peek() == '\n') {
line++;
}

Advance();

if (IsAtEnd()) {
// unterminated string
throw new ParserException("Unterminated single quoted value on line " + line);
}
}

Advance(); // closing quote
AddToken(Token.Type.SingleQuote);
}

private void General()
{
while (!IsAtEnd() && Char.IsLetterOrDigit(Peek())) {
Expand Down Expand Up @@ -393,6 +417,11 @@ private static bool IsAnsiQuote(char c)
return c == '"';
}

private static bool IsSingleQuote(char c)
{
return c == '\'';
}

private void DelimiterDeclaration() {

// add our declaration keyword
Expand Down
1 change: 1 addition & 0 deletions product/roundhouse.databases.mysql/parser/Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum Type {
Text, // SQL script text
Quote, // quoted text
AnsiQuote, // ANSI quoted text
SingleQuote, // Single quited text
Whitespace, // whitespace
EndOfLine, // end of line
EndOfFile // end of file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void should_split_on_delimiters()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(2, statements.Count);
}
Expand All @@ -60,7 +60,7 @@ public void should_honor_single_character_delimiter()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(2, statements.Count);
}
Expand All @@ -74,7 +74,7 @@ public void should_honor_tricky_single_character_delimiter()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(2, statements.Count);
}
Expand All @@ -88,7 +88,7 @@ public void should_honor_double_character_delimiter()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(2, statements.Count);
}
Expand All @@ -102,7 +102,7 @@ public void should_honor_tricky_double_character_delimiter()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(2, statements.Count);
}
Expand All @@ -116,7 +116,7 @@ public void should_honor_multicharacter_delimiter()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(2, statements.Count);
}
Expand All @@ -130,21 +130,40 @@ public void should_honor_trailing_delimiter()
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

TestContext.Out.WriteLine("Statements parsed: " + statements.Count);
WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("select * from test1" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(3, statements.Count);
}

[Observation]
public void should_honor_quoted_semicolon()
{
string script = "set ps = 'select * from test;';\nprepare ps;\nexecute ps;";

Parser parser = new Parser(script);
List<ParsedStatement> statements = parser.Parse();
WriteStatements(statements);

WriteOutput("Statements parsed: " + statements.Count);
Assert.AreEqual("set ps = 'select * from test;'" + Environment.NewLine, statements[0].Value);
Assert.AreEqual(3, statements.Count);
}

private void WriteStatements(List<ParsedStatement> statements) {
int index = 0;
foreach (ParsedStatement statement in statements) {
TestContext.Out.WriteLine(index + ":");
WriteOutput(index + ":");
WriteStatement(statement);
index++;
}
}

private void WriteStatement(ParsedStatement statement) {
TestContext.Out.Write(statement.Value);
WriteOutput(statement.Value);
}

private void WriteOutput(string value) {
//NUnit.Framework.TestContext.Progress.WriteLine(value);
}
}
}
Expand Down

0 comments on commit 48bc258

Please sign in to comment.