@volter/twin-planetscale 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +473 -0
- package/api/src/fetch.ts +50 -0
- package/api/src/generated/surface.gen.json +1 -0
- package/api/src/generated/ui.gen.json +1 -0
- package/api/src/index.ts +19 -0
- package/api/src/manifest.ts +136 -0
- package/api/src/screens/deploy-request.tsx +111 -0
- package/api/src/screens/service-tokens.tsx +141 -0
- package/api/src/screens/session.tsx +117 -0
- package/api/src/semantics/audit.ts +82 -0
- package/api/src/semantics/backups.ts +258 -0
- package/api/src/semantics/branches.ts +201 -0
- package/api/src/semantics/deploy-requests.ts +493 -0
- package/api/src/semantics/index.ts +371 -0
- package/api/src/semantics/shared.ts +141 -0
- package/api/src/semantics/time.ts +77 -0
- package/api/src/token-gate.ts +96 -0
- package/dist/api/src/fetch.d.ts +8 -0
- package/dist/api/src/fetch.js +51 -0
- package/dist/api/src/fetch.ts +50 -0
- package/dist/api/src/generated/surface.gen.json +1 -0
- package/dist/api/src/generated/ui.gen.json +1 -0
- package/dist/api/src/index.ts +19 -0
- package/dist/api/src/manifest.d.ts +2 -0
- package/dist/api/src/manifest.js +113 -0
- package/dist/api/src/manifest.ts +136 -0
- package/dist/api/src/screens/deploy-request.d.ts +7 -0
- package/dist/api/src/screens/deploy-request.js +106 -0
- package/dist/api/src/screens/deploy-request.tsx +111 -0
- package/dist/api/src/screens/service-tokens.d.ts +3 -0
- package/dist/api/src/screens/service-tokens.js +134 -0
- package/dist/api/src/screens/service-tokens.tsx +141 -0
- package/dist/api/src/screens/session.d.ts +11 -0
- package/dist/api/src/screens/session.js +108 -0
- package/dist/api/src/screens/session.tsx +117 -0
- package/dist/api/src/semantics/audit.d.ts +31 -0
- package/dist/api/src/semantics/audit.js +80 -0
- package/dist/api/src/semantics/audit.ts +82 -0
- package/dist/api/src/semantics/backups.d.ts +37 -0
- package/dist/api/src/semantics/backups.js +264 -0
- package/dist/api/src/semantics/backups.ts +258 -0
- package/dist/api/src/semantics/branches.d.ts +53 -0
- package/dist/api/src/semantics/branches.js +197 -0
- package/dist/api/src/semantics/branches.ts +201 -0
- package/dist/api/src/semantics/deploy-requests.d.ts +47 -0
- package/dist/api/src/semantics/deploy-requests.js +491 -0
- package/dist/api/src/semantics/deploy-requests.ts +493 -0
- package/dist/api/src/semantics/index.d.ts +20 -0
- package/dist/api/src/semantics/index.js +381 -0
- package/dist/api/src/semantics/index.ts +371 -0
- package/dist/api/src/semantics/shared.d.ts +36 -0
- package/dist/api/src/semantics/shared.js +132 -0
- package/dist/api/src/semantics/shared.ts +141 -0
- package/dist/api/src/semantics/time.d.ts +2 -0
- package/dist/api/src/semantics/time.js +81 -0
- package/dist/api/src/semantics/time.ts +77 -0
- package/dist/api/src/token-gate.d.ts +9 -0
- package/dist/api/src/token-gate.js +97 -0
- package/dist/api/src/token-gate.ts +96 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +61 -0
- package/dist/src/generated/surface.gen.json +1 -0
- package/dist/src/generated/ui.gen.json +1 -0
- package/dist/src/index.d.ts +26 -0
- package/dist/src/index.js +156 -0
- package/dist/src/manifest.d.ts +2 -0
- package/dist/src/manifest.js +41 -0
- package/dist/src/planetscale-budget.d.ts +78 -0
- package/dist/src/planetscale-budget.js +305 -0
- package/dist/src/planetscale-capabilities.d.ts +10 -0
- package/dist/src/planetscale-capabilities.js +3977 -0
- package/dist/src/planetscale-collation-weights.gen.d.ts +4 -0
- package/dist/src/planetscale-collation-weights.gen.js +12 -0
- package/dist/src/planetscale-collation.d.ts +70 -0
- package/dist/src/planetscale-collation.js +391 -0
- package/dist/src/planetscale-conformance.d.ts +8 -0
- package/dist/src/planetscale-conformance.js +213 -0
- package/dist/src/planetscale-connector.d.ts +150 -0
- package/dist/src/planetscale-connector.js +532 -0
- package/dist/src/planetscale-deploy.d.ts +26 -0
- package/dist/src/planetscale-deploy.js +235 -0
- package/dist/src/planetscale-information-schema.d.ts +32 -0
- package/dist/src/planetscale-information-schema.js +299 -0
- package/dist/src/planetscale-mysql.d.ts +33 -0
- package/dist/src/planetscale-mysql.js +547 -0
- package/dist/src/planetscale-roles.d.ts +11 -0
- package/dist/src/planetscale-roles.js +60 -0
- package/dist/src/planetscale-row.d.ts +12 -0
- package/dist/src/planetscale-row.js +39 -0
- package/dist/src/planetscale-server.d.ts +42 -0
- package/dist/src/planetscale-server.js +137 -0
- package/dist/src/planetscale-sql.d.ts +701 -0
- package/dist/src/planetscale-sql.js +7167 -0
- package/dist/src/planetscale-store.d.ts +126 -0
- package/dist/src/planetscale-store.js +827 -0
- package/dist/src/planetscale-twin.d.ts +48 -0
- package/dist/src/planetscale-twin.js +290 -0
- package/dist/src/planetscale-values.d.ts +139 -0
- package/dist/src/planetscale-values.js +719 -0
- package/dist/src/planetscale-wire.d.ts +110 -0
- package/dist/src/planetscale-wire.js +188 -0
- package/dist/src/semantics/psdb.d.ts +18 -0
- package/dist/src/semantics/psdb.js +30 -0
- package/package.json +58 -0
- package/src/cli.ts +58 -0
- package/src/generated/surface.gen.json +1 -0
- package/src/generated/ui.gen.json +1 -0
- package/src/index.ts +267 -0
- package/src/manifest.ts +60 -0
- package/src/planetscale-budget.ts +347 -0
- package/src/planetscale-capabilities.ts +3862 -0
- package/src/planetscale-collation-weights.gen.ts +13 -0
- package/src/planetscale-collation.ts +378 -0
- package/src/planetscale-conformance.ts +237 -0
- package/src/planetscale-connector.ts +571 -0
- package/src/planetscale-deploy.ts +197 -0
- package/src/planetscale-information-schema.ts +322 -0
- package/src/planetscale-mysql.ts +339 -0
- package/src/planetscale-roles.ts +71 -0
- package/src/planetscale-row.ts +43 -0
- package/src/planetscale-server.ts +162 -0
- package/src/planetscale-sql.ts +5957 -0
- package/src/planetscale-store.ts +869 -0
- package/src/planetscale-twin.ts +338 -0
- package/src/planetscale-values.ts +572 -0
- package/src/planetscale-wire.ts +274 -0
- package/src/semantics/psdb.ts +57 -0
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
import { type Collation, type DT } from './planetscale-collation.js';
|
|
2
|
+
/**
|
|
3
|
+
* One stored cell. ALWAYS the MySQL TEXT representation of the value, or null.
|
|
4
|
+
*
|
|
5
|
+
* This is not a shortcut — it is the wire's own model. psdb packs every column of every row as raw
|
|
6
|
+
* bytes with a per-column byte length (`row.lengths`/`row.values`), and the CLIENT casts those
|
|
7
|
+
* bytes by the field's declared type (dist/cast.js: INT32 → parseInt, FLOAT64 → parseFloat, JSON →
|
|
8
|
+
* JSON.parse, INT64 → left as a string, BLOB → Uint8Array). Storing text plus the column's type is
|
|
9
|
+
* therefore isomorphic to what the vendor stores as far as this protocol can ever observe.
|
|
10
|
+
*/
|
|
11
|
+
export type Cell = string | null;
|
|
12
|
+
/** Vitess `query.Type` enum names, as protojson spells them — the values `Field.type` carries. */
|
|
13
|
+
export declare const VITESS_TYPES: readonly ["NULL", "INT8", "UINT8", "INT16", "UINT16", "INT24", "UINT24", "INT32", "UINT32", "INT64", "UINT64", "FLOAT32", "FLOAT64", "TIMESTAMP", "DATE", "TIME", "DATETIME", "YEAR", "DECIMAL", "TEXT", "BLOB", "VARCHAR", "VARBINARY", "CHAR", "BINARY", "BIT", "ENUM", "SET", "GEOMETRY", "JSON", "EXPRESSION"];
|
|
14
|
+
export type VitessType = (typeof VITESS_TYPES)[number];
|
|
15
|
+
/** MySQL's binary collation id. `@planetscale/database`'s `cast` treats charset 63 as BINARY and
|
|
16
|
+
* returns a `Uint8Array` for it (dist/cast.js `isBinary`), so getting this wrong changes the
|
|
17
|
+
* JavaScript type an integrator receives. utf8mb4_general_ci is 45, which is what a text column
|
|
18
|
+
* on a PlanetScale database reports. */
|
|
19
|
+
export declare const BINARY_CHARSET = 63;
|
|
20
|
+
export declare const UTF8MB4_CHARSET = 45;
|
|
21
|
+
/** MySQL column flags, as `Field.flags` reports them (mysql_com.h). Only the ones this engine
|
|
22
|
+
* actually sets are named; the rest are deliberately absent rather than guessed. */
|
|
23
|
+
export declare const FLAG_NOT_NULL = 1;
|
|
24
|
+
export declare const FLAG_PRI_KEY = 2;
|
|
25
|
+
export declare const FLAG_UNIQUE_KEY = 4;
|
|
26
|
+
export declare const FLAG_BLOB = 16;
|
|
27
|
+
export declare const FLAG_UNSIGNED = 32;
|
|
28
|
+
export declare const FLAG_BINARY = 128;
|
|
29
|
+
export declare const FLAG_AUTO_INCREMENT = 512;
|
|
30
|
+
/** The published PlanetScale system limits this engine ENFORCES, with the page they came from.
|
|
31
|
+
* Live-read 2026-08-31 from planetscale.com/docs/reference/planetscale-system-limits. */
|
|
32
|
+
export declare const PLANETSCALE_LIMITS: {
|
|
33
|
+
readonly source: "https://planetscale.com/docs/reference/planetscale-system-limits (read 2026-08-31)";
|
|
34
|
+
/** "Per-query rows returned, updated, or deleted: 100k". */
|
|
35
|
+
readonly maxRowsPerQuery: 100000;
|
|
36
|
+
/** "Tables per database schema (including views): 2048". */
|
|
37
|
+
readonly maxTablesPerSchema: 2048;
|
|
38
|
+
/** "Columns per table: 1017". */
|
|
39
|
+
readonly maxColumnsPerTable: 1017;
|
|
40
|
+
};
|
|
41
|
+
/** The version string both wires report (`VERSION()`, `@@version`, the native handshake). */
|
|
42
|
+
export declare const SERVER_VERSION = "8.0.0-volter-twin";
|
|
43
|
+
/** MySQL 8's default sql_mode (manual 7.1.11), which PlanetScale runs with and this engine
|
|
44
|
+
* enforces: strict writes, no zero dates, division by zero an error on write, full GROUP BY. */
|
|
45
|
+
export declare const SQL_MODE = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION";
|
|
46
|
+
/**
|
|
47
|
+
* The system variables a client can read (`SELECT @@name`, `@@session.name`), with the values this
|
|
48
|
+
* engine's behaviour actually has: `lower_case_table_names` is 2 because table names keep their
|
|
49
|
+
* declared lettercase and compare case-insensitively; `transaction_isolation` is READ-COMMITTED
|
|
50
|
+
* because every statement reads the latest committed rows (no REPEATABLE READ snapshot). Any other
|
|
51
|
+
* name is MySQL's errno 1193.
|
|
52
|
+
*/
|
|
53
|
+
export declare const SYSTEM_VARIABLES: Record<string, string | number>;
|
|
54
|
+
/**
|
|
55
|
+
* A query failure, carrying BOTH halves of what PlanetScale actually returns: the vtrpc code that
|
|
56
|
+
* lands in `ExecuteResponse.error.code` and the MySQL errno/sqlstate that MySQL clients key on.
|
|
57
|
+
*
|
|
58
|
+
* WHAT IS DELIBERATELY NOT FABRICATED: a real PlanetScale error message is prefixed with the
|
|
59
|
+
* vttablet routing context — `target: <keyspace>.<shard>.<tablet_type>: vttablet: rpc error: code =
|
|
60
|
+
* … desc = ` — which encodes the keyspace, shard and tablet type of the deployment that answered.
|
|
61
|
+
* A local twin has no keyspace or shard, so inventing that prefix would be asserting a fact about a
|
|
62
|
+
* cluster that does not exist. The MySQL half (message text, `(errno N) (sqlstate S)`) IS real and
|
|
63
|
+
* is reproduced verbatim; `planetscale.errors.vttablet_prefix` files the omission as a todo.
|
|
64
|
+
*/
|
|
65
|
+
export declare class SqlError extends Error {
|
|
66
|
+
/** the vtrpc code, protojson-spelled (`NOT_FOUND`, `INVALID_ARGUMENT`, `ALREADY_EXISTS`, …). */
|
|
67
|
+
readonly code: string;
|
|
68
|
+
readonly errno: number;
|
|
69
|
+
readonly sqlState: string;
|
|
70
|
+
constructor(message: string,
|
|
71
|
+
/** the vtrpc code, protojson-spelled (`NOT_FOUND`, `INVALID_ARGUMENT`, `ALREADY_EXISTS`, …). */
|
|
72
|
+
code: string, errno: number, sqlState: string);
|
|
73
|
+
}
|
|
74
|
+
export declare const parseError: (position: number, near: string) => SqlError;
|
|
75
|
+
/**
|
|
76
|
+
* An operation this twin does not model. Vitess's own refusal for a statement its planner cannot
|
|
77
|
+
* build — the message begins `unsupported: ` and the vtrpc code is UNIMPLEMENTED. A twin MUST take
|
|
78
|
+
* this path rather than answering an empty result set: a fabricated `[]` reads to the caller as
|
|
79
|
+
* "the query ran and matched nothing", which is the exact fake-success the bar forbids.
|
|
80
|
+
*/
|
|
81
|
+
export declare const unsupported: (what: string) => SqlError;
|
|
82
|
+
export type ColumnDef = {
|
|
83
|
+
name: string;
|
|
84
|
+
/** the base type, uppercased and length-stripped: `VARCHAR`, `BIGINT`, `JSON`, … */
|
|
85
|
+
dataType: string;
|
|
86
|
+
/** the full MySQL rendering, as `Field.columnType` reports it: `varchar(255)`, `bigint unsigned`. */
|
|
87
|
+
columnType: string;
|
|
88
|
+
length: number | null;
|
|
89
|
+
unsigned: boolean;
|
|
90
|
+
nullable: boolean;
|
|
91
|
+
/** `undefined` = the column declared no DEFAULT (distinct from `DEFAULT NULL`, which is `null`). */
|
|
92
|
+
defaultValue?: Cell;
|
|
93
|
+
/** Was the DEFAULT written as a hex literal (`DEFAULT x'00ff'`)? Then it is already bytes and
|
|
94
|
+
* `execCreateTable` must not UTF-8-encode it. */
|
|
95
|
+
defaultIsBinaryLiteral?: boolean;
|
|
96
|
+
/** `DEFAULT CURRENT_TIMESTAMP[(fsp)]`: the fractional-seconds precision. The value is read from
|
|
97
|
+
* the World clock (`ExecOptions.now`) when a row is inserted, never from the wall clock. */
|
|
98
|
+
defaultCurrentTimestamp?: number;
|
|
99
|
+
/** An expression default, `DEFAULT (expr)` (MySQL 8.0.13+): its text as COLUMN_DEFAULT reports it,
|
|
100
|
+
* with the literal value it evaluates to held in `defaultValue`. */
|
|
101
|
+
defaultExpression?: string;
|
|
102
|
+
autoIncrement: boolean;
|
|
103
|
+
primaryKey: boolean;
|
|
104
|
+
unique: boolean;
|
|
105
|
+
/** A character column's character set and collation, resolved at CREATE TABLE from the column's
|
|
106
|
+
* own `CHARACTER SET`/`COLLATE`/`BINARY`, else the table's, else the database default. */
|
|
107
|
+
charset?: string;
|
|
108
|
+
collation?: string;
|
|
109
|
+
/** Parse-time only: the column's `BINARY` attribute (its charset's _bin collation). */
|
|
110
|
+
binaryAttribute?: boolean;
|
|
111
|
+
/** Parse-time only: how the DEFAULT was written — a number literal, a string literal, or a
|
|
112
|
+
* parenthesised expression — which decides how CREATE TABLE converts it to the column's type. */
|
|
113
|
+
defaultLiteral?: 'number' | 'string' | 'expression';
|
|
114
|
+
};
|
|
115
|
+
/** One column of an index: its name, an optional prefix length and its direction. */
|
|
116
|
+
export type IndexPart = {
|
|
117
|
+
name: string;
|
|
118
|
+
length?: number;
|
|
119
|
+
desc?: boolean;
|
|
120
|
+
};
|
|
121
|
+
/** A non-unique secondary index. It changes access paths, not results — this engine has one access
|
|
122
|
+
* path (a scan) — but it is part of the catalog INFORMATION_SCHEMA.STATISTICS reports. */
|
|
123
|
+
export type IndexDef = {
|
|
124
|
+
name: string;
|
|
125
|
+
columns: IndexPart[];
|
|
126
|
+
type: 'BTREE' | 'FULLTEXT';
|
|
127
|
+
};
|
|
128
|
+
export type TableDef = {
|
|
129
|
+
name: string;
|
|
130
|
+
columns: ColumnDef[];
|
|
131
|
+
/** column names forming the PRIMARY KEY, in declaration order. Empty = no primary key. */
|
|
132
|
+
primaryKey: string[];
|
|
133
|
+
/** each UNIQUE constraint as `{ name, columns }` — the name is what errno 1062 reports. `parts`
|
|
134
|
+
* keeps each column's prefix length and direction for the catalog. */
|
|
135
|
+
uniques: Array<{
|
|
136
|
+
name: string;
|
|
137
|
+
columns: string[];
|
|
138
|
+
parts?: IndexPart[];
|
|
139
|
+
}>;
|
|
140
|
+
/** non-unique secondary and FULLTEXT indexes, in declaration order. */
|
|
141
|
+
indexes?: IndexDef[];
|
|
142
|
+
/** the table's declared default character set and collation (`DEFAULT CHARSET=… COLLATE=…`). */
|
|
143
|
+
charset?: string;
|
|
144
|
+
collation?: string;
|
|
145
|
+
/** the persisted AUTO_INCREMENT watermark. InnoDB 8.0 persists this across restarts, and so does
|
|
146
|
+
* this engine — which is also what stops a delete-then-insert from reusing a retired id. */
|
|
147
|
+
autoIncrement: number;
|
|
148
|
+
};
|
|
149
|
+
export type RowRec = {
|
|
150
|
+
/** the engine's internal row identity — never a column, never exposed on the wire. Minted from
|
|
151
|
+
* the MAX rowid present in the table (see `nextRowId`), never from a row COUNT: a count-mint
|
|
152
|
+
* collides the instant a row above the count exists, which is what silently clobbers a
|
|
153
|
+
* connector-pulled row. */
|
|
154
|
+
rowid: number;
|
|
155
|
+
cells: Record<string, Cell>;
|
|
156
|
+
};
|
|
157
|
+
/** The in-memory image one statement executes against. */
|
|
158
|
+
export type Database = {
|
|
159
|
+
/** the schema/database name — what `Field.database` reports and what errno 1146 names. */
|
|
160
|
+
name: string;
|
|
161
|
+
tables: Map<string, TableDef>;
|
|
162
|
+
rows: Map<string, RowRec[]>;
|
|
163
|
+
};
|
|
164
|
+
export declare const emptyDatabase: (name: string) => Database;
|
|
165
|
+
/** MySQL identifiers are case-insensitive on the platforms PlanetScale runs (lower_case_table_names
|
|
166
|
+
* = 1), so tables are keyed lowercase while the DECLARED spelling is preserved for display. */
|
|
167
|
+
export declare const tableKey: (name: string) => string;
|
|
168
|
+
export declare function findTable(db: Database, name: string): TableDef;
|
|
169
|
+
export declare function tableRows(db: Database, name: string): RowRec[];
|
|
170
|
+
/**
|
|
171
|
+
* Row ids at or above this belong to the CONNECTOR: a pulled row's id is derived from the real
|
|
172
|
+
* row's own identity (see `planetscale-connector.ts`, `pulledRowId`), not from its position in a
|
|
173
|
+
* `SELECT`, so a re-pull re-derives the same subject and a new real row gets a new one.
|
|
174
|
+
*
|
|
175
|
+
* The band exists because the two minting rules must never meet. §9 round one reproduced the
|
|
176
|
+
* collision end-to-end when they shared a namespace: pull 1 → rowids 1,2; a local INSERT →
|
|
177
|
+
* `nextRowId` = 3; pull 2, now returning a third real row, positionally assigned it rowid 3 as
|
|
178
|
+
* well — so it landed on the LOCAL row's subject, the real row was silently dropped, and `syncPull`
|
|
179
|
+
* reported deltas that changed nothing. Disjoint bands make that unrepresentable rather than
|
|
180
|
+
* unlikely.
|
|
181
|
+
*/
|
|
182
|
+
export declare const PULLED_ROWID_BASE: number;
|
|
183
|
+
/**
|
|
184
|
+
* The next LOCAL row id: MAX(existing local) + 1 — entropy-free, and collision-free in both
|
|
185
|
+
* directions. Pulled ids are skipped (they live in their own band, above), so a local mint can
|
|
186
|
+
* never land on a pulled row and a pull can never land on a local one.
|
|
187
|
+
*
|
|
188
|
+
* Never a row COUNT: a count-mint collides the moment a row above the count exists.
|
|
189
|
+
*/
|
|
190
|
+
export declare function nextRowId(rows: RowRec[]): number;
|
|
191
|
+
/**
|
|
192
|
+
* The mapping the whole protocol rests on. `@planetscale/database`'s `cast` (dist/cast.js) branches
|
|
193
|
+
* ONLY on `field.type` and `field.charset`, so this table decides what JavaScript type an
|
|
194
|
+
* integrator receives: INT32 → `number`, INT64 → `string` (bigint-safe, deliberately NOT cast),
|
|
195
|
+
* FLOAT64 → `number`, JSON → a parsed object, DATETIME/DATE/TIME → the raw string, anything with
|
|
196
|
+
* charset 63 → `Uint8Array`, everything else → a decoded UTF-8 string.
|
|
197
|
+
*/
|
|
198
|
+
export declare function vitessTypeFor(column: {
|
|
199
|
+
dataType: string;
|
|
200
|
+
unsigned: boolean;
|
|
201
|
+
}): VitessType;
|
|
202
|
+
export declare const isNumericVitessType: (t: VitessType) => boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Does a column of this vitess type report charset 63?
|
|
205
|
+
*
|
|
206
|
+
* TWO families do, and conflating them was a §9 round-one defect: the NUMERIC types report binary
|
|
207
|
+
* because MySQL has no collation for a number, and the BLOB/BINARY/VARBINARY family reports it
|
|
208
|
+
* because the value genuinely IS bytes. `@planetscale/database`'s `cast` branches on
|
|
209
|
+
* `field.charset === 63` alone (dist/cast.js, `isBinary`), so a VARBINARY expression served with
|
|
210
|
+
* charset 45 comes back to the caller as a mojibake STRING instead of a `Uint8Array` — and its
|
|
211
|
+
* payload is UTF-8-expanded, so the byte lengths are wrong too.
|
|
212
|
+
*/
|
|
213
|
+
export declare const isBinaryCharsetType: (t: VitessType) => boolean;
|
|
214
|
+
/**
|
|
215
|
+
* UTF-8-encode a string into this engine's byte-string form (one character per byte).
|
|
216
|
+
*
|
|
217
|
+
* A BINARY column's cell is always held this way, because that is what the wire packs verbatim and
|
|
218
|
+
* what `LENGTH()` counts. Text arriving for such a column is encoded HERE, at write time.
|
|
219
|
+
*/
|
|
220
|
+
export declare function toByteString(value: string): string;
|
|
221
|
+
/** The wire-shape of one result column. Mirrors `@planetscale/database`'s exported `Field`. */
|
|
222
|
+
export type Field = {
|
|
223
|
+
name: string;
|
|
224
|
+
type: VitessType;
|
|
225
|
+
table?: string;
|
|
226
|
+
orgTable?: string;
|
|
227
|
+
database?: string;
|
|
228
|
+
orgName?: string;
|
|
229
|
+
columnLength?: number;
|
|
230
|
+
charset?: number;
|
|
231
|
+
flags?: number;
|
|
232
|
+
columnType?: string;
|
|
233
|
+
/** Engine-internal, never on the wire: the collation a character result column compares under
|
|
234
|
+
* (a derived table's column or an IN subquery's operand reads it back). */
|
|
235
|
+
collation?: string;
|
|
236
|
+
};
|
|
237
|
+
export declare function fieldForColumn(db: Database, table: TableDef, column: ColumnDef, alias?: string): Field;
|
|
238
|
+
type TokKind = 'ident' | 'quoted-ident' | 'string' | 'number' | 'hex' | 'punct' | 'eof';
|
|
239
|
+
type Token = {
|
|
240
|
+
kind: TokKind;
|
|
241
|
+
value: string;
|
|
242
|
+
pos: number;
|
|
243
|
+
};
|
|
244
|
+
/** `noBackslashEscapes`: the session's NO_BACKSLASH_ESCAPES SQL mode ("Disable the use of the backslash character (\\) as
|
|
245
|
+
* an escape character within strings … backslash becomes an ordinary character like any other", manual 7.1.11). */
|
|
246
|
+
export declare function tokenize(sql: string, noBackslashEscapes?: boolean): Token[];
|
|
247
|
+
export type Expr =
|
|
248
|
+
/** `collation` is an introducer's (`_utf8mb4'x'`); a plain string literal takes the connection's. */
|
|
249
|
+
{
|
|
250
|
+
kind: 'literal';
|
|
251
|
+
value: Cell;
|
|
252
|
+
hint: VitessType;
|
|
253
|
+
collation?: string;
|
|
254
|
+
hex?: true;
|
|
255
|
+
}
|
|
256
|
+
/** `expr COLLATE name`: an EXPLICIT collation for the comparison it takes part in. */
|
|
257
|
+
| {
|
|
258
|
+
kind: 'collate';
|
|
259
|
+
arg: Expr;
|
|
260
|
+
collation: string;
|
|
261
|
+
} | {
|
|
262
|
+
kind: 'column';
|
|
263
|
+
table?: string;
|
|
264
|
+
name: string;
|
|
265
|
+
} | {
|
|
266
|
+
kind: 'star';
|
|
267
|
+
table?: string;
|
|
268
|
+
} | {
|
|
269
|
+
kind: 'unary';
|
|
270
|
+
op: 'NOT' | '-' | 'BINARY' | '~';
|
|
271
|
+
arg: Expr;
|
|
272
|
+
}
|
|
273
|
+
/** `x IS [NOT] TRUE | FALSE | UNKNOWN`: a truth test that is never NULL (manual 14.4.2). */
|
|
274
|
+
| {
|
|
275
|
+
kind: 'is';
|
|
276
|
+
arg: Expr;
|
|
277
|
+
value: 'TRUE' | 'FALSE' | 'UNKNOWN';
|
|
278
|
+
negated: boolean;
|
|
279
|
+
}
|
|
280
|
+
/** `x MEMBER OF (json_array)` (8.0.17+). */
|
|
281
|
+
| {
|
|
282
|
+
kind: 'member';
|
|
283
|
+
arg: Expr;
|
|
284
|
+
doc: Expr;
|
|
285
|
+
}
|
|
286
|
+
/** `CAST(x AS type)` / `CONVERT(x, type)` / `CONVERT(x USING charset)`: `to` is the target type. */
|
|
287
|
+
| {
|
|
288
|
+
kind: 'cast';
|
|
289
|
+
arg: Expr;
|
|
290
|
+
to: ColumnDef;
|
|
291
|
+
atTimeZone?: string;
|
|
292
|
+
} | {
|
|
293
|
+
kind: 'binary';
|
|
294
|
+
op: string;
|
|
295
|
+
left: Expr;
|
|
296
|
+
right: Expr;
|
|
297
|
+
} | {
|
|
298
|
+
kind: 'isnull';
|
|
299
|
+
arg: Expr;
|
|
300
|
+
negated: boolean;
|
|
301
|
+
}
|
|
302
|
+
/** `x IN (a, b)`, or `x IN (SELECT …)` when `subquery` is set (then `list` is empty). */
|
|
303
|
+
| {
|
|
304
|
+
kind: 'in';
|
|
305
|
+
arg: Expr;
|
|
306
|
+
list: Expr[];
|
|
307
|
+
negated: boolean;
|
|
308
|
+
subquery?: SelectStatement;
|
|
309
|
+
run?: SubqueryRun;
|
|
310
|
+
} | {
|
|
311
|
+
kind: 'like';
|
|
312
|
+
arg: Expr;
|
|
313
|
+
pattern: Expr;
|
|
314
|
+
negated: boolean;
|
|
315
|
+
escape?: Expr;
|
|
316
|
+
} | {
|
|
317
|
+
kind: 'between';
|
|
318
|
+
arg: Expr;
|
|
319
|
+
low: Expr;
|
|
320
|
+
high: Expr;
|
|
321
|
+
negated: boolean;
|
|
322
|
+
} | {
|
|
323
|
+
kind: 'call';
|
|
324
|
+
name: string;
|
|
325
|
+
args: Expr[];
|
|
326
|
+
star: boolean;
|
|
327
|
+
distinct?: boolean;
|
|
328
|
+
order?: OrderTerm[];
|
|
329
|
+
separator?: string;
|
|
330
|
+
}
|
|
331
|
+
/** A row constructor, `(a, b)`, compared element-wise (`=`, `<`, `IN`). */
|
|
332
|
+
| {
|
|
333
|
+
kind: 'row';
|
|
334
|
+
items: Expr[];
|
|
335
|
+
}
|
|
336
|
+
/** A scalar subquery, `(SELECT …)`. `run` is attached when the statement is bound for execution. */
|
|
337
|
+
| {
|
|
338
|
+
kind: 'subquery';
|
|
339
|
+
select: SelectStatement;
|
|
340
|
+
run?: SubqueryRun;
|
|
341
|
+
} | {
|
|
342
|
+
kind: 'exists';
|
|
343
|
+
select: SelectStatement;
|
|
344
|
+
run?: SubqueryRun;
|
|
345
|
+
} | {
|
|
346
|
+
kind: 'case';
|
|
347
|
+
operand?: Expr;
|
|
348
|
+
whens: Array<{
|
|
349
|
+
when: Expr;
|
|
350
|
+
then: Expr;
|
|
351
|
+
}>;
|
|
352
|
+
otherwise?: Expr;
|
|
353
|
+
}
|
|
354
|
+
/** A column BOUND to one source of the executing statement: `src` indexes the row tuple and
|
|
355
|
+
* `def` carries the column's declared type. Produced by binding, never by the parser. */
|
|
356
|
+
| {
|
|
357
|
+
kind: 'slot';
|
|
358
|
+
src: number;
|
|
359
|
+
col: string;
|
|
360
|
+
def: ColumnDef;
|
|
361
|
+
};
|
|
362
|
+
/** A bound subquery's evaluator: its result set, given the (outer) row it is evaluated for. */
|
|
363
|
+
export type SubqueryRun = ((row: EvalRow) => {
|
|
364
|
+
fields: Field[];
|
|
365
|
+
rows: Cell[][];
|
|
366
|
+
}) & {
|
|
367
|
+
/** the result columns, typed statically: known before (and without) running it. */
|
|
368
|
+
fields: () => Field[];
|
|
369
|
+
};
|
|
370
|
+
export type SelectItem = {
|
|
371
|
+
expr: Expr;
|
|
372
|
+
alias?: string;
|
|
373
|
+
text: string;
|
|
374
|
+
};
|
|
375
|
+
export type OrderTerm = {
|
|
376
|
+
expr: Expr;
|
|
377
|
+
desc: boolean;
|
|
378
|
+
};
|
|
379
|
+
/** One table in FROM: a stored table (or INFORMATION_SCHEMA view), or a DERIVED TABLE, a
|
|
380
|
+
* parenthesised subquery MySQL requires an alias for (errno 1248), materialised once and then read
|
|
381
|
+
* exactly as a table is. */
|
|
382
|
+
export type TableFactor = {
|
|
383
|
+
table: string;
|
|
384
|
+
schema?: string;
|
|
385
|
+
alias?: string;
|
|
386
|
+
} | {
|
|
387
|
+
derived: SelectStatement;
|
|
388
|
+
alias: string;
|
|
389
|
+
};
|
|
390
|
+
/** A joined table: `[INNER|CROSS] JOIN t [ON …]` or `LEFT [OUTER] JOIN t ON …`. */
|
|
391
|
+
export type JoinClause = {
|
|
392
|
+
kind: 'inner' | 'left';
|
|
393
|
+
factor: TableFactor;
|
|
394
|
+
on?: Expr;
|
|
395
|
+
};
|
|
396
|
+
/** One comma-separated FROM item: a table factor and the joins chained onto it. */
|
|
397
|
+
export type FromItem = {
|
|
398
|
+
factor: TableFactor;
|
|
399
|
+
joins: JoinClause[];
|
|
400
|
+
};
|
|
401
|
+
export type SelectStatement = {
|
|
402
|
+
kind: 'select';
|
|
403
|
+
items: SelectItem[];
|
|
404
|
+
distinct?: boolean;
|
|
405
|
+
from?: FromItem[];
|
|
406
|
+
where?: Expr;
|
|
407
|
+
groupBy?: Expr[];
|
|
408
|
+
having?: Expr;
|
|
409
|
+
order: OrderTerm[];
|
|
410
|
+
limit?: number;
|
|
411
|
+
offset?: number;
|
|
412
|
+
/** `FOR UPDATE` / `FOR SHARE` / `LOCK IN SHARE MODE`: a locking read. */
|
|
413
|
+
lock?: 'update' | 'share';
|
|
414
|
+
};
|
|
415
|
+
export type IsolationLevel = 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SERIALIZABLE';
|
|
416
|
+
export type Statement = SelectStatement
|
|
417
|
+
/** `alias`/`aliasColumns`: the new row's name in ON DUPLICATE KEY UPDATE (`VALUES … AS new [(a, b)]`, 8.0.19+). */
|
|
418
|
+
| {
|
|
419
|
+
kind: 'insert';
|
|
420
|
+
table: string;
|
|
421
|
+
columns: string[];
|
|
422
|
+
rows: Expr[][];
|
|
423
|
+
ignore: boolean;
|
|
424
|
+
onDuplicate?: Array<{
|
|
425
|
+
column: string;
|
|
426
|
+
value: Expr;
|
|
427
|
+
}>;
|
|
428
|
+
alias?: string;
|
|
429
|
+
aliasColumns?: string[];
|
|
430
|
+
} | {
|
|
431
|
+
kind: 'update';
|
|
432
|
+
table: string;
|
|
433
|
+
alias?: string;
|
|
434
|
+
set: Array<{
|
|
435
|
+
table?: string;
|
|
436
|
+
column: string;
|
|
437
|
+
value: Expr;
|
|
438
|
+
}>;
|
|
439
|
+
where?: Expr;
|
|
440
|
+
order: OrderTerm[];
|
|
441
|
+
limit?: number;
|
|
442
|
+
}
|
|
443
|
+
/** The multiple-table form: `UPDATE table_references SET [t.]col = expr, … [WHERE …]` (execUpdateMulti). */
|
|
444
|
+
| {
|
|
445
|
+
kind: 'update-multi';
|
|
446
|
+
from: FromItem[];
|
|
447
|
+
set: Array<{
|
|
448
|
+
table?: string;
|
|
449
|
+
column: string;
|
|
450
|
+
value: Expr;
|
|
451
|
+
}>;
|
|
452
|
+
where?: Expr;
|
|
453
|
+
} | {
|
|
454
|
+
kind: 'delete';
|
|
455
|
+
table: string;
|
|
456
|
+
where?: Expr;
|
|
457
|
+
order: OrderTerm[];
|
|
458
|
+
limit?: number;
|
|
459
|
+
} | {
|
|
460
|
+
kind: 'create-table';
|
|
461
|
+
table: string;
|
|
462
|
+
ifNotExists: boolean;
|
|
463
|
+
columns: ColumnDef[];
|
|
464
|
+
primaryKey: string[];
|
|
465
|
+
uniques: TableDef['uniques'];
|
|
466
|
+
indexes: IndexDef[];
|
|
467
|
+
charset?: string;
|
|
468
|
+
collation?: string;
|
|
469
|
+
} | {
|
|
470
|
+
kind: 'drop-table';
|
|
471
|
+
table: string;
|
|
472
|
+
ifExists: boolean;
|
|
473
|
+
} | {
|
|
474
|
+
kind: 'create-table-select';
|
|
475
|
+
table: string;
|
|
476
|
+
ifNotExists: boolean;
|
|
477
|
+
select: SelectStatement;
|
|
478
|
+
}
|
|
479
|
+
/** `ALTER TABLE t ADD [COLUMN] col_def [FIRST | AFTER c], …`: the one alteration this engine models. */
|
|
480
|
+
| {
|
|
481
|
+
kind: 'alter-add-columns';
|
|
482
|
+
table: string;
|
|
483
|
+
adds: Array<{
|
|
484
|
+
column: ColumnDef;
|
|
485
|
+
first?: boolean;
|
|
486
|
+
after?: string;
|
|
487
|
+
}>;
|
|
488
|
+
}
|
|
489
|
+
/** `ALTER TABLE t DROP [COLUMN] c, …`: a statement of drops only. */
|
|
490
|
+
| {
|
|
491
|
+
kind: 'alter-drop-columns';
|
|
492
|
+
table: string;
|
|
493
|
+
drops: string[];
|
|
494
|
+
} | {
|
|
495
|
+
kind: 'truncate';
|
|
496
|
+
table: string;
|
|
497
|
+
} | {
|
|
498
|
+
kind: 'show-tables';
|
|
499
|
+
} | {
|
|
500
|
+
kind: 'show-warnings';
|
|
501
|
+
} | {
|
|
502
|
+
kind: 'show-create-table';
|
|
503
|
+
table: string;
|
|
504
|
+
} | {
|
|
505
|
+
kind: 'describe';
|
|
506
|
+
table: string;
|
|
507
|
+
}
|
|
508
|
+
/** `SET [SESSION] TRANSACTION ISOLATION LEVEL …` / `SET [SESSION] TRANSACTION READ ONLY|WRITE`. */
|
|
509
|
+
| {
|
|
510
|
+
kind: 'set-transaction';
|
|
511
|
+
isolation?: IsolationLevel;
|
|
512
|
+
access?: 'READ WRITE' | 'READ ONLY';
|
|
513
|
+
scope: 'next' | 'session';
|
|
514
|
+
}
|
|
515
|
+
/** `SET @var := expr, …` and `SET [SESSION] sql_mode = expr`: the session's user variables and its SQL mode. */
|
|
516
|
+
| {
|
|
517
|
+
kind: 'set-vars';
|
|
518
|
+
user: Array<{
|
|
519
|
+
name: string;
|
|
520
|
+
value: Expr;
|
|
521
|
+
}>;
|
|
522
|
+
sqlMode?: Expr;
|
|
523
|
+
timeZone?: Expr;
|
|
524
|
+
names?: {
|
|
525
|
+
charset: string;
|
|
526
|
+
collation?: string;
|
|
527
|
+
};
|
|
528
|
+
} | {
|
|
529
|
+
kind: 'begin';
|
|
530
|
+
access?: 'READ WRITE' | 'READ ONLY';
|
|
531
|
+
} | {
|
|
532
|
+
kind: 'commit';
|
|
533
|
+
} | {
|
|
534
|
+
kind: 'rollback';
|
|
535
|
+
};
|
|
536
|
+
/** A stored table's character columns with their collations filled in from the table's (for a
|
|
537
|
+
* catalog written before columns carried their own). Lenient: an unrecognised stored name leaves
|
|
538
|
+
* the column to the database default rather than failing the whole image. */
|
|
539
|
+
export declare function withColumnCollations(table: TableDef): TableDef;
|
|
540
|
+
export declare function parseStatement(sql: string, sqlMode?: string): Statement;
|
|
541
|
+
/**
|
|
542
|
+
* Is this expression's RESULT binary — i.e. bytes rather than text?
|
|
543
|
+
*
|
|
544
|
+
* MySQL propagates binariness through an expression: `CONCAT(binary_col, …)` is binary, `UPPER` on
|
|
545
|
+
* a binary value is a no-op that stays binary, and a hex literal is binary. This ONE predicate
|
|
546
|
+
* governs storage (a source already in bytes is not re-encoded: `UPDATE b SET p = p` must not
|
|
547
|
+
* double the value), the result type and charset of an expression (charset 63, so the client
|
|
548
|
+
* returns a `Uint8Array`), and LENGTH / CHAR_LENGTH (bytes are counted, not re-encoded).
|
|
549
|
+
*
|
|
550
|
+
* `table` may be undefined (the constant-row `SELECT … FROM dual` path), where no column exists.
|
|
551
|
+
*/
|
|
552
|
+
export declare function staticBinary(e: Expr | undefined, table: TableDef | undefined): boolean;
|
|
553
|
+
/** A row under evaluation: the table's cells, plus the schema needed to type a comparison. A
|
|
554
|
+
* statement bound over several sources (joins, subqueries) reads its `slot` columns from `tuple`,
|
|
555
|
+
* one cell record per source, where a missing record is a LEFT JOIN's null extension. */
|
|
556
|
+
export type EvalRow = {
|
|
557
|
+
cells: Record<string, Cell>;
|
|
558
|
+
table?: TableDef;
|
|
559
|
+
database?: string;
|
|
560
|
+
tuple?: Tuple;
|
|
561
|
+
/** Evaluating a value an INSERT or UPDATE stores: under strict mode with ERROR_FOR_DIVISION_BY_ZERO
|
|
562
|
+
* (MySQL 8's default sql_mode) a division by zero there is errno 1365, not NULL. */
|
|
563
|
+
write?: boolean;
|
|
564
|
+
/** ON DUPLICATE KEY UPDATE: the row the INSERT proposed, read by `VALUES(col)` and through the
|
|
565
|
+
* row alias (`AS new` → `new.col`, or its column aliases, `AS new (m, n)` → `m`). */
|
|
566
|
+
values?: Record<string, Cell>;
|
|
567
|
+
valuesAlias?: string;
|
|
568
|
+
/** lowercased column alias → the table column it names (only with `AS new (m, n)`). */
|
|
569
|
+
valuesNames?: Map<string, string>;
|
|
570
|
+
/** The World clock's instant for the statement, which the clock functions read (INSERT values). */
|
|
571
|
+
now?: string;
|
|
572
|
+
};
|
|
573
|
+
export type Tuple = Array<Record<string, Cell> | undefined>;
|
|
574
|
+
/** MySQL `LIKE`: `%` = any sequence, `_` = any single character, `\` escapes both, every other
|
|
575
|
+
* character matched per character under `collation` (default: the connection's, utf8mb4_0900_ai_ci). */
|
|
576
|
+
export declare function likeMatch(value: string, pattern: string, collation?: Collation): boolean;
|
|
577
|
+
type Cls = 'int' | 'decimal' | 'double' | 'string' | 'binary' | 'temporal' | 'json' | 'null';
|
|
578
|
+
/** An operand of a comparison: its type, the class it compares in, and (for strings) the
|
|
579
|
+
* collation and derivation it brings. */
|
|
580
|
+
type Operand = {
|
|
581
|
+
cls: Cls;
|
|
582
|
+
dt: DT;
|
|
583
|
+
type: ColumnDef | null;
|
|
584
|
+
};
|
|
585
|
+
/** The key a UNIQUE/PRIMARY KEY value of `column` is enforced (and locked) under: two values
|
|
586
|
+
* collide exactly when the column's collation calls them equal (MySQL errno 1062). */
|
|
587
|
+
export declare function uniqueKeyPart(column: ColumnDef | undefined, value: string): string;
|
|
588
|
+
export declare function evalExpr(e: Expr, row: EvalRow): Cell;
|
|
589
|
+
/** The context of a value being stored: MySQL's messages name the column and the row. */
|
|
590
|
+
export type StoreContext = {
|
|
591
|
+
/** strict mode (MySQL 8's default STRICT_TRANS_TABLES): an invalid or out-of-range value is an
|
|
592
|
+
* error; without it (INSERT IGNORE) the value is adjusted to the nearest valid one. */
|
|
593
|
+
strict: boolean;
|
|
594
|
+
/** 1-based row number within the statement, as the messages print it. */
|
|
595
|
+
row: number;
|
|
596
|
+
table: string;
|
|
597
|
+
/** the World clock's instant (a TIME stored into a DATETIME takes today's date). */
|
|
598
|
+
now?: string;
|
|
599
|
+
};
|
|
600
|
+
/** The value a NOT NULL column takes when a non-strict write (INSERT IGNORE) supplies NULL: its
|
|
601
|
+
* type's implicit default (manual 13.6 "Data Type Default Values"). */
|
|
602
|
+
export declare function implicitDefault(col: ColumnDef): string;
|
|
603
|
+
/**
|
|
604
|
+
* Convert a value to `col`'s type for storage, as MySQL 8 does under its default sql_mode
|
|
605
|
+
* (STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE; manual 7.1.11 "Server SQL Modes", 13
|
|
606
|
+
* "Data Types"): integers rounded and range-checked (1264), strings that are not numbers refused
|
|
607
|
+
* (1366, or 1265 when only a prefix is numeric), DECIMAL rounded to its scale and padded, DOUBLE
|
|
608
|
+
* and FLOAT stored at their precision, temporals read from any accepted spelling and stored
|
|
609
|
+
* canonically at the column's fsp (1292 for an unreadable or zero date), JSON validated and stored
|
|
610
|
+
* normalized (3140), strings and binary strings checked against their length (1406), ENUM/SET
|
|
611
|
+
* checked against their members (1265). Without strict mode the value is adjusted instead.
|
|
612
|
+
*/
|
|
613
|
+
export declare function storeValue(col: ColumnDef, value: Cell, src: Operand, c: StoreContext): Cell;
|
|
614
|
+
/** What one statement produced, in engine terms. `planetscale-wire.ts` turns this into protojson. */
|
|
615
|
+
export type QueryOutcome = {
|
|
616
|
+
fields: Field[];
|
|
617
|
+
rows: Cell[][];
|
|
618
|
+
rowsAffected: number;
|
|
619
|
+
insertId: number;
|
|
620
|
+
/** subject writes the caller must persist. Empty for a pure read. */
|
|
621
|
+
writes: Write[];
|
|
622
|
+
/** the transaction verb this statement is, if any — the store owns the session bookkeeping. */
|
|
623
|
+
transaction?: 'begin' | 'commit' | 'rollback';
|
|
624
|
+
/** START TRANSACTION's access mode, or SET TRANSACTION's characteristics, for the store to hold. */
|
|
625
|
+
access?: 'READ WRITE' | 'READ ONLY';
|
|
626
|
+
setTransaction?: {
|
|
627
|
+
scope: 'next' | 'session';
|
|
628
|
+
access?: 'READ WRITE' | 'READ ONLY';
|
|
629
|
+
isolation?: IsolationLevel;
|
|
630
|
+
};
|
|
631
|
+
/** the stored rows a locking read (`FOR UPDATE` / `FOR SHARE`) returned; the store locks them. */
|
|
632
|
+
locked?: Array<{
|
|
633
|
+
table: string;
|
|
634
|
+
rowid: number;
|
|
635
|
+
}>;
|
|
636
|
+
/** the session's variables after a SET of them, for the caller to carry in the session it answers */
|
|
637
|
+
vars?: SessionVars;
|
|
638
|
+
};
|
|
639
|
+
export type Write = {
|
|
640
|
+
kind: 'table';
|
|
641
|
+
table: TableDef;
|
|
642
|
+
} | {
|
|
643
|
+
kind: 'drop-table';
|
|
644
|
+
table: string;
|
|
645
|
+
} | {
|
|
646
|
+
kind: 'row';
|
|
647
|
+
table: string;
|
|
648
|
+
row: RowRec;
|
|
649
|
+
} | {
|
|
650
|
+
kind: 'delete-row';
|
|
651
|
+
table: string;
|
|
652
|
+
rowid: number;
|
|
653
|
+
};
|
|
654
|
+
export type ExecOptions = {
|
|
655
|
+
/** `readOnly` twins refuse every write with MySQL's own errno 1290 — never a silent no-op. */
|
|
656
|
+
readOnly?: boolean;
|
|
657
|
+
/** The World clock's instant for this statement (ISO-8601). `DEFAULT CURRENT_TIMESTAMP` reads
|
|
658
|
+
* it; without it such a default is refused rather than taken from the wall clock. */
|
|
659
|
+
now?: string;
|
|
660
|
+
/** The statement runs in a READ ONLY transaction: a write is MySQL's errno 1792. */
|
|
661
|
+
transactionReadOnly?: boolean;
|
|
662
|
+
/** The session's user variables and SQL mode, as the client's session carries them (SessionVars). */
|
|
663
|
+
vars?: SessionVars;
|
|
664
|
+
};
|
|
665
|
+
/** A user variable's value and the type it holds (manual 11.4: "User variables can be assigned a value from a limited set
|
|
666
|
+
* of data types: integer, decimal, floating-point, binary or nonbinary string, or NULL value"), as a Vitess BindVariable
|
|
667
|
+
* types it. */
|
|
668
|
+
export type UserVariable = {
|
|
669
|
+
value: Cell;
|
|
670
|
+
type: VitessType;
|
|
671
|
+
};
|
|
672
|
+
/** What a session holds between statements: its user variables (by lowercased name; manual 11.4: "User variable names are
|
|
673
|
+
* not case-sensitive") and its sql_mode, when it set one. */
|
|
674
|
+
export type SessionVars = {
|
|
675
|
+
user: Record<string, UserVariable>;
|
|
676
|
+
sqlMode?: string;
|
|
677
|
+
collationConnection?: string;
|
|
678
|
+
timeZone?: string;
|
|
679
|
+
warnings?: Array<{
|
|
680
|
+
level: string;
|
|
681
|
+
code: number;
|
|
682
|
+
message: string;
|
|
683
|
+
}>;
|
|
684
|
+
};
|
|
685
|
+
export declare function execStatement(db: Database, stmt: Statement, opts?: ExecOptions): QueryOutcome;
|
|
686
|
+
export type SelectPlan = {
|
|
687
|
+
correlated: boolean;
|
|
688
|
+
/** the result columns, typed statically from the select list (no row is read to type them). */
|
|
689
|
+
fields: () => Field[];
|
|
690
|
+
execute: (outer: Tuple | undefined) => {
|
|
691
|
+
fields: Field[];
|
|
692
|
+
rows: Cell[][];
|
|
693
|
+
locked: Array<{
|
|
694
|
+
table: string;
|
|
695
|
+
rowid: number;
|
|
696
|
+
}>;
|
|
697
|
+
};
|
|
698
|
+
};
|
|
699
|
+
/** Parse and execute in one step — the entry point the store and every test use. */
|
|
700
|
+
export declare function runSql(db: Database, sql: string, opts?: ExecOptions): QueryOutcome;
|
|
701
|
+
export {};
|