-
Notifications
You must be signed in to change notification settings - Fork 246
[Proposal] Continuous SQLancer fuzzing for Cloudberry (5 bugs from a first run, looking for volunteers) #1952
ProposersProposal StatusUnder Discussion AbstractHi all, @roseduan and I recently pointed SQLancer at Cloudberry Given how little effort this took, we think Cloudberry would benefit from running SQLancer regularly and automatically. SQLancer is already listed as a planned testing item on the project roadmap (#868), and it has paid off here before: @shmiwy found #594 and #596 with it in 2024, both since fixed (#722, #598), and @congxuebin's #317 in 2023 was a useful data point even though it turned out to be expected behaviour. What we are proposing is to make this routine instead of an occasional one-off. To be upfront: neither of us can drive the automation work ourselves right now. We are posting this to share what we found, sketch a plan that we think is realistic, and see whether a few people would like to pick up pieces of it, with our help getting started. What we found
All five reproduce on current The run used the stock Reproducers1. ORCA drops the Agg for DISTINCT over a nullable UNIQUE column create table repro (c0 numeric unique); insert into repro values (1), (2), (null), (null), (null); select distinct c0 from repro; -- optimizer=on -> 5 rows (plan is Gather Motion -> Seq Scan, no aggregate) -- optimizer=off -> 3 rows 2. Merge FULL JOIN with a provably-empty side CREATE TABLE gs_part (a int) PARTITION BY RANGE (a) DISTRIBUTED BY (a); CREATE TABLE gs_r (a int) DISTRIBUTED BY (a); CREATE TABLE gs_s (a int) DISTRIBUTED BY (a); SET optimizer = on; EXPLAIN SELECT * FROM gs_s, gs_r FULL JOIN gs_part ON gs_r.a = gs_part.a; -- ERROR: unexpected gang size: 3 (nodeMotion.c) 3. Bogus index qualification with an INCLUDE column CREATE TABLE bogus_t (c0 boolean, c1 boolean); CREATE INDEX bogus_i ON bogus_t (c0) INCLUDE (c1); INSERT INTO bogus_t VALUES (true, true), (false, true), (true, false); SET optimizer = on; SELECT * FROM bogus_t WHERE c1; -- ERROR: bogus index qualification (nodeIndexscan.c) -- EXPLAIN shows "Index Cond: (c1 = true)" on bogus_i; c1 is not a key column 4. QD segfault when extended statistics do not cover all filtered columns CREATE TABLE t3 (c0 boolean, c1 text, c2 int) DISTRIBUTED BY (c0); INSERT INTO t3 SELECT (g%2=0), 'x'||g, g FROM generate_series(1,100) g; CREATE STATISTICS s0 (dependencies) ON c0, c1 FROM t3; -- covers c0, c1 only ANALYZE t3; SET optimizer = on; SELECT * FROM (SELECT ALL t3.c0 AS t3c0, t3.c1 AS t3c1, t3.c2 AS t3c2 FROM t3 WHERE (t3.c0) IS TRUE GROUP BY t3.c0, t3.c1, t3.c2 ORDER BY t3.c1) AS result WHERE result.t3c0 = TRUE AND result.t3c1 = '' AND result.t3c2 > 0; -- c2 not covered -- SIGSEGV in CExtendedStatsProcessor::ApplyCorrelatedStatsToScaleFactorFilterCalculation -- optimizer=off returns 0 rows 5. Selectivity outside [0, 1] under an outer join (assert build) CREATE TABLE m1(c0 inet); CREATE TABLE m2(c0 inet); INSERT INTO m2 VALUES ('88.147.138.141'), ('76.163.212.11'), ('214.10.65.144'); ANALYZE m1, m2; SELECT COUNT(*) FROM ONLY m1 LEFT OUTER JOIN m2 ON true WHERE (m1.c0 IS NOT NULL) OR (m2.c0 BETWEEN SYMMETRIC '75.175.243.19' AND '230.9.216.68'); -- FailedAssertion("pselec >= 0.0 && pselec <= 1.0", costsize.c) -- adjust_selectivity_for_nulltest() is Cloudberry code (gp_adjust_selectivity_for_outerjoins); -- upstream PostgreSQL has no equivalent assertion, a non-assert build just gets a bad estimate Try it yourself in about 10 minutes# Cloudberry with asserts + a demo cluster on port 7000 ./configure --enable-cassert --enable-debug <your usual flags> && make -j$(nproc) install make create-demo-cluster && source gpAux/gpdemo/gpdemo-env.sh createdb test # the postgres provider connects to "test" first # SQLancer (no recent Maven Central release, so build from main) git clone --depth 1 https://github.com/sqlancer/sqlancer && cd sqlancer && mvn -q package -DskipTests java -jar target/sqlancer-*.jar --num-threads 4 --num-queries 1000 --timeout-seconds 3600 \ --username gpadmin --password '' \ postgres --connection-url postgresql://localhost:7000/test \ --oracle NOREC --test-tablespaces false --test-collations false # also try --oracle QUERY_PARTITIONING (TLP). Failing cases land in ./logs/postgres/<db>.log # as a replayable script with the random seed in the header. For each one, re-run the # final query with optimizer=on and optimizer=off and compare. Motivation
What we have not done, so nobody over-reads the result: we used the stock PostgreSQL provider (no ImplementationRough shape of what "SQLancer runs continuously and files de-duplicated issues" would take. None of this is decided; it is a starting point for whoever picks it up. 1. A Cloudberry provider for SQLancerSQLancer has no Greenplum or Cloudberry provider today, but there is a close precedent: the Citus provider subclasses
Where should it live?
A practical note for any option: there is no recent Maven Central release of SQLancer, so CI would pin a git SHA and build the jar (about 2 minutes) or cache it by SHA. 2. A scheduled run
3. Triage and de-duplicationThree bug classes, three signatures:
Reporting can start small and grow: a nightly comment on one rolling tracking issue that a human triages, then automatic issue filing once the noise is understood. When automated: carry the signature in an HTML comment in the issue body, search existing issues by signature before filing, cap new issues at a few per run, keep a suppression file for known signatures, and always include the SQLancer seed and commit so a maintainer can replay exactly. Labels: 4. Regression protectionBoth fix PRs add the minimal reproducer to the regression suite; we would suggest keeping that habit for SQLancer-found bugs so the suite grows with the fuzzer. Fuzzing itself should never gate PRs (it is random and PR CI has enough to do). An optional Rollout / Adoption PlanWhat we will do
What we are hoping for: volunteers. Each piece below stands alone, so nobody has to sign up for all of it.
Questions
If this sounds reasonable and one or two people are interested, we will open a tracking issue with the four tasks above as |
All reactions
-
👍 2
Replies: 3 comments 1 reply
💯
All reactions
SQLancer is a great tool for us to discover potential bugs in Cloudberry. And I will continue working on deeper integration with Clouderry. I will also create a MR in sqlancer in the near future, and welcome everyone to run it with cludberry to find more issues.
All reactions
-
👍 1
Yep! Very useful tool.
Could you provide detailed instructions on how to launch it in the development environment?
It will be great to perform regular checks. But they should be done by a skilled developer. I do not believe in the results of auto-scans. They usually provide a lot of false positives.
How I see it, right now I am developing Anser (and, in fact, the same considerations apply to many other changes - for example, #1762). At some point, I will decide that I want to enable it for much broader query types. I will conduct some performance tests. However, I should also be sure that there are no other issues, such as wrong results or core dumps. I need good assistance to check, and SQLancer can help me to make sure everything is OK.
How to organize it - let's open an issue on the found bugs. The only subtle point here is that we should thoroughly describe the issue, make good examples of how to reproduce it, and what the expected behavior is. I am going to involve new developers in our community, and it will be a great task to start doing something. Of course, not all issues are simple; some of them are quite tricky. So what? Developing databases is not easy.
All reactions
-
👍 1
Maybe @roseduan could help provide more details on it.