Skip to content

Commit 5deab6f

Browse files
authored
Merge pull request #60 from ProxySQL/fix/shard-prune-pg-docs
feat: prune OR/range, pool PostgreSQL, 2PC stress, honest docs
2 parents 7e0a05f + ff941ac commit 5deab6f

21 files changed

Lines changed: 2250 additions & 227 deletions

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Trust the `Makefile` over prose. Extension recipes live in `CLAUDE.md`. `docs/su
77
- Parser: header-only templates in `include/sql_parser/` except `src/sql_parser/{arena,parser}.cpp`
88
- Engine: headers in `include/sql_engine/` (`operators/`, `functions/`, `rules/`); compiled files are the explicit `ENGINE_SRCS` list
99
- High-level API: `Session<D>` (`include/sql_engine/session.h`) — parse → plan → optimize → distribute → execute
10-
- Production remote path: `ThreadSafeMultiRemoteExecutor`, not the single-connection executors
10+
- Production remote path: `ThreadSafeMultiRemoteExecutor` (pooled MySQL **and** PostgreSQL), not the single-connection executors
1111
- All shard routing (SELECT prune and DML) goes through `ShardMap`. Do not add a private hash in the planner.
1212
- Backend URL / shard-spec parsing: `tool_config_parser` — do not add another copy in tools
1313
- Do not edit `third_party/`

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ echo "SELECT 1 + 2, UPPER('hello'), COALESCE(NULL, 42)" | ./sqlengine
9393
# Against a MySQL backend
9494
./sqlengine --backend "mysql://root:pass@127.0.0.1:3306/mydb?name=primary"
9595

96-
# Sharded across two backends
96+
# Sharded across two backends (2PC is on; optional --txn-log PATH)
9797
./sqlengine \
9898
--backend "mysql://root:pass@host1:3306/db?name=shard1" \
9999
--backend "mysql://root:pass@host2:3306/db?name=shard2" \
@@ -171,20 +171,20 @@ ResultSet rs = executor.execute(plan);
171171
#include "sql_engine/session.h"
172172
#include "sql_engine/thread_safe_executor.h"
173173
#include "sql_engine/shard_map.h"
174-
#include "sql_engine/local_txn.h"
174+
#include "sql_engine/distributed_txn.h"
175175

176-
// Backends (connection-pooled, thread-safe)
176+
// Backends (connection-pooled, thread-safe; MySQL or PostgreSQL)
177177
ThreadSafeMultiRemoteExecutor executor;
178178
executor.add_backend({.name = "shard1", .host = "h1", .port = 3306, ...});
179179
executor.add_backend({.name = "shard2", .host = "h2", .port = 3306, ...});
180180

181181
// Sharding policy: "users" is sharded on "id" across shard1, shard2
182182
ShardMap shards;
183-
shards.add_sharded_table("users", "id", {"shard1", "shard2"});
183+
shards.add_table({"users", "id", {{"shard1"}, {"shard2"}}});
184184

185-
// Catalog, transactions, session
185+
// Catalog + 2PC (required for atomic multi-shard DML)
186186
InMemoryCatalog catalog; /* ... add_table(...) ... */
187-
LocalTransactionManager txn;
187+
DistributedTransactionManager txn(executor);
188188
Session<Dialect::MySQL> session(catalog, txn);
189189
session.set_remote_executor(&executor);
190190
session.set_shard_map(&shards);
@@ -354,11 +354,11 @@ auto report = recovery.recover();
354354
355355
### Distributed execution
356356
357-
- **Shard routing** — shard-key lookups go to one backend; scatter queries go to all
358-
- **Distributed aggregation** — per-shard partial aggregates + coordinator merge (COUNT+SUM+MIN+MAX + AVG from SUM/COUNT)
359-
- **Distributed sort** — per-shard sort + coordinator merge
360-
- **Cross-shard joins** — hash-join coordinator; materialized subquery cache
361-
- **Cross-shard DML** — scatter INSERT/UPDATE/DELETE when no shard key; single-shard when key present
357+
- **Shard routing** — equality / `IN` / `OR` of equalities prune via `ShardMap`; RANGE also prunes `<`/`>`/`BETWEEN`. Placeholders scatter.
358+
- **Distributed aggregation** — per-shard partial aggregates + coordinator merge (`COUNT`/`SUM`/`MIN`/`MAX`/`AVG`). `COUNT(DISTINCT)` gathers then aggregates locally.
359+
- **Distributed sort** — per-shard sort + coordinator merge when keys are table columns
360+
- **Joins** — co-located same-key joins push down; otherwise gather both sides and join locally
361+
- **Cross-shard DML** — routed by `ShardMap`; missing/non-literal shard key and multi-table DML on shards fail closed
362362
- **Cross-shard INSERT ... SELECT** — source materialized, rows routed by destination shard key
363363
364364
### Transactions
@@ -372,10 +372,10 @@ auto report = recovery.recover();
372372
373373
### Backends & connectivity
374374
375-
- **MySQL** — libmysqlclient with pooled and single-connection paths, UTF-8, configurable timeouts
376-
- **PostgreSQL** — libpq with statement_timeout, UTC-normalized TIMESTAMPTZ handling
375+
- **MySQL** — libmysqlclient with pooled (`ThreadSafeMultiRemoteExecutor`) and single-connection paths
376+
- **PostgreSQL** — libpq pooled on the same executor, plus a single-connection path; `statement_timeout` and UTC TIMESTAMPTZ
377377
- **SSL/TLS** — `ssl_mode`, `ssl_ca`, `ssl_cert`, `ssl_key` configurable per backend for both dialects
378-
- **Connection pool** — thread-safe with health checks, reconnection, RAII `ConnectionGuard`
378+
- **Connection pool** — thread-safe per dialect, RAII checkout, poison-on-error
379379
- **MySQL wire-protocol server** — `mysql_server` speaks the MySQL protocol; backends are ParserSQL engines
380380
381381
### Thread-safety
@@ -388,7 +388,7 @@ auto report = recovery.recover();
388388
389389
| Tool | Build | Purpose |
390390
|---|---|---|
391-
| `sqlengine` | `make build-sqlengine` | Interactive SQL CLI; stdin, one-shot, or REPL; optional backends and sharding |
391+
| `sqlengine` | `make build-sqlengine` | Interactive SQL CLI; 2PC when `--backend` is set; optional `--txn-log` |
392392
| `mysql_server` | `make mysql-server` | MySQL wire-protocol server fronted by the ParserSQL engine |
393393
| `corpus_test` | `make build-corpus-test` | Read SQL from stdin/files, parse each, report OK/PARTIAL/ERROR |
394394
| `engine_stress_test` | `make engine-stress` | Direct-API engine stress test |

0 commit comments

Comments
 (0)