sqlancer.postgres.gen.PostgresSetGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sqlancer Show documentation
Show all versions of sqlancer Show documentation
SQLancer finds logic bugs in Database Management Systems through automatic testing
package sqlancer.postgres.gen;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Function;
import sqlancer.Randomly;
import sqlancer.common.query.SQLQueryAdapter;
import sqlancer.postgres.PostgresGlobalState;
public final class PostgresSetGenerator {
private PostgresSetGenerator() {
}
private enum ConfigurationOption {
// https://www.postgresql.org/docs/11/runtime-config-wal.html
// This parameter can only be set at server start.
// WAL_LEVEL("wal_level", (r) -> Randomly.fromOptions("replica", "minimal", "logical")),
// FSYNC("fsync", (r) -> Randomly.fromOptions(1, 0)),
SYNCHRONOUS_COMMIT("synchronous_commit",
(r) -> Randomly.fromOptions("remote_apply", "remote_write", "local", "off")),
WAL_COMPRESSION("wal_compression", (r) -> Randomly.fromOptions(1, 0)),
// wal_buffer: server start
// wal_writer_delay: server start
// wal_writer_flush_after
COMMIT_DELAY("commit_delay", (r) -> r.getInteger(0, 100000)),
COMMIT_SIBLINGS("commit_siblings", (r) -> r.getInteger(0, 1000)),
// 19.5.2. Checkpoints
// checkpoint_timeout
// checkpoint_completion_target
// checkpoint_flush_after
// checkpoint_warning
// max_wal_size
// min_wal_size
// 19.5.3. Archiving
// archive_mode
// archive_command
// archive_timeout
// https://www.postgresql.org/docs/11/runtime-config-statistics.html
// 19.9.1. Query and Index Statistics Collector
TRACK_ACTIVITIES("track_activities", (r) -> Randomly.fromOptions(1, 0)),
// track_activity_query_size
TRACK_COUNTS("track_counts", (r) -> Randomly.fromOptions(1, 0)),
TRACK_IO_TIMING("track_io_timing", (r) -> Randomly.fromOptions(1, 0)),
TRACK_FUNCTIONS("track_functions", (r) -> Randomly.fromOptions("'none'", "'pl'", "'all'")),
// stats_temp_directory
// TODO 19.9.2. Statistics Monitoring
// https://www.postgresql.org/docs/11/runtime-config-autovacuum.html
// all can only be set at server-conf time
// 19.11. Client Connection Defaults
VACUUM_FREEZE_TABLE_AGE("vacuum_freeze_table_age", (r) -> Randomly.fromOptions(0, 5, 10, 100, 500, 2000000000)),
VACUUM_FREEZE_MIN_AGE("vacuum_freeze_min_age", (r) -> Randomly.fromOptions(0, 5, 10, 100, 500, 1000000000)),
VACUUM_MULTIXACT_FREEZE_TABLE_AGE("vacuum_multixact_freeze_table_age",
(r) -> Randomly.fromOptions(0, 5, 10, 100, 500, 2000000000)),
VACUUM_MULTIXACT_FREEZE_MIN_AGE("vacuum_multixact_freeze_min_age",
(r) -> Randomly.fromOptions(0, 5, 10, 100, 500, 1000000000)),
VACUUM_CLEANUP_INDEX_SCALE_FACTOR("vacuum_cleanup_index_scale_factor",
(r) -> Randomly.fromOptions(0.0, 0.0000001, 0.00001, 0.01, 0.1, 1, 10, 100, 100000, 10000000000.0)),
// TODO others
GIN_FUZZY_SEARCH_LIMIT("gin_fuzzy_search_limit", (r) -> r.getInteger(0, 2147483647)),
// 19.13. Version and Platform Compatibility
DEFAULT_WITH_OIDS("default_with_oids", (r) -> Randomly.fromOptions(0, 1)),
SYNCHRONIZED_SEQSCANS("synchronize_seqscans", (r) -> Randomly.fromOptions(0, 1)),
// https://www.postgresql.org/docs/devel/runtime-config-query.html
ENABLE_BITMAPSCAN("enable_bitmapscan", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_GATHERMERGE("enable_gathermerge", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_HASHJOIN("enable_hashjoin", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_INDEXSCAN("enable_indexscan", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_INDEXONLYSCAN("enable_indexonlyscan", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_MATERIAL("enable_material", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_MERGEJOIN("enable_mergejoin", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_NESTLOOP("enable_nestloop", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_PARALLEL_APPEND("enable_parallel_append", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_PARALLEL_HASH("enable_parallel_hash", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_PARTITION_PRUNING("enable_partition_pruning", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_PARTITIONWISE_JOIN("enable_partitionwise_join", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_PARTITIONWISE_AGGREGATE("enable_partitionwise_aggregate", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_SEGSCAN("enable_seqscan", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_SORT("enable_sort", (r) -> Randomly.fromOptions(1, 0)),
ENABLE_TIDSCAN("enable_tidscan", (r) -> Randomly.fromOptions(1, 0)),
// 19.7.2. Planner Cost Constants (complete as of March 2020)
// https://www.postgresql.org/docs/current/runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS
SEQ_PAGE_COST("seq_page_cost", (r) -> Randomly.fromOptions(0d, 0.00001, 0.05, 0.1, 1, 10, 10000)),
RANDOM_PAGE_COST("random_page_cost", (r) -> Randomly.fromOptions(0d, 0.00001, 0.05, 0.1, 1, 10, 10000)),
CPU_TUPLE_COST("cpu_tuple_cost", (r) -> Randomly.fromOptions(0d, 0.00001, 0.05, 0.1, 1, 10, 10000)),
CPU_INDEX_TUPLE_COST("cpu_index_tuple_cost", (r) -> Randomly.fromOptions(0d, 0.00001, 0.05, 0.1, 1, 10, 10000)),
CPU_OPERATOR_COST("cpu_operator_cost", (r) -> Randomly.fromOptions(0d, 0.000001, 0.0025, 0.1, 1, 10, 10000)),
PARALLEL_SETUP_COST("parallel_setup_cost", (r) -> r.getLong(0, Long.MAX_VALUE)),
PARALLEL_TUPLE_COST("parallel_tuple_cost", (r) -> r.getLong(0, Long.MAX_VALUE)),
MIN_PARALLEL_TABLE_SCAN_SIZE("min_parallel_table_scan_size", (r) -> r.getInteger(0, 715827882)),
MIN_PARALLEL_INDEX_SCAN_SIZE("min_parallel_index_scan_size", (r) -> r.getInteger(0, 715827882)),
EFFECTIVE_CACHE_SIZE("effective_cache_size", (r) -> r.getInteger(1, 2147483647)),
JIT_ABOVE_COST("jit_above_cost", (r) -> Randomly.fromOptions(0, r.getLong(-1, Long.MAX_VALUE - 1))),
JIT_INLINE_ABOVE_COST("jit_inline_above_cost", (r) -> Randomly.fromOptions(0, r.getLong(-1, Long.MAX_VALUE))),
JIT_OPTIMIZE_ABOVE_COST("jit_optimize_above_cost",
(r) -> Randomly.fromOptions(0, r.getLong(-1, Long.MAX_VALUE))),
// 19.7.3. Genetic Query Optimizer (complete as of March 2020)
// https://www.postgresql.org/docs/current/runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO
GEQO("geqo", (r) -> Randomly.fromOptions(1, 0)),
GEQO_THRESHOLD("geqo_threshold", (r) -> r.getInteger(2, 2147483647)),
GEQO_EFFORT("geqo_effort", (r) -> r.getInteger(1, 10)),
GEQO_POO_SIZE("geqo_pool_size", (r) -> r.getInteger(0, 2147483647)),
GEQO_GENERATIONS("geqo_generations", (r) -> r.getInteger(0, 2147483647)),
GEQO_SELECTION_BIAS("geqo_selection_bias", (r) -> Randomly.fromOptions(1.5, 1.8, 2.0)),
GEQO_SEED("geqo_seed", (r) -> Randomly.fromOptions(0, 0.5, 1)),
// 19.7.4. Other Planner Options (complete as of March 2020)
// https://www.postgresql.org/docs/current/runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER
DEFAULT_STATISTICS_TARGET("default_statistics_target", (r) -> r.getInteger(1, 10000)),
CONSTRAINT_EXCLUSION("constraint_exclusion", (r) -> Randomly.fromOptions("on", "off", "partition")),
CURSOR_TUPLE_FRACTION("cursor_tuple_fraction",
(r) -> Randomly.fromOptions(0.0, 0.1, 0.000001, 1, 0.5, 0.9999999)),
FROM_COLLAPSE_LIMIT("from_collapse_limit", (r) -> r.getInteger(1, Integer.MAX_VALUE)),
JIT("jit", (r) -> Randomly.fromOptions(1, 0)),
JOIN_COLLAPSE_LIMIT("join_collapse_limit", (r) -> r.getInteger(1, Integer.MAX_VALUE)),
PARALLEL_LEADER_PARTICIPATION("parallel_leader_participation", (r) -> Randomly.fromOptions(1, 0)),
FORCE_PARALLEL_MODE("force_parallel_mode", (r) -> Randomly.fromOptions("off", "on", "regress")),
PLAN_CACHE_MODE("plan_cache_mode",
(r) -> Randomly.fromOptions("auto", "force_generic_plan", "force_custom_plan"));
private String optionName;
private Function op;
ConfigurationOption(String optionName, Function op) {
this.optionName = optionName;
this.op = op;
}
}
public static SQLQueryAdapter create(PostgresGlobalState globalState) {
StringBuilder sb = new StringBuilder();
ArrayList options = new ArrayList<>(Arrays.asList(ConfigurationOption.values()));
options.remove(ConfigurationOption.DEFAULT_WITH_OIDS);
ConfigurationOption option = Randomly.fromList(options);
sb.append("SET ");
if (Randomly.getBoolean()) {
sb.append(Randomly.fromOptions("SESSION", "LOCAL"));
sb.append(" ");
}
sb.append(option.optionName);
sb.append("=");
if (Randomly.getBoolean()) {
sb.append("DEFAULT");
} else {
sb.append(option.op.apply(globalState.getRandomly()));
}
return new SQLQueryAdapter(sb.toString());
}
}