# MySQL

Lightweight in-memory MySQL implementation speaking the real wire protocol.

| Key | Value |
|-----|-------|
| Port | 3306 |
| Protocol | Wire protocol (TCP) |
| Size | ~90 KB |
| Startup | < 200ms |

## Default Connection

```
mysql://parlel:parlel@localhost:3306/parlel
```

| Parameter | Value |
|-----------|-------|
| User | `parlel` |
| Password | `parlel` |
| Database | `parlel` |

## Supported SQL

### DDL

```sql
CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  email VARCHAR(255) NOT NULL,
  name VARCHAR(255),
  age INT DEFAULT 0,
  active BOOLEAN DEFAULT true
);

ALTER TABLE users ADD COLUMN role VARCHAR(50);
ALTER TABLE users DROP COLUMN role;
CREATE INDEX idx_users_email ON users (email);
CREATE UNIQUE INDEX idx_users_email_unique ON users (email);
DROP INDEX idx_users_email ON users;
TRUNCATE TABLE users;
DROP TABLE users;
```

### DML

```sql
INSERT INTO users (email, name) VALUES ('alice@test.com', 'Alice');
INSERT INTO users (email, name, age) VALUES ('bob@test.com', 'Bob', 30);

SELECT * FROM users;
SELECT name, email FROM users;
SELECT * FROM users WHERE id = 1;
SELECT * FROM users WHERE age > 25;
SELECT * FROM users WHERE name LIKE 'A%';
SELECT COUNT(*) FROM users;
SELECT * FROM users ORDER BY name ASC;
SELECT * FROM users LIMIT 10 OFFSET 5;
SELECT * FROM users WHERE id IN (1, 2, 3);
SELECT * FROM users WHERE age BETWEEN 20 AND 30;

UPDATE users SET name = 'Alice Updated' WHERE id = 1;
DELETE FROM users WHERE id = 1;
```

### Introspection

```sql
SELECT 1;
SHOW TABLES;
SHOW DATABASES;
DESCRIBE users;
EXPLAIN SELECT * FROM users;
```

### Transactions & sessions

```sql
BEGIN;                 -- or START TRANSACTION
COMMIT;
ROLLBACK;
SAVEPOINT sp1;
USE parlel;
SET autocommit = 1;
```

`GRANT`, `REVOKE`, `CREATE USER`, and `ALTER USER` are accepted as no-ops so
ORMs and migration tools that issue them do not error.

## Usage Examples

### Via SDK

```typescript
const instance = await startParallel({ services: [{ name: "mysql" }] });
const port = instance.services.get("mysql").port;

import mysql from "mysql2/promise";
const conn = await mysql.createConnection({
  host: "localhost",
  port,
  user: "parlel",
  password: "parlel",
  database: "parlel",
});

await conn.query("CREATE TABLE items (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100))");
await conn.query("INSERT INTO items (name) VALUES (?)", ["Widget"]);
const [rows] = await conn.query("SELECT * FROM items");
```

### Via CLI + mysql client

```bash
parlel up mysql        # starts on the default port 3306
mysql -h 127.0.0.1 -P 3306 -u parlel -pparlel parlel
parlel down mysql
```

## Access via MCP (Parlel Sandbox)

When MySQL runs inside a Parlel sandbox, drive it through the sandbox's MCP
endpoint with the `parlel_execute` tool. Pass raw SQL as `command` (multiple
statements may be separated by `;`):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "parlel_execute",
    "arguments": {
      "service": "mysql",
      "command": "CREATE TABLE t (id INT, name VARCHAR(50)); INSERT INTO t (id, name) VALUES (1, 'Ada'); SELECT * FROM t;"
    }
  }
}
```

Each statement returns `{ statement, fields, rows, error }`.

## Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

| Feature | Status |
|---------|--------|
| CRUD (`INSERT`/`SELECT`/`UPDATE`/`DELETE`) | ✅ Supported |
| `WHERE` with numeric-aware `=` `!=` `<` `>` `<=` `>=`, `AND`/`OR` | ✅ Supported |
| `IN (...)` / `NOT IN`, `BETWEEN`, `LIKE`, `IS [NOT] NULL` | ✅ Supported |
| `ORDER BY` (numeric + text, `ASC`/`DESC`), `LIMIT` | ✅ Supported |
| Transactions (`BEGIN`/`COMMIT`/`ROLLBACK`) | ◐ Accepted (no isolation enforcement) |
| Indexes / foreign keys | ◐ Accepted (not physically enforced — results stay correct) |
| `JOIN` | ⟳ Roadmap — single-table queries only |
| Aggregates / `GROUP BY` | ⟳ Roadmap |
| Stored procedures / triggers | ⟳ Roadmap — not executed |
