[Proposal] Continuous SQLancer fuzzing for Cloudberry (5 bugs from a first run, looking for volunteers) #1952
Replies: 3 comments
|
💯 |
|
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. |
|
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. |
Uh oh!
There was an error while loading. Please reload this page.
Proposers
@roseduan, @my-ship-it
Proposal Status
Under Discussion
Abstract
Hi all,
@roseduan and I recently pointed SQLancer at Cloudberry
mainto see what would happen. Using the stock PostgreSQL provider and no Cloudberry-specific tuning, a few hours of fuzzing surfaced 5 distinct bugs: one silent wrong result, two internal ERRORs, one backend segfault, and one assertion failure. Rose has fix PRs up for two of them, and the other three are filed as issues below.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
SELECT DISTINCT/GROUP BYon a nullableUNIQUEcolumn returns duplicate NULLs (silent wrong result)FULL JOINwhose one side is provably empty (e.g. a partitioned table with no partitions):ERROR: unexpected gang sizeINCLUDE-only index column is pushed into the Index Cond:ERROR: bogus index qualificationdependenciesstatistics object does not cover all filtered columnsORselectivity outside [0, 1] under aLEFT JOINtrips the assertion inadjust_selectivity_for_nulltest()(assert-enabled build)All five reproduce on current
mainwith a 3-segment demo cluster built with--enable-cassert.The run used the stock
postgresprovider against a 3-segment demo cluster built with--enable-cassert. Theoptimizer=onvsoffcomparison that exposed bug #1 was done by hand on the failing queries; SQLancer itself does not do that yet (see Implementation).Reproducers
1. ORCA drops the Agg for DISTINCT over a nullable UNIQUE column
2. Merge FULL JOIN with a provably-empty side
3. Bogus index qualification with an INCLUDE column
4. QD segfault when extended statistics do not cover all filtered columns
5. Selectivity outside [0, 1] under an outer join (assert build)
Try it yourself in about 10 minutes
Motivation
optimizer=onandoptimizer=offdisagree is a bug in one of them. SQLancer calls this idea Differential Query Plans (DQP, SIGMOD 2024) and implements it for MySQL/MariaDB/TiDB via optimizer hints. For Cloudberry it reduces to running each generated query under both settings and comparing result sets. Nobody is generating random queries to exercise that today.adjust_selectivity_for_nulltest), not inherited Postgres code. In other words, the code that is unique to this project is exactly the code that no one else is fuzzing for us. That also means there is probably more low-hanging fruit here, which is good news for anyone who enjoys optimizer bugs.optimizer=offleg on an assert build is essentially free coverage for the Postgres-planner side that we do not get otherwise.What we have not done, so nobody over-reads the result: we used the stock PostgreSQL provider (no
DISTRIBUTED BY, partitions, or AO/AOCO/PAX tables in the generated schemas), we comparedoptimizeron/off by hand, we have not measured the false-positive rate from syntax Cloudberry intentionally does not support, and we have no CI cost numbers yet.Implementation
Rough 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 SQLancer
SQLancer has no Greenplum or Cloudberry provider today, but there is a close precedent: the Citus provider subclasses
PostgresProvider/PostgresSchema/PostgresOptions(about 1.4k lines versus about 10k for PostgreSQL) and overrides only database creation and the expected-error lists. A Cloudberry provider would follow the same pattern and add:DISTRIBUTED BY (...)/DISTRIBUTED REPLICATED/DISTRIBUTED RANDOMLYon generated tables, partitioned tables, andUSING ao_row | ao_column | paxstorage.UNIQUE constraint must contain all columns in the table's distribution key,PRIMARY KEY and DISTRIBUTED RANDOMLY are incompatible,INSERT ON CONFLICT is not supported for appendoptimized relations, scrollable /WITH HOLDcursors,INHERITSwith replicated tables, and so on), plus Citus-style per-issue flags so known open bugs do not keep re-firing.OPTIMIZER_DIFForacle: execute each generated query underoptimizer=onandoff, compare sorted result sets. The TiDBDQPOracleis about 60 lines and a good template. It should also checkoptimizer_trace_fallbackso that ORCA falling back to the planner is not counted as agreement.--use-reducercan minimize its failures. Today the reducer works for the shared NoREC and TLP-WHERE oracles; other oracles and crashes need a small external delta-debugger (replay the log viapsql, drop statements greedily while the failure persists).Where should it live?
sqlancer/sqlanceris our preference: the Citus provider was contributed the same way, and it gives the work visibility beyond this project. Upstream asks for a GitHub Actions job that boots the DBMS, style-clean code, and does prune providers nobody maintains (CnosDB, TDEngine, StoneDB were removed), so (a) implies keeping a Cloudberry container image usable in their CI.src/test/sqlancer). SQLancer registers providers in its ownMain, so this effectively means vendoring a SQLancer fork; we mention it for completeness.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
optimizer=onand once withoff, via connection options. This already catches crashes and internal errors under each planner.OPTIMIZER_DIFForacle from section 1.schedule:workflow with a small matrix ({on, off} x {TLP, NoREC}), each job: debug build (or reuse that day'sbuild-dbg-cloudberryartifact), demo cluster, a time-boxed SQLancer run, then triage. Four jobs of roughly 4 hours each is a small fraction of the ASF Actions budget and stays under the 6-hour job limit. No self-hosted runners needed to start.3. Triage and de-duplication
Three bug classes, three signatures:
gdb -batch -ex bton the core (the existinganalyze_core_dumps.shalready does this), signature = hash of the top frames after droppingabort/ExceptionalCondition/raise.(file.c:NNN)location Cloudberry already appends, with literals stripped.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:
type: Orcaorplannerfrom the signature, plus asqlancerlabel if the community is happy to add one (or reusetype: Testing+help wanted).4. Regression protection
Both 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
run-sqlancerPR label that triggers a short fixed-seed run as a non-required check could be useful for ORCA PRs later.Rollout / Adoption Plan
What we will do
good first issueto someone who wants to get into ORCA.What we are hoping for: volunteers. Each piece below stands alone, so nobody has to sign up for all of it.
optimizeron and off, artifacts uploadedschedule/workflow_dispatchworkflow that produces logs on demandOPTIMIZER_DIFForacle plus reproducers for the reducerQuestions
sqlancerlabel be welcome, or should we reusetype: Testing+help wanted?If this sounds reasonable and one or two people are interested, we will open a tracking issue with the four tasks above as
help wantedsub-tasks after about a week of discussion. Either way, thanks for reading, and we hope the reproducers are useful on their own.All reactions