Skip to content
Open
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
19 changes: 19 additions & 0 deletions src/sqlancer/postgres/PostgresGlobalState.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class PostgresGlobalState extends SQLGlobalState<PostgresOptions, Postgre
// store and allow filtering by function volatility classifications
private final Map<String, Character> functionsAndTypes = new HashMap<>();
private List<Character> allowedFunctionTypes = Arrays.asList(IMMUTABLE, STABLE, VOLATILE);
private int majorVersion;

@Override
public void setConnection(SQLConnection con) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -93,6 +95,19 @@ private List<String> 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<String> getOperators() {
return operators;
}
Expand Down Expand Up @@ -150,4 +165,8 @@ public List<Character> getAllowedFunctionTypes() {
return this.allowedFunctionTypes;
}

public int getMajorVersion() {
return majorVersion;
}

}
29 changes: 28 additions & 1 deletion src/sqlancer/postgres/gen/PostgresVacuumGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -25,12 +31,27 @@ public static SQLQueryAdapter create(PostgresGlobalState globalState) {
for (int i = 0; i < Randomly.smallNumber() + 1; i++) {
ArrayList<String> 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));
}
Expand Down Expand Up @@ -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);
}

Expand Down