Skip to content

Commit 2ed3129

Browse files
authored
fix(pglt_statement_splitter): properly split for windows (#216)
* chore(pglt_statement_splitter): add test for comments * debug * debug * debug * debug * maybe fix? * debug * debug * fix? * fix? * cleanup * fix: weorkflow * fix: weorkflow * chore: add test for consecutive newlines * fix: regex
1 parent 5e55838 commit 2ed3129

File tree

6 files changed

+65
-10
lines changed

6 files changed

+65
-10
lines changed

.github/workflows/publish.dispatch.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
return;
4040
}
4141
42-
if (releases.length < 100) {
42+
if (releases.length < 100) {
4343
exhausted = true;
4444
} else if (page >= 10) {
4545
throw new Error("We iterated over 10 pages. Does the script work?");
@@ -55,8 +55,8 @@ jobs:
5555
- name: Abort
5656
if: steps.validate-release.outputs.has-release != 'true'
5757
run: |
58-
{
59-
echo "Tag ${{ github.event.inputs.release_tag }} not found."
58+
{
59+
echo "Tag ${{ github.event.inputs.release-tag }} not found."
6060
exit 1
6161
}
6262

.github/workflows/publish.reusable.yml

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ on:
99
is-prerelease:
1010
type: string
1111
required: true
12-
default: "false"
1312

1413
jobs:
1514
publish:
@@ -52,17 +51,17 @@ jobs:
5251
- name: Publish npm packages as nightly
5352
if: inputs.is-prerelease == 'true'
5453
run: |
55-
for package in packages/@pglt/*; do
56-
npm publish $package --tag nightly --access public --provenance
54+
for package in packages/@pglt/*; do
55+
npm publish "$package" --tag nightly --access public --provenance
5756
done
5857
env:
5958
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} #
6059

6160
- name: Publish npm packages as latest
6261
if: inputs.is-prerelease != 'true'
6362
run: |
64-
for package in packages/@pglt/*; do
65-
npm publish $package --tag latest --access public --provenance
63+
for package in packages/@pglt/*; do
64+
npm publish "$package" --tag latest --access public --provenance
6665
done
6766
env:
6867
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

crates/pglt_lexer/src/lib.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,18 @@ pub static WHITESPACE_TOKENS: &[SyntaxKind] = &[
6161
SyntaxKind::SqlComment,
6262
];
6363

64-
static PATTERN_LEXER: LazyLock<Regex> =
65-
LazyLock::new(|| Regex::new(r"(?P<whitespace> +)|(?P<newline>\r?\n+)|(?P<tab>\t+)").unwrap());
64+
static PATTERN_LEXER: LazyLock<Regex> = LazyLock::new(|| {
65+
#[cfg(windows)]
66+
{
67+
// On Windows, treat \r\n as a single newline token
68+
Regex::new(r"(?P<whitespace> +)|(?P<newline>(\r\n|\n)+)|(?P<tab>\t+)").unwrap()
69+
}
70+
#[cfg(not(windows))]
71+
{
72+
// On other platforms, just check for \n
73+
Regex::new(r"(?P<whitespace> +)|(?P<newline>\n+)|(?P<tab>\t+)").unwrap()
74+
}
75+
});
6676

6777
fn whitespace_tokens(input: &str) -> VecDeque<Token> {
6878
let mut tokens = VecDeque::new();
@@ -202,6 +212,22 @@ mod tests {
202212
assert_eq!(tokens[1].kind, SyntaxKind::Newline);
203213
}
204214

215+
#[test]
216+
fn test_consecutive_newlines() {
217+
// Test with multiple consecutive newlines
218+
#[cfg(windows)]
219+
let input = "select\r\n\r\n1";
220+
#[cfg(not(windows))]
221+
let input = "select\n\n1";
222+
223+
let tokens = lex(input).unwrap();
224+
225+
// Check that we have exactly one newline token between "select" and "1"
226+
assert_eq!(tokens[0].kind, SyntaxKind::Select);
227+
assert_eq!(tokens[1].kind, SyntaxKind::Newline);
228+
assert_eq!(tokens[2].kind, SyntaxKind::Iconst);
229+
}
230+
205231
#[test]
206232
fn test_whitespace_tokens() {
207233
let input = "select 1";

crates/pglt_statement_splitter/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ mod tests {
114114
]);
115115
}
116116

117+
#[test]
118+
fn single_newlines() {
119+
Tester::from("select 1\nfrom contact\n\nselect 3")
120+
.expect_statements(vec!["select 1\nfrom contact", "select 3"]);
121+
}
122+
117123
#[test]
118124
fn alter_column() {
119125
Tester::from("alter table users alter column email drop not null;")

crates/pglt_statement_splitter/src/parser.rs

+11
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,17 @@ impl Parser {
183183
}
184184
}
185185

186+
#[cfg(windows)]
187+
/// Returns true if the token is relevant for the paring process
188+
///
189+
/// On windows, a newline is represented by `\r\n` which is two characters.
190+
fn is_irrelevant_token(t: &Token) -> bool {
191+
WHITESPACE_TOKENS.contains(&t.kind)
192+
&& (t.kind != SyntaxKind::Newline || t.text == "\r\n" || t.text.chars().count() == 1)
193+
}
194+
195+
#[cfg(not(windows))]
196+
/// Returns true if the token is relevant for the paring process
186197
fn is_irrelevant_token(t: &Token) -> bool {
187198
WHITESPACE_TOKENS.contains(&t.kind)
188199
&& (t.kind != SyntaxKind::Newline || t.text.chars().count() == 1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- test
2+
select id, name, test1231234123, unknown from co;
3+
4+
-- in between two statements
5+
6+
select 14433313331333 -- after a statement
7+
8+
alter table --within a statement
9+
test drop column id;
10+
11+
select lower('test');
12+
--after a statement
13+

0 commit comments

Comments
 (0)