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

feat: define database StatementPart, add identifierChain to TablesSuggestion, remove useless totos, migrate drop tests to typescript #96

Merged
merged 6 commits into from
Nov 30, 2023
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
5 changes: 5 additions & 0 deletions CODE_CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ You can always link those rules in your PR without hesitation if you see that th
- Don't use `foo` or `bar` custom names, always use `test_{object}`, e.g. `SELECT * FROM test_table`, not `SELECT * FROM hehe_haha`. If you need multiple names, use `_{number}` suffix, e.g. `SELECT test_field, test_field_2 FROM test_table;`
- Write all the static tokens in UPPER_CASE, and all the custom variables in lower_case, e.g. `SELECT test_field`
- Always test your statements on errors, and if there's an unexpected error, just add `TODO: fix unhandled error` error

What we'll do later:

- Add required in-between tests, e.g. `parseGeneralSql('DROP DATABASE', ' test_database')`. Currently most of the tests are only checking if query is good when the cursor is at the end.
- Add more shared grouping tests.
14 changes: 10 additions & 4 deletions src/parsing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,19 @@ export type StatementPart =
identifierChain: IdentifierChainEntry[]
tables: Table[]
qualified: boolean,
}
| {
type: "database"
location: Location,
identifierChain: IdentifierChainEntry[],
};

export interface TablesSuggestion {
prependFrom?: boolean; // TODO: figure our if it's optional
prependQuestionMark?: boolean; // TODO: figure our if it's optional
onlyTables?: boolean; // TODO: figure our if it's optional
onlyViews?: boolean; // TODO: figure our if it's optional
prependFrom?: boolean;
prependQuestionMark?: boolean;
onlyTables?: boolean;
onlyViews?: boolean;
identifierChain?: IdentifierChainEntry[];
}

export interface DatabasesSuggestion {
Expand Down
12 changes: 12 additions & 0 deletions src/parsing/parsers/generic/jison/alter/alter_common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,16 @@ test('should suggest ALTER', () => {

const suggestion: KeywordSuggestion = { value: 'ALTER', weight: -1 };
expect(parseResult.suggestKeywords).toContainEqual(suggestion);
})

test('should suggest ALTER objects', () => {
const parseResult = parseGenericSql('ALTER ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'TABLE', weight: -1 },
{ value: 'VIEW', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(suggestions)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've decided to move those tests closer to their definition. Even though it can be separated to alter_table, alter_view files. But the actual code that suggests it is alter_common, so it's better this way.

})
10 changes: 0 additions & 10 deletions src/parsing/parsers/generic/jison/alter/alter_table.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import {
DatabasesSuggestion,
KeywordSuggestion,
parseGenericSql, TablesSuggestion,
} from '../../../../index';
import {expect, test} from '@jest/globals';

test('should suggest altering table', () => {
const parseResult = parseGenericSql('ALTER ', '');

expect(parseResult.errors).toBeUndefined();

const suggestion: KeywordSuggestion = { value: 'TABLE', weight: -1 };
expect(parseResult.suggestKeywords).toContainEqual(suggestion);
})

test('should suggest tables to alter', () => {
const parseResult = parseGenericSql('ALTER TABLE ', '');

Expand Down
11 changes: 1 addition & 10 deletions src/parsing/parsers/generic/jison/alter/alter_view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,6 @@ import {
} from '../../../../index';
import {expect, test} from '@jest/globals';

test('should suggest altering views', () => {
const parseResult = parseGenericSql('ALTER ', '');

expect(parseResult.errors).toBeUndefined();

const suggestion: KeywordSuggestion = { value: 'VIEW', weight: -1 };
expect(parseResult.suggestKeywords).toContainEqual(suggestion);
})

test('should suggest views to alter', () => {
const parseResult = parseGenericSql('ALTER VIEW ', '');

Expand Down Expand Up @@ -52,7 +43,7 @@ test('should suggest SELECT', () => {
expect(parseResult.suggestKeywords).toEqual(suggestion);
})

test('should not report errors on full ALTER VIEW statement and fill locations', () => {
test('should not report errors on full statement and fill locations', () => {
const parseResult = parseGenericSqlWithoutCursor('ALTER VIEW test_view AS SELECT test_field, test_field_2 FROM test_table;');

expect(parseResult.errors).toBeUndefined();
Expand Down
15 changes: 15 additions & 0 deletions src/parsing/parsers/generic/jison/create/create_common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,19 @@ test('should suggest CREATE', () => {

const suggestion: KeywordSuggestion = { value: 'CREATE', weight: -1 };
expect(parseResult.suggestKeywords).toContainEqual(suggestion);
})

test('should suggest CREATE objects', () => {
const parseResult = parseGenericSql('CREATE ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'DATABASE', weight: -1 },
{ value: 'ROLE', weight: -1 },
{ value: 'SCHEMA', weight: -1 },
{ value: 'TABLE', weight: -1 },
{ value: 'VIEW', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(suggestions)
})
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@ import {expect, test} from '@jest/globals';
// - 'something IF NOT [exists]'
// - 'something [IF NOT EXISTS] something2'

test('should suggest creating DATABASE and SCHEMA', () => {
const parseResult = parseGenericSql('CREATE ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'DATABASE', weight: -1 },
{ value: 'SCHEMA', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestions))
})

// TODO: remove duplicates, because databaseOrSchema should be tested separately
test('should suggest IF NOT EXISTS for database creation', () => {
const parseResult = parseGenericSql('CREATE DATABASE ', '');
Expand All @@ -46,12 +34,12 @@ test('should suggest IF NOT EXISTS for schema creation', () => {
})

// TODO: remove duplicates, because databaseOrSchema should be tested separately
test('should not report errors on full CREATE DATABASE statement', () => {
test('should not report errors on full statement', () => {
const parseResult = parseGenericSqlWithoutCursor('CREATE DATABASE test_database;');
expect(parseResult.errors).toBeUndefined();
})

test('should not report errors on full CREATE SCHEMA statement and fill locations', () => {
test('should not report errors on full statement and fill locations', () => {
const parseResult = parseGenericSqlWithoutCursor('CREATE SCHEMA test_schema;');

expect(parseResult.errors).toBeUndefined();
Expand Down
16 changes: 2 additions & 14 deletions src/parsing/parsers/generic/jison/create/create_role.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import {
KeywordSuggestion,
parseGenericSql, parseGenericSqlWithoutCursor, StatementPart,
parseGenericSqlWithoutCursor, StatementPart,
} from '../../../../index';
import {expect, test} from '@jest/globals';

test('should suggest creating ROLE', () => {
const parseResult = parseGenericSql('CREATE ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'ROLE', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestions))
})

test('should not report errors on full CREATE ROLE statement and fill locations', () => {
test('should not report errors on full statement and fill locations', () => {
const parseResult = parseGenericSqlWithoutCursor('CREATE ROLE test_role;');

expect(parseResult.errors).toBeUndefined();
Expand Down
13 changes: 1 addition & 12 deletions src/parsing/parsers/generic/jison/create/create_table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@ import {
} from '../../../../index';
import {expect, test} from '@jest/globals';

test('should suggest creating TABLE', () => {
const parseResult = parseGenericSql('CREATE ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'TABLE', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestions))
})

test('should suggest IF NOT EXISTS', () => {
const parseResult = parseGenericSql('CREATE TABLE ', '');

Expand Down Expand Up @@ -62,7 +51,7 @@ test('should suggest data types when some types are already written', () => {
expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestions))
})

test('should not report errors on full CREATE TABLE statement', () => {
test('should not report errors on full statement and fill locations', () => {
const parseResult = parseGenericSqlWithoutCursor('CREATE TABLE test_table (id INT, age FLOAT);');

expect(parseResult.errors).toBeUndefined();
Expand Down
15 changes: 2 additions & 13 deletions src/parsing/parsers/generic/jison/create/create_view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@ import {
} from '../../../../index';
import {expect, test} from '@jest/globals';

test('should suggest creating VIEW', () => {
const parseResult = parseGenericSql('CREATE ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'VIEW', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestions))
})

test('should suggest IF NOT EXISTS', () => {
const parseResult = parseGenericSql('CREATE VIEW ', '');

Expand Down Expand Up @@ -49,12 +38,12 @@ test('should suggest SELECT', () => {
expect(parseResult.suggestKeywords).toEqual(suggestions)
})

test('should not report errors on full CREATE VIEW statement without comment', () => {
test('should not report errors on full statement without comment', () => {
const parseResult = parseGenericSqlWithoutCursor('CREATE VIEW test_view AS SELECT test_field, test_field_2 FROM test_table;');
expect(parseResult.errors).toBeUndefined();
})

test('should not report errors on full CREATE VIEW statement and fill locations', () => {
test('should not report errors on full statement and fill locations', () => {
const parseResult = parseGenericSqlWithoutCursor('CREATE VIEW test_view COMMENT "test" AS SELECT test_field, test_field_2 FROM test_table;');

expect(parseResult.errors).toBeUndefined();
Expand Down
9 changes: 4 additions & 5 deletions src/parsing/parsers/generic/jison/delete/delete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import {
ColumnSuggestion,
KeywordSuggestion,
parseGenericSql,
parseGenericSqlWithoutCursor, StatementPart,
parseGenericSqlWithoutCursor, StatementPart, TablesSuggestion,
} from '../../../../index';
import {expect, test} from '@jest/globals';

// TODO: reuse it in more places
const SUGGEST_TABLES_VALUE = {};

test('should suggest DELETE', () => {
const parseResult = parseGenericSql('', '');

Expand All @@ -31,7 +28,9 @@ test('should suggest tables', () => {
const parseResult = parseGenericSql('DELETE FROM ', '');

expect(parseResult.errors).toBeUndefined();
expect(parseResult.suggestTables).toEqual(SUGGEST_TABLES_VALUE);

const tablesSuggestion: TablesSuggestion = {};
expect(parseResult.suggestTables).toEqual(tablesSuggestion);
})

test('should suggest WHERE', () => {
Expand Down
11 changes: 0 additions & 11 deletions src/parsing/parsers/generic/jison/drop/drop_common.test.json

This file was deleted.

31 changes: 31 additions & 0 deletions src/parsing/parsers/generic/jison/drop/drop_common.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
KeywordSuggestion,
parseGenericSql
} from '../../../../index';
import {expect, test} from '@jest/globals';

test('should suggest DROP on empty query', () => {
const parseResult = parseGenericSql('', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'DROP', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(expect.arrayContaining(suggestions))
})

test('should suggest DROP objects', () => {
const parseResult = parseGenericSql('DROP ', '');

expect(parseResult.errors).toBeUndefined();

const suggestions: KeywordSuggestion[] = [
{ value: 'DATABASE', weight: -1 },
{ value: 'ROLE', weight: -1 },
{ value: 'SCHEMA', weight: -1 },
{ value: 'TABLE', weight: -1 },
{ value: 'VIEW', weight: -1 },
];
expect(parseResult.suggestKeywords).toEqual(suggestions)
})
58 changes: 0 additions & 58 deletions src/parsing/parsers/generic/jison/drop/drop_database.test.json

This file was deleted.

Loading
Loading