Skip to content

Commit a2c4aef

Browse files
committed
Merge branch 'DBTOOLS-2075_fix_npe' into 'master'
DBTOOLS-2075 fixed NPE See merge request codekeeper/pgcodekeeper-core!273
2 parents edd2223 + 531744a commit a2c4aef

11 files changed

Lines changed: 197 additions & 1104 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616

1717
### Fixed
1818

19+
- Fixed parser errors for PostgreSQL.
20+
1921
## [14.4.1] - 2026-05-06
2022

2123
### Fixed

CHANGELOG.ru.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
### Исправлено
1818

19+
- Исправлены ошибки парсинга в PostgreSQL.
20+
1921
## [14.4.1] - 2026-05-06
2022

2123
### Исправлено

src/main/antlr4/org/pgcodekeeper/core/database/pg/parser/generated/SQLParser.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3886,7 +3886,7 @@ from_item
38863886

38873887
from_primary
38883888
: ONLY? schema_qualified_name MULTIPLY? alias_clause? (TABLESAMPLE method=identifier LEFT_PAREN vex (COMMA vex)* RIGHT_PAREN (REPEATABLE vex)?)?
3889-
| LATERAL? table_subquery alias_clause
3889+
| LATERAL? table_subquery alias_clause?
38903890
| LATERAL? function_call (WITH ORDINALITY)?
38913891
(AS from_function_column_def
38923892
| AS? alias=identifier (LEFT_PAREN column_alias+=identifier (COMMA column_alias+=identifier)* RIGHT_PAREN | from_function_column_def)?

src/main/java/org/pgcodekeeper/core/database/pg/parser/expr/PgSelect.java

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,37 +33,7 @@
3333
import org.pgcodekeeper.core.database.api.schema.meta.IMetaContainer;
3434
import org.pgcodekeeper.core.database.base.parser.QNameParser;
3535
import org.pgcodekeeper.core.database.pg.parser.PgParserUtils;
36-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.After_opsContext;
37-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Alias_clauseContext;
38-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.From_function_column_defContext;
39-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.From_itemContext;
40-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.From_primaryContext;
41-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.From_rows_with_aliasContext;
42-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Function_callContext;
43-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Groupby_clauseContext;
44-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Grouping_elementContext;
45-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Grouping_element_listContext;
46-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.IdentifierContext;
47-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.IndirectionContext;
48-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Indirection_listContext;
49-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Indirection_varContext;
50-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Orderby_clauseContext;
51-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Perform_stmtContext;
52-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Schema_qualified_nameContext;
53-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Select_listContext;
54-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Select_opsContext;
55-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Select_primaryContext;
56-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Select_stmtContext;
57-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Select_stmt_no_parensContext;
58-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Select_sublistContext;
59-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Table_subqueryContext;
60-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Value_expression_primaryContext;
61-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Values_stmtContext;
62-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Values_valuesContext;
63-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.VexContext;
64-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.Window_definitionContext;
65-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.With_clauseContext;
66-
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.With_queryContext;
36+
import org.pgcodekeeper.core.database.pg.parser.generated.SQLParser.*;
6737
import org.pgcodekeeper.core.database.pg.parser.rulectx.PgSelectOps;
6838
import org.pgcodekeeper.core.database.pg.parser.rulectx.PgSelectStmt;
6939
import org.pgcodekeeper.core.database.pg.parser.rulectx.PgVex;
@@ -582,16 +552,19 @@ private void from(From_itemContext fromItem) {
582552
lateralAllowed = primary.LATERAL() != null;
583553
List<ModPair<String, String>> columnList = new PgSelect(this).analyze(subquery.select_stmt());
584554

585-
String tableSubQueryAlias = alias.alias.getText();
586-
addReference(tableSubQueryAlias, null);
555+
var aliasCtx = alias.alias;
556+
if (aliasCtx != null) {
557+
String tableSubQueryAlias = aliasCtx.getText();
558+
addReference(tableSubQueryAlias, null);
587559

588-
var columnAliases = alias.column_alias;
589-
for (int i = 0; i < columnAliases.size() && i < columnList.size(); i++) {
590-
columnList.set(i, new ModPair<>(columnAliases.get(i).getText(),
591-
columnList.get(i).getSecond()));
592-
}
560+
var columnAliases = alias.column_alias;
561+
for (int i = 0; i < columnAliases.size() && i < columnList.size(); i++) {
562+
columnList.set(i, new ModPair<>(columnAliases.get(i).getText(),
563+
columnList.get(i).getSecond()));
564+
}
593565

594-
complexNamespace.put(tableSubQueryAlias, new ArrayList<>(columnList));
566+
complexNamespace.put(tableSubQueryAlias, new ArrayList<>(columnList));
567+
}
595568
} finally {
596569
lateralAllowed = oldLateral;
597570
}

src/test/java/org/pgcodekeeper/core/it/parser/pg/PgParserTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ class PgParserTest {
122122
//some strings are unsupported
123123
"strings",
124124
"subscription",
125-
"subselect",
126125
"sysviews",
127126
"time",
128127
"timestamp",
@@ -137,7 +136,6 @@ class PgParserTest {
137136
"user_mapping",
138137
"view",
139138
"window",
140-
"with",
141139
"pg_unicode_escaping"
142140
})
143141
void parse(final String fileNameTemplate) throws IOException {
@@ -150,7 +148,9 @@ void parse(final String fileNameTemplate) throws IOException {
150148
"groupingsets, 47",
151149
"partition_aggregate, 1",
152150
"partition_prune, 6",
153-
"select, 2"
151+
"select, 2",
152+
"subselect, 1",
153+
"with, 1",
154154
})
155155
void parse(String fileNameTemplate, int allowedAmbiguity) throws IOException {
156156
List<Object> errors = new ArrayList<>();

src/test/resources/org/pgcodekeeper/core/it/parser/pg/select.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1456,4 +1456,5 @@ SELECT js,
14561456
js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?"
14571457
FROM (VALUES ('[{"a":"1"},
14581458
{"b":"2","b":"3"}]')) foo(js);
1459-
SELECT _txt IS JSON;
1459+
SELECT _txt IS JSON;
1460+
select count(*) from (select tt.a, tt.b, tt.c, tt.d from testtable tt group by 1,2,3,4);

src/test/resources/org/pgcodekeeper/core/it/parser/pg/select_refs.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1115,4 +1115,5 @@ Reference: action = SELECT, line number = 1418, charPositionInLine = 0
11151115
Reference: action = SELECT, line number = 1420, charPositionInLine = 0
11161116
Reference: action = SELECT, line number = 1445, charPositionInLine = 0
11171117
Reference: action = SELECT, line number = 1452, charPositionInLine = 0
1118-
Reference: action = SELECT, line number = 1459, charPositionInLine = 0
1118+
Reference: action = SELECT, line number = 1459, charPositionInLine = 0
1119+
Reference: action = SELECT, line number = 1460, charPositionInLine = 0

0 commit comments

Comments
 (0)