Skip to content

Commit

Permalink
fix: postgresql alter view columns suggestions (#134)
Browse files Browse the repository at this point in the history
* fix: create viewName in psql grammar

* fix: psql alter view statement now has view names context
  • Loading branch information
roberthovsepyan authored Feb 15, 2024
1 parent a9aef1c commit ed60a24
Show file tree
Hide file tree
Showing 7 changed files with 11,900 additions and 11,794 deletions.

Large diffs are not rendered by default.

23,625 changes: 11,837 additions & 11,788 deletions src/autocomplete/postgresql/generated/PostgreSqlParser.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ import { TableAliasClauseContext } from "./PostgreSqlParser.js";
import { FunctionAliasClauseContext } from "./PostgreSqlParser.js";
import { JoinTypeContext } from "./PostgreSqlParser.js";
import { JoinQualifierContext } from "./PostgreSqlParser.js";
import { ViewNameContext } from "./PostgreSqlParser.js";
import { RelationExpressionContext } from "./PostgreSqlParser.js";
import { RelationExpressionListContext } from "./PostgreSqlParser.js";
import { RelationExpressionOptionalAliasContext } from "./PostgreSqlParser.js";
Expand Down Expand Up @@ -3674,6 +3675,12 @@ export class PostgreSqlParserVisitor<Result> extends AbstractParseTreeVisitor<Re
* @return the visitor result
*/
visitJoinQualifier?: (ctx: JoinQualifierContext) => Result;
/**
* Visit a parse tree produced by `PostgreSqlParser.viewName`.
* @param ctx the parse tree
* @return the visitor result
*/
visitViewName?: (ctx: ViewNameContext) => Result;
/**
* Visit a parse tree produced by `PostgreSqlParser.relationExpression`.
* @param ctx the parse tree
Expand Down
6 changes: 5 additions & 1 deletion src/autocomplete/postgresql/grammar/PostgreSqlParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ alterTableStatement
| ALTER INDEX (IF_P EXISTS)? qualifiedName (alterTableCommands | indexPartitionCommand)
| ALTER INDEX ALL IN_P TABLESPACE name (OWNED BY roleList)? SET TABLESPACE name optionalNowait
| ALTER SEQUENCE (IF_P EXISTS)? qualifiedName alterTableCommands
| ALTER VIEW (IF_P EXISTS)? qualifiedName alterTableCommands
| ALTER VIEW (IF_P EXISTS)? viewName alterTableCommands
| ALTER MATERIALIZED VIEW (IF_P EXISTS)? qualifiedName alterTableCommands
| ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name (OWNED BY roleList)? SET TABLESPACE name optionalNowait
| ALTER FOREIGN TABLE (IF_P EXISTS)? relationExpression alterTableCommands
Expand Down Expand Up @@ -2937,6 +2937,10 @@ joinQualifier
| ON expression1
;

viewName
: qualifiedName
;

relationExpression
: qualifiedName STAR?
| ONLY (qualifiedName | OPEN_PAREN qualifiedName CLOSE_PAREN)
Expand Down
13 changes: 13 additions & 0 deletions src/autocomplete/postgresql/postgreSqlAutocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
RelationExpressionContext,
TableReferenceContext,
Target_labelContext,
ViewNameContext,
} from './generated/PostgreSqlParser.js';
import {PostgreSqlParserVisitor} from './generated/PostgreSqlParserVisitor.js';
import {TableQueryPosition, TokenDictionary, getPreviousToken} from '../../lib/tables.js';
Expand Down Expand Up @@ -154,6 +155,18 @@ class PostgreSqlSymbolTableVisitor

return this.visitChildren(context) as {};
};

visitViewName = (context: ViewNameContext): {} => {
try {
this.symbolTable.addNewSymbolOfType(TableSymbol, this.scope, context.getText());
} catch (error) {
if (!(error instanceof c3.DuplicateSymbolError)) {
throw error;
}
}

return this.visitChildren(context) as {};
};
}

function generateSuggestionsFromRules(
Expand Down
20 changes: 18 additions & 2 deletions src/tests/postgresql/alter/alter-column.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import {ColumnSuggestion, parsePostgreSqlQueryWithoutCursor} from '../../..';
import {parsePostgreSqlQueryWithCursor} from '../../lib';

// This doesn't work for now because SymbolTableVisitor doesn't visit qualified_name to get the view name
test.skip('should suggest view name after ALTER COLUMN', () => {
test('should suggest view name after ALTER COLUMN', () => {
const parseResult = parsePostgreSqlQueryWithCursor('ALTER VIEW test_view ALTER COLUMN |');
const columnSuggestion: ColumnSuggestion = {tables: [{name: 'test_view'}]};

expect(parseResult.suggestColumns).toEqual(columnSuggestion);
});

test('should suggest view name after ALTER COLUMN between statements', () => {
const parseResult = parsePostgreSqlQueryWithCursor(
'ALTER TABLE before_table DROP COLUMN id; ALTER VIEW test_view ALTER COLUMN | ; ALTER TABLE after_table DROP COLUMN id;',
);
const columnSuggestion: ColumnSuggestion = {tables: [{name: 'test_view'}]};

expect(parseResult.suggestColumns).toEqual(columnSuggestion);
});

test('should suggest table name after ALTER COLUMN', () => {
const parseResult = parsePostgreSqlQueryWithCursor('ALTER TABLE test_table ALTER COLUMN |');
const columnSuggestion: ColumnSuggestion = {tables: [{name: 'test_table'}]};
Expand All @@ -32,3 +40,11 @@ test('should not report errors', () => {

expect(parseResult.errors).toHaveLength(0);
});

test('should not report errors', () => {
const parseResult = parsePostgreSqlQueryWithoutCursor(
'ALTER VIEW test_view ALTER COLUMN id SET DEFAULT 1;',
);

expect(parseResult.errors).toHaveLength(0);
});
20 changes: 18 additions & 2 deletions src/tests/postgresql/alter/rename-column.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import {ColumnSuggestion, KeywordSuggestion, parsePostgreSqlQueryWithoutCursor} from '../../..';
import {parsePostgreSqlQueryWithCursor} from '../../lib';

// This doesn't work for now because SymbolTableVisitor doesn't visit qualified_name to get the view name
test.skip('should suggest view name after RENAME COLUMN', () => {
test('should suggest view name after RENAME COLUMN', () => {
const parseResult = parsePostgreSqlQueryWithCursor('ALTER VIEW test_view RENAME COLUMN |');
const columnSuggestion: ColumnSuggestion = {tables: [{name: 'test_view'}]};

expect(parseResult.suggestColumns).toEqual(columnSuggestion);
});

test('should suggest view name after RENAME COLUMN between statements', () => {
const parseResult = parsePostgreSqlQueryWithCursor(
'ALTER TABLE before_table DROP COLUMN id; ALTER VIEW test_view RENAME COLUMN | ; ALTER TABLE after_table DROP COLUMN id;',
);
const columnSuggestion: ColumnSuggestion = {tables: [{name: 'test_view'}]};

expect(parseResult.suggestColumns).toEqual(columnSuggestion);
});

test('should suggest table name after RENAME COLUMN', () => {
const parseResult = parsePostgreSqlQueryWithCursor('ALTER TABLE test_table RENAME COLUMN |');
const columnSuggestion: ColumnSuggestion = {tables: [{name: 'test_table'}]};
Expand Down Expand Up @@ -39,3 +47,11 @@ test('should not report errors', () => {

expect(parseResult.errors).toHaveLength(0);
});

test('should not report errors', () => {
const parseResult = parsePostgreSqlQueryWithoutCursor(
'ALTER VIEW test_view RENAME COLUMN id TO name;',
);

expect(parseResult.errors).toHaveLength(0);
});

0 comments on commit ed60a24

Please sign in to comment.