Skip to content

Commit

Permalink
Fix regression for jdbi#2481
Browse files Browse the repository at this point in the history
A regression was highlighted that the change in 3.41.2 swallowed `-`
characters at the end of named parameters and break expressions such
as `:foo->>'stuff'`.

- Rework the grammar to not support `-` as the last character.
- Align the HashStatementLexer to the ColonStatementLexer
- Add tests

This addresses jdbi#2481 (comment)
  • Loading branch information
hgschmie committed Oct 1, 2023
1 parent df5e9e8 commit 2013c6a
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ fragment COLON: {_input.LA(2) != ':'}? ':';
fragment DOUBLE_COLON: {_input.LA(2) == ':'}? '::';
fragment QUESTION: {_input.LA(2) != '?'}? '?';
fragment DOUBLE_QUESTION: {_input.LA(2) == '?'}? '??';
fragment NAME: JAVA_LETTER | [0-9] | '.' | '?.' | '-';
fragment NAME_END: JAVA_LETTER | [0-9] | '.' | '?.';
fragment NAME: NAME_END | '-';

/* Lovingly lifted from https://github.com/antlr/grammars-v4/blob/master/java/JavaLexer.g4 */
fragment JAVA_LETTER : [a-zA-Z$_] | ~[\u0000-\u007F\uD800-\uDBFF] | [\uD800-\uDBFF] [\uDC00-\uDFFF];
Expand All @@ -32,7 +33,7 @@ QUOTED_TEXT: QUOTE (ESCAPE_QUOTE | ~'\'')* QUOTE;
DOUBLE_QUOTED_TEXT: DOUBLE_QUOTE (~'"')+ DOUBLE_QUOTE;
ESCAPED_TEXT : ESCAPE . ;

NAMED_PARAM: COLON (NAME)+;
NAMED_PARAM: COLON (NAME* NAME_END);
POSITIONAL_PARAM: QUESTION;

LITERAL: DOUBLE_COLON | DOUBLE_QUESTION | .;
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ fragment DOUBLE_QUOTE: '"';
fragment HASH: '#';
fragment QUESTION: {_input.LA(2) != '?'}? '?';
fragment DOUBLE_QUESTION: {_input.LA(2) == '?'}? '??';
fragment NAME: JAVA_LETTER | [0-9] | '.' | '?.';
fragment NAME_END: JAVA_LETTER | [0-9] | '.' | '?.';
fragment NAME: NAME_END | '-';

/* Lovingly lifted from https://github.com/antlr/grammars-v4/blob/master/java/JavaLexer.g4 */
fragment JAVA_LETTER : [a-zA-Z$_] | ~[\u0000-\u007F\uD800-\uDBFF] | [\uD800-\uDBFF] [\uDC00-\uDFFF];
Expand All @@ -31,7 +32,7 @@ QUOTED_TEXT: QUOTE (ESCAPE_QUOTE | ~'\'')* QUOTE;
DOUBLE_QUOTED_TEXT: DOUBLE_QUOTE (~'"')+ DOUBLE_QUOTE;
ESCAPED_TEXT : ESCAPE . ;

NAMED_PARAM: HASH (NAME)+;
NAMED_PARAM: HASH (NAME* NAME_END);
POSITIONAL_PARAM: QUESTION;

LITERAL: DOUBLE_QUESTION | .;
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,60 @@ public void testEmojiParameterNames() {
.append(")")
.build());
}

@Test
public void test2481DashRegression() {
assertThat(parser.parse("select :data->>'field'", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data")
.append("->>'field'")
.build());
}

// grammar always allowed name ending with .
@Test
public void test2481DotRegression() {
assertThat(parser.parse("select :data.", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data.")
.build());
}

@Test
public void test2481DashStarting() {
assertThat(parser.parse("select :-data", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("-data")
.build());
}

@Test
public void test2481DotStarting() {
assertThat(parser.parse("select :.data", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter(".data")
.build());
}

@Test
public void test2481DashName() {
assertThat(parser.parse("select :data-foo-bar", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data-foo-bar")
.build());
}

@Test
public void test2481DotName() {
assertThat(parser.parse("select :data.foo.bar", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data.foo.bar")
.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,60 @@ public void testEmojiParameterNames() {
.append(")")
.build());
}

@Test
public void test2481DashRegression() {
assertThat(parser.parse("select #data->>'field'", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data")
.append("->>'field'")
.build());
}

// grammar always allowed name ending with .
@Test
public void test2481DotRegression() {
assertThat(parser.parse("select #data.", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data.")
.build());
}

@Test
public void test2481DashStarting() {
assertThat(parser.parse("select #-data", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("-data")
.build());
}

@Test
public void test2481DotStarting() {
assertThat(parser.parse("select #.data", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter(".data")
.build());
}

@Test
public void test2481DashName() {
assertThat(parser.parse("select #data-foo-bar", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data-foo-bar")
.build());
}

@Test
public void test2481DotName() {
assertThat(parser.parse("select #data.foo.bar", ctx))
.isEqualTo(ParsedSql.builder()
.append("select ")
.appendNamedParameter("data.foo.bar")
.build());
}
}

0 comments on commit 2013c6a

Please sign in to comment.