Skip to content

Commit e58ec69

Browse files
committed
Merge branch 'DBTOOLS-2153_bug_parser_and_analyze' into 'master'
DBTOOLS-2153 fixed bug parser and analyze See merge request codekeeper/pgcodekeeper-core!299
2 parents 69f869b + 7a730ad commit e58ec69

11 files changed

Lines changed: 146 additions & 9 deletions

File tree

CHANGELOG.md

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

2222
### Changed
2323

24+
- Disabled dependency analysis for objects that could not be parsed correctly, reducing the number of irrelevant errors displayed to the user.
25+
2426
### Fixed
2527

2628
- Fixed a parsing error for the `ALTER SEQUENCE ... SET LOGGED/UNLOGGED` command for regular sequences in PostgreSQL.

CHANGELOG.ru.md

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

2222
### Изменено
2323

24+
- Отключен анализ зависимостей объектов, которые не получилось правильно распарсить, что уменьшило количество нерелевантных ошибок, отображаемых пользователю.
25+
2426
### Исправлено
2527

2628
- Исправлена ошибка парсинга команды `ALTER SEQUENCE ... SET LOGGED/UNLOGGED` для классических последовательностей в PostgreSQL.

src/main/java/org/pgcodekeeper/core/database/base/loader/AbstractJdbcLoader.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ protected <P extends Parser, R> void submitAntlrTask(BiFunction<List<Object>, St
7979
throw new MonitorCancelledRuntimeException();
8080
}
8181
setCurrentObject(object);
82-
finalizer.accept(r);
82+
if (list.isEmpty()) {
83+
finalizer.accept(r);
84+
}
8385
});
8486
}
8587

src/main/java/org/pgcodekeeper/core/database/pg/parser/statement/PgCreateFunction.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,10 @@ private void analyzeFunctionDefinition(PgAbstractFunction function, String langu
278278
AntlrTaskManager.submit(antlrTasks,
279279
() -> PgParserUtils.createSqlParser(def, name, err, start).sql(),
280280
funcCtx -> {
281-
errors.addAll(err);
281+
if (!err.isEmpty()) {
282+
errors.addAll(err);
283+
return;
284+
}
282285
PgFuncProcAnalysisLauncher launcher = new PgFuncProcAnalysisLauncher(
283286
function, funcCtx, fileName, funcArgs, settings.isEnableFunctionBodiesDependencies());
284287
launcher.setOffset(start);
@@ -292,7 +295,10 @@ private void analyzeFunctionDefinition(PgAbstractFunction function, String langu
292295
return parser.plpgsql_function();
293296
},
294297
funcCtx -> {
295-
errors.addAll(err);
298+
if (!err.isEmpty()) {
299+
errors.addAll(err);
300+
return;
301+
}
296302
PgFuncProcAnalysisLauncher launcher = new PgFuncProcAnalysisLauncher(
297303
function, funcCtx, fileName, funcArgs, settings.isEnableFunctionBodiesDependencies());
298304
launcher.setOffset(start);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*******************************************************************************
2+
* Copyright 2017-2026 TAXTELECOM, LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*******************************************************************************/
16+
17+
package org.pgcodekeeper.core.database.pg.loader;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.pgcodekeeper.core.TestUtils;
21+
import org.pgcodekeeper.core.database.pg.PgDatabaseProvider;
22+
import org.pgcodekeeper.core.settings.CoreSettings;
23+
24+
import java.io.IOException;
25+
26+
import static org.junit.jupiter.api.Assertions.assertFalse;
27+
import static org.junit.jupiter.api.Assertions.assertTrue;
28+
29+
class PgDumpLoaderTest {
30+
31+
@Test
32+
void skipAddAnalysisLauncherTest() throws IOException, InterruptedException {
33+
String resource = "broken_procedure.sql";
34+
var settings = new CoreSettings();
35+
settings.setEnableFunctionBodiesDependencies(true);
36+
var l = new PgDatabaseProvider().getDumpLoader(TestUtils.getFilePath(resource, getClass()), settings);
37+
var db = l.load();
38+
assertFalse(l.getErrors().isEmpty());
39+
assertTrue(db.getAnalysisLaunchers().isEmpty());
40+
}
41+
}

src/test/java/org/pgcodekeeper/core/it/IntegrationTestUtils.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ public static IDatabase loadTestDump(IDatabaseProvider databaseProvider, String
5858
public static IDatabase loadTestDump(IDatabaseProvider databaseProvider, String resource, Class<?> c,
5959
ISettings settings, boolean analysis)
6060
throws IOException, InterruptedException {
61+
return loadTestDump(databaseProvider, resource, c, settings, analysis, false);
62+
}
63+
64+
65+
public static IDatabase loadTestDump(IDatabaseProvider databaseProvider, String resource, Class<?> c,
66+
ISettings settings, boolean analysis, boolean hasErrors)
67+
throws IOException, InterruptedException {
6168
InputStreamProvider input = () -> c.getResourceAsStream(resource);
6269
String inputObjectName = "test/" + c.getName() + '/' + resource;
6370

@@ -68,7 +75,11 @@ public static IDatabase loadTestDump(IDatabaseProvider databaseProvider, String
6875
FullAnalyze.fullAnalyze(db, settings.getErrors(), settings.getVersion());
6976
}
7077

71-
TestUtils.assertErrors(settings.getErrors());
78+
if (hasErrors) {
79+
Assertions.assertFalse(settings.getErrors().isEmpty());
80+
} else {
81+
TestUtils.assertErrors(settings.getErrors());
82+
}
7283
return db;
7384
}
7485

src/test/java/org/pgcodekeeper/core/model/graph/pg/PgDepcyFinderTest.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class PgDepcyFinderTest {
3939
"view, public.v1",
4040
}, useHeadersInDisplayName = true)
4141
void compareReverseGraph(String fileName, String objectName) throws IOException, InterruptedException {
42-
compareGraph(fileName, FILES_POSTFIX.DEPS_REVERSE_TXT, objectName, true);
42+
compareGraph(fileName, FILES_POSTFIX.DEPS_REVERSE_TXT, objectName, true, false);
4343
}
4444

4545
@ParameterizedTest
@@ -64,19 +64,29 @@ void compareReverseGraph(String fileName, String objectName) throws IOException,
6464
"table_constraint, public.test_fk_1.fk",
6565
}, useHeadersInDisplayName = true)
6666
void compareBothGraph(String fileName, String objectName) throws IOException, InterruptedException {
67-
compareGraph(fileName, FILES_POSTFIX.DEPS_TXT, objectName, false);
68-
compareGraph(fileName, FILES_POSTFIX.DEPS_REVERSE_TXT, objectName, true);
67+
compareGraph(fileName, FILES_POSTFIX.DEPS_TXT, objectName, false, false);
68+
compareGraph(fileName, FILES_POSTFIX.DEPS_REVERSE_TXT, objectName, true, false);
6969
}
7070

71-
void compareGraph(String fileName, FILES_POSTFIX expectedPostfix, String objectName, boolean isReverse)
71+
@ParameterizedTest
72+
@CsvSource(value = {
73+
"fileName, objectName",
74+
"procedure_with_reserved_token, public.\"treat\""
75+
}, useHeadersInDisplayName = true)
76+
void compareBothGraphWithErrors(String fileName, String objectName) throws IOException, InterruptedException {
77+
compareGraph(fileName, FILES_POSTFIX.DEPS_TXT, objectName, false, true);
78+
compareGraph(fileName, FILES_POSTFIX.DEPS_REVERSE_TXT, objectName, true, true);
79+
}
80+
81+
void compareGraph(String fileName, FILES_POSTFIX expectedPostfix, String objectName, boolean isReverse, boolean hasErrors)
7282
throws IOException, InterruptedException {
7383
var settings = new CoreSettings();
7484
PgDatabaseProvider databaseProvider = new PgDatabaseProvider();
7585

7686
settings.setEnableFunctionBodiesDependencies(true);
7787

7888
IDatabase db = IntegrationTestUtils.loadTestDump(databaseProvider, fileName + FILES_POSTFIX.SQL,
79-
getClass(), settings);
89+
getClass(), settings, true, hasErrors);
8090

8191
var deps = DepcyFinder.byPatterns(10, isReverse, Collections.emptyList(), false, db, List.of(objectName));
8292
String actual = String.join("\n", deps);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CREATE OR REPLACE PROCEDURE public.lock_and_agg_items(p_id_1 integer, p_id_2 integer)
2+
LANGUAGE plpgsql
3+
AS $$
4+
DECLARE
5+
_rows public.treat[];
6+
BEGIN
7+
WITH locked_rows AS (
8+
SELECT *
9+
FROM public.treat
10+
WHERE id IN (p_id_1, p_id_2)
11+
FOR UPDATE
12+
)
13+
SELECT array_agg(x::public.treat)
14+
INTO _rows
15+
FROM locked_rows x;
16+
END;
17+
$$;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
CREATE TYPE public."treat" AS (
2+
id integer,
3+
name text,
4+
value numeric,
5+
created_at timestamp
6+
);
7+
8+
CREATE OR REPLACE PROCEDURE public.with_unquoted_token(p_id_1 integer, p_id_2 integer)
9+
LANGUAGE plpgsql
10+
AS $$
11+
DECLARE
12+
_rows public.treat[];
13+
BEGIN
14+
WITH locked_rows AS (
15+
SELECT *
16+
FROM public.treat
17+
WHERE id IN (p_id_1, p_id_2)
18+
FOR UPDATE
19+
)
20+
SELECT array_agg(x::public.treat)
21+
INTO _rows
22+
FROM locked_rows x;
23+
END;
24+
$$;
25+
26+
CREATE OR REPLACE PROCEDURE public.with_quoted_token(p_id_1 integer, p_id_2 integer)
27+
LANGUAGE plpgsql
28+
AS $$
29+
DECLARE
30+
_rows public."treat"[];
31+
BEGIN
32+
WITH locked_rows AS (
33+
SELECT *
34+
FROM public."treat"
35+
WHERE id IN (p_id_1, p_id_2)
36+
FOR UPDATE
37+
)
38+
SELECT array_agg(x::public."treat")
39+
INTO _rows
40+
FROM locked_rows x;
41+
END;
42+
$$;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
TYPE public."treat"
2+
PROCEDURE public.with_quoted_token(integer, integer)

0 commit comments

Comments
 (0)