From ebd7c899f16ad9608ae04b7a0c8b69a098a6d593 Mon Sep 17 00:00:00 2001 From: Pratyksh Date: Sat, 5 Apr 2025 23:27:30 +0530 Subject: [PATCH 1/2] Added PostgreSQL v13 VACUUM PARALLEL option support --- .../postgres/PostgresGlobalState.java | 19 ++++++++++++ .../postgres/gen/PostgresVacuumGenerator.java | 29 ++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/sqlancer/postgres/PostgresGlobalState.java b/src/sqlancer/postgres/PostgresGlobalState.java index 0f2c7ebdb..a5cdceec6 100644 --- a/src/sqlancer/postgres/PostgresGlobalState.java +++ b/src/sqlancer/postgres/PostgresGlobalState.java @@ -27,6 +27,7 @@ public class PostgresGlobalState extends SQLGlobalState functionsAndTypes = new HashMap<>(); private List allowedFunctionTypes = Arrays.asList(IMMUTABLE, STABLE, VOLATILE); + private int majorVersion; @Override public void setConnection(SQLConnection con) { @@ -36,6 +37,7 @@ public void setConnection(SQLConnection con) { this.operators = getOperators(getConnection()); this.collates = getCollnames(getConnection()); this.tableAccessMethods = getTableAccessMethods(getConnection()); + this.majorVersion = getMajorVersion(getConnection()); } catch (SQLException e) { throw new AssertionError(e); } @@ -93,6 +95,19 @@ private List getTableAccessMethods(SQLConnection con) throws SQLExceptio return tableAccessMethods; } + private int getMajorVersion(SQLConnection con) throws SQLException { + try (Statement s = con.createStatement()) { + try (ResultSet rs = s.executeQuery("SHOW server_version_num;")) { + if (rs.next()) { + // Server version returns a number like 130018 for 13.18 + // Divide by 10000 to get major version (13) + return rs.getInt(1) / 10000; + } + } + } + return 0; // Default to 0 if version cannot be determined + } + public List getOperators() { return operators; } @@ -150,4 +165,8 @@ public List getAllowedFunctionTypes() { return this.allowedFunctionTypes; } + public int getMajorVersion() { + return majorVersion; + } + } diff --git a/src/sqlancer/postgres/gen/PostgresVacuumGenerator.java b/src/sqlancer/postgres/gen/PostgresVacuumGenerator.java index ef32db45a..67b02f743 100644 --- a/src/sqlancer/postgres/gen/PostgresVacuumGenerator.java +++ b/src/sqlancer/postgres/gen/PostgresVacuumGenerator.java @@ -10,6 +10,12 @@ import sqlancer.postgres.PostgresGlobalState; import sqlancer.postgres.PostgresSchema.PostgresTable; +/** + * Generates VACUUM commands for PostgreSQL. + * This implementation supports PostgreSQL 13 features including the PARALLEL option. + * The PARALLEL option specifies the number of parallel worker processes to use when running + * a parallel vacuum (only applies to the collection of table data, not indexes). + */ public final class PostgresVacuumGenerator { private PostgresVacuumGenerator() { @@ -25,12 +31,27 @@ public static SQLQueryAdapter create(PostgresGlobalState globalState) { for (int i = 0; i < Randomly.smallNumber() + 1; i++) { ArrayList opts = new ArrayList<>(Arrays.asList("FULL", "FREEZE", "ANALYZE", "VERBOSE", "DISABLE_PAGE_SKIPPING", "SKIP_LOCKED", "INDEX_CLEANUP", "TRUNCATE")); + + // Add PARALLEL option if PostgreSQL version is 13 or higher + int majorVersion = globalState.getMajorVersion(); + if (majorVersion >= 13) { + opts.add("PARALLEL"); + } + String option = Randomly.fromList(opts); if (i != 0) { sb.append(", "); } sb.append(option); - if (Randomly.getBoolean()) { + + // For PostgreSQL v13+, PARALLEL always needs a value + if (option.equals("PARALLEL") && majorVersion >= 13) { + // PARALLEL takes integer value between 0 and 1024 + sb.append(" "); + sb.append(Randomly.getNotCachedInteger(0, 4)); // Use reasonable value for testing + } + // For other options, randomly decide whether to append a value + else if (Randomly.getBoolean()) { sb.append(" "); sb.append(Randomly.fromOptions(1, 0)); } @@ -60,6 +81,12 @@ public static SQLQueryAdapter create(PostgresGlobalState globalState) { */ errors.add("ERROR: ANALYZE option must be specified when a column list is provided"); errors.add("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL"); + + // Add error specific to PostgreSQL v13's PARALLEL option + if (globalState.getMajorVersion() >= 13) { + errors.add("VACUUM option PARALLEL cannot be used with FULL"); + } + return new SQLQueryAdapter(sb.toString(), errors); } From d13a845cb02a5ea765b6ba372b69a924c33d9588 Mon Sep 17 00:00:00 2001 From: Pratyksh Date: Sun, 6 Apr 2025 15:09:07 +0530 Subject: [PATCH 2/2] Added the new verison 13 in the main.yml file --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 373ea3896..1744f6a3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -467,7 +467,7 @@ jobs: - name: Set up PostgreSQL uses: harmon758/postgresql-action@v1.0.0 with: - postgresql version: '12' + postgresql version: '13' postgresql user: 'sqlancer' postgresql password: 'sqlancer' postgresql db: 'test'