Skip to content

Commit

Permalink
fix: Handle multiline sql without spaces
Browse files Browse the repository at this point in the history
When replacing multiline comment, it is now done with a space instead of
nothing since this would be valid sql:
```sql
SELECT pid FROM/*comment*/pg_stat_activity;
```
But replacing the comment with "" would make it incorrect.

Also join the lines in query on getContent with a space to remove the
need for spaces in the sql. Previously this sql:
```sql
SELECT some_column
FROM some_table;
```
would result in this error: `[error] column "some_columnfrom" does not
exist`
This PR fixes that.
  • Loading branch information
nossrannug committed Jun 22, 2022
1 parent 9b51f22 commit 45e465a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 33 deletions.
8 changes: 1 addition & 7 deletions src/reader/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ class Query {
public category: string;

public getContent() {
let content: string = "";

this.lines.forEach((line) => {
content += line.content;
});

return content;
return this.lines.map(line => line.content.trim()).join(" ");
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/reader/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ export function putContentIntoLines(contents: string): Query[] {
}

if (contents[i] === Keyword.Newline) {
if (currentQueryContent.length > 0) {
if (currentQueryContent.trim().length > 0) {
query.lines.push(new Line(currentQueryContent, lineNumber));
}
currentQueryContent = "";
lineNumber++;
}

if (contents[i] === ";") {
if (currentQueryContent.length > 0) {
if (currentQueryContent.trim().length > 0) {
query.lines.push(new Line(currentQueryContent, lineNumber));
}
queriesFromFile.push(query);
Expand All @@ -53,7 +53,7 @@ export function putContentIntoLines(contents: string): Query[] {
* 3. Rejoin the lines together as a single string.
*/
function stripComments(content: string): string {
content = content.replace(reMultilineComments, "");
content = content.replace(reMultilineComments, " ");
const contentInLines = content.split(Keyword.Newline);

for (let i = 0; i < contentInLines.length; i++) {
Expand Down
46 changes: 23 additions & 23 deletions test/unit/reader/reader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,63 +4,63 @@ import {
} from "../../../src/reader/reader";
import { Query } from "../../../src/reader/query";
import { Line } from "../../../src/reader/line";

let query, queryWithComments;
beforeEach(() => {
this.query = new Query();
this.query.lines = [
new Line("DELETE", 1),
new Line(" FROM ", 2),
new Line(" person WHERE ", 4),
query = new Query();
query.lines = [
new Line(" DELETE", 1),
new Line("FROM", 2),
new Line("person WHERE", 4),
new Line(" age > 5;", 5),
];

this.queryWithComments = new Query();
this.queryWithComments.lines = [
queryWithComments = new Query();
queryWithComments.lines = [
new Line("DELETE", 1),
new Line(" FROM ", 2),
new Line(" person WHERE ", 4),
new Line(" age > 5;", 6),
new Line("FROM", 2),
new Line("person WHERE", 4),
new Line("age > 5;", 6),
];
});

test("We correctly read a file", () => {
const expected: any = [this.query];
const input = "DELETE\n FROM \n\n person WHERE \n age > 5;";
const expected: any = [query];
const input = " DELETE\nFROM\n\nperson WHERE\n age > 5;";
const actual = putContentIntoLines(input);
expect(actual).toEqual(expected);
});

test.each([
// Test we ignore '--' comments
["DELETE\n FROM \n\n person WHERE \n-- Remove old people\n age > 5;"],
["DELETE\nFROM\n\nperson WHERE\n-- Remove old people\nage > 5;"],

// We ignore '#' comments
["DELETE\n FROM \n\n person WHERE \n# Remove old people\n age > 5;"],
["DELETE\nFROM\n\nperson WHERE\n# Remove old people\nage > 5;"],

// We ignore '/*' comments on a single line
["DELETE\n FROM \n\n person WHERE \n/* Remove old people*/\n age > 5;"],
["DELETE\nFROM\n\nperson WHERE\n/* Remove old people*/\nage > 5;"],
])("We ignore comments in files", (input) => {
const actual = putContentIntoLines(input);
expect(actual).toEqual([this.queryWithComments]);
expect(actual).toEqual([queryWithComments]);
});

test("We correctly reconstruct our query from lines", () => {
const expected: string = "DELETE FROM person WHERE age > 5;";
const actual = this.query.getContent();
const expected: string = "DELETE FROM person WHERE age > 5;";
const actual = query.getContent();
expect(actual).toEqual(expected);
});

test("We correctly construct lines in a query from a string", () => {
const expected: any = [this.query];
const expected: any = [query];

const input = "DELETE\n FROM \n\n person WHERE \n age > 5;";
const input = " DELETE\nFROM\n\nperson WHERE\n age > 5;";
const actual = getQueryFromLine(input);
expect(actual).toEqual(expected);
});

test("We should ignore multiline comments", () => {
const input =
"/*\n * catpants\n*/DELETE\n FROM \n\n person /*comment */WHERE \n/*\n\n this is useless*/ age > 5;";
"/*\n * catpants\n*/DELETE\nFROM\n\nperson/*comment */WHERE\n/*\n\n this is useless*/age > 5;";

expect(getQueryFromLine(input)).toEqual([this.query]);
expect(getQueryFromLine(input)).toEqual([query]);
});

0 comments on commit 45e465a

Please sign in to comment.