Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RD 10961 + RD 10948 fixes #434

Merged
merged 6 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -699,10 +699,10 @@ class RawSqlVisitor(

override def visitIdnt(ctx: PsqlParser.IdntContext): SqlBaseNode = Option(ctx)
.map { context =>
val isDoubleQuoted = context.DOUBLE_QUOTED_STRING() != null
val isDoubleQuoted = context.STRING_IDENTIFIER_START() != null
val value =
if (isDoubleQuoted) {
val text = context.DOUBLE_QUOTED_STRING().getText
val text = context.getText
val withoutLast =
if (!text.endsWith("\"")) {
addError("Missing closing \"", context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class TestSqlCompilerServiceAirports
private val hostname = sys.env.getOrElse("FDW_HOSTNAME", "localhost")
private val port = sys.env.getOrElse("FDW_HOSTNAME", "5432")
private val username = sys.env.getOrElse("FDW_USERNAME", "postgres")
private val password = sys.env.getOrElse("FDW_PASSWORD", "1234")
private val password = sys.env.getOrElse("FDW_PASSWORD", "")

property("raw.creds.jdbc.fdw.host", hostname)
property("raw.creds.jdbc.fdw.port", port)
Expand Down Expand Up @@ -963,35 +963,38 @@ class TestSqlCompilerServiceAirports
assert(v.messages.exists(_.message contains "the input does not form a valid statement or expression"))
}

test("""RD-10948+10961"""){_ =>
test("""RD-10948+10961""") { _ =>
assume(password != "")
val q = """:
|""".stripMargin
|""".stripMargin
val ValidateResponse(errors) = compilerService.validate(q, asJson())
assert(errors.nonEmpty)
}

test("""RD-10948"""){_ =>
test("""RD-10948""") { _ =>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not forget to remove that test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I alternated it as we discussed

assume(password != "")
val q = """SELECT * FROM
|(VALUES
| (1, 'aravind', 'aravind@gmail.com', '123456'),
| (2, 'arjun', 'arjun@gmail.com', '11223344')
|) as i(id, first_name, email, password)
|WHERE email = :email AND password:
|""".stripMargin
|(VALUES
| (1, 'janedoe', 'janedoe@raw-labs.com', '123'),
| (2, 'janedoe', 'janedoe@raw-labs.com', '123')
|) as i(id, first_name, email, password)
|WHERE email = :email AND password:
|""".stripMargin
val ValidateResponse(errors) = compilerService.validate(q, asJson())
assert(errors.nonEmpty)
}

test("""RD-10961"""){_ =>
test("""RD-10961""") { _ =>
assume(password != "")
val q = """-- @default id 1
|
|SELECT * FROM
|(VALUES
| (1, 'John', 'Doe', DATE '2023-01-01'),
| (2, 'Jane', 'Doe', DATE '2024-01-01')
|) as i(id, first_name, last_name, birthday)
|WHERE id = :id && id = :
|""".stripMargin
|
|SELECT * FROM
|(VALUES
| (1, 'John', 'Doe', DATE '2023-01-02'),
| (2, 'Jane', 'Doe', DATE '2024-01-03')
|) as i(id, first_name, last_name, birthday)
|WHERE id = :id && id = :
|""".stripMargin
val ValidateResponse(errors) = compilerService.validate(q, asJson())
assert(errors.nonEmpty)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test would crash during the line before. What error does one get now?

Copy link
Contributor Author

@alexzerntev alexzerntev May 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax error at or near "="
Is this error expected?

}
Expand Down
68 changes: 41 additions & 27 deletions sql-client/src/test/scala/raw/client/sql/TestSqlParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import raw.client.sql.antlr4.{
SqlProgramNode,
SqlProjNode,
SqlStatementNode,
SqlStringLiteralNode,
SqlWithComaSeparatorNode
}

Expand Down Expand Up @@ -242,7 +243,7 @@ class TestSqlParser extends AnyFunSuite {
}

test("Test multiple param occurrences") {
val code = """SELECT * FROM example.airports WHERE city = :param and airport_id = :param"""".stripMargin
val code = """SELECT * FROM example.airports WHERE city = :param and airport_id = :param""".stripMargin
val result = doTest(code)
assert(result.isSuccess)
result.params.get("param") match {
Expand Down Expand Up @@ -409,28 +410,6 @@ class TestSqlParser extends AnyFunSuite {
assert(result.isSuccess)
}

test("Test missing closing double quote identifier") {
val code = """select somethin."asdf from anything""".stripMargin
val result = doTest(code)
assert(result.errors.size == 1)
assert(
result.errors.head.message == "Missing closing \""
)
result.tree match {
case SqlProgramNode(statement) => statement match {
case SqlStatementNode(statementItems) =>
assert(statementItems.size == 4)
statementItems(1) match {
case SqlProjNode(identifiers) => identifiers(1) match {
case identifier: SqlIdentifierNode =>
assert(identifier.name == "asdf")
assert(identifier.isQuoted)
}
}
}
}
}

test("Test missing identifier after dot") {
val code = """SELECT * FROM example.airports
|WHERE ai.
Expand Down Expand Up @@ -593,21 +572,56 @@ class TestSqlParser extends AnyFunSuite {

test("single quoted identifier with a newline") {
val code = """SELECT "c
| si
| bon" FROM x
|""".stripMargin
| si
| bon" FROM x
|""".stripMargin
val result = doTest(code)
assert(result.isSuccess)
}

test("colon in the end of the code with a newline") {
val code = """:
|""".stripMargin
|""".stripMargin
val result = doTest(code)
assert(result.isSuccess)
val SqlProgramNode(stmt) = result.tree
assert(result.positions.getStart(stmt).isDefined)
assert(result.positions.getStart(stmt).flatMap(_.optOffset).isDefined)
assert(result.positions.getFinish(stmt).flatMap(_.optOffset).isDefined)
}

test("multiline string-identifier test") {
val code = """select "
|a
|" from anything """.stripMargin
val result = doTest(code)
val SqlProgramNode(stmt) = result.tree
stmt match {
case SqlStatementNode(statementItems) =>
assert(statementItems.size == 4)
statementItems(1) match {
case node: SqlIdentifierNode =>
val finish = result.positions.getFinish(node)
assert(finish.get.line == 3)
}
}
}

test("multiline string test") {
val code = """select '
|a
|' from anything """.stripMargin
val result = doTest(code)
val SqlProgramNode(stmt) = result.tree
stmt match {
case SqlStatementNode(statementItems) =>
assert(statementItems.size == 4)
statementItems(1) match {
case node: SqlStringLiteralNode =>
val finish = result.positions.getFinish(node)
assert(finish.get.line == 3)
}
}
}

}
21 changes: 15 additions & 6 deletions sql-parser/src/main/java/raw/psql/grammar/PsqlLexer.g4
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
lexer grammar PsqlLexer;

UNICODE: 'U&';

// Comments
LINE_COMMENT_START: '--' -> pushMode(INSIDE_SINGLE_LINE_COMMENT);

MULTI_LINE_COMMENT_START: '/*' -> pushMode(INSIDE_MULTI_LINE_COMMENT);

QUOTE: '\'';
STRING_LITERAL_START: '\'' -> pushMode(INSIDE_STRING_LITERAL);
STRING_IDENTIFIER_START: '"' -> pushMode(INSIDE_STRING_IDENTIFIER);

DOT: '.';
STAR: '*';
COMMA: ',';
Expand Down Expand Up @@ -44,8 +48,6 @@ CONCAT: '||';
REGEX_CASE_INSENSITIVE_MATCH: '~*';
REGEX_CASE_INSENSITIVE_NOT_MATCH: '!~*';

UNICODE: 'U&';


DOUBLE_COLON: '::';

Expand All @@ -55,8 +57,6 @@ FLOATING_POINT: DIGIT+ '.' DIGIT* EXPONENT?;
PARAM: ':' WORD;

// Strings
DOUBLE_QUOTED_STRING: '"' (~[" \u0000] | '""')* '"'?;
SINGLE_QUOTED_STRING: '\'' (ESC | ~['\\])* '\'';
TICKS_QUOTED_STRING: '`' (ESC | ~[`\\])* '`';

BIGSERIAL: B I G S E R I A L;
Expand Down Expand Up @@ -1009,7 +1009,16 @@ ML_STAR: '*';

mode INSIDE_UNKNOWN_WORD;

UNKNOWN_WORD_END: [ \t\r\n;EOF] -> popMode;
UNKNOWN_WORD_END: [ \t\r\n;EOF] -> popMode, skip;
UNKNOWN_WORD_END2: [)] -> type(R_PAREN), popMode;

IN_UNKNOWN_WORD: ~[;)];

mode INSIDE_STRING_LITERAL;
STRING_LITERAL_END: '\'' -> popMode;
STRING_LITERAL_CONTENT: (ESC | ~['\\]);

mode INSIDE_STRING_IDENTIFIER;
STRING_ESCAPE: '"' '"';
STRING_IDENTIFIER_END: '"' -> popMode;
STRING_IDENTIFIER_CONTENT: (ESC | ~["]);
Loading